1557 lines
52 KiB
Dart
1557 lines
52 KiB
Dart
// Copyright 2017 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:convert';
|
|
import 'dart:ui';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
class TestTree extends Object with DiagnosticableTreeMixin {
|
|
TestTree({
|
|
this.name,
|
|
this.style,
|
|
this.children: const <TestTree>[],
|
|
this.properties: const <DiagnosticsNode>[],
|
|
});
|
|
|
|
final String name;
|
|
final List<TestTree> children;
|
|
final List<DiagnosticsNode> properties;
|
|
final DiagnosticsTreeStyle style;
|
|
|
|
@override
|
|
List<DiagnosticsNode> debugDescribeChildren() {
|
|
final List<DiagnosticsNode> children = <DiagnosticsNode>[];
|
|
for (TestTree child in this.children) {
|
|
children.add(child.toDiagnosticsNode(
|
|
name: 'child ${child.name}',
|
|
style: child.style,
|
|
));
|
|
}
|
|
return children;
|
|
}
|
|
|
|
@override
|
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
if (style != null)
|
|
properties.defaultDiagnosticsTreeStyle = style;
|
|
|
|
this.properties.forEach(properties.add);
|
|
}
|
|
}
|
|
|
|
enum ExampleEnum {
|
|
hello,
|
|
world,
|
|
deferToChild,
|
|
}
|
|
|
|
/// Encode and decode to JSON to make sure all objects in the JSON for the
|
|
/// [DiagnosticsNode] are valid JSON.
|
|
Map<String, Object> simulateJsonSerialization(DiagnosticsNode node) {
|
|
return JSON.decode(JSON.encode(node.toJsonMap()));
|
|
}
|
|
|
|
void validateNodeJsonSerialization(DiagnosticsNode node) {
|
|
validateNodeJsonSerializationHelper(simulateJsonSerialization(node), node);
|
|
}
|
|
|
|
void validateNodeJsonSerializationHelper(Map<String, Object> json, DiagnosticsNode node) {
|
|
expect(json['name'], equals(node.name));
|
|
expect(json['showSeparator'], equals(node.showSeparator));
|
|
expect(json['description'], equals(node.toDescription()));
|
|
expect(json['level'], equals(describeEnum(node.level)));
|
|
expect(json['showName'], equals(node.showName));
|
|
expect(json['emptyBodyDescription'], equals(node.emptyBodyDescription));
|
|
expect(json['style'], equals(describeEnum(node.style)));
|
|
final String valueToString = node is DiagnosticsProperty ? node.valueToString() : node.value.toString();
|
|
expect(json['valueToString'], equals(valueToString));
|
|
expect(json['type'], equals(node.runtimeType.toString()));
|
|
expect(json['hasChildren'], equals(node.getChildren().isNotEmpty));
|
|
}
|
|
|
|
void validatePropertyJsonSerialization(DiagnosticsProperty<Object> property) {
|
|
validatePropertyJsonSerializationHelper(simulateJsonSerialization(property), property);
|
|
}
|
|
|
|
void validateStringPropertyJsonSerialization(StringProperty property) {
|
|
final Map<String, Object> json = simulateJsonSerialization(property);
|
|
expect(json['quoted'], equals(property.quoted));
|
|
validatePropertyJsonSerializationHelper(json, property);
|
|
}
|
|
|
|
void validateFlagPropertyJsonSerialization(FlagProperty property) {
|
|
final Map<String, Object> json = simulateJsonSerialization(property);
|
|
expect(json['ifTrue'], equals(property.ifTrue));
|
|
|
|
if (property.ifTrue != null) {
|
|
expect(json['ifTrue'], equals(property.ifTrue));
|
|
} else {
|
|
expect(json.containsKey('ifTrue'), isFalse);
|
|
}
|
|
|
|
if (property.ifFalse != null) {
|
|
expect(json['ifFalse'], property.ifFalse);
|
|
} else {
|
|
expect(json.containsKey('isFalse'), isFalse);
|
|
}
|
|
validatePropertyJsonSerializationHelper(json, property);
|
|
}
|
|
|
|
void validateDoublePropertyJsonSerialization(DoubleProperty property) {
|
|
final Map<String, Object> json = simulateJsonSerialization(property);
|
|
if (property.unit != null) {
|
|
expect(json['unit'], equals(property.unit));
|
|
} else {
|
|
expect(json.containsKey('unit'), isFalse);
|
|
}
|
|
|
|
expect(json['numberToString'], equals(property.numberToString()));
|
|
|
|
validatePropertyJsonSerializationHelper(json, property);
|
|
}
|
|
|
|
void validateObjectFlagPropertyJsonSerialization(ObjectFlagProperty<Object> property) {
|
|
final Map<String, Object> json = simulateJsonSerialization(property);
|
|
if (property.ifPresent != null) {
|
|
expect(json['ifPresent'], equals(property.ifPresent));
|
|
} else {
|
|
expect(json.containsKey('ifPresent'), isFalse);
|
|
}
|
|
|
|
validatePropertyJsonSerializationHelper(json, property);
|
|
}
|
|
|
|
void validateIterablePropertyJsonSerialization(IterableProperty<Object> property) {
|
|
final Map<String, Object> json = simulateJsonSerialization(property);
|
|
if (property.value != null) {
|
|
final List<Object> valuesJson = json['values'];
|
|
final List<String> expectedValues = property.value.map<String>((Object value) => value.toString()).toList();
|
|
expect(listEquals(valuesJson, expectedValues), isTrue);
|
|
} else {
|
|
expect(json.containsKey('values'), isFalse);
|
|
}
|
|
|
|
validatePropertyJsonSerializationHelper(json, property);
|
|
}
|
|
|
|
void validatePropertyJsonSerializationHelper(final Map<String, Object> json, DiagnosticsProperty<Object> property) {
|
|
if (property.defaultValue != kNoDefaultValue) {
|
|
expect(json['defaultValue'], equals(property.defaultValue.toString()));
|
|
} else {
|
|
expect(json.containsKey('defaultValue'), isFalse);
|
|
}
|
|
|
|
if (property.ifEmpty != null) {
|
|
expect(json['ifEmpty'], equals(property.ifEmpty));
|
|
} else {
|
|
expect(json.containsKey('ifEmpty'), isFalse);
|
|
}
|
|
if (property.ifNull != null) {
|
|
expect(json['ifNull'], equals(property.ifNull));
|
|
} else {
|
|
expect(json.containsKey('ifNull'), isFalse);
|
|
}
|
|
|
|
if (property.tooltip != null) {
|
|
expect(json['tooltip'], equals(property.tooltip));
|
|
} else {
|
|
expect(json.containsKey('tooltip'), isFalse);
|
|
}
|
|
|
|
expect(json['missingIfNull'], equals(property.missingIfNull));
|
|
if (property.exception != null) {
|
|
expect(json['exception'], equals(property.exception.toString()));
|
|
} else {
|
|
expect(json.containsKey('exception'), isFalse);
|
|
}
|
|
expect(json['propertyType'], equals(property.propertyType.toString()));
|
|
expect(json['valueToString'], equals(property.valueToString()));
|
|
expect(json.containsKey('defaultLevel'), isTrue);
|
|
if (property.value is Diagnosticable) {
|
|
expect(json['isDiagnosticableValue'], isTrue);
|
|
} else {
|
|
expect(json.containsKey('isDiagnosticableValue'), isFalse);
|
|
}
|
|
validateNodeJsonSerializationHelper(json, property);
|
|
}
|
|
|
|
void main() {
|
|
test('TreeDiagnosticsMixin control test', () async {
|
|
void goldenStyleTest(String description,
|
|
{DiagnosticsTreeStyle style,
|
|
DiagnosticsTreeStyle lastChildStyle,
|
|
String golden = ''}) {
|
|
final TestTree tree = new TestTree(children: <TestTree>[
|
|
new TestTree(name: 'node A', style: style),
|
|
new TestTree(
|
|
name: 'node B',
|
|
children: <TestTree>[
|
|
new TestTree(name: 'node B1', style: style),
|
|
new TestTree(name: 'node B2', style: style),
|
|
new TestTree(name: 'node B3', style: lastChildStyle ?? style),
|
|
],
|
|
style: style,
|
|
),
|
|
new TestTree(name: 'node C', style: lastChildStyle ?? style),
|
|
], style: lastChildStyle);
|
|
|
|
expect(tree, hasAGoodToStringDeep);
|
|
expect(
|
|
tree.toDiagnosticsNode(style: style).toStringDeep(),
|
|
equalsIgnoringHashCodes(golden),
|
|
reason: description,
|
|
);
|
|
validateNodeJsonSerialization(tree.toDiagnosticsNode());
|
|
}
|
|
|
|
goldenStyleTest(
|
|
'dense',
|
|
style: DiagnosticsTreeStyle.dense,
|
|
golden:
|
|
'TestTree#00000\n'
|
|
'├child node A: TestTree#00000\n'
|
|
'├child node B: TestTree#00000\n'
|
|
'│├child node B1: TestTree#00000\n'
|
|
'│├child node B2: TestTree#00000\n'
|
|
'│└child node B3: TestTree#00000\n'
|
|
'└child node C: TestTree#00000\n',
|
|
);
|
|
|
|
goldenStyleTest(
|
|
'sparse',
|
|
style: DiagnosticsTreeStyle.sparse,
|
|
golden:
|
|
'TestTree#00000\n'
|
|
' ├─child node A: TestTree#00000\n'
|
|
' ├─child node B: TestTree#00000\n'
|
|
' │ ├─child node B1: TestTree#00000\n'
|
|
' │ ├─child node B2: TestTree#00000\n'
|
|
' │ └─child node B3: TestTree#00000\n'
|
|
' └─child node C: TestTree#00000\n',
|
|
);
|
|
|
|
goldenStyleTest(
|
|
'dashed',
|
|
style: DiagnosticsTreeStyle.offstage,
|
|
golden:
|
|
'TestTree#00000\n'
|
|
' ╎╌child node A: TestTree#00000\n'
|
|
' ╎╌child node B: TestTree#00000\n'
|
|
' ╎ ╎╌child node B1: TestTree#00000\n'
|
|
' ╎ ╎╌child node B2: TestTree#00000\n'
|
|
' ╎ └╌child node B3: TestTree#00000\n'
|
|
' └╌child node C: TestTree#00000\n',
|
|
);
|
|
|
|
goldenStyleTest(
|
|
'leaf children',
|
|
style: DiagnosticsTreeStyle.sparse,
|
|
lastChildStyle: DiagnosticsTreeStyle.transition,
|
|
golden:
|
|
'TestTree#00000\n'
|
|
' ├─child node A: TestTree#00000\n'
|
|
' ├─child node B: TestTree#00000\n'
|
|
' │ ├─child node B1: TestTree#00000\n'
|
|
' │ ├─child node B2: TestTree#00000\n'
|
|
' │ ╘═╦══ child node B3 ═══\n'
|
|
' │ ║ TestTree#00000\n'
|
|
' │ ╚═══════════\n'
|
|
' ╘═╦══ child node C ═══\n'
|
|
' ║ TestTree#00000\n'
|
|
' ╚═══════════\n',
|
|
);
|
|
|
|
// You would never really want to make everything a leaf child like this
|
|
// but you can and still get a readable tree.
|
|
// The joint between single and double lines here is a bit clunky
|
|
// but we could correct that if there is any real use for this style.
|
|
goldenStyleTest(
|
|
'leaf',
|
|
style: DiagnosticsTreeStyle.transition,
|
|
golden:
|
|
'TestTree#00000:\n'
|
|
' ╞═╦══ child node A ═══\n'
|
|
' │ ║ TestTree#00000\n'
|
|
' │ ╚═══════════\n'
|
|
' ╞═╦══ child node B ═══\n'
|
|
' │ ║ TestTree#00000:\n'
|
|
' │ ║ ╞═╦══ child node B1 ═══\n'
|
|
' │ ║ │ ║ TestTree#00000\n'
|
|
' │ ║ │ ╚═══════════\n'
|
|
' │ ║ ╞═╦══ child node B2 ═══\n'
|
|
' │ ║ │ ║ TestTree#00000\n'
|
|
' │ ║ │ ╚═══════════\n'
|
|
' │ ║ ╘═╦══ child node B3 ═══\n'
|
|
' │ ║ ║ TestTree#00000\n'
|
|
' │ ║ ╚═══════════\n'
|
|
' │ ╚═══════════\n'
|
|
' ╘═╦══ child node C ═══\n'
|
|
' ║ TestTree#00000\n'
|
|
' ╚═══════════\n',
|
|
);
|
|
|
|
goldenStyleTest(
|
|
'whitespace',
|
|
style: DiagnosticsTreeStyle.whitespace,
|
|
golden:
|
|
'TestTree#00000:\n'
|
|
' child node A: TestTree#00000\n'
|
|
' child node B: TestTree#00000:\n'
|
|
' child node B1: TestTree#00000\n'
|
|
' child node B2: TestTree#00000\n'
|
|
' child node B3: TestTree#00000\n'
|
|
' child node C: TestTree#00000\n',
|
|
);
|
|
|
|
// Single line mode does not display children.
|
|
goldenStyleTest(
|
|
'single line',
|
|
style: DiagnosticsTreeStyle.singleLine,
|
|
golden: 'TestTree#00000',
|
|
);
|
|
});
|
|
|
|
test('TreeDiagnosticsMixin tree with properties test', () async {
|
|
void goldenStyleTest(String description, {
|
|
DiagnosticsTreeStyle style,
|
|
DiagnosticsTreeStyle lastChildStyle,
|
|
@required String golden,
|
|
}) {
|
|
final TestTree tree = new TestTree(
|
|
properties: <DiagnosticsNode>[
|
|
new StringProperty('stringProperty1', 'value1', quoted: false),
|
|
new DoubleProperty('doubleProperty1', 42.5),
|
|
new DoubleProperty('roundedProperty', 1.0 / 3.0),
|
|
new StringProperty('DO_NOT_SHOW', 'DO_NOT_SHOW', level: DiagnosticLevel.hidden, quoted: false),
|
|
new DiagnosticsProperty<Object>('DO_NOT_SHOW_NULL', null, defaultValue: null),
|
|
new DiagnosticsProperty<Object>('nullProperty', null),
|
|
new StringProperty('node_type', '<root node>', showName: false, quoted: false),
|
|
],
|
|
children: <TestTree>[
|
|
new TestTree(name: 'node A', style: style),
|
|
new TestTree(
|
|
name: 'node B',
|
|
properties: <DiagnosticsNode>[
|
|
new StringProperty('p1', 'v1', quoted: false),
|
|
new StringProperty('p2', 'v2', quoted: false),
|
|
],
|
|
children: <TestTree>[
|
|
new TestTree(name: 'node B1', style: style),
|
|
new TestTree(
|
|
name: 'node B2',
|
|
properties: <DiagnosticsNode>[new StringProperty('property1', 'value1', quoted: false)],
|
|
style: style,
|
|
),
|
|
new TestTree(
|
|
name: 'node B3',
|
|
properties: <DiagnosticsNode>[
|
|
new StringProperty('node_type', '<leaf node>', showName: false, quoted: false),
|
|
new IntProperty('foo', 42),
|
|
],
|
|
style: lastChildStyle ?? style,
|
|
),
|
|
],
|
|
style: style,
|
|
),
|
|
new TestTree(
|
|
name: 'node C',
|
|
properties: <DiagnosticsNode>[
|
|
new StringProperty('foo', 'multi\nline\nvalue!', quoted: false),
|
|
],
|
|
style: lastChildStyle ?? style,
|
|
),
|
|
],
|
|
style: lastChildStyle,
|
|
);
|
|
|
|
if (tree.style != DiagnosticsTreeStyle.singleLine)
|
|
expect(tree, hasAGoodToStringDeep);
|
|
|
|
expect(
|
|
tree.toDiagnosticsNode(style: style).toStringDeep(),
|
|
equalsIgnoringHashCodes(golden),
|
|
reason: description,
|
|
);
|
|
validateNodeJsonSerialization(tree.toDiagnosticsNode());
|
|
}
|
|
|
|
goldenStyleTest(
|
|
'sparse',
|
|
style: DiagnosticsTreeStyle.sparse,
|
|
golden:
|
|
'TestTree#00000\n'
|
|
' │ stringProperty1: value1\n'
|
|
' │ doubleProperty1: 42.5\n'
|
|
' │ roundedProperty: 0.3\n'
|
|
' │ nullProperty: null\n'
|
|
' │ <root node>\n'
|
|
' │\n'
|
|
' ├─child node A: TestTree#00000\n'
|
|
' ├─child node B: TestTree#00000\n'
|
|
' │ │ p1: v1\n'
|
|
' │ │ p2: v2\n'
|
|
' │ │\n'
|
|
' │ ├─child node B1: TestTree#00000\n'
|
|
' │ ├─child node B2: TestTree#00000\n'
|
|
' │ │ property1: value1\n'
|
|
' │ │\n'
|
|
' │ └─child node B3: TestTree#00000\n'
|
|
' │ <leaf node>\n'
|
|
' │ foo: 42\n'
|
|
' │\n'
|
|
' └─child node C: TestTree#00000\n'
|
|
' foo:\n'
|
|
' multi\n'
|
|
' line\n'
|
|
' value!\n',
|
|
);
|
|
|
|
goldenStyleTest(
|
|
'dense',
|
|
style: DiagnosticsTreeStyle.dense,
|
|
golden:
|
|
'TestTree#00000(stringProperty1: value1, doubleProperty1: 42.5, roundedProperty: 0.3, nullProperty: null, <root node>)\n'
|
|
'├child node A: TestTree#00000\n'
|
|
'├child node B: TestTree#00000(p1: v1, p2: v2)\n'
|
|
'│├child node B1: TestTree#00000\n'
|
|
'│├child node B2: TestTree#00000(property1: value1)\n'
|
|
'│└child node B3: TestTree#00000(<leaf node>, foo: 42)\n'
|
|
'└child node C: TestTree#00000(foo: multi\\nline\\nvalue!)\n',
|
|
);
|
|
|
|
goldenStyleTest(
|
|
'dashed',
|
|
style: DiagnosticsTreeStyle.offstage,
|
|
golden:
|
|
'TestTree#00000\n'
|
|
' │ stringProperty1: value1\n'
|
|
' │ doubleProperty1: 42.5\n'
|
|
' │ roundedProperty: 0.3\n'
|
|
' │ nullProperty: null\n'
|
|
' │ <root node>\n'
|
|
' │\n'
|
|
' ╎╌child node A: TestTree#00000\n'
|
|
' ╎╌child node B: TestTree#00000\n'
|
|
' ╎ │ p1: v1\n'
|
|
' ╎ │ p2: v2\n'
|
|
' ╎ │\n'
|
|
' ╎ ╎╌child node B1: TestTree#00000\n'
|
|
' ╎ ╎╌child node B2: TestTree#00000\n'
|
|
' ╎ ╎ property1: value1\n'
|
|
' ╎ ╎\n'
|
|
' ╎ └╌child node B3: TestTree#00000\n'
|
|
' ╎ <leaf node>\n'
|
|
' ╎ foo: 42\n'
|
|
' ╎\n'
|
|
' └╌child node C: TestTree#00000\n'
|
|
' foo:\n'
|
|
' multi\n'
|
|
' line\n'
|
|
' value!\n',
|
|
);
|
|
|
|
goldenStyleTest(
|
|
'leaf children',
|
|
style: DiagnosticsTreeStyle.sparse,
|
|
lastChildStyle: DiagnosticsTreeStyle.transition,
|
|
golden:
|
|
'TestTree#00000\n'
|
|
' │ stringProperty1: value1\n'
|
|
' │ doubleProperty1: 42.5\n'
|
|
' │ roundedProperty: 0.3\n'
|
|
' │ nullProperty: null\n'
|
|
' │ <root node>\n'
|
|
' │\n'
|
|
' ├─child node A: TestTree#00000\n'
|
|
' ├─child node B: TestTree#00000\n'
|
|
' │ │ p1: v1\n'
|
|
' │ │ p2: v2\n'
|
|
' │ │\n'
|
|
' │ ├─child node B1: TestTree#00000\n'
|
|
' │ ├─child node B2: TestTree#00000\n'
|
|
' │ │ property1: value1\n'
|
|
' │ │\n'
|
|
' │ ╘═╦══ child node B3 ═══\n'
|
|
' │ ║ TestTree#00000:\n'
|
|
' │ ║ <leaf node>\n'
|
|
' │ ║ foo: 42\n'
|
|
' │ ╚═══════════\n'
|
|
' ╘═╦══ child node C ═══\n'
|
|
' ║ TestTree#00000:\n'
|
|
' ║ foo:\n'
|
|
' ║ multi\n'
|
|
' ║ line\n'
|
|
' ║ value!\n'
|
|
' ╚═══════════\n',
|
|
);
|
|
|
|
// You would never really want to make everything a transition child like
|
|
// this but you can and still get a readable tree.
|
|
goldenStyleTest(
|
|
'transition',
|
|
style: DiagnosticsTreeStyle.transition,
|
|
golden:
|
|
'TestTree#00000:\n'
|
|
' stringProperty1: value1\n'
|
|
' doubleProperty1: 42.5\n'
|
|
' roundedProperty: 0.3\n'
|
|
' nullProperty: null\n'
|
|
' <root node>\n'
|
|
' ╞═╦══ child node A ═══\n'
|
|
' │ ║ TestTree#00000\n'
|
|
' │ ╚═══════════\n'
|
|
' ╞═╦══ child node B ═══\n'
|
|
' │ ║ TestTree#00000:\n'
|
|
' │ ║ p1: v1\n'
|
|
' │ ║ p2: v2\n'
|
|
' │ ║ ╞═╦══ child node B1 ═══\n'
|
|
' │ ║ │ ║ TestTree#00000\n'
|
|
' │ ║ │ ╚═══════════\n'
|
|
' │ ║ ╞═╦══ child node B2 ═══\n'
|
|
' │ ║ │ ║ TestTree#00000:\n'
|
|
' │ ║ │ ║ property1: value1\n'
|
|
' │ ║ │ ╚═══════════\n'
|
|
' │ ║ ╘═╦══ child node B3 ═══\n'
|
|
' │ ║ ║ TestTree#00000:\n'
|
|
' │ ║ ║ <leaf node>\n'
|
|
' │ ║ ║ foo: 42\n'
|
|
' │ ║ ╚═══════════\n'
|
|
' │ ╚═══════════\n'
|
|
' ╘═╦══ child node C ═══\n'
|
|
' ║ TestTree#00000:\n'
|
|
' ║ foo:\n'
|
|
' ║ multi\n'
|
|
' ║ line\n'
|
|
' ║ value!\n'
|
|
' ╚═══════════\n',
|
|
);
|
|
|
|
goldenStyleTest(
|
|
'whitespace',
|
|
style: DiagnosticsTreeStyle.whitespace,
|
|
golden:
|
|
'TestTree#00000:\n'
|
|
' stringProperty1: value1\n'
|
|
' doubleProperty1: 42.5\n'
|
|
' roundedProperty: 0.3\n'
|
|
' nullProperty: null\n'
|
|
' <root node>\n'
|
|
' child node A: TestTree#00000\n'
|
|
' child node B: TestTree#00000:\n'
|
|
' p1: v1\n'
|
|
' p2: v2\n'
|
|
' child node B1: TestTree#00000\n'
|
|
' child node B2: TestTree#00000:\n'
|
|
' property1: value1\n'
|
|
' child node B3: TestTree#00000:\n'
|
|
' <leaf node>\n'
|
|
' foo: 42\n'
|
|
' child node C: TestTree#00000:\n'
|
|
' foo:\n'
|
|
' multi\n'
|
|
' line\n'
|
|
' value!\n',
|
|
);
|
|
|
|
// Single line mode does not display children.
|
|
goldenStyleTest(
|
|
'single line',
|
|
style: DiagnosticsTreeStyle.singleLine,
|
|
golden: 'TestTree#00000(stringProperty1: value1, doubleProperty1: 42.5, roundedProperty: 0.3, nullProperty: null, <root node>)',
|
|
);
|
|
|
|
// There isn't anything interesting for this case as the children look the
|
|
// same with and without children. TODO(jacobr): this is an ugly test case.
|
|
// only difference is odd not clearly desirable density of B3 being right
|
|
// next to node C.
|
|
goldenStyleTest(
|
|
'single line last child',
|
|
style: DiagnosticsTreeStyle.sparse,
|
|
lastChildStyle: DiagnosticsTreeStyle.singleLine,
|
|
golden:
|
|
'TestTree#00000\n'
|
|
' │ stringProperty1: value1\n'
|
|
' │ doubleProperty1: 42.5\n'
|
|
' │ roundedProperty: 0.3\n'
|
|
' │ nullProperty: null\n'
|
|
' │ <root node>\n'
|
|
' │\n'
|
|
' ├─child node A: TestTree#00000\n'
|
|
' ├─child node B: TestTree#00000\n'
|
|
' │ │ p1: v1\n'
|
|
' │ │ p2: v2\n'
|
|
' │ │\n'
|
|
' │ ├─child node B1: TestTree#00000\n'
|
|
' │ ├─child node B2: TestTree#00000\n'
|
|
' │ │ property1: value1\n'
|
|
' │ │\n'
|
|
' │ └─child node B3: TestTree#00000(<leaf node>, foo: 42)\n'
|
|
' └─child node C: TestTree#00000(foo: multi\\nline\\nvalue!)\n',
|
|
);
|
|
});
|
|
|
|
test('transition test', () {
|
|
// Test multiple styles integrating together in the same tree due to using
|
|
// transition to go between styles that would otherwise be incompatible.
|
|
final TestTree tree = new TestTree(
|
|
style: DiagnosticsTreeStyle.sparse,
|
|
properties: <DiagnosticsNode>[
|
|
new StringProperty('stringProperty1', 'value1'),
|
|
],
|
|
children: <TestTree>[
|
|
new TestTree(
|
|
style: DiagnosticsTreeStyle.transition,
|
|
name: 'node transition',
|
|
properties: <DiagnosticsNode>[
|
|
new StringProperty('p1', 'v1'),
|
|
new TestTree(
|
|
properties: <DiagnosticsNode>[
|
|
new DiagnosticsProperty<bool>('survived', true),
|
|
],
|
|
).toDiagnosticsNode(name: 'tree property', style: DiagnosticsTreeStyle.whitespace),
|
|
],
|
|
children: <TestTree>[
|
|
new TestTree(name: 'dense child', style: DiagnosticsTreeStyle.dense),
|
|
new TestTree(
|
|
name: 'dense',
|
|
properties: <DiagnosticsNode>[new StringProperty('property1', 'value1')],
|
|
style: DiagnosticsTreeStyle.dense,
|
|
),
|
|
new TestTree(
|
|
name: 'node B3',
|
|
properties: <DiagnosticsNode>[
|
|
new StringProperty('node_type', '<leaf node>', showName: false, quoted: false),
|
|
new IntProperty('foo', 42),
|
|
],
|
|
style: DiagnosticsTreeStyle.dense
|
|
),
|
|
],
|
|
),
|
|
new TestTree(
|
|
name: 'node C',
|
|
properties: <DiagnosticsNode>[
|
|
new StringProperty('foo', 'multi\nline\nvalue!', quoted: false),
|
|
],
|
|
style: DiagnosticsTreeStyle.sparse,
|
|
),
|
|
],
|
|
);
|
|
|
|
expect(tree, hasAGoodToStringDeep);
|
|
expect(
|
|
tree.toDiagnosticsNode().toStringDeep(),
|
|
equalsIgnoringHashCodes(
|
|
'TestTree#00000\n'
|
|
' │ stringProperty1: "value1"\n'
|
|
' ╞═╦══ child node transition ═══\n'
|
|
' │ ║ TestTree#00000:\n'
|
|
' │ ║ p1: "v1"\n'
|
|
' │ ║ tree property: TestTree#00000:\n'
|
|
' │ ║ survived: true\n'
|
|
' │ ║ ├child dense child: TestTree#00000\n'
|
|
' │ ║ ├child dense: TestTree#00000(property1: "value1")\n'
|
|
' │ ║ └child node B3: TestTree#00000(<leaf node>, foo: 42)\n'
|
|
' │ ╚═══════════\n'
|
|
' └─child node C: TestTree#00000\n'
|
|
' foo:\n'
|
|
' multi\n'
|
|
' line\n'
|
|
' value!\n',
|
|
),
|
|
);
|
|
});
|
|
|
|
test('describeEnum test', () {
|
|
expect(describeEnum(ExampleEnum.hello), equals('hello'));
|
|
expect(describeEnum(ExampleEnum.world), equals('world'));
|
|
expect(describeEnum(ExampleEnum.deferToChild), equals('deferToChild'));
|
|
});
|
|
|
|
test('string property test', () {
|
|
expect(
|
|
new StringProperty('name', 'value', quoted: false).toString(),
|
|
equals('name: value'),
|
|
);
|
|
|
|
final StringProperty stringProperty = new StringProperty(
|
|
'name',
|
|
'value',
|
|
description: 'VALUE',
|
|
ifEmpty: '<hidden>',
|
|
quoted: false,
|
|
);
|
|
expect(stringProperty.toString(), equals('name: VALUE'));
|
|
validateStringPropertyJsonSerialization(stringProperty);
|
|
|
|
expect(
|
|
new StringProperty(
|
|
'name',
|
|
'value',
|
|
showName: false,
|
|
ifEmpty: '<hidden>',
|
|
quoted: false,
|
|
).toString(),
|
|
equals('value'),
|
|
);
|
|
|
|
expect(
|
|
new StringProperty('name', '', ifEmpty: '<hidden>').toString(),
|
|
equals('name: <hidden>'),
|
|
);
|
|
|
|
expect(
|
|
new StringProperty(
|
|
'name',
|
|
'',
|
|
ifEmpty: '<hidden>',
|
|
showName: false,
|
|
).toString(),
|
|
equals('<hidden>'),
|
|
);
|
|
|
|
expect(new StringProperty('name', null).isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(new StringProperty('name', 'value', level: DiagnosticLevel.hidden).isFiltered(DiagnosticLevel.info), isTrue);
|
|
expect(new StringProperty('name', null, defaultValue: null).isFiltered(DiagnosticLevel.info), isTrue);
|
|
final StringProperty quoted = new StringProperty(
|
|
'name',
|
|
'value',
|
|
quoted: true,
|
|
);
|
|
expect(quoted.toString(), equals('name: "value"'));
|
|
validateStringPropertyJsonSerialization(quoted);
|
|
|
|
expect(
|
|
new StringProperty('name', 'value', showName: false).toString(),
|
|
equals('"value"'),
|
|
);
|
|
|
|
expect(
|
|
new StringProperty(
|
|
'name',
|
|
null,
|
|
showName: false,
|
|
quoted: true,
|
|
).toString(),
|
|
equals('null'),
|
|
);
|
|
});
|
|
|
|
test('bool property test', () {
|
|
final DiagnosticsProperty<bool> trueProperty = new DiagnosticsProperty<bool>('name', true);
|
|
final DiagnosticsProperty<bool> falseProperty = new DiagnosticsProperty<bool>('name', false);
|
|
expect(trueProperty.toString(), equals('name: true'));
|
|
expect(trueProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(trueProperty.value, isTrue);
|
|
expect(falseProperty.toString(), equals('name: false'));
|
|
expect(falseProperty.value, isFalse);
|
|
expect(falseProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
validatePropertyJsonSerialization(trueProperty);
|
|
validatePropertyJsonSerialization(falseProperty);
|
|
final DiagnosticsProperty<bool> truthyProperty = new DiagnosticsProperty<bool>(
|
|
'name',
|
|
true,
|
|
description: 'truthy',
|
|
);
|
|
expect(
|
|
truthyProperty.toString(),
|
|
equals('name: truthy'),
|
|
);
|
|
validatePropertyJsonSerialization(truthyProperty);
|
|
expect(
|
|
new DiagnosticsProperty<bool>('name', true, showName: false).toString(),
|
|
equals('true'),
|
|
);
|
|
|
|
expect(new DiagnosticsProperty<bool>('name', null).isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(new DiagnosticsProperty<bool>('name', true, level: DiagnosticLevel.hidden).isFiltered(DiagnosticLevel.info), isTrue);
|
|
expect(new DiagnosticsProperty<bool>('name', null, defaultValue: null).isFiltered(DiagnosticLevel.info), isTrue);
|
|
final DiagnosticsProperty<bool> missingBool = new DiagnosticsProperty<bool>('name', null, ifNull: 'missing');
|
|
expect(
|
|
missingBool.toString(),
|
|
equals('name: missing'),
|
|
);
|
|
validatePropertyJsonSerialization(missingBool);
|
|
});
|
|
|
|
test('flag property test', () {
|
|
final FlagProperty trueFlag = new FlagProperty(
|
|
'myFlag',
|
|
value: true,
|
|
ifTrue: 'myFlag',
|
|
);
|
|
final FlagProperty falseFlag = new FlagProperty(
|
|
'myFlag',
|
|
value: false,
|
|
ifTrue: 'myFlag',
|
|
);
|
|
expect(trueFlag.toString(), equals('myFlag'));
|
|
validateFlagPropertyJsonSerialization(trueFlag);
|
|
validateFlagPropertyJsonSerialization(falseFlag);
|
|
|
|
expect(trueFlag.value, isTrue);
|
|
expect(falseFlag.value, isFalse);
|
|
|
|
expect(trueFlag.isFiltered(DiagnosticLevel.fine), isFalse);
|
|
expect(falseFlag.isFiltered(DiagnosticLevel.fine), isTrue);
|
|
});
|
|
|
|
test('property with tooltip test', () {
|
|
final DiagnosticsProperty<String> withTooltip = new DiagnosticsProperty<String>(
|
|
'name',
|
|
'value',
|
|
tooltip: 'tooltip',
|
|
);
|
|
expect(
|
|
withTooltip.toString(),
|
|
equals('name: value (tooltip)'),
|
|
);
|
|
expect(withTooltip.value, equals('value'));
|
|
expect(withTooltip.isFiltered(DiagnosticLevel.fine), isFalse);
|
|
validatePropertyJsonSerialization(withTooltip);
|
|
});
|
|
|
|
test('double property test', () {
|
|
final DoubleProperty doubleProperty = new DoubleProperty(
|
|
'name',
|
|
42.0,
|
|
);
|
|
expect(doubleProperty.toString(), equals('name: 42.0'));
|
|
expect(doubleProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(doubleProperty.value, equals(42.0));
|
|
validateDoublePropertyJsonSerialization(doubleProperty);
|
|
|
|
expect(new DoubleProperty('name', 1.3333).toString(), equals('name: 1.3'));
|
|
|
|
expect(new DoubleProperty('name', null).toString(), equals('name: null'));
|
|
expect(new DoubleProperty('name', null).isFiltered(DiagnosticLevel.info), equals(false));
|
|
|
|
expect(
|
|
new DoubleProperty('name', null, ifNull: 'missing').toString(),
|
|
equals('name: missing'),
|
|
);
|
|
|
|
final DoubleProperty doubleWithUnit = new DoubleProperty('name', 42.0, unit: 'px');
|
|
expect(doubleWithUnit.toString(), equals('name: 42.0px'));
|
|
validateDoublePropertyJsonSerialization(doubleWithUnit);
|
|
});
|
|
|
|
|
|
test('unsafe double property test', () {
|
|
final DoubleProperty safe = new DoubleProperty.lazy(
|
|
'name',
|
|
() => 42.0,
|
|
);
|
|
expect(safe.toString(), equals('name: 42.0'));
|
|
expect(safe.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(safe.value, equals(42.0));
|
|
validateDoublePropertyJsonSerialization(safe);
|
|
expect(
|
|
new DoubleProperty.lazy('name', () => 1.3333).toString(),
|
|
equals('name: 1.3'),
|
|
);
|
|
|
|
expect(
|
|
new DoubleProperty.lazy('name', () => null).toString(),
|
|
equals('name: null'),
|
|
);
|
|
expect(
|
|
new DoubleProperty.lazy('name', () => null).isFiltered(DiagnosticLevel.info),
|
|
equals(false),
|
|
);
|
|
|
|
final DoubleProperty throwingProperty = new DoubleProperty.lazy(
|
|
'name',
|
|
() => throw new FlutterError('Invalid constraints'),
|
|
);
|
|
// TODO(jacobr): it would be better if throwingProperty.object threw an
|
|
// exception.
|
|
expect(throwingProperty.value, isNull);
|
|
expect(throwingProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(
|
|
throwingProperty.toString(),
|
|
equals('name: EXCEPTION (FlutterError)'),
|
|
);
|
|
expect(throwingProperty.level, equals(DiagnosticLevel.error));
|
|
validateDoublePropertyJsonSerialization(throwingProperty);
|
|
});
|
|
|
|
test('percent property', () {
|
|
expect(
|
|
new PercentProperty('name', 0.4).toString(),
|
|
equals('name: 40.0%'),
|
|
);
|
|
|
|
final PercentProperty complexPercentProperty = new PercentProperty('name', 0.99, unit: 'invisible', tooltip: 'almost transparent');
|
|
expect(
|
|
complexPercentProperty.toString(),
|
|
equals('name: 99.0% invisible (almost transparent)'),
|
|
);
|
|
validateDoublePropertyJsonSerialization(complexPercentProperty);
|
|
|
|
expect(
|
|
new PercentProperty('name', null, unit: 'invisible', tooltip: '!').toString(),
|
|
equals('name: null (!)'),
|
|
);
|
|
|
|
expect(
|
|
new PercentProperty('name', 0.4).value,
|
|
0.4,
|
|
);
|
|
expect(
|
|
new PercentProperty('name', 0.0).toString(),
|
|
equals('name: 0.0%'),
|
|
);
|
|
expect(
|
|
new PercentProperty('name', -10.0).toString(),
|
|
equals('name: 0.0%'),
|
|
);
|
|
expect(
|
|
new PercentProperty('name', 1.0).toString(),
|
|
equals('name: 100.0%'),
|
|
);
|
|
expect(
|
|
new PercentProperty('name', 3.0).toString(),
|
|
equals('name: 100.0%'),
|
|
);
|
|
expect(
|
|
new PercentProperty('name', null).toString(),
|
|
equals('name: null'),
|
|
);
|
|
expect(
|
|
new PercentProperty(
|
|
'name',
|
|
null,
|
|
ifNull: 'missing',
|
|
).toString(),
|
|
equals('name: missing'),
|
|
);
|
|
expect(
|
|
new PercentProperty(
|
|
'name',
|
|
null,
|
|
ifNull: 'missing',
|
|
showName: false,
|
|
).toString(),
|
|
equals('missing'),
|
|
);
|
|
expect(
|
|
new PercentProperty(
|
|
'name',
|
|
0.5,
|
|
showName: false,
|
|
).toString(),
|
|
equals('50.0%'),
|
|
);
|
|
});
|
|
|
|
test('callback property test', () {
|
|
final Function onClick = () {};
|
|
final ObjectFlagProperty<Function> present = new ObjectFlagProperty<Function>(
|
|
'onClick',
|
|
onClick,
|
|
ifPresent: 'clickable',
|
|
);
|
|
final ObjectFlagProperty<Function> missing = new ObjectFlagProperty<Function>(
|
|
'onClick',
|
|
null,
|
|
ifPresent: 'clickable',
|
|
);
|
|
|
|
expect(present.toString(), equals('clickable'));
|
|
expect(present.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(present.value, equals(onClick));
|
|
validateObjectFlagPropertyJsonSerialization(present);
|
|
expect(missing.toString(), equals('onClick: null'));
|
|
expect(missing.isFiltered(DiagnosticLevel.fine), isTrue);
|
|
validateObjectFlagPropertyJsonSerialization(missing);
|
|
});
|
|
|
|
test('missing callback property test', () {
|
|
void onClick() { }
|
|
|
|
final ObjectFlagProperty<Function> present = new ObjectFlagProperty<Function>(
|
|
'onClick',
|
|
onClick,
|
|
ifNull: 'disabled',
|
|
);
|
|
final ObjectFlagProperty<Function> missing = new ObjectFlagProperty<Function>(
|
|
'onClick',
|
|
null,
|
|
ifNull: 'disabled',
|
|
);
|
|
|
|
expect(present.toString(), equals('onClick: Closure: () => void'));
|
|
expect(present.isFiltered(DiagnosticLevel.fine), isTrue);
|
|
expect(present.value, equals(onClick));
|
|
expect(missing.toString(), equals('disabled'));
|
|
expect(missing.isFiltered(DiagnosticLevel.info), isFalse);
|
|
validateObjectFlagPropertyJsonSerialization(present);
|
|
validateObjectFlagPropertyJsonSerialization(missing);
|
|
});
|
|
|
|
test('describe bool property', () {
|
|
final FlagProperty yes = new FlagProperty(
|
|
'name',
|
|
value: true,
|
|
ifTrue: 'YES',
|
|
ifFalse: 'NO',
|
|
showName: true,
|
|
);
|
|
final FlagProperty no = new FlagProperty(
|
|
'name',
|
|
value: false,
|
|
ifTrue: 'YES',
|
|
ifFalse: 'NO',
|
|
showName: true,
|
|
);
|
|
expect(yes.toString(), equals('name: YES'));
|
|
expect(yes.level, equals(DiagnosticLevel.info));
|
|
expect(yes.value, isTrue);
|
|
validateFlagPropertyJsonSerialization(yes);
|
|
expect(no.toString(), equals('name: NO'));
|
|
expect(no.level, equals(DiagnosticLevel.info));
|
|
expect(no.value, isFalse);
|
|
validateFlagPropertyJsonSerialization(no);
|
|
|
|
expect(
|
|
new FlagProperty(
|
|
'name',
|
|
value: true,
|
|
ifTrue: 'YES',
|
|
ifFalse: 'NO',
|
|
).toString(),
|
|
equals('YES'),
|
|
);
|
|
|
|
expect(
|
|
new FlagProperty(
|
|
'name',
|
|
value: false,
|
|
ifTrue: 'YES',
|
|
ifFalse: 'NO',
|
|
).toString(),
|
|
equals('NO'),
|
|
);
|
|
|
|
expect(
|
|
new FlagProperty(
|
|
'name',
|
|
value: true,
|
|
ifTrue: 'YES',
|
|
ifFalse: 'NO',
|
|
level: DiagnosticLevel.hidden,
|
|
showName: true,
|
|
).level,
|
|
equals(DiagnosticLevel.hidden),
|
|
);
|
|
});
|
|
|
|
test('enum property test', () {
|
|
final EnumProperty<ExampleEnum> hello = new EnumProperty<ExampleEnum>(
|
|
'name',
|
|
ExampleEnum.hello,
|
|
);
|
|
final EnumProperty<ExampleEnum> world = new EnumProperty<ExampleEnum>(
|
|
'name',
|
|
ExampleEnum.world,
|
|
);
|
|
final EnumProperty<ExampleEnum> deferToChild = new EnumProperty<ExampleEnum>(
|
|
'name',
|
|
ExampleEnum.deferToChild,
|
|
);
|
|
final EnumProperty<ExampleEnum> nullEnum = new EnumProperty<ExampleEnum>(
|
|
'name',
|
|
null,
|
|
);
|
|
expect(hello.level, equals(DiagnosticLevel.info));
|
|
expect(hello.value, equals(ExampleEnum.hello));
|
|
expect(hello.toString(), equals('name: hello'));
|
|
validatePropertyJsonSerialization(hello);
|
|
|
|
expect(world.level, equals(DiagnosticLevel.info));
|
|
expect(world.value, equals(ExampleEnum.world));
|
|
expect(world.toString(), equals('name: world'));
|
|
validatePropertyJsonSerialization(world);
|
|
|
|
expect(deferToChild.level, equals(DiagnosticLevel.info));
|
|
expect(deferToChild.value, equals(ExampleEnum.deferToChild));
|
|
expect(deferToChild.toString(), equals('name: deferToChild'));
|
|
validatePropertyJsonSerialization(deferToChild);
|
|
|
|
expect(nullEnum.level, equals(DiagnosticLevel.info));
|
|
expect(nullEnum.value, isNull);
|
|
expect(nullEnum.toString(), equals('name: null'));
|
|
validatePropertyJsonSerialization(nullEnum);
|
|
|
|
final EnumProperty<ExampleEnum> matchesDefault = new EnumProperty<ExampleEnum>(
|
|
'name',
|
|
ExampleEnum.hello,
|
|
defaultValue: ExampleEnum.hello,
|
|
);
|
|
expect(matchesDefault.toString(), equals('name: hello'));
|
|
expect(matchesDefault.value, equals(ExampleEnum.hello));
|
|
expect(matchesDefault.isFiltered(DiagnosticLevel.info), isTrue);
|
|
validatePropertyJsonSerialization(matchesDefault);
|
|
|
|
expect(
|
|
new EnumProperty<ExampleEnum>(
|
|
'name',
|
|
ExampleEnum.hello,
|
|
level: DiagnosticLevel.hidden,
|
|
).level,
|
|
equals(DiagnosticLevel.hidden),
|
|
);
|
|
});
|
|
|
|
test('int property test', () {
|
|
final IntProperty regular = new IntProperty(
|
|
'name',
|
|
42,
|
|
);
|
|
expect(regular.toString(), equals('name: 42'));
|
|
expect(regular.value, equals(42));
|
|
expect(regular.level, equals(DiagnosticLevel.info));
|
|
|
|
final IntProperty nullValue = new IntProperty(
|
|
'name',
|
|
null,
|
|
);
|
|
expect(nullValue.toString(), equals('name: null'));
|
|
expect(nullValue.value, isNull);
|
|
expect(nullValue.level, equals(DiagnosticLevel.info));
|
|
|
|
final IntProperty hideNull = new IntProperty(
|
|
'name',
|
|
null,
|
|
defaultValue: null,
|
|
);
|
|
expect(hideNull.toString(), equals('name: null'));
|
|
expect(hideNull.value, isNull);
|
|
expect(hideNull.isFiltered(DiagnosticLevel.info), isTrue);
|
|
|
|
final IntProperty nullDescription = new IntProperty(
|
|
'name',
|
|
null,
|
|
ifNull: 'missing',
|
|
);
|
|
expect(nullDescription.toString(), equals('name: missing'));
|
|
expect(nullDescription.value, isNull);
|
|
expect(nullDescription.level, equals(DiagnosticLevel.info));
|
|
|
|
final IntProperty hideName = new IntProperty(
|
|
'name',
|
|
42,
|
|
showName: false,
|
|
);
|
|
expect(hideName.toString(), equals('42'));
|
|
expect(hideName.value, equals(42));
|
|
expect(hideName.level, equals(DiagnosticLevel.info));
|
|
|
|
final IntProperty withUnit = new IntProperty(
|
|
'name',
|
|
42,
|
|
unit: 'pt',
|
|
);
|
|
expect(withUnit.toString(), equals('name: 42pt'));
|
|
expect(withUnit.value, equals(42));
|
|
expect(withUnit.level, equals(DiagnosticLevel.info));
|
|
|
|
final IntProperty defaultValue = new IntProperty(
|
|
'name',
|
|
42,
|
|
defaultValue: 42,
|
|
);
|
|
expect(defaultValue.toString(), equals('name: 42'));
|
|
expect(defaultValue.value, equals(42));
|
|
expect(defaultValue.isFiltered(DiagnosticLevel.info), isTrue);
|
|
|
|
final IntProperty notDefaultValue = new IntProperty(
|
|
'name',
|
|
43,
|
|
defaultValue: 42,
|
|
);
|
|
expect(notDefaultValue.toString(), equals('name: 43'));
|
|
expect(notDefaultValue.value, equals(43));
|
|
expect(notDefaultValue.level, equals(DiagnosticLevel.info));
|
|
|
|
final IntProperty hidden = new IntProperty(
|
|
'name',
|
|
42,
|
|
level: DiagnosticLevel.hidden,
|
|
);
|
|
expect(hidden.toString(), equals('name: 42'));
|
|
expect(hidden.value, equals(42));
|
|
expect(hidden.level, equals(DiagnosticLevel.hidden));
|
|
});
|
|
|
|
test('object property test', () {
|
|
final Rect rect = new Rect.fromLTRB(0.0, 0.0, 20.0, 20.0);
|
|
final DiagnosticsNode simple = new DiagnosticsProperty<Rect>(
|
|
'name',
|
|
rect,
|
|
);
|
|
expect(simple.value, equals(rect));
|
|
expect(simple.level, equals(DiagnosticLevel.info));
|
|
expect(simple.toString(), equals('name: Rect.fromLTRB(0.0, 0.0, 20.0, 20.0)'));
|
|
validatePropertyJsonSerialization(simple);
|
|
|
|
final DiagnosticsNode withDescription = new DiagnosticsProperty<Rect>(
|
|
'name',
|
|
rect,
|
|
description: 'small rect',
|
|
);
|
|
expect(withDescription.value, equals(rect));
|
|
expect(withDescription.level, equals(DiagnosticLevel.info));
|
|
expect(withDescription.toString(), equals('name: small rect'));
|
|
validatePropertyJsonSerialization(withDescription);
|
|
|
|
final DiagnosticsProperty<Object> nullProperty = new DiagnosticsProperty<Object>(
|
|
'name',
|
|
null,
|
|
);
|
|
expect(nullProperty.value, isNull);
|
|
expect(nullProperty.level, equals(DiagnosticLevel.info));
|
|
expect(nullProperty.toString(), equals('name: null'));
|
|
validatePropertyJsonSerialization(nullProperty);
|
|
|
|
final DiagnosticsProperty<Object> hideNullProperty = new DiagnosticsProperty<Object>(
|
|
'name',
|
|
null,
|
|
defaultValue: null,
|
|
);
|
|
expect(hideNullProperty.value, isNull);
|
|
expect(hideNullProperty.isFiltered(DiagnosticLevel.info), isTrue);
|
|
expect(hideNullProperty.toString(), equals('name: null'));
|
|
validatePropertyJsonSerialization(hideNullProperty);
|
|
|
|
final DiagnosticsNode nullDescription = new DiagnosticsProperty<Object>(
|
|
'name',
|
|
null,
|
|
ifNull: 'missing',
|
|
);
|
|
expect(nullDescription.value, isNull);
|
|
expect(nullDescription.level, equals(DiagnosticLevel.info));
|
|
expect(nullDescription.toString(), equals('name: missing'));
|
|
validatePropertyJsonSerialization(nullDescription);
|
|
|
|
final DiagnosticsProperty<Rect> hideName = new DiagnosticsProperty<Rect>(
|
|
'name',
|
|
rect,
|
|
showName: false,
|
|
level: DiagnosticLevel.warning
|
|
);
|
|
expect(hideName.value, equals(rect));
|
|
expect(hideName.level, equals(DiagnosticLevel.warning));
|
|
expect(hideName.toString(), equals('Rect.fromLTRB(0.0, 0.0, 20.0, 20.0)'));
|
|
validatePropertyJsonSerialization(hideName);
|
|
|
|
final DiagnosticsProperty<Rect> hideSeparator = new DiagnosticsProperty<Rect>(
|
|
'Creator',
|
|
rect,
|
|
showSeparator: false,
|
|
);
|
|
expect(hideSeparator.value, equals(rect));
|
|
expect(hideSeparator.level, equals(DiagnosticLevel.info));
|
|
expect(
|
|
hideSeparator.toString(),
|
|
equals('Creator Rect.fromLTRB(0.0, 0.0, 20.0, 20.0)'),
|
|
);
|
|
validatePropertyJsonSerialization(hideSeparator);
|
|
});
|
|
|
|
test('lazy object property test', () {
|
|
final Rect rect = new Rect.fromLTRB(0.0, 0.0, 20.0, 20.0);
|
|
final DiagnosticsNode simple = new DiagnosticsProperty<Rect>.lazy(
|
|
'name',
|
|
() => rect,
|
|
description: 'small rect',
|
|
);
|
|
expect(simple.value, equals(rect));
|
|
expect(simple.level, equals(DiagnosticLevel.info));
|
|
expect(simple.toString(), equals('name: small rect'));
|
|
validatePropertyJsonSerialization(simple);
|
|
|
|
final DiagnosticsProperty<Object> nullProperty = new DiagnosticsProperty<Object>.lazy(
|
|
'name',
|
|
() => null,
|
|
description: 'missing',
|
|
);
|
|
expect(nullProperty.value, isNull);
|
|
expect(nullProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(nullProperty.toString(), equals('name: missing'));
|
|
validatePropertyJsonSerialization(nullProperty);
|
|
|
|
final DiagnosticsNode hideNullProperty = new DiagnosticsProperty<Object>.lazy(
|
|
'name',
|
|
() => null,
|
|
description: 'missing',
|
|
defaultValue: null,
|
|
);
|
|
expect(hideNullProperty.value, isNull);
|
|
expect(hideNullProperty.isFiltered(DiagnosticLevel.info), isTrue);
|
|
expect(hideNullProperty.toString(), equals('name: missing'));
|
|
validatePropertyJsonSerialization(hideNullProperty);
|
|
|
|
final DiagnosticsNode hideName = new DiagnosticsProperty<Rect>.lazy(
|
|
'name',
|
|
() => rect,
|
|
description: 'small rect',
|
|
showName: false,
|
|
);
|
|
expect(hideName.value, equals(rect));
|
|
expect(hideName.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(hideName.toString(), equals('small rect'));
|
|
validatePropertyJsonSerialization(hideName);
|
|
|
|
final DiagnosticsProperty<Object> throwingWithDescription = new DiagnosticsProperty<Object>.lazy(
|
|
'name',
|
|
() => throw new FlutterError('Property not available'),
|
|
description: 'missing',
|
|
defaultValue: null,
|
|
);
|
|
expect(throwingWithDescription.value, isNull);
|
|
expect(throwingWithDescription.exception, isFlutterError);
|
|
expect(throwingWithDescription.isFiltered(DiagnosticLevel.info), false);
|
|
expect(throwingWithDescription.toString(), equals('name: missing'));
|
|
validatePropertyJsonSerialization(throwingWithDescription);
|
|
|
|
final DiagnosticsProperty<Object> throwingProperty = new DiagnosticsProperty<Object>.lazy(
|
|
'name',
|
|
() => throw new FlutterError('Property not available'),
|
|
defaultValue: null,
|
|
);
|
|
expect(throwingProperty.value, isNull);
|
|
expect(throwingProperty.exception, isFlutterError);
|
|
expect(throwingProperty.isFiltered(DiagnosticLevel.info), false);
|
|
expect(throwingProperty.toString(), equals('name: EXCEPTION (FlutterError)'));
|
|
validatePropertyJsonSerialization(throwingProperty);
|
|
});
|
|
|
|
test('color property test', () {
|
|
// Add more tests if colorProperty becomes more than a wrapper around
|
|
// objectProperty.
|
|
const Color color = const Color.fromARGB(255, 255, 255, 255);
|
|
final DiagnosticsProperty<Color> simple = new DiagnosticsProperty<Color>(
|
|
'name',
|
|
color,
|
|
);
|
|
validatePropertyJsonSerialization(simple);
|
|
expect(simple.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(simple.value, equals(color));
|
|
expect(simple.propertyType, equals(Color));
|
|
expect(simple.toString(), equals('name: Color(0xffffffff)'));
|
|
validatePropertyJsonSerialization(simple);
|
|
});
|
|
|
|
test('flag property test', () {
|
|
final FlagProperty show = new FlagProperty(
|
|
'wasLayout',
|
|
value: true,
|
|
ifTrue: 'layout computed',
|
|
);
|
|
expect(show.name, equals('wasLayout'));
|
|
expect(show.value, isTrue);
|
|
expect(show.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(show.toString(), equals('layout computed'));
|
|
validateFlagPropertyJsonSerialization(show);
|
|
|
|
final FlagProperty hide = new FlagProperty(
|
|
'wasLayout',
|
|
value: false,
|
|
ifTrue: 'layout computed',
|
|
);
|
|
expect(hide.name, equals('wasLayout'));
|
|
expect(hide.value, isFalse);
|
|
expect(hide.level, equals(DiagnosticLevel.hidden));
|
|
expect(hide.toString(), equals('wasLayout: false'));
|
|
validateFlagPropertyJsonSerialization(hide);
|
|
|
|
final FlagProperty hideTrue = new FlagProperty(
|
|
'wasLayout',
|
|
value: true,
|
|
ifFalse: 'no layout computed',
|
|
);
|
|
expect(hideTrue.name, equals('wasLayout'));
|
|
expect(hideTrue.value, isTrue);
|
|
expect(hideTrue.level, equals(DiagnosticLevel.hidden));
|
|
expect(hideTrue.toString(), equals('wasLayout: true'));
|
|
validateFlagPropertyJsonSerialization(hideTrue);
|
|
});
|
|
|
|
test('has property test', () {
|
|
final Function onClick = () {};
|
|
final ObjectFlagProperty<Function> has = new ObjectFlagProperty<Function>.has(
|
|
'onClick',
|
|
onClick,
|
|
);
|
|
expect(has.name, equals('onClick'));
|
|
expect(has.value, equals(onClick));
|
|
expect(has.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(has.toString(), equals('has onClick'));
|
|
validateObjectFlagPropertyJsonSerialization(has);
|
|
|
|
final ObjectFlagProperty<Function> missing = new ObjectFlagProperty<Function>.has(
|
|
'onClick',
|
|
null,
|
|
);
|
|
expect(missing.name, equals('onClick'));
|
|
expect(missing.value, isNull);
|
|
expect(missing.isFiltered(DiagnosticLevel.info), isTrue);
|
|
expect(missing.toString(), equals('onClick: null'));
|
|
validateObjectFlagPropertyJsonSerialization(missing);
|
|
});
|
|
|
|
test('iterable property test', () {
|
|
final List<int> ints = <int>[1,2,3];
|
|
final IterableProperty<int> intsProperty = new IterableProperty<int>(
|
|
'ints',
|
|
ints,
|
|
);
|
|
expect(intsProperty.value, equals(ints));
|
|
expect(intsProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(intsProperty.toString(), equals('ints: 1, 2, 3'));
|
|
|
|
final IterableProperty<Object> emptyProperty = new IterableProperty<Object>(
|
|
'name',
|
|
<Object>[],
|
|
);
|
|
expect(emptyProperty.value, isEmpty);
|
|
expect(emptyProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(emptyProperty.toString(), equals('name: []'));
|
|
validateIterablePropertyJsonSerialization(emptyProperty);
|
|
|
|
final IterableProperty<Object> nullProperty = new IterableProperty<Object>(
|
|
'list',
|
|
null,
|
|
);
|
|
expect(nullProperty.value, isNull);
|
|
expect(nullProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(nullProperty.toString(), equals('list: null'));
|
|
validateIterablePropertyJsonSerialization(nullProperty);
|
|
|
|
final IterableProperty<Object> hideNullProperty = new IterableProperty<Object>(
|
|
'list',
|
|
null,
|
|
defaultValue: null,
|
|
);
|
|
expect(hideNullProperty.value, isNull);
|
|
expect(hideNullProperty.isFiltered(DiagnosticLevel.info), isTrue);
|
|
expect(hideNullProperty.level, equals(DiagnosticLevel.fine));
|
|
expect(hideNullProperty.toString(), equals('list: null'));
|
|
validateIterablePropertyJsonSerialization(hideNullProperty);
|
|
|
|
final List<Object> objects = <Object>[
|
|
new Rect.fromLTRB(0.0, 0.0, 20.0, 20.0),
|
|
const Color.fromARGB(255, 255, 255, 255),
|
|
];
|
|
final IterableProperty<Object> objectsProperty = new IterableProperty<Object>(
|
|
'objects',
|
|
objects,
|
|
);
|
|
expect(objectsProperty.value, equals(objects));
|
|
expect(objectsProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(
|
|
objectsProperty.toString(),
|
|
equals('objects: Rect.fromLTRB(0.0, 0.0, 20.0, 20.0), Color(0xffffffff)'),
|
|
);
|
|
validateIterablePropertyJsonSerialization(objectsProperty);
|
|
|
|
final IterableProperty<Object> multiLineProperty = new IterableProperty<Object>(
|
|
'objects',
|
|
objects,
|
|
style: DiagnosticsTreeStyle.whitespace,
|
|
);
|
|
expect(multiLineProperty.value, equals(objects));
|
|
expect(multiLineProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(
|
|
multiLineProperty.toString(),
|
|
equals(
|
|
'objects:\n'
|
|
'Rect.fromLTRB(0.0, 0.0, 20.0, 20.0)\n'
|
|
'Color(0xffffffff)',
|
|
),
|
|
);
|
|
expect(
|
|
multiLineProperty.toStringDeep(),
|
|
equals(
|
|
'objects:\n'
|
|
' Rect.fromLTRB(0.0, 0.0, 20.0, 20.0)\n'
|
|
' Color(0xffffffff)\n',
|
|
),
|
|
);
|
|
validateIterablePropertyJsonSerialization(multiLineProperty);
|
|
|
|
expect(
|
|
new TestTree(
|
|
properties: <DiagnosticsNode>[multiLineProperty],
|
|
).toStringDeep(),
|
|
equalsIgnoringHashCodes(
|
|
'TestTree#00000\n'
|
|
' objects:\n'
|
|
' Rect.fromLTRB(0.0, 0.0, 20.0, 20.0)\n'
|
|
' Color(0xffffffff)\n',
|
|
),
|
|
);
|
|
|
|
expect(
|
|
new TestTree(
|
|
properties: <DiagnosticsNode>[objectsProperty, new IntProperty('foo', 42)],
|
|
style: DiagnosticsTreeStyle.singleLine,
|
|
).toStringDeep(),
|
|
equalsIgnoringHashCodes(
|
|
'TestTree#00000(objects: [Rect.fromLTRB(0.0, 0.0, 20.0, 20.0), Color(0xffffffff)], foo: 42)',
|
|
),
|
|
);
|
|
|
|
// Iterable with a single entry. Verify that rendering is sensible and that
|
|
// multi line rendering isn't used even though it is not helpful.
|
|
final List<Object> singleElementList = <Object>[const Color.fromARGB(255, 255, 255, 255)];
|
|
|
|
final IterableProperty<Object> objectProperty = new IterableProperty<Object>(
|
|
'object',
|
|
singleElementList,
|
|
style: DiagnosticsTreeStyle.whitespace,
|
|
);
|
|
expect(objectProperty.value, equals(singleElementList));
|
|
expect(objectProperty.isFiltered(DiagnosticLevel.info), isFalse);
|
|
expect(
|
|
objectProperty.toString(),
|
|
equals('object: Color(0xffffffff)'),
|
|
);
|
|
expect(
|
|
objectProperty.toStringDeep(),
|
|
equals('object: Color(0xffffffff)\n'),
|
|
);
|
|
validateIterablePropertyJsonSerialization(objectProperty);
|
|
expect(
|
|
new TestTree(
|
|
name: 'root',
|
|
properties: <DiagnosticsNode>[objectProperty],
|
|
).toStringDeep(),
|
|
equalsIgnoringHashCodes(
|
|
'TestTree#00000\n'
|
|
' object: Color(0xffffffff)\n',
|
|
),
|
|
);
|
|
});
|
|
|
|
test('message test', () {
|
|
final DiagnosticsNode message = new DiagnosticsNode.message('hello world');
|
|
expect(message.toString(), equals('hello world'));
|
|
expect(message.name, isEmpty);
|
|
expect(message.value, isNull);
|
|
expect(message.showName, isFalse);
|
|
validateNodeJsonSerialization(message);
|
|
|
|
final DiagnosticsNode messageProperty = new MessageProperty('diagnostics', 'hello world');
|
|
expect(messageProperty.toString(), equals('diagnostics: hello world'));
|
|
expect(messageProperty.name, equals('diagnostics'));
|
|
expect(messageProperty.value, isNull);
|
|
expect(messageProperty.showName, isTrue);
|
|
validatePropertyJsonSerialization(messageProperty);
|
|
});
|
|
}
|