Merge pull request #26193 from dart-lang/strongrename
Minor change to fix some strong-mode errors
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 385849f..860c029 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -646,6 +646,11 @@
bool get isPublic;
/**
+ * Return `true` if this element has an annotation of the form '@required'.
+ */
+ bool get isRequired;
+
+ /**
* Return `true` if this element is synthetic. A synthetic element is an
* element that is not represented in the source code explicitly, but is
* implied by the source code, such as the default constructor for a class
@@ -830,6 +835,12 @@
* a proxy object.
*/
bool get isProxy;
+
+ /**
+ * Return `true` if this annotation marks the associated member as being
+ * required.
+ */
+ bool get isRequired;
}
/**
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 01da784f..ba28157 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1649,6 +1649,17 @@
static String PROXY_VARIABLE_NAME = "proxy";
/**
+ * The name of the class used to mark a parameter as being required.
+ */
+ static String _REQUIRED_CLASS_NAME = "Required";
+
+ /**
+ * The name of the top-level variable used to mark a parameter as being
+ * required.
+ */
+ static String _REQUIRED_VARIABLE_NAME = "required";
+
+ /**
* The element representing the field, variable, or constructor being used as
* an annotation.
*/
@@ -1720,6 +1731,15 @@
element.name == PROXY_VARIABLE_NAME &&
element.library?.isDartCore == true;
+ @override
+ bool get isRequired =>
+ element is ConstructorElement &&
+ element.enclosingElement.name == _REQUIRED_CLASS_NAME &&
+ element.library?.name == _META_LIB_NAME ||
+ element is PropertyAccessorElement &&
+ element.name == _REQUIRED_VARIABLE_NAME &&
+ element.library?.name == _META_LIB_NAME;
+
/**
* Get the library containing this annotation.
*/
@@ -1935,6 +1955,16 @@
bool get isPublic => !isPrivate;
@override
+ bool get isRequired {
+ for (ElementAnnotation annotation in metadata) {
+ if (annotation.isRequired) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @override
bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
@override
@@ -4093,6 +4123,9 @@
bool get isPublic => !isPrivate;
@override
+ bool get isRequired => false;
+
+ @override
bool get isSynthetic => true;
@override
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 8e9fcff..99b87b2 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -71,6 +71,9 @@
bool get isProxy => actualElement.isProxy;
@override
+ bool get isRequired => actualElement.isRequired;
+
+ @override
bool get isValidMixin => actualElement.isValidMixin;
@override
@@ -362,6 +365,9 @@
bool get isPublic => actualElement.isPublic;
@override
+ bool get isRequired => actualElement.isRequired;
+
+ @override
bool get isSynthetic => actualElement.isSynthetic;
@override
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 0ac6d4a..f467ce2 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -473,6 +473,9 @@
bool get isPublic => _baseElement.isPublic;
@override
+ bool get isRequired => _baseElement.isRequired;
+
+ @override
bool get isSynthetic => _baseElement.isSynthetic;
@override
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 3345a61..4a78c0d 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -2683,6 +2683,7 @@
HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
HintCode.INVALID_ASSIGNMENT,
HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
+ HintCode.MISSING_REQUIRED_PARAM,
HintCode.MISSING_RETURN,
HintCode.NULL_AWARE_IN_CONDITION,
HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER,
@@ -3572,6 +3573,17 @@
"The member '{0}' can only be used within instance members of subclasses of '{1}'");
/**
+ * Generate a hint for a constructor, function or method invocation where a
+ * required parameter is missing.
+ *
+ * Parameters:
+ * 0: the name of the parameter
+ * 1: an optional reason
+ */
+ static const HintCode MISSING_REQUIRED_PARAM = const HintCode(
+ 'MISSING_REQUIRED_PARAM', "The parameter '{0}' is required. {1}");
+
+ /**
* Generate a hint for methods or functions that have a return type, but do
* not have a non-void return statement on all branches. At the end of methods
* or functions with no return, Dart implicitly returns `null`, avoiding these
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c77d13a..aa3651e 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -818,6 +818,8 @@
InterfaceType interfaceType = type;
_checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
_checkForConstOrNewWithEnum(node, typeName, interfaceType);
+ _checkForMissingRequiredParam(
+ node.staticElement?.type, node.argumentList, node.constructorName);
if (_isInConstInstanceCreation) {
_checkForConstWithNonConst(node);
_checkForConstWithUndefinedConstructor(
@@ -929,6 +931,8 @@
} else {
_checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
}
+ _checkForMissingRequiredParam(
+ node.staticInvokeType, node.argumentList, methodName);
return super.visitMethodInvocation(node);
}
@@ -3725,6 +3729,50 @@
[name.name]);
}
+ void _checkForMissingRequiredParam(
+ DartType type, ArgumentList argumentList, AstNode node) {
+ if (type is FunctionType) {
+ List<ParameterElement> parameters = type.parameters;
+ for (ParameterElement param in parameters) {
+ if (param.parameterKind == ParameterKind.NAMED) {
+ ElementAnnotationImpl annotation = _getRequiredAnnotation(param);
+ if (annotation != null) {
+ String paramName = param.name;
+ if (!_containsNamedExpression(argumentList, paramName)) {
+ DartObject constantValue = annotation.constantValue;
+ String reason =
+ constantValue.getField('reason')?.toStringValue() ?? '';
+ // Append a `.` if needed.
+ if (reason != null &&
+ reason.isNotEmpty &&
+ !reason.endsWith('.')) {
+ reason += '.';
+ }
+
+ _errorReporter.reportErrorForNode(
+ HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param
+ .metadata
+ .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
+
+ bool _containsNamedExpression(ArgumentList args, String name) {
+ for (Expression expression in args.arguments) {
+ if (expression is NamedExpression) {
+ if (expression.name.label.name == name) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Check whether the given [executableElement] collides with the name of a
* static method in one of its superclasses, and reports the appropriate
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index a65aba0..5cb69d9 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -3250,7 +3250,7 @@
List<idl.UnlinkedExprAssignOperator> _assignmentOperators;
List<double> _doubles;
List<int> _ints;
- bool _isInvalid;
+ bool _isValidConst;
List<idl.UnlinkedConstOperation> _operations;
List<EntityRefBuilder> _references;
List<String> _strings;
@@ -3292,15 +3292,15 @@
}
@override
- bool get isInvalid => _isInvalid ??= false;
+ bool get isValidConst => _isValidConst ??= false;
/**
- * Indicates whether the expression is not a valid potentially constant
+ * Indicates whether the expression is a valid potentially constant
* expression.
*/
- void set isInvalid(bool _value) {
+ void set isValidConst(bool _value) {
assert(!_finished);
- _isInvalid = _value;
+ _isValidConst = _value;
}
@override
@@ -3341,11 +3341,11 @@
_strings = _value;
}
- UnlinkedConstBuilder({List<idl.UnlinkedExprAssignOperator> assignmentOperators, List<double> doubles, List<int> ints, bool isInvalid, List<idl.UnlinkedConstOperation> operations, List<EntityRefBuilder> references, List<String> strings})
+ UnlinkedConstBuilder({List<idl.UnlinkedExprAssignOperator> assignmentOperators, List<double> doubles, List<int> ints, bool isValidConst, List<idl.UnlinkedConstOperation> operations, List<EntityRefBuilder> references, List<String> strings})
: _assignmentOperators = assignmentOperators,
_doubles = doubles,
_ints = ints,
- _isInvalid = isInvalid,
+ _isValidConst = isValidConst,
_operations = operations,
_references = references,
_strings = strings;
@@ -3394,7 +3394,7 @@
if (offset_ints != null) {
fbBuilder.addOffset(1, offset_ints);
}
- if (_isInvalid == true) {
+ if (_isValidConst == true) {
fbBuilder.addBool(5, true);
}
if (offset_operations != null) {
@@ -3425,7 +3425,7 @@
List<idl.UnlinkedExprAssignOperator> _assignmentOperators;
List<double> _doubles;
List<int> _ints;
- bool _isInvalid;
+ bool _isValidConst;
List<idl.UnlinkedConstOperation> _operations;
List<idl.EntityRef> _references;
List<String> _strings;
@@ -3449,9 +3449,9 @@
}
@override
- bool get isInvalid {
- _isInvalid ??= const fb.BoolReader().vTableGet(_bp, 5, false);
- return _isInvalid;
+ bool get isValidConst {
+ _isValidConst ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+ return _isValidConst;
}
@override
@@ -3480,7 +3480,7 @@
if (assignmentOperators.isNotEmpty) _result["assignmentOperators"] = assignmentOperators.map((_value) => _value.toString().split('.')[1]).toList();
if (doubles.isNotEmpty) _result["doubles"] = doubles.map((_value) => _value.isFinite ? _value : _value.toString()).toList();
if (ints.isNotEmpty) _result["ints"] = ints;
- if (isInvalid != false) _result["isInvalid"] = isInvalid;
+ if (isValidConst != false) _result["isValidConst"] = isValidConst;
if (operations.isNotEmpty) _result["operations"] = operations.map((_value) => _value.toString().split('.')[1]).toList();
if (references.isNotEmpty) _result["references"] = references.map((_value) => _value.toJson()).toList();
if (strings.isNotEmpty) _result["strings"] = strings;
@@ -3492,7 +3492,7 @@
"assignmentOperators": assignmentOperators,
"doubles": doubles,
"ints": ints,
- "isInvalid": isInvalid,
+ "isValidConst": isValidConst,
"operations": operations,
"references": references,
"strings": strings,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index bc34862..2a41e6c 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -515,7 +515,7 @@
assignToRef,
/**
- * Pop from the stack `value` and `target`. Get the name of the property from
+ * Pop from the stack `target` and `value`. Get the name of the property from
* `UnlinkedConst.strings` and assign the `value` to the named property of the
* `target`. This operation is used when we know that the `target` is an
* object reference expression, e.g. `new Foo().a.b.c` or `a.b[0].c.d`.
@@ -531,7 +531,7 @@
assignToProperty,
/**
- * Pop from the stack `value`, `index` and `target`. Perform
+ * Pop from the stack `index`, `target` and `value`. Perform
* `target[index] op= value` where `op` is the next assignment operator from
* [UnlinkedConst.assignmentOperators]. Push `value` back into the stack.
*
@@ -580,7 +580,36 @@
* This operation should be used for invocation of a method invocation
* where `target` is know to be an object instance.
*/
- invokeMethod
+ invokeMethod,
+
+ /**
+ * Begin a new cascade section. Duplicate the top value of the stack.
+ */
+ cascadeSectionBegin,
+
+ /**
+ * End a new cascade section. Pop the top value from the stack and throw it
+ * away.
+ */
+ cascadeSectionEnd,
+
+ /**
+ * Pop the top value from the stack and cast it to the type with reference
+ * from [UnlinkedConst.references], push the result into the stack.
+ */
+ typeCast,
+
+ /**
+ * Pop the top value from the stack and check whether is is a subclass of the
+ * type with reference from [UnlinkedConst.references], push the result into
+ * the stack.
+ */
+ typeCheck,
+
+ /**
+ * Pop the top value from the stack and raise an exception with this value.
+ */
+ throwException
}
/**
@@ -1394,10 +1423,10 @@
ints:[uint] (id: 1);
/**
- * Indicates whether the expression is not a valid potentially constant
+ * Indicates whether the expression is a valid potentially constant
* expression.
*/
- isInvalid:bool (id: 5);
+ isValidConst:bool (id: 5);
/**
* Sequence of operations to execute (starting with an empty stack) to form
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 1e17ec0..8f86380 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -1011,11 +1011,11 @@
List<int> get ints;
/**
- * Indicates whether the expression is not a valid potentially constant
+ * Indicates whether the expression is a valid potentially constant
* expression.
*/
@Id(5)
- bool get isInvalid;
+ bool get isValidConst;
/**
* Sequence of operations to execute (starting with an empty stack) to form
@@ -1343,7 +1343,7 @@
assignToRef,
/**
- * Pop from the stack `value` and `target`. Get the name of the property from
+ * Pop from the stack `target` and `value`. Get the name of the property from
* `UnlinkedConst.strings` and assign the `value` to the named property of the
* `target`. This operation is used when we know that the `target` is an
* object reference expression, e.g. `new Foo().a.b.c` or `a.b[0].c.d`.
@@ -1359,7 +1359,7 @@
assignToProperty,
/**
- * Pop from the stack `value`, `index` and `target`. Perform
+ * Pop from the stack `index`, `target` and `value`. Perform
* `target[index] op= value` where `op` is the next assignment operator from
* [UnlinkedConst.assignmentOperators]. Push `value` back into the stack.
*
@@ -1409,6 +1409,35 @@
* where `target` is know to be an object instance.
*/
invokeMethod,
+
+ /**
+ * Begin a new cascade section. Duplicate the top value of the stack.
+ */
+ cascadeSectionBegin,
+
+ /**
+ * End a new cascade section. Pop the top value from the stack and throw it
+ * away.
+ */
+ cascadeSectionEnd,
+
+ /**
+ * Pop the top value from the stack and cast it to the type with reference
+ * from [UnlinkedConst.references], push the result into the stack.
+ */
+ typeCast,
+
+ /**
+ * Pop the top value from the stack and check whether is is a subclass of the
+ * type with reference from [UnlinkedConst.references], push the result into
+ * the stack.
+ */
+ typeCheck,
+
+ /**
+ * Pop the top value from the stack and raise an exception with this value.
+ */
+ throwException,
}
/**
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index d35b8da..0f642ef 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -146,6 +146,9 @@
} else if (type is VoidTypeImpl) {
result.reference = compilationUnit.addRawReference('void');
return result;
+ } else if (type is BottomTypeImpl) {
+ result.reference = compilationUnit.addRawReference('*bottom*');
+ return result;
} else if (type is TypeParameterType) {
TypeParameterElementForLink element = type.element;
result.paramReference =
@@ -214,6 +217,13 @@
}
@override
+ DartType get asStaticType =>
+ enclosingElement.enclosingElement._linker.typeProvider.typeType;
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => null;
+
+ @override
List<ConstructorElementForLink> get constructors;
@override
@@ -262,11 +272,6 @@
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
- /**
- * Throw away any information produced by a previous call to [link].
- */
- void unlink();
}
/**
@@ -442,31 +447,17 @@
for (ConstructorElementForLink constructorElement in constructors) {
constructorElement.link(compilationUnit);
}
- for (MethodElementForLink methodElement in methods) {
- methodElement.link(compilationUnit);
- }
- for (PropertyAccessorElementForLink propertyAccessorElement in accessors) {
- propertyAccessorElement.link(compilationUnit);
- }
- for (FieldElementForLink_ClassField fieldElement in fields) {
- fieldElement.link(compilationUnit);
- }
- }
-
- @override
- void unlink() {
- hasBeenInferred = false;
- for (ConstructorElementForLink constructorElement in constructors) {
- constructorElement.unlink();
- }
- for (MethodElementForLink methodElement in methods) {
- methodElement.unlink();
- }
- for (PropertyAccessorElementForLink propertyAccessorElement in accessors) {
- propertyAccessorElement.unlink();
- }
- for (FieldElementForLink_ClassField fieldElement in fields) {
- fieldElement.unlink();
+ if (compilationUnit.library._linker.strongMode) {
+ for (MethodElementForLink methodElement in methods) {
+ methodElement.link(compilationUnit);
+ }
+ for (PropertyAccessorElementForLink propertyAccessorElement
+ in accessors) {
+ propertyAccessorElement.link(compilationUnit);
+ }
+ for (FieldElementForLink_ClassField fieldElement in fields) {
+ fieldElement.link(compilationUnit);
+ }
}
}
@@ -556,9 +547,6 @@
@override
void link(CompilationUnitElementInBuildUnit compilationUnit) {}
-
- @override
- void unlink() {}
}
/**
@@ -722,6 +710,9 @@
} else if (type.syntheticReturnType != null) {
// TODO(paulberry): implement.
throw new UnimplementedError();
+ } else if (type.implicitFunctionTypeIndices.isNotEmpty) {
+ // TODO(paulberry): implement.
+ throw new UnimplementedError();
} else {
DartType getTypeArgument(int i) {
if (i < type.typeArguments.length) {
@@ -852,15 +843,13 @@
}
/**
- * Throw away any information produced by a previous call to [link].
+ * Throw away any information stored in the summary by a previous call to
+ * [link].
*/
void unlink() {
_linkedUnit.constCycles.clear();
_linkedUnit.references.length = _unlinkedUnit.references.length;
_linkedUnit.types.clear();
- for (ClassElementForLink classElement in types) {
- classElement.unlink();
- }
}
/**
@@ -1154,6 +1143,16 @@
ConstVariableNode get asConstVariable => null;
@override
+ DartType get asStaticType {
+ // Referring to a constructor directly is an error, so just use
+ // `dynamic`.
+ return DynamicTypeImpl.instance;
+ }
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => null;
+
+ @override
bool get isCycleFree {
if (!_constNode.isEvaluated) {
new ConstDependencyWalker().walk(_constNode);
@@ -1445,16 +1444,6 @@
parameterElement.link(compilationUnit);
}
}
-
- /**
- * Throw away any information produced by type inference.
- */
- void unlink() {
- for (ParameterElementForLink parameterElement in parameters) {
- parameterElement.unlink();
- }
- _inferredReturnType = null;
- }
}
/**
@@ -1472,7 +1461,12 @@
@override
final ClassElementForLink_Class enclosingElement;
- DartType _inferredType;
+ /**
+ * If this is an instance field, the type that was computed by
+ * [InstanceMemberInferrer].
+ */
+ DartType _inferredInstanceType;
+
DartType _declaredType;
FieldElementForLink_ClassField(ClassElementForLink_Class enclosingElement,
@@ -1485,8 +1479,9 @@
@override
DartType get type {
- if (_inferredType != null) {
- return _inferredType;
+ assert(!isStatic);
+ if (_inferredInstanceType != null) {
+ return _inferredInstanceType;
} else if (_declaredType == null) {
if (unlinkedVariable.type == null) {
_declaredType = DynamicTypeImpl.instance;
@@ -1500,8 +1495,9 @@
@override
void set type(DartType inferredType) {
- assert(_inferredType == null);
- _inferredType = inferredType;
+ assert(!isStatic);
+ assert(_inferredInstanceType == null);
+ _inferredInstanceType = inferredType;
}
/**
@@ -1509,15 +1505,18 @@
* [compilationUnit].
*/
void link(CompilationUnitElementInBuildUnit compilationUnit) {
- compilationUnit._storeLinkedType(
- unlinkedVariable.inferredTypeSlot, _inferredType, enclosingElement);
- }
-
- /**
- * Throw away any information produced by type inference.
- */
- void unlink() {
- _inferredType = null;
+ if (hasImplicitType) {
+ if (isStatic) {
+ TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode;
+ if (typeInferenceNode != null) {
+ compilationUnit._storeLinkedType(unlinkedVariable.inferredTypeSlot,
+ typeInferenceNode.inferredType, enclosingElement);
+ }
+ } else {
+ compilationUnit._storeLinkedType(unlinkedVariable.inferredTypeSlot,
+ _inferredInstanceType, enclosingElement);
+ }
+ }
}
}
@@ -1546,6 +1545,15 @@
}
@override
+ DartType get asStaticType {
+ // TODO(paulberry): implement.
+ throw new UnimplementedError();
+ }
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => null;
+
+ @override
bool get isStatic => true;
@override
@@ -1614,12 +1622,31 @@
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
+/**
+ * Element representing the initializer expression of a variable.
+ */
class FunctionElementForLink_Initializer implements FunctionElementImpl {
+ /**
+ * The variable for which this element is the initializer.
+ */
+ final VariableElementForLink _variable;
+
+ FunctionElementForLink_Initializer(this._variable);
+
@override
DartType get returnType {
- // TODO(paulberry): for type inference, compute and return the type of the
- // initializer expression.
- return DynamicTypeImpl.instance;
+ // If this is a variable whose type needs inferring, infer it.
+ TypeInferenceNode typeInferenceNode = _variable._typeInferenceNode;
+ if (typeInferenceNode != null) {
+ return typeInferenceNode.inferredType;
+ } else {
+ // There's no reason linking should need to access the type of
+ // this FunctionElement, since the variable doesn't need its
+ // type inferred.
+ assert(false);
+ // But for robustness, return the dynamic type.
+ return DynamicTypeImpl.instance;
+ }
}
@override
@@ -1802,7 +1829,8 @@
}
/**
- * Throw away any information produced by a previous call to [link].
+ * Throw away any information stored in the summary by a previous call to
+ * [link].
*/
void unlink() {
_linkedLibrary.dependencies.length =
@@ -1918,6 +1946,18 @@
ConstVariableNode get asConstVariable => _constNode;
@override
+ DartType get asStaticType {
+ // TODO(paulberry): implement.
+ throw new UnimplementedError();
+ }
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode {
+ // TODO(paulberry): implement.
+ throw new UnimplementedError();
+ }
+
+ @override
DartType buildType(DartType getTypeArgument(int i),
List<int> implicitFunctionTypeIndices) =>
DynamicTypeImpl.instance;
@@ -2027,13 +2067,6 @@
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
- /**
- * Throw away any information produced by type inference.
- */
- void unlink() {
- _inferredType = null;
- }
}
/**
@@ -2088,6 +2121,18 @@
ConstVariableNode get asConstVariable;
/**
+ * Return the static type of the entity referred to by thi element.
+ */
+ DartType get asStaticType;
+
+ /**
+ * If this element can be used in a getter context as a type inference
+ * dependency, return the [TypeInferenceNode] for the inferred type.
+ * Otherwise return `null`.
+ */
+ TypeInferenceNode get asTypeInferenceNode;
+
+ /**
* Return the type indicated by this element when it is used in a
* type instantiation context. If this element can't legally be
* instantiated as a type, return the dynamic type.
@@ -2141,6 +2186,194 @@
}
/**
+ * Specialization of [DependencyWalker] for performing type inferrence
+ * on static and top level variables.
+ */
+class TypeInferenceDependencyWalker
+ extends DependencyWalker<TypeInferenceNode> {
+ @override
+ void evaluate(TypeInferenceNode v) {
+ v.evaluate(false);
+ }
+
+ @override
+ void evaluateScc(List<TypeInferenceNode> scc) {
+ for (TypeInferenceNode v in scc) {
+ v.evaluate(true);
+ }
+ }
+}
+
+/**
+ * Specialization of [Node] used to construct the type inference dependency
+ * graph.
+ */
+class TypeInferenceNode extends Node<TypeInferenceNode> {
+ /**
+ * The [FieldElement] or [TopLevelVariableElement] to which this
+ * node refers.
+ */
+ final VariableElementForLink variableElement;
+
+ /**
+ * If a type has been inferred for this node, the inferred type (may be
+ * `dynamic`). Otherwise `null`.
+ */
+ DartType _inferredType;
+
+ TypeInferenceNode(this.variableElement);
+
+ /**
+ * Infer a type for this node if necessary, and return it.
+ */
+ DartType get inferredType {
+ if (_inferredType == null) {
+ new TypeInferenceDependencyWalker().walk(this);
+ assert(_inferredType != null);
+ }
+ return _inferredType;
+ }
+
+ @override
+ bool get isEvaluated => _inferredType != null;
+
+ /**
+ * Collect the type inference dependencies in [unlinkedConst] (which should be
+ * interpreted relative to [compilationUnit]) and store them in
+ * [dependencies].
+ */
+ void collectDependencies(
+ List<TypeInferenceNode> dependencies,
+ UnlinkedConst unlinkedConst,
+ CompilationUnitElementForLink compilationUnit) {
+ if (unlinkedConst == null) {
+ return;
+ }
+ int refPtr = 0;
+ for (UnlinkedConstOperation operation in unlinkedConst.operations) {
+ switch (operation) {
+ case UnlinkedConstOperation.pushReference:
+ EntityRef ref = unlinkedConst.references[refPtr++];
+ // TODO(paulberry): cache these resolved references for
+ // later use by evaluate().
+ TypeInferenceNode dependency =
+ compilationUnit._resolveRef(ref.reference).asTypeInferenceNode;
+ if (dependency != null) {
+ dependencies.add(dependency);
+ }
+ break;
+ case UnlinkedConstOperation.makeTypedList:
+ case UnlinkedConstOperation.invokeConstructor:
+ refPtr++;
+ break;
+ case UnlinkedConstOperation.makeTypedMap:
+ refPtr += 2;
+ break;
+ default:
+ break;
+ }
+ }
+ assert(refPtr == unlinkedConst.references.length);
+ }
+
+ @override
+ List<TypeInferenceNode> computeDependencies() {
+ List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
+ collectDependencies(
+ dependencies,
+ variableElement.unlinkedVariable.constExpr,
+ variableElement.compilationUnit);
+ return dependencies;
+ }
+
+ @override
+ void evaluate(bool inCycle) {
+ if (inCycle) {
+ _inferredType = DynamicTypeImpl.instance;
+ } else if (!variableElement.unlinkedVariable.constExpr.isValidConst) {
+ // TODO(paulberry): delete this case and fix errors.
+ throw new UnimplementedError();
+ } else {
+ // Perform RPN evaluation of the cycle, using a stack of
+ // inferred types.
+ List<DartType> stack = <DartType>[];
+ int refPtr = 0;
+ int intPtr = 0;
+ UnlinkedConst unlinkedConst = variableElement.unlinkedVariable.constExpr;
+ TypeProvider typeProvider =
+ variableElement.compilationUnit.enclosingElement._linker.typeProvider;
+ for (UnlinkedConstOperation operation in unlinkedConst.operations) {
+ switch (operation) {
+ case UnlinkedConstOperation.pushInt:
+ intPtr++;
+ stack.add(typeProvider.intType);
+ break;
+ case UnlinkedConstOperation.pushNull:
+ stack.add(BottomTypeImpl.instance);
+ break;
+ case UnlinkedConstOperation.pushReference:
+ EntityRef ref = unlinkedConst.references[refPtr++];
+ if (ref.paramReference != 0) {
+ stack.add(typeProvider.typeType);
+ } else {
+ // Synthetic function types can't be directly referred
+ // to by expressions.
+ assert(ref.syntheticReturnType == null);
+ // Nor can implicit function types derived from
+ // function-typed parameters.
+ assert(ref.implicitFunctionTypeIndices.isEmpty);
+ ReferenceableElementForLink element =
+ variableElement.compilationUnit._resolveRef(ref.reference);
+ TypeInferenceNode typeInferenceNode = element.asTypeInferenceNode;
+ if (typeInferenceNode != null) {
+ assert(typeInferenceNode.isEvaluated);
+ stack.add(typeInferenceNode._inferredType);
+ } else {
+ stack.add(element.asStaticType);
+ }
+ }
+ break;
+ case UnlinkedConstOperation.makeTypedList:
+ refPtr++;
+ stack.length -= unlinkedConst.ints[intPtr++];
+ // TODO(paulberry): implement.
+ stack.add(DynamicTypeImpl.instance);
+ break;
+ case UnlinkedConstOperation.makeTypedMap:
+ refPtr += 2;
+ // TODO(paulberry): implement.
+ throw new UnimplementedError('$operation');
+ case UnlinkedConstOperation.invokeConstructor:
+ // TODO(paulberry): don't just pop the args; use their types
+ // to infer the type of type arguments.
+ stack.length -=
+ unlinkedConst.ints[intPtr++] + unlinkedConst.ints[intPtr++];
+ EntityRef ref = unlinkedConst.references[refPtr++];
+ ConstructorElementForLink element = variableElement.compilationUnit
+ ._resolveRef(ref.reference)
+ .asConstructor;
+ if (ref.typeArguments.isNotEmpty) {
+ // TODO(paulberry): handle type arguments
+ throw new UnimplementedError();
+ }
+ // TODO(paulberry): do we have to follow constructor
+ // redirections?
+ stack.add(element.enclosingElement.type);
+ break;
+ default:
+ // TODO(paulberry): implement.
+ throw new UnimplementedError('$operation');
+ }
+ }
+ assert(refPtr == unlinkedConst.references.length);
+ assert(intPtr == unlinkedConst.ints.length);
+ assert(stack.length == 1);
+ _inferredType = stack[0];
+ }
+ }
+}
+
+/**
* Element representing a type parameter resynthesized from a summary during
* linking.
*/
@@ -2403,6 +2636,12 @@
ConstVariableNode get asConstVariable => null;
@override
+ DartType get asStaticType => DynamicTypeImpl.instance;
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => null;
+
+ @override
DartType buildType(DartType getTypeArgument(int i),
List<int> implicitFunctionTypeIndices) =>
DynamicTypeImpl.instance;
@@ -2429,6 +2668,13 @@
*/
ConstNode _constNode;
+ /**
+ * If this variable has an initializer and an implicit type, and the enclosing
+ * library is part of the build unit being linked, the variable's node in the
+ * type inference dependency graph. Otherwise `null`.
+ */
+ TypeInferenceNode _typeInferenceNode;
+
FunctionElementForLink_Initializer _initializer;
/**
@@ -2439,6 +2685,9 @@
VariableElementForLink(this.unlinkedVariable, this.compilationUnit) {
if (compilationUnit.isInBuildUnit && unlinkedVariable.constExpr != null) {
_constNode = new ConstVariableNode(this);
+ if (unlinkedVariable.type == null) {
+ _typeInferenceNode = new TypeInferenceNode(this);
+ }
}
}
@@ -2449,11 +2698,25 @@
ConstVariableNode get asConstVariable => _constNode;
@override
+ DartType get asStaticType {
+ // TODO(paulberry): implement.
+ throw new UnimplementedError();
+ }
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => _typeInferenceNode;
+
+ @override
bool get hasImplicitType => unlinkedVariable.type == null;
@override
- FunctionElementForLink_Initializer get initializer =>
- _initializer ??= new FunctionElementForLink_Initializer();
+ FunctionElementForLink_Initializer get initializer {
+ if (unlinkedVariable.constExpr == null) {
+ return null;
+ } else {
+ return _initializer ??= new FunctionElementForLink_Initializer(this);
+ }
+ }
@override
bool get isConst => unlinkedVariable.isConst;
@@ -2579,7 +2842,8 @@
}
/**
- * Throw away any information produced by a previous call to [link].
+ * Throw away any information stored in the summary by a previous call to
+ * [link].
*/
void unlink() {
for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 726e5f9..63a7f0f 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -286,7 +286,7 @@
Expression get expr => stack.single;
Expression build() {
- if (uc.isInvalid) {
+ if (!uc.isValidConst) {
return AstFactory.identifier3(r'$$invalidConstExpr$$');
}
for (UnlinkedConstOperation operation in uc.operations) {
@@ -457,6 +457,11 @@
case UnlinkedConstOperation.assignToIndex:
case UnlinkedConstOperation.extractIndex:
case UnlinkedConstOperation.invokeMethod:
+ case UnlinkedConstOperation.cascadeSectionBegin:
+ case UnlinkedConstOperation.cascadeSectionEnd:
+ case UnlinkedConstOperation.typeCast:
+ case UnlinkedConstOperation.typeCheck:
+ case UnlinkedConstOperation.throwException:
throw new UnimplementedError('$operation');
}
}
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 0bd88af..f8d96a1 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -76,7 +76,13 @@
EntityRefBuilder serializeIdentifier(Identifier identifier) {
EntityRefBuilder b = new EntityRefBuilder();
if (identifier is SimpleIdentifier) {
- b.reference = visitor.serializeSimpleReference(identifier.name);
+ int index = visitor.serializeSimpleReference(identifier.name,
+ allowTypeParameter: true);
+ if (index < 0) {
+ b.paramReference = -index;
+ } else {
+ b.reference = index;
+ }
} else if (identifier is PrefixedIdentifier) {
int prefix = visitor.serializeSimpleReference(identifier.prefix.name);
b.reference =
@@ -707,8 +713,12 @@
/**
* Serialize a reference to a name declared either at top level or in a
* nested scope.
+ *
+ * If [allowTypeParameter] is `true`, then references to type
+ * parameters are allowed, and are returned as negative numbers.
*/
- int serializeSimpleReference(String name) {
+ int serializeSimpleReference(String name, {bool allowTypeParameter: false}) {
+ int indexOffset = 0;
for (int i = scopes.length - 1; i >= 0; i--) {
_Scope scope = scopes[i];
_ScopedEntity entity = scope[name];
@@ -716,6 +726,9 @@
if (entity is _ScopedClassMember) {
return serializeReference(
serializeReference(null, entity.className), name);
+ } else if (allowTypeParameter && entity is _ScopedTypeParameter) {
+ int paramReference = indexOffset + entity.index;
+ return -paramReference;
} else {
// Invalid reference to a type parameter. Should never happen in
// legal Dart code.
@@ -724,6 +737,9 @@
throw new StateError('Invalid identifier reference');
}
}
+ if (scope is _TypeParameterScope) {
+ indexOffset += scope.length;
+ }
}
return serializeReference(null, name);
}
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 7566b6d..8a6a4e1 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -46,7 +46,7 @@
/**
* See [UnlinkedConstBuilder.isInvalid].
*/
- bool isInvalid = false;
+ bool isValidConst = true;
/**
* See [UnlinkedConstBuilder.operations].
@@ -92,7 +92,7 @@
try {
_serialize(expr);
} on StateError {
- isInvalid = true;
+ isValidConst = false;
}
}
@@ -136,10 +136,8 @@
* serializer.
*/
UnlinkedConstBuilder toBuilder() {
- if (isInvalid) {
- return new UnlinkedConstBuilder(isInvalid: true);
- }
return new UnlinkedConstBuilder(
+ isValidConst: isValidConst,
operations: operations,
assignmentOperators: assignmentOperators,
ints: ints,
@@ -149,22 +147,25 @@
}
/**
- * Push the given assignable [expr] and return the kind of assignment
- * operation that should be used.
+ * Push the operation for the given assignable [expr].
*/
- UnlinkedConstOperation _pushAssignable(Expression expr) {
+ void _pushAssignable(Expression expr) {
if (_isIdentifierSequence(expr)) {
EntityRefBuilder ref = serializeIdentifierSequence(expr);
references.add(ref);
- return UnlinkedConstOperation.assignToRef;
+ operations.add(UnlinkedConstOperation.assignToRef);
} else if (expr is PropertyAccess) {
- _serialize(expr.target);
+ if (!expr.isCascaded) {
+ _serialize(expr.target);
+ }
strings.add(expr.propertyName.name);
- return UnlinkedConstOperation.assignToProperty;
+ operations.add(UnlinkedConstOperation.assignToProperty);
} else if (expr is IndexExpression) {
- _serialize(expr.target);
+ if (!expr.isCascaded) {
+ _serialize(expr.target);
+ }
_serialize(expr.index);
- return UnlinkedConstOperation.assignToIndex;
+ operations.add(UnlinkedConstOperation.assignToIndex);
} else {
throw new StateError('Unsupported assignable: $expr');
}
@@ -222,6 +223,9 @@
operations.add(UnlinkedConstOperation.pushReference);
}
} else if (expr is InstanceCreationExpression) {
+ if (!expr.isConst) {
+ isValidConst = false;
+ }
serializeInstanceCreation(
serializeConstructorName(
expr.constructorName.type, expr.constructorName.name),
@@ -248,11 +252,36 @@
} else if (expr is ParenthesizedExpression) {
_serialize(expr.expression);
} else if (expr is IndexExpression) {
+ isValidConst = false;
_serialize(expr.target);
_serialize(expr.index);
operations.add(UnlinkedConstOperation.extractIndex);
} else if (expr is AssignmentExpression) {
_serializeAssignment(expr);
+ } else if (expr is CascadeExpression) {
+ _serializeCascadeExpression(expr);
+ } else if (expr is FunctionExpression) {
+ isValidConst = false;
+ // TODO(scheglov) implement
+ operations.add(UnlinkedConstOperation.pushNull);
+ } else if (expr is FunctionExpressionInvocation) {
+ isValidConst = false;
+ // TODO(scheglov) implement
+ operations.add(UnlinkedConstOperation.pushNull);
+ } else if (expr is AsExpression) {
+ isValidConst = false;
+ _serialize(expr.expression);
+ _serialize(expr.type.name);
+ operations.add(UnlinkedConstOperation.typeCast);
+ } else if (expr is IsExpression) {
+ isValidConst = false;
+ _serialize(expr.expression);
+ _serialize(expr.type.name);
+ operations.add(UnlinkedConstOperation.typeCheck);
+ } else if (expr is ThrowExpression) {
+ isValidConst = false;
+ _serialize(expr.expression);
+ operations.add(UnlinkedConstOperation.throwException);
} else {
throw new StateError('Unknown expression type: $expr');
}
@@ -277,6 +306,9 @@
}
void _serializeAssignment(AssignmentExpression expr) {
+ isValidConst = false;
+ // Push the value.
+ _serialize(expr.rightHandSide);
// Push the assignment operator.
TokenType operator = expr.operator.type;
UnlinkedExprAssignOperator assignmentOperator;
@@ -310,13 +342,8 @@
throw new StateError('Unknown assignment operator: $operator');
}
assignmentOperators.add(assignmentOperator);
- // Push the target and prepare the assignment operation.
- Expression leftHandSide = expr.leftHandSide;
- UnlinkedConstOperation assignOperation = _pushAssignable(leftHandSide);
- // Push the value.
- _serialize(expr.rightHandSide);
- // Push the target-specific assignment operation.
- operations.add(assignOperation);
+ // Push the assignment to the LHS.
+ _pushAssignable(expr.leftHandSide);
}
void _serializeBinaryExpression(BinaryExpression expr) {
@@ -366,6 +393,15 @@
}
}
+ void _serializeCascadeExpression(CascadeExpression expr) {
+ _serialize(expr.target);
+ for (Expression section in expr.cascadeSections) {
+ operations.add(UnlinkedConstOperation.cascadeSectionBegin);
+ _serialize(section);
+ operations.add(UnlinkedConstOperation.cascadeSectionEnd);
+ }
+ }
+
void _serializeListLiteral(ListLiteral expr) {
List<Expression> elements = expr.elements;
elements.forEach(_serialize);
@@ -396,6 +432,10 @@
}
void _serializeMethodInvocation(MethodInvocation invocation) {
+ if (invocation.target != null ||
+ invocation.methodName.name != 'identical') {
+ isValidConst = false;
+ }
Expression target = invocation.target;
SimpleIdentifier methodName = invocation.methodName;
ArgumentList argumentList = invocation.argumentList;
@@ -405,7 +445,9 @@
_serializeArguments(argumentList);
operations.add(UnlinkedConstOperation.invokeMethodRef);
} else {
- _serialize(target);
+ if (!invocation.isCascaded) {
+ _serialize(target);
+ }
_serializeArguments(argumentList);
strings.add(methodName.name);
operations.add(UnlinkedConstOperation.invokeMethod);
@@ -451,9 +493,9 @@
void _serializePrefixPostfixIncDec(
Expression operand, UnlinkedExprAssignOperator operator) {
+ isValidConst = false;
assignmentOperators.add(operator);
- UnlinkedConstOperation assignOperation = _pushAssignable(operand);
- operations.add(assignOperation);
+ _pushAssignable(operand);
}
void _serializePropertyAccess(PropertyAccess expr) {
@@ -504,6 +546,9 @@
if (expr is SimpleIdentifier) {
AstNode parent = expr.parent;
if (parent is MethodInvocation && parent.methodName == expr) {
+ if (parent.isCascaded) {
+ return false;
+ }
return parent.target == null || _isIdentifierSequence(parent.target);
}
return true;
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 6f606d5..3315785 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -1358,9 +1358,10 @@
if (identifier is SimpleIdentifier) {
Element element = identifier.staticElement;
if (element is TypeParameterElement) {
- throw new StateError('Constants may not refer to type parameters.');
- }
- if (_isPrelinkResolvableElement(element)) {
+ int typeParameterIndex =
+ serializer.findTypeParameterIndex(element.type, context);
+ return new EntityRefBuilder(paramReference: typeParameterIndex);
+ } else if (_isPrelinkResolvableElement(element)) {
int ref = serializer._getElementReferenceId(element);
return new EntityRefBuilder(reference: ref);
} else {
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 735fc78..fa3da21 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -107,7 +107,11 @@
const _MustCallSuper mustCallSuper = const _MustCallSuper();
const _Override override = const _Override();
const _Protected protected = const _Protected();
-const _Required required = const _Required();
+const Required required = const Required();
+class Required {
+ final String reason;
+ const Required([this.reason]);
+}
class _Factory {
const _Factory();
@@ -1523,6 +1527,104 @@
verify([source]);
}
+ void test_required_constructor_param() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class C {
+ C({@Required('must specify an `a`') int a}) {}
+}
+
+main() {
+ new C();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+ verify([source]);
+ }
+
+ void test_required_constructor_param_no_reason() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class C {
+ C({@required int a}) {}
+}
+
+main() {
+ new C();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+ verify([source]);
+ }
+
+ void test_required_constructor_param_null_reason() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class C {
+ C({@Required(null) int a}) {}
+}
+
+main() {
+ new C();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+ verify([source]);
+ }
+
+ void test_required_constructor_param_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class C {
+ C({@required int a}) {}
+}
+
+main() {
+ new C(a: 2);
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_required_function_param() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+void f({@Required('must specify an `a`') int a}) {}
+
+main() {
+ f();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+ verify([source]);
+ }
+
+ void test_required_method_param() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ void m({@Required('must specify an `a`') int a}) {}
+}
+f() {
+ new A().m();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
+ verify([source]);
+ }
+
void test_typeCheck_type_is_Null() {
Source source = addSource(r'''
m(i) {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index dab2b10..aa938d7 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -147,6 +147,7 @@
@reflectiveTest
abstract class ResynthesizeTest extends AbstractSingleUnitTest {
Set<Source> otherLibrarySources = new Set<Source>();
+ bool constantInitializersAreInvalid = false;
bool get checkPropagatedTypes => true;
@@ -430,7 +431,11 @@
} else if (oItem is ConstructorFieldInitializer &&
rItem is ConstructorFieldInitializer) {
compareConstAsts(rItem.fieldName, oItem.fieldName, desc);
- compareConstAsts(rItem.expression, oItem.expression, desc);
+ if (constantInitializersAreInvalid) {
+ _assertUnresolvedIdentifier(rItem.expression, desc);
+ } else {
+ compareConstAsts(rItem.expression, oItem.expression, desc);
+ }
} else if (oItem is SuperConstructorInvocation &&
rItem is SuperConstructorInvocation) {
compareElements(rItem.staticElement, oItem.staticElement, desc);
@@ -1163,8 +1168,12 @@
resynthesized.constantValue, original.constantValue, desc);
} else {
Expression initializer = resynthesizedActual.constantInitializer;
- compareConstAsts(initializer, originalActual.constantInitializer,
- '$desc initializer');
+ if (constantInitializersAreInvalid) {
+ _assertUnresolvedIdentifier(initializer, desc);
+ } else {
+ compareConstAsts(initializer, originalActual.constantInitializer,
+ '$desc initializer');
+ }
}
}
checkPossibleMember(resynthesized, original, desc);
@@ -1291,17 +1300,6 @@
prepareAnalysisContext(createOptions());
}
- test_const_invalid_field_const() {
- checkLibrary(
- r'''
-class C {
- static const f = 1 + foo();
-}
-int foo() => 42;
-''',
- allowErrors: true);
- }
-
test_class_abstract() {
checkLibrary('abstract class C {}');
}
@@ -1639,7 +1637,20 @@
''');
}
+ test_const_invalid_field_const() {
+ constantInitializersAreInvalid = true;
+ checkLibrary(
+ r'''
+class C {
+ static const f = 1 + foo();
+}
+int foo() => 42;
+''',
+ allowErrors: true);
+ }
+
test_const_invalid_field_final() {
+ constantInitializersAreInvalid = true;
checkLibrary(
r'''
class C {
@@ -1651,6 +1662,7 @@
}
test_const_invalid_topLevel() {
+ constantInitializersAreInvalid = true;
checkLibrary(
r'''
const v = 1 + foo();
@@ -2393,6 +2405,7 @@
}
test_constructor_initializers_field_notConst() {
+ constantInitializersAreInvalid = true;
checkLibrary(
'''
class C {
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index ac64c85..1858f8f 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -43,16 +43,6 @@
}
@override
- test_field_inferred_type_nonstatic_implicit_initialized() {
- // TODO(paulberry): fix.
- }
-
- @override
- test_field_inferred_type_static_implicit_initialized() {
- // TODO(paulberry): fix.
- }
-
- @override
test_field_propagated_type_final_immediate() {
// TODO(paulberry): fix.
}
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 5010cbd..a34f921 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -3007,7 +3007,13 @@
''';
UnlinkedVariable variable =
serializeClassText(text, allowErrors: true).fields[0];
- _assertUnlinkedConst(variable.constExpr, isInvalid: true);
+ _assertUnlinkedConst(variable.constExpr, operators: [
+ UnlinkedConstOperation.pushReference
+ ], referenceValidators: [
+ (EntityRef r) {
+ return checkParamTypeRef(r, 1);
+ }
+ ]);
}
test_constExpr_pushReference_unresolved_prefix0() {
@@ -5951,16 +5957,16 @@
A a = new A();
final v = (a.b.c.f[1] = 5);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
- UnlinkedConstOperation.pushReference,
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushReference,
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.assignToIndex,
], assignmentOperators: [
(UnlinkedExprAssignOperator.assign)
], ints: [
- 1,
- 5
+ 5,
+ 1
], strings: [], referenceValidators: [
(EntityRef r) => checkTypeRef(r, null, null, 'f',
expectedKind: ReferenceKind.unresolved,
@@ -5990,7 +5996,9 @@
A a = new A();
final v = (a.b[1].c[2].f[3] = 5);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ // 5
+ UnlinkedConstOperation.pushInt,
// a.b[1]
UnlinkedConstOperation.pushReference,
UnlinkedConstOperation.pushInt,
@@ -6002,15 +6010,14 @@
// f[3] = 5
UnlinkedConstOperation.extractProperty,
UnlinkedConstOperation.pushInt,
- UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.assignToIndex,
], assignmentOperators: [
(UnlinkedExprAssignOperator.assign)
], ints: [
+ 5,
1,
2,
3,
- 5
], strings: [
'c',
'f'
@@ -6030,16 +6037,16 @@
List<int> a = <int>[0, 1, 2];
final v = (a[1] = 5);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
- UnlinkedConstOperation.pushReference,
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushReference,
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.assignToIndex,
], assignmentOperators: [
(UnlinkedExprAssignOperator.assign)
], ints: [
+ 5,
1,
- 5
], strings: [], referenceValidators: [
(EntityRef r) => checkTypeRef(r, null, null, 'a',
expectedKind: ReferenceKind.topLevelPropertyAccessor)
@@ -6056,16 +6063,16 @@
}
final v = (new C().f = 5);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
- UnlinkedConstOperation.invokeConstructor,
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.invokeConstructor,
UnlinkedConstOperation.assignToProperty,
], assignmentOperators: [
(UnlinkedExprAssignOperator.assign)
], ints: [
+ 5,
0,
0,
- 5
], strings: [
'f'
], referenceValidators: [
@@ -6084,7 +6091,7 @@
}
final v = (C.f = 1);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.assignToRef,
], assignmentOperators: [
@@ -6117,7 +6124,7 @@
A a = new A();
final v = (a.b.c.f = 1);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.assignToRef,
], assignmentOperators: [
@@ -6164,7 +6171,7 @@
int a = 0;
final v = (a = 1);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.assignToRef,
], assignmentOperators: [
@@ -6190,7 +6197,7 @@
import 'a.dart';
final v = (a = 1);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.assignToRef,
], assignmentOperators: [
@@ -6216,7 +6223,7 @@
import 'a.dart' as p;
final v = (p.a = 1);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.assignToRef,
], assignmentOperators: [
@@ -6232,6 +6239,194 @@
]);
}
+ test_expr_cascadeSection_assignToIndex() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+class C {
+ List<int> items;
+}
+final C c = new C();
+final v = c.items..[1] = 2;
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushReference,
+ // ..[1] = 2
+ UnlinkedConstOperation.cascadeSectionBegin,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.assignToIndex,
+ // c
+ UnlinkedConstOperation.cascadeSectionEnd,
+ ], assignmentOperators: [
+ UnlinkedExprAssignOperator.assign,
+ ], ints: [
+ 2,
+ 1
+ ], strings: [], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'items',
+ expectedKind: ReferenceKind.unresolved,
+ prefixExpectations: [
+ new _PrefixExpectation(
+ ReferenceKind.topLevelPropertyAccessor, 'c'),
+ ])
+ ]);
+ }
+
+ test_expr_cascadeSection_assignToProperty() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+class C {
+ int f1 = 0;
+ int f2 = 0;
+}
+final v = new C()..f1 = 1..f2 += 2;
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ // new C()
+ UnlinkedConstOperation.invokeConstructor,
+ // ..f1 = 1
+ UnlinkedConstOperation.cascadeSectionBegin,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.assignToProperty,
+ // C
+ UnlinkedConstOperation.cascadeSectionEnd,
+ // ..f2 += 2
+ UnlinkedConstOperation.cascadeSectionBegin,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.assignToProperty,
+ // C
+ UnlinkedConstOperation.cascadeSectionEnd,
+ ], assignmentOperators: [
+ UnlinkedExprAssignOperator.assign,
+ UnlinkedExprAssignOperator.plus,
+ ], ints: [
+ 0, 0, // new C()
+ 1, // f1 = 1
+ 2, // f2 += 2
+ ], strings: [
+ 'f1',
+ 'f2',
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'C',
+ expectedKind: ReferenceKind.classOrEnum)
+ ]);
+ }
+
+ test_expr_cascadeSection_embedded() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+class A {
+ int fa1;
+ B b;
+ int fa2;
+}
+class B {
+ int fb;
+}
+final v = new A()
+ ..fa1 = 1
+ ..b = (new B()..fb = 2)
+ ..fa2 = 3;
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ // new A()
+ UnlinkedConstOperation.invokeConstructor,
+ // ..fa1 = 1
+ UnlinkedConstOperation.cascadeSectionBegin,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.assignToProperty,
+ UnlinkedConstOperation.cascadeSectionEnd,
+ // ..b
+ UnlinkedConstOperation.cascadeSectionBegin,
+ // new B()
+ UnlinkedConstOperation.invokeConstructor,
+ // ..fb = 2
+ UnlinkedConstOperation.cascadeSectionBegin,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.assignToProperty,
+ UnlinkedConstOperation.cascadeSectionEnd,
+ // ..b = <pop value>
+ UnlinkedConstOperation.assignToProperty,
+ UnlinkedConstOperation.cascadeSectionEnd,
+ // ..fa2 = 3
+ UnlinkedConstOperation.cascadeSectionBegin,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.assignToProperty,
+ UnlinkedConstOperation.cascadeSectionEnd,
+ ], assignmentOperators: [
+ UnlinkedExprAssignOperator.assign,
+ UnlinkedExprAssignOperator.assign,
+ UnlinkedExprAssignOperator.assign,
+ UnlinkedExprAssignOperator.assign,
+ ], ints: [
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 2,
+ 3,
+ ], strings: [
+ 'fa1',
+ 'fb',
+ 'b',
+ 'fa2',
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'A',
+ expectedKind: ReferenceKind.classOrEnum),
+ (EntityRef r) => checkTypeRef(r, null, null, 'B',
+ expectedKind: ReferenceKind.classOrEnum),
+ ]);
+ }
+
+ test_expr_cascadeSection_invokeMethod() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+class A {
+ int m(int _) => 0;
+}
+final A a = new A();
+final v = a..m(5).abs()..m(6);
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ // a
+ UnlinkedConstOperation.pushReference,
+ // ..m(5)
+ UnlinkedConstOperation.cascadeSectionBegin,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.invokeMethod,
+ // ..abs()
+ UnlinkedConstOperation.invokeMethod,
+ // a
+ UnlinkedConstOperation.cascadeSectionEnd,
+ // ..m(6)
+ UnlinkedConstOperation.cascadeSectionBegin,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.invokeMethod,
+ // a
+ UnlinkedConstOperation.cascadeSectionEnd,
+ ], ints: [
+ 5, 0, 1, // m(5)
+ 0, 0, // abs()
+ 6, 0, 1, // m(5)
+ ], strings: [
+ 'm',
+ 'abs',
+ 'm',
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'a',
+ expectedKind: ReferenceKind.topLevelPropertyAccessor),
+ ]);
+ }
+
test_expr_extractIndex_ofClassField() {
if (skipNonConstInitializers) {
return;
@@ -6242,7 +6437,7 @@
}
final v = new C().items[5];
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.invokeConstructor,
UnlinkedConstOperation.extractProperty,
UnlinkedConstOperation.pushInt,
@@ -6269,7 +6464,7 @@
}
final v = new C().f;
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.invokeConstructor,
UnlinkedConstOperation.extractProperty,
], ints: [
@@ -6283,6 +6478,72 @@
]);
}
+ test_expr_functionExpression_asArgument() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = foo(5, () => 42);
+foo(a, b) {}
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushNull,
+ UnlinkedConstOperation.invokeMethodRef
+ ], ints: [
+ 5,
+ 0,
+ 2
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+ expectedKind: ReferenceKind.topLevelFunction)
+ ]);
+ }
+
+ test_expr_functionExpression_withBlockBody() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = () { return 42; };
+''');
+ _assertUnlinkedConst(variable.constExpr,
+ isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+ }
+
+ test_expr_functionExpression_withExpressionBody() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = () => 42;
+''');
+ _assertUnlinkedConst(variable.constExpr,
+ isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+ }
+
+ test_expr_functionExpressionInvocation_withBlockBody() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = ((a, b) {return 42;})(1, 2);
+''');
+ _assertUnlinkedConst(variable.constExpr,
+ isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+ }
+
+ test_expr_functionExpressionInvocation_withExpressionBody() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = ((a, b) => 42)(1, 2);
+''');
+ _assertUnlinkedConst(variable.constExpr,
+ isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+ }
+
test_expr_invokeMethod_instance() {
if (skipNonConstInitializers) {
return;
@@ -6293,7 +6554,7 @@
}
final v = new C().m(1, b: 2, c: 3);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.invokeConstructor,
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.pushInt,
@@ -6334,7 +6595,7 @@
A a = new A();
final v = a.b.c.m(10, 20);
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.invokeMethodRef,
@@ -6370,7 +6631,7 @@
import 'a.dart' as p;
final v = p.C.m();
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.invokeMethodRef,
], ints: [
0,
@@ -6386,6 +6647,62 @@
]);
}
+ test_expr_throwException() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = throw 1 + 2;
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.add,
+ UnlinkedConstOperation.throwException,
+ ], ints: [
+ 1,
+ 2
+ ]);
+ }
+
+ test_expr_typeCast() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = 42 as num;
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushReference,
+ UnlinkedConstOperation.typeCast,
+ ], ints: [
+ 42
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num',
+ expectedKind: ReferenceKind.classOrEnum)
+ ]);
+ }
+
+ test_expr_typeCheck() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+final v = 42 is num;
+''');
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+ UnlinkedConstOperation.pushInt,
+ UnlinkedConstOperation.pushReference,
+ UnlinkedConstOperation.typeCheck,
+ ], ints: [
+ 42
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num',
+ expectedKind: ReferenceKind.classOrEnum)
+ ]);
+ }
+
test_field() {
UnlinkedClass cls = serializeClassText('class C { int i; }');
UnlinkedVariable variable = findVariable('i', variables: cls.fields);
@@ -6434,7 +6751,7 @@
static int m() => 42;
}''').fields[0];
expect(variable.isFinal, isTrue);
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.invokeMethodRef,
UnlinkedConstOperation.add,
@@ -8843,7 +9160,7 @@
int a = 0;
final v = $expr;
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.add,
@@ -8904,7 +9221,7 @@
int a = 0;
final v = $expr;
''');
- _assertUnlinkedConst(variable.constExpr, operators: [
+ _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
UnlinkedConstOperation.assignToRef,
UnlinkedConstOperation.pushInt,
UnlinkedConstOperation.add,
@@ -8922,7 +9239,7 @@
* TODO(scheglov) rename "Const" to "Expr" everywhere
*/
void _assertUnlinkedConst(UnlinkedConst constExpr,
- {bool isInvalid: false,
+ {bool isValidConst: true,
List<UnlinkedConstOperation> operators: const <UnlinkedConstOperation>[],
List<UnlinkedExprAssignOperator> assignmentOperators:
const <UnlinkedExprAssignOperator>[],
@@ -8932,7 +9249,7 @@
List<_EntityRefValidator> referenceValidators:
const <_EntityRefValidator>[]}) {
expect(constExpr, isNotNull);
- expect(constExpr.isInvalid, isInvalid);
+ expect(constExpr.isValidConst, isValidConst);
expect(constExpr.operations, operators);
expect(constExpr.ints, ints);
expect(constExpr.doubles, doubles);
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index f990a26..1315016 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -309,6 +309,7 @@
/// A local variable used encode the direct (uncaptured) references to [this].
class ThisLocal extends Local {
final ExecutableElement executableContext;
+ final hashCode = ++ElementX.elementHashCode;
ThisLocal(this.executableContext);
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index b7822d7..7c675af 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -188,7 +188,9 @@
DiagnosticReporter get reporter;
CoreTypes get coreTypes;
- bool retainCaches;
+ /// If set to `true` resolution caches will not be cleared. Use this only for
+ /// testing.
+ bool retainCachesForTesting;
void resolveTypedef(TypedefElement typdef);
void resolveClass(ClassElement cls);
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 39fc9b9..2cfadd3 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1959,7 +1959,7 @@
final Map<Element, ResolutionImpact> _resolutionImpactCache =
<Element, ResolutionImpact>{};
final Map<Element, WorldImpact> _worldImpactCache = <Element, WorldImpact>{};
- bool retainCaches = false;
+ bool retainCachesForTesting = false;
_CompilerResolution(this.compiler);
@@ -2031,7 +2031,7 @@
assert(invariant(element, !element.isSynthesized || tree == null));
ResolutionImpact resolutionImpact =
compiler.resolver.resolve(element);
- if (compiler.serialization.supportSerialization || retainCaches) {
+ if (compiler.serialization.supportSerialization || retainCachesForTesting) {
// [ResolutionImpact] is currently only used by serialization. The
// enqueuer uses the [WorldImpact] which is always cached.
// TODO(johnniwinther): Align these use cases better; maybe only
@@ -2054,7 +2054,7 @@
@override
void uncacheWorldImpact(Element element) {
- if (retainCaches) return;
+ if (retainCachesForTesting) return;
if (compiler.serialization.isDeserialized(element)) return;
assert(invariant(element, _worldImpactCache[element] != null,
message: "WorldImpact not computed for $element."));
@@ -2064,7 +2064,7 @@
@override
void emptyCache() {
- if (retainCaches) return;
+ if (retainCachesForTesting) return;
for (Element element in _worldImpactCache.keys) {
_worldImpactCache[element] = const WorldImpact();
}
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
index 8df9c18..5262138 100644
--- a/pkg/compiler/lib/src/dart_types.dart
+++ b/pkg/compiler/lib/src/dart_types.dart
@@ -445,6 +445,8 @@
}
class InterfaceType extends GenericType {
+ int _hashCode;
+
InterfaceType(ClassElement element,
[List<DartType> typeArguments = const <DartType>[]])
: super(element, typeArguments) {
@@ -503,7 +505,7 @@
return member;
}
- int get hashCode => super.hashCode;
+ int get hashCode => _hashCode ??= super.hashCode;
InterfaceType asRaw() => super.asRaw();
@@ -825,6 +827,8 @@
return visitor.visitDynamicType(this, argument);
}
+ int get hashCode => 91;
+
String toString() => name;
}
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index 6c2e843..85fd159 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -9,6 +9,8 @@
import '../common/names.dart' show
Names,
Uris;
+import '../core_types.dart' show
+ CoreClasses;
import '../dart_types.dart' show
DartType,
InterfaceType,
@@ -430,6 +432,12 @@
}
@override
+ bool implementsFunction(CoreClasses coreClasses) {
+ return asInstanceOf(coreClasses.functionClass) != null ||
+ callType != null;
+ }
+
+ @override
bool isSubclassOf(ClassElement cls) {
// Use [declaration] for both [this] and [cls], because
// declaration classes hold the superclass hierarchy.
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index be8b45c..bed7cea 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -13,8 +13,6 @@
import '../constants/constant_constructors.dart';
import '../constants/constructors.dart';
import '../constants/expressions.dart';
-import '../core_types.dart' show
- CoreClasses;
import '../dart_types.dart';
import '../diagnostics/messages.dart' show
MessageTemplate;
@@ -2701,11 +2699,6 @@
backendMembers.forEach(f);
}
- bool implementsFunction(CoreClasses coreClasses) {
- return asInstanceOf(coreClasses.functionClass) != null ||
- callType != null;
- }
-
// TODO(johnniwinther): Remove these when issue 18630 is fixed.
ClassElement get patch => super.patch;
ClassElement get origin => super.origin;
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
index d9877a4..86c3337 100644
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/element_serialization.dart
@@ -308,10 +308,13 @@
mixins = mixins.reversed.toList();
InterfaceType supertype = element.thisType.asInstanceOf(superclass);
-
encoder.setType(Key.SUPERTYPE, supertype);
encoder.setTypes(Key.MIXINS, mixins);
encoder.setTypes(Key.INTERFACES, element.interfaces.toList());
+ FunctionType callType = element.declaration.callType;
+ if (callType != null) {
+ encoder.setType(Key.CALL_TYPE, element.callType);
+ }
if (element.isMixinApplication) {
MixinApplicationElement mixinElement = element;
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index c91561b..5bc9d23 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -39,7 +39,6 @@
Iterable set1,
Iterable set2,
[bool elementEquivalence(a, b) = equality]) {
-
Set remaining = set2.toSet();
for (var element1 in set1) {
bool found = false;
diff --git a/pkg/compiler/lib/src/serialization/keys.dart b/pkg/compiler/lib/src/serialization/keys.dart
index 9ee569d..7758be6 100644
--- a/pkg/compiler/lib/src/serialization/keys.dart
+++ b/pkg/compiler/lib/src/serialization/keys.dart
@@ -10,6 +10,7 @@
static const Key ARGUMENTS = const Key('arguments');
static const Key BOUND = const Key('bound');
static const Key CALL_STRUCTURE = const Key('callStructure');
+ static const Key CALL_TYPE = const Key('callType');
static const Key CANONICAL_URI = const Key('canonicalUri');
static const Key CLASS = const Key('class');
static const Key COMPILATION_UNIT = const Key('compilation-unit');
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index dc6ede2..7c02c7a 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -747,7 +747,6 @@
}
abstract class ClassElementMixin implements ElementZ, ClassElement {
-
InterfaceType _createType(List<DartType> typeArguments) {
return new InterfaceType(this, typeArguments);
}
@@ -779,11 +778,6 @@
bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
@override
- bool implementsFunction(CoreClasses coreClasses) {
- return _unsupported('implementsFunction');
- }
-
- @override
bool get isEnumClass => false;
@override
@@ -827,6 +821,7 @@
DartType _supertype;
OrderedTypeSet _allSupertypesAndSelf;
Link<DartType> _interfaces;
+ FunctionType _callType;
ClassElementZ(ObjectDecoder decoder)
: super(decoder);
@@ -860,6 +855,7 @@
_allSupertypesAndSelf =
new OrderedTypeSetBuilder(this)
.createOrderedTypeSet(_supertype, _interfaces);
+ _callType = _decoder.getType(Key.CALL_TYPE, isOptional: true);
}
}
}
@@ -901,6 +897,12 @@
@override
bool get isUnnamedMixinApplication => false;
+
+ @override
+ FunctionType get callType {
+ _ensureSuperHierarchy();
+ return _callType;
+ }
}
abstract class MixinApplicationElementMixin
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index 818a6d7..bed1d60 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -181,6 +181,8 @@
_directSubclasses = _directSubclasses.prepend(subclass);
}
+ Iterable<ClassHierarchyNode> get directSubclasses => _directSubclasses;
+
/// Returns `true` if [other] is contained in the subtree of this node.
///
/// This means that [other] is a subclass of [cls].
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 5c71adc..8003189 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -38,3 +38,6 @@
# Service protocol is not supported when running a full application snapshot.
[ ($runtime == dart_product) ]
*: SkipByDesign
+
+[ $compiler == dart2analyzer ]
+evaluate_activation_in_method_class_test: CompileTimeError # Issue 24478
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index cad89e5..26e51fe 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1109,6 +1109,7 @@
bool optimized,
intptr_t osr_id) {
ASSERT(!FLAG_precompiled_mode);
+ ASSERT(!optimized || function.was_compiled());
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
Thread* const thread = Thread::Current();
@@ -1165,7 +1166,11 @@
}
const bool success = helper.Compile(pipeline);
- if (!success) {
+ if (success) {
+ if (!optimized) {
+ function.set_was_compiled(true);
+ }
+ } else {
if (optimized) {
if (Compiler::IsBackgroundCompilation()) {
// Try again later, background compilation may abort because of
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 9ee6365..c8a5f28 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -609,7 +609,9 @@
if (constant != NULL) {
return new(Z) ConstantInstr(constant->value());
} else {
- return new(Z) ParameterInstr(i, graph->graph_entry());
+ ParameterInstr* param = new(Z) ParameterInstr(i, graph->graph_entry());
+ param->UpdateType(*argument->Type());
+ return param;
}
}
@@ -637,10 +639,9 @@
return false;
}
- // Function has no type feedback. With precompilation we don't rely on
- // type feedback.
- if (!FLAG_precompiled_mode &&
- function.ic_data_array() == Object::null()) {
+ // Do not rely on function type feedback or presence of code to determine
+ // if a function was compiled.
+ if (!FLAG_precompiled_mode && !function.was_compiled()) {
TRACE_INLINING(THR_Print(" Bailout: not compiled yet\n"));
PRINT_INLINING_TREE("Not compiled",
&call_data->caller, &function, call_data->call);
@@ -832,6 +833,13 @@
DEBUG_ASSERT(callee_graph->VerifyUseLists());
} else {
JitOptimizer optimizer(callee_graph);
+
+ optimizer.ApplyClassIds();
+ DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
+ FlowGraphTypePropagator::Propagate(callee_graph);
+ DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
optimizer.ApplyICData();
DEBUG_ASSERT(callee_graph->VerifyUseLists());
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 814ed36..4f9f8d0 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -5840,7 +5840,7 @@
}
-void Function::set_kind_tag(intptr_t value) const {
+void Function::set_kind_tag(uint32_t value) const {
StoreNonPointer(&raw_ptr()->kind_tag_, static_cast<uint32_t>(value));
}
@@ -6492,6 +6492,7 @@
result.set_is_generated_body(false);
result.set_always_inline(false);
result.set_is_polymorphic_target(false);
+ result.set_was_compiled(false);
result.set_owner(owner);
result.set_token_pos(token_pos);
result.set_end_token_pos(token_pos);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 91d8e0e..9a946b0 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2433,10 +2433,11 @@
StoreNonPointer(&raw_ptr()->usage_counter_, value);
}
- int16_t deoptimization_counter() const {
+ int8_t deoptimization_counter() const {
return raw_ptr()->deoptimization_counter_;
}
- void set_deoptimization_counter(int16_t value) const {
+ void set_deoptimization_counter(int8_t value) const {
+ ASSERT(value >= 0);
StoreNonPointer(&raw_ptr()->deoptimization_counter_, value);
}
@@ -2718,6 +2719,15 @@
void set_modifier(RawFunction::AsyncModifier value) const;
+ // 'was_compiled' is true if the function was compiled once in this
+ // VM instantiation. It independent from presence of type feedback
+ // (ic_data_array) and code, whihc may be loaded from a snapshot.
+ void set_was_compiled(bool value) const {
+ StoreNonPointer(&raw_ptr()->was_compiled_, value ? 1 : 0);
+ }
+ bool was_compiled() const { return raw_ptr()->was_compiled_ == 1; }
+
+
// static: Considered during class-side or top-level resolution rather than
// instance-side resolution.
// const: Valid target of a const constructor call.
@@ -2824,7 +2834,7 @@
RawScript* eval_script() const;
void set_eval_script(const Script& value) const;
void set_num_optional_parameters(intptr_t value) const; // Encoded value.
- void set_kind_tag(intptr_t value) const;
+ void set_kind_tag(uint32_t value) const;
void set_data(const Object& value) const;
static RawFunction* New();
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index bfccf94..323fed4 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -852,7 +852,8 @@
int32_t usage_counter_; // Incremented while function is running.
int16_t num_fixed_parameters_;
int16_t num_optional_parameters_; // > 0: positional; < 0: named.
- int16_t deoptimization_counter_;
+ int8_t deoptimization_counter_;
+ int8_t was_compiled_;
uint32_t kind_tag_; // See Function::KindTagBits.
uint16_t optimized_instruction_count_;
uint16_t optimized_call_site_count_;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 7c861e2..e8fcf69 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -733,10 +733,11 @@
func.set_optimized_call_site_count(0);
} else {
func.set_usage_counter(reader->Read<int32_t>());
- func.set_deoptimization_counter(reader->Read<int16_t>());
+ func.set_deoptimization_counter(reader->Read<int8_t>());
func.set_optimized_instruction_count(reader->Read<uint16_t>());
func.set_optimized_call_site_count(reader->Read<uint16_t>());
}
+ func.set_was_compiled(false);
// Set all the object fields.
READ_OBJECT_FIELDS(func,
@@ -814,7 +815,7 @@
} else {
writer->Write<int32_t>(0);
}
- writer->Write<int16_t>(ptr()->deoptimization_counter_);
+ writer->Write<int8_t>(ptr()->deoptimization_counter_);
writer->Write<uint16_t>(ptr()->optimized_instruction_count_);
writer->Write<uint16_t>(ptr()->optimized_call_site_count_);
}
diff --git a/sdk/lib/_blink/dartium/_blink_dartium.dart b/sdk/lib/_blink/dartium/_blink_dartium.dart
index 03e0eed..609fd88 100644
--- a/sdk/lib/_blink/dartium/_blink_dartium.dart
+++ b/sdk/lib/_blink/dartium/_blink_dartium.dart
@@ -23301,6 +23301,7 @@
// In any case, returns a typed JS wrapper compatibile with dart:html and the new
// typed JS Interop.
static defineInterceptorCustomElement(jsObject, Type type) native "Utils_defineInterceptorCustomElement";
+ static defineInterceptor(jsObject, Type type) native "Utils_defineInterceptor";
static setInstanceInterceptor(o, Type type, {bool customElement: false}) native "Utils_setInstanceInterceptor";
// This method will throw if the element isn't actually a real Element.
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 89565e1..87fc341 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -259,13 +259,13 @@
* _outputSink.add(data);
* }
*
- * void addError(e, [st]) => _outputSink(e, st);
+ * void addError(e, [st]) => _outputSink.addError(e, st);
* void close() => _outputSink.close();
* }
*
* class DuplicationTransformer implements StreamTransformer<String, String> {
* // Some generic types ommitted for brevety.
- * Stream bind(Stream stream) => new Stream<String>.eventTransform(
+ * Stream bind(Stream stream) => new Stream<String>.eventTransformed(
* stream,
* (EventSink sink) => new DuplicationSink(sink));
* }
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index b54fc76..b9db444 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -20088,6 +20088,10 @@
*/
void registerElement(String tag, Type customElementClass,
{String extendsTag}) {
+ // Hack to setup an interceptor for HTMLElement so it isn't changed when a custom element is created.
+ var jsHTMLElementPrototype = js.JsNative.getProperty(js.JsNative.getProperty(js.context, 'HTMLElement'),'prototype');
+ _blink.Blink_Utils.defineInterceptor(jsHTMLElementPrototype, HtmlElement.instanceRuntimeType);
+
// Figure out which DOM class is being extended from the user's Dart class.
var classMirror = reflectClass(customElementClass);
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index af6214e..3fe27f7 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -1354,14 +1354,6 @@
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/32
WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-002_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/33
# Must fix failures below after JsInterop checkin.
-WebPlatformTest/custom-elements/instantiating/createElement_A02_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElementNS_A04_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElementNS_A03_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: RuntimeError # Issue 26134
-WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Issue 26134
WebPlatformTest/dom/nodes/Node-appendChild_t01: RuntimeError # Issue 26134
WebPlatformTest/dom/nodes/attributes/setAttribute_A01_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/Document/createElement-invalid-names_t01: RuntimeError # Issue 26134
@@ -1371,7 +1363,6 @@
LayoutTests/fast/dom/HTMLTemplateElement/cycles_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/computed-style-set-property_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/custom/element-type_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/custom/type-extensions_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/custom/element-upgrade_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/custom/document-register-type-extensions_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/custom/document-register-namespace_t01: RuntimeError # Issue 26134
diff --git a/tests/compiler/dart2js/serialization_analysis_test.dart b/tests/compiler/dart2js/serialization_analysis_test.dart
index ebbc6f0..373fb89 100644
--- a/tests/compiler/dart2js/serialization_analysis_test.dart
+++ b/tests/compiler/dart2js/serialization_analysis_test.dart
@@ -17,6 +17,10 @@
const List<Test> TESTS = const <Test>[
const Test(const {
+ 'main.dart': 'main() {}'
+ }),
+
+ const Test(const {
'main.dart': 'main() => print("Hello World");'
}),
diff --git a/tests/compiler/dart2js/serialization_impact_test.dart b/tests/compiler/dart2js/serialization_impact_test.dart
index 0bd4833..2fbd212 100644
--- a/tests/compiler/dart2js/serialization_impact_test.dart
+++ b/tests/compiler/dart2js/serialization_impact_test.dart
@@ -37,25 +37,28 @@
Compiler compilerNormal = compilerFor(
memorySourceFiles: sourceFiles,
options: [Flags.analyzeOnly]);
- compilerNormal.resolution.retainCaches = true;
+ compilerNormal.resolution.retainCachesForTesting = true;
await compilerNormal.run(entryPoint);
Compiler compilerDeserialized = compilerFor(
memorySourceFiles: sourceFiles,
options: [Flags.analyzeOnly]);
- compilerDeserialized.resolution.retainCaches = true;
+ compilerDeserialized.resolution.retainCachesForTesting = true;
deserialize(compilerDeserialized, serializedData);
await compilerDeserialized.run(entryPoint);
- checkResolutionImpacts(compilerNormal, compilerDeserialized);
+ checkResolutionImpacts(compilerNormal, compilerDeserialized, verbose: true);
}
/// Check equivalence of [impact1] and [impact2].
void checkImpacts(Element element1, Element element2,
- ResolutionImpact impact1, ResolutionImpact impact2) {
+ ResolutionImpact impact1, ResolutionImpact impact2,
+ {bool verbose: false}) {
if (impact1 == null || impact2 == null) return;
- print('Checking impacts for $element1 vs $element2');
+ if (verbose) {
+ print('Checking impacts for $element1 vs $element2');
+ }
testResolutionImpactEquivalence(impact1, impact2, const CheckStrategy());
}
@@ -63,7 +66,10 @@
/// Check equivalence between all resolution impacts common to [compiler1] and
/// [compiler2].
-void checkResolutionImpacts(Compiler compiler1, Compiler compiler2) {
+void checkResolutionImpacts(
+ Compiler compiler1,
+ Compiler compiler2,
+ {bool verbose: false}) {
void checkMembers(Element member1, Element member2) {
if (member1.isClass && member2.isClass) {
@@ -87,7 +93,8 @@
checkImpacts(
member1, member2,
compiler1.resolution.getResolutionImpact(member1),
- compiler2.serialization.deserializer.getResolutionImpact(member2));
+ compiler2.serialization.deserializer.getResolutionImpact(member2),
+ verbose: verbose);
}
}
diff --git a/tests/compiler/dart2js/serialization_model_test.dart b/tests/compiler/dart2js/serialization_model_test.dart
new file mode 100644
index 0000000..b8cef25
--- /dev/null
+++ b/tests/compiler/dart2js/serialization_model_test.dart
@@ -0,0 +1,224 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization_model_test;
+
+import 'dart:async';
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common/backend_api.dart';
+import 'package:compiler/src/common/names.dart';
+import 'package:compiler/src/common/resolution.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/dart_types.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/serialization/element_serialization.dart';
+import 'package:compiler/src/serialization/impact_serialization.dart';
+import 'package:compiler/src/serialization/json_serializer.dart';
+import 'package:compiler/src/serialization/serialization.dart';
+import 'package:compiler/src/serialization/equivalence.dart';
+import 'package:compiler/src/serialization/task.dart';
+import 'package:compiler/src/universe/world_impact.dart';
+import 'package:compiler/src/universe/class_set.dart';
+import 'package:compiler/src/universe/use.dart';
+import 'memory_compiler.dart';
+import 'serialization_helper.dart';
+import 'serialization_analysis_test.dart';
+import 'serialization_impact_test.dart';
+import 'serialization_test.dart';
+
+main(List<String> arguments) {
+ String filename;
+ for (String arg in arguments) {
+ if (!arg.startsWith('-')) {
+ filename = arg;
+ }
+ }
+ bool verbose = arguments.contains('-v');
+
+ asyncTest(() async {
+ print('------------------------------------------------------------------');
+ print('serialize dart:core');
+ print('------------------------------------------------------------------');
+ String serializedData;
+ File file = new File('out.data');
+ if (arguments.contains('-l')) {
+ if (file.existsSync()) {
+ print('Loading data from $file');
+ serializedData = file.readAsStringSync();
+ }
+ }
+ if (serializedData == null) {
+ serializedData = await serializeDartCore();
+ if (arguments.contains('-s')) {
+ print('Saving data to $file');
+ file.writeAsStringSync(serializedData);
+ }
+ }
+ if (filename != null) {
+ Uri entryPoint = Uri.base.resolve(nativeToUriPath(filename));
+ await check(serializedData, entryPoint);
+ } else {
+ Uri entryPoint = Uri.parse('memory:main.dart');
+ for (Test test in TESTS) {
+ if (test.sourceFiles['main.dart']
+ .contains('main(List<String> arguments)')) {
+ // TODO(johnniwinther): Check this test.
+ continue;
+ }
+ print('==============================================================');
+ print(test.sourceFiles);
+ await check(
+ serializedData,
+ entryPoint,
+ sourceFiles: test.sourceFiles,
+ verbose: verbose);
+ }
+ }
+ });
+}
+
+Future check(
+ String serializedData,
+ Uri entryPoint,
+ {Map<String, String> sourceFiles: const <String, String>{},
+ bool verbose: false}) async {
+
+ print('------------------------------------------------------------------');
+ print('compile normal');
+ print('------------------------------------------------------------------');
+ Compiler compilerNormal = compilerFor(
+ memorySourceFiles: sourceFiles,
+ options: [Flags.analyzeOnly]);
+ compilerNormal.resolution.retainCachesForTesting = true;
+ await compilerNormal.run(entryPoint);
+ compilerNormal.world.populate();
+
+ print('------------------------------------------------------------------');
+ print('compile deserialized');
+ print('------------------------------------------------------------------');
+ Compiler compilerDeserialized = compilerFor(
+ memorySourceFiles: sourceFiles,
+ options: [Flags.analyzeOnly]);
+ compilerDeserialized.resolution.retainCachesForTesting = true;
+ deserialize(compilerDeserialized, serializedData);
+ await compilerDeserialized.run(entryPoint);
+ compilerDeserialized.world.populate();
+
+ checkResolutionImpacts(
+ compilerNormal, compilerDeserialized,
+ verbose: verbose);
+
+ checkSets(
+ compilerNormal.resolverWorld.directlyInstantiatedClasses,
+ compilerDeserialized.resolverWorld.directlyInstantiatedClasses,
+ "Directly instantiated classes mismatch",
+ areElementsEquivalent,
+ verbose: verbose);
+
+ checkSets(
+ compilerNormal.resolverWorld.instantiatedTypes,
+ compilerDeserialized.resolverWorld.instantiatedTypes,
+ "Instantiated types mismatch",
+ areTypesEquivalent,
+ // TODO(johnniwinther): Ensure that all instantiated types are tracked.
+ failOnUnfound: false,
+ verbose: verbose);
+
+ checkSets(
+ compilerNormal.resolverWorld.isChecks,
+ compilerDeserialized.resolverWorld.isChecks,
+ "Is-check mismatch",
+ areTypesEquivalent,
+ verbose: verbose);
+
+ checkSets(
+ compilerNormal.enqueuer.resolution.processedElements,
+ compilerDeserialized.enqueuer.resolution.processedElements,
+ "Processed element mismatch",
+ areElementsEquivalent,
+ verbose: verbose);
+
+ checkClassHierarchyNodes(
+ compilerNormal.world.getClassHierarchyNode(
+ compilerNormal.coreClasses.objectClass),
+ compilerDeserialized.world.getClassHierarchyNode(
+ compilerDeserialized.coreClasses.objectClass),
+ verbose: verbose);
+}
+
+void checkClassHierarchyNodes(
+ ClassHierarchyNode a, ClassHierarchyNode b,
+ {bool verbose: false}) {
+ if (verbose) {
+ print('Checking $a vs $b');
+ }
+ Expect.isTrue(
+ areElementsEquivalent(a.cls, b.cls),
+ "Element identity mismatch for ${a.cls} vs ${b.cls}.");
+ Expect.equals(
+ a.isDirectlyInstantiated,
+ b.isDirectlyInstantiated,
+ "Value mismatch for 'isDirectlyInstantiated' for ${a.cls} vs ${b.cls}.");
+ Expect.equals(
+ a.isIndirectlyInstantiated,
+ b.isIndirectlyInstantiated,
+ "Value mismatch for 'isIndirectlyInstantiated' "
+ "for ${a.cls} vs ${b.cls}.");
+ // TODO(johnniwinther): Enforce a canonical and stable order on direct
+ // subclasses.
+ for (ClassHierarchyNode child in a.directSubclasses) {
+ bool found = false;
+ for (ClassHierarchyNode other in b.directSubclasses) {
+ if (areElementsEquivalent(child.cls, other.cls)) {
+ checkClassHierarchyNodes(child, other,
+ verbose: verbose);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ Expect.isFalse(
+ child.isInstantiated, 'Missing subclass ${child.cls} of ${a.cls}');
+ }
+ }
+}
+
+void checkSets(
+ Iterable set1,
+ Iterable set2,
+ String messagePrefix,
+ bool areEquivalent(a, b),
+ {bool failOnUnfound: true,
+ bool verbose: false}) {
+ List common = [];
+ List unfound = [];
+ Set remaining = computeSetDifference(
+ set1, set2, common, unfound, areEquivalent);
+ StringBuffer sb = new StringBuffer();
+ sb.write("$messagePrefix:");
+ if (verbose) {
+ sb.write("\n Common:\n ${common.join('\n ')}");
+ }
+ if (unfound.isNotEmpty || verbose) {
+ sb.write("\n Unfound:\n ${unfound.join('\n ')}");
+ }
+ if (remaining.isNotEmpty || verbose) {
+ sb.write("\n Extra: \n ${remaining.join('\n ')}");
+ }
+ String message = sb.toString();
+ if (unfound.isNotEmpty || remaining.isNotEmpty) {
+
+ if (failOnUnfound || remaining.isNotEmpty) {
+ Expect.fail(message);
+ } else {
+ print(message);
+ }
+ } else if (verbose) {
+ print(message);
+ }
+}
diff --git a/tests/compiler/dart2js/serialization_test.dart b/tests/compiler/dart2js/serialization_test.dart
index 26740bc..c19fb61 100644
--- a/tests/compiler/dart2js/serialization_test.dart
+++ b/tests/compiler/dart2js/serialization_test.dart
@@ -171,19 +171,24 @@
return true;
}
-/// Check equivalence of the two iterables, [set1] and [set1], as sets using
-/// [elementEquivalence] to compute the pair-wise equivalence.
+/// Computes the set difference between [set1] and [set2] using
+/// [elementEquivalence] to determine element equivalence.
///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-bool checkSetEquivalence(
- var object1,
- var object2,
- String property,
+/// Elements both in [set1] and [set2] are added to [common], elements in [set1]
+/// but not in [set2] are added to [unfound], and the set of elements in [set2]
+/// but not in [set1] are returned.
+Set computeSetDifference(
Iterable set1,
Iterable set2,
- bool sameElement(a, b)) {
- List common = [];
- List unfound = [];
+ List common,
+ List unfound,
+ [bool sameElement(a, b) = equality]) {
+ // TODO(johnniwinther): Avoid the quadratic cost here. Some ideas:
+ // - convert each set to a list and sort it first, then compare by walking
+ // both lists in parallel
+ // - map each element to a canonical object, create a map containing those
+ // mappings, use the mapped sets to compare (then operations like
+ // set.difference would work)
Set remaining = set2.toSet();
for (var element1 in set1) {
bool found = false;
@@ -200,6 +205,24 @@
unfound.add(element1);
}
}
+ return remaining;
+}
+
+/// Check equivalence of the two iterables, [set1] and [set1], as sets using
+/// [elementEquivalence] to compute the pair-wise equivalence.
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkSetEquivalence(
+ var object1,
+ var object2,
+ String property,
+ Iterable set1,
+ Iterable set2,
+ bool sameElement(a, b)) {
+ List common = [];
+ List unfound = [];
+ Set remaining =
+ computeSetDifference(set1, set2, common, unfound, sameElement);
if (unfound.isNotEmpty || remaining.isNotEmpty) {
String message =
"Set mismatch for `$property` on $object1 vs $object2: \n"
diff --git a/tests/html/html.status b/tests/html/html.status
index 742f19d..6862539 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -39,6 +39,7 @@
[ $compiler == dart2js && $browser ]
custom/created_callback_test: Fail # Support for created constructor. Issue 14835
fontface_loaded_test: Fail # Support for promises.
+js_test/JsArray: RuntimeError # Issue 26197
[ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim || $runtime == ff || $ie) ]
custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 18acb05..ee710f8 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -9,7 +9,7 @@
vars.update({
"dartium_chromium_commit": "f41b46133f75612579588ba14265a7e241406b0e",
- "dartium_webkit_commit": "d87a444a070555396e0b2167329bccb95b419435",
+ "dartium_webkit_commit": "d4cfc86d765d59fd7048c7272b924a1a9e9ce5fe",
"chromium_base_revision": "338390",
# We use mirrors of all github repos to guarantee reproducibility and
diff --git a/tools/dom/scripts/generate_blink_file.py b/tools/dom/scripts/generate_blink_file.py
index 2f69b0c..cdac697 100644
--- a/tools/dom/scripts/generate_blink_file.py
+++ b/tools/dom/scripts/generate_blink_file.py
@@ -131,6 +131,7 @@
// In any case, returns a typed JS wrapper compatibile with dart:html and the new
// typed JS Interop.
static defineInterceptorCustomElement(jsObject, Type type) native "Utils_defineInterceptorCustomElement";
+ static defineInterceptor(jsObject, Type type) native "Utils_defineInterceptor";
static setInstanceInterceptor(o, Type type, {bool customElement: false}) native "Utils_setInstanceInterceptor";
// This method will throw if the element isn't actually a real Element.
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 7768aad..a52e369 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -362,6 +362,10 @@
_registerCustomElement(JS('', 'window'), this, tag, customElementClass,
extendsTag);
$else
+ // Hack to setup an interceptor for HTMLElement so it isn't changed when a custom element is created.
+ var jsHTMLElementPrototype = js.JsNative.getProperty(js.JsNative.getProperty(js.context, 'HTMLElement'),'prototype');
+ _blink.Blink_Utils.defineInterceptor(jsHTMLElementPrototype, HtmlElement.instanceRuntimeType);
+
// Figure out which DOM class is being extended from the user's Dart class.
var classMirror = reflectClass(customElementClass);
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index d514bd6..1d39071 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -12,17 +12,14 @@
import "path.dart";
import "utils.dart";
-Future _executeCommand(String executable,
- List<String> args,
- [String stdin = ""]) {
+Future _executeCommand(String executable, List<String> args,
+ [String stdin = ""]) {
return _executeCommandRaw(executable, args, stdin).then((results) => null);
}
-Future _executeCommandGetOutput(String executable,
- List<String> args,
- [String stdin = ""]) {
- return _executeCommandRaw(executable, args, stdin)
- .then((output) => output);
+Future _executeCommandGetOutput(String executable, List<String> args,
+ [String stdin = ""]) {
+ return _executeCommandRaw(executable, args, stdin).then((output) => output);
}
/**
@@ -32,11 +29,12 @@
* If the exit code of the process was nonzero it will complete with an error.
* If starting the process failed, it will complete with an error as well.
*/
-Future _executeCommandRaw(String executable,
- List<String> args,
- [String stdin = ""]) {
+Future _executeCommandRaw(String executable, List<String> args,
+ [String stdin = ""]) {
Future<String> getOutput(Stream<List<int>> stream) {
- return stream.transform(UTF8.decoder).toList()
+ return stream
+ .transform(UTF8.decoder)
+ .toList()
.then((data) => data.join(""));
}
@@ -47,16 +45,18 @@
}
process.stdin.close();
- var futures = [getOutput(process.stdout),
- getOutput(process.stderr),
- process.exitCode];
+ var futures = [
+ getOutput(process.stdout),
+ getOutput(process.stderr),
+ process.exitCode
+ ];
return Future.wait(futures).then((results) {
bool success = results[2] == 0;
if (!success) {
var error = "Running: '\$ $executable ${args.join(' ')}' failed:"
- "stdout: \n ${results[0]}"
- "stderr: \n ${results[1]}"
- "exitCode: \n ${results[2]}";
+ "stdout: \n ${results[0]}"
+ "stderr: \n ${results[1]}"
+ "exitCode: \n ${results[2]}";
throw new Exception(error);
} else {
DebugLogger.info("Success: $executable finished");
@@ -153,8 +153,18 @@
*/
class AndroidHelper {
static Future createAvd(String name, String target) {
- var args = ['--silent', 'create', 'avd', '--name', '$name',
- '--target', '$target', '--force', '--abi', 'armeabi-v7a'];
+ var args = [
+ '--silent',
+ 'create',
+ 'avd',
+ '--name',
+ '$name',
+ '--target',
+ '$target',
+ '--force',
+ '--abi',
+ 'armeabi-v7a'
+ ];
// We're adding newlines to stdin to simulate <enter>.
return _executeCommand("android", args, "\n\n\n\n");
}
@@ -189,15 +199,15 @@
checkUntilBooted() {
_adbCommandGetOutput(['shell', 'getprop', 'sys.boot_completed'])
.then((String stdout) {
- stdout = stdout.trim();
- if (stdout == '1') {
- completer.complete();
- } else {
- new Timer(timeout, checkUntilBooted);
- }
- }).catchError((error) {
- new Timer(timeout, checkUntilBooted);
- });
+ stdout = stdout.trim();
+ if (stdout == '1') {
+ completer.complete();
+ } else {
+ new Timer(timeout, checkUntilBooted);
+ }
+ }).catchError((error) {
+ new Timer(timeout, checkUntilBooted);
+ });
}
checkUntilBooted();
return completer.future;
@@ -250,9 +260,16 @@
* Start the given intent on the device.
*/
Future startActivity(Intent intent) {
- var arguments = ['shell', 'am', 'start', '-W',
- '-a', intent.action,
- '-n', "${intent.package}/${intent.activity}"];
+ var arguments = [
+ 'shell',
+ 'am',
+ 'start',
+ '-W',
+ '-a',
+ intent.action,
+ '-n',
+ "${intent.package}/${intent.activity}"
+ ];
if (intent.dataUri != null) {
arguments.addAll(['-d', intent.dataUri]);
}
@@ -312,10 +329,12 @@
return Process.run('adb', ['devices']).then((ProcessResult result) {
if (result.exitCode != 0) {
throw new Exception("Could not list devices [stdout: ${result.stdout},"
- "stderr: ${result.stderr}]");
+ "stderr: ${result.stderr}]");
}
- return _deviceLineRegexp.allMatches(result.stdout)
- .map((Match m) => m.group(1)).toList();
+ return _deviceLineRegexp
+ .allMatches(result.stdout)
+ .map((Match m) => m.group(1))
+ .toList();
});
}
}
@@ -331,4 +350,3 @@
Intent(this.action, this.package, this.activity, [this.dataUri]);
}
-
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index a6d061c..6e37549 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -7,6 +7,7 @@
import "dart:convert" show LineSplitter, UTF8, JSON;
import "dart:core";
import "dart:io";
+import "dart:math" show max, min;
import 'android.dart';
import 'http_server.dart';
@@ -66,9 +67,8 @@
Browser();
- factory Browser.byName(String name,
- String executablePath,
- [bool checkedMode = false]) {
+ factory Browser.byName(String name, String executablePath,
+ [bool checkedMode = false]) {
var browser;
if (name == 'firefox') {
browser = new Firefox();
@@ -89,12 +89,21 @@
return browser;
}
- static const List<String> SUPPORTED_BROWSERS =
- const ['safari', 'ff', 'firefox', 'chrome', 'ie9', 'ie10',
- 'ie11', 'dartium'];
+ static const List<String> SUPPORTED_BROWSERS = const [
+ 'safari',
+ 'ff',
+ 'firefox',
+ 'chrome',
+ 'ie9',
+ 'ie10',
+ 'ie11',
+ 'dartium'
+ ];
- static const List<String> BROWSERS_WITH_WINDOW_SUPPORT =
- const ['ie11', 'ie10'];
+ static const List<String> BROWSERS_WITH_WINDOW_SUPPORT = const [
+ 'ie11',
+ 'ie10'
+ ];
// TODO(kustermann): add standard support for chrome on android
static bool supportedBrowser(String name) {
@@ -143,10 +152,10 @@
* Start the browser using the supplied argument.
* This sets up the error handling and usage logging.
*/
- Future<bool> startBrowser(String command,
- List<String> arguments,
- {Map<String,String> environment}) {
- return Process.start(command, arguments, environment: environment)
+ Future<bool> startBrowserProcess(String command, List<String> arguments,
+ {Map<String, String> environment}) {
+ return Process
+ .start(command, arguments, environment: environment)
.then((startedProcess) {
_logEvent("Started browser using $command ${arguments.join(' ')}");
process = startedProcess;
@@ -168,7 +177,7 @@
// handles alive even though the direct subprocess is dead.
Timer watchdogTimer;
- void closeStdout([_]){
+ void closeStdout([_]) {
if (!stdoutIsDone) {
stdoutDone.complete();
stdoutIsDone = true;
@@ -191,7 +200,7 @@
}
stdoutSubscription =
- process.stdout.transform(UTF8.decoder).listen((data) {
+ process.stdout.transform(UTF8.decoder).listen((data) {
_addStdout(data);
}, onError: (error) {
// This should _never_ happen, but we really want this in the log
@@ -200,21 +209,21 @@
}, onDone: closeStdout);
stderrSubscription =
- process.stderr.transform(UTF8.decoder).listen((data) {
+ process.stderr.transform(UTF8.decoder).listen((data) {
_addStderr(data);
}, onError: (error) {
// This should _never_ happen, but we really want this in the log
// if it actually does due to dart:io or vm bug.
_logEvent("An error occured in the process stderr handling: $error");
- }, onDone: closeStderr);
+ }, onDone: closeStderr);
process.exitCode.then((exitCode) {
_logEvent("Browser closed with exitcode $exitCode");
if (!stdoutIsDone || !stderrIsDone) {
watchdogTimer = new Timer(MAX_STDIO_DELAY, () {
- DebugLogger.warning(
- "$MAX_STDIO_DELAY_PASSED_MESSAGE (browser: $this)");
+ DebugLogger
+ .warning("$MAX_STDIO_DELAY_PASSED_MESSAGE (browser: $this)");
watchdogTimer = null;
stdoutSubscription.cancel();
stderrSubscription.cancel();
@@ -254,7 +263,7 @@
* where it will be reported for failing tests. Used to report which
* android device a failing test is running on.
*/
- void logBrowserInfoToTestBrowserOutput() { }
+ void logBrowserInfoToTestBrowserOutput() {}
String toString();
@@ -273,19 +282,22 @@
* Directories where safari stores state. We delete these if the deleteCache
* is set
*/
- static const List<String> CACHE_DIRECTORIES =
- const ["Library/Caches/com.apple.Safari",
- "Library/Safari",
- "Library/Saved Application State/com.apple.Safari.savedState",
- "Library/Caches/Metadata/Safari"];
-
+ static const List<String> CACHE_DIRECTORIES = const [
+ "Library/Caches/com.apple.Safari",
+ "Library/Safari",
+ "Library/Saved Application State/com.apple.Safari.savedState",
+ "Library/Caches/Metadata/Safari"
+ ];
Future<bool> allowPopUps() {
var command = "defaults";
- var args = ["write", "com.apple.safari",
- "com.apple.Safari.ContentPageGroupIdentifier."
- "WebKit2JavaScriptCanOpenWindowsAutomatically",
- "1"];
+ var args = [
+ "write",
+ "com.apple.safari",
+ "com.apple.Safari.ContentPageGroupIdentifier."
+ "WebKit2JavaScriptCanOpenWindowsAutomatically",
+ "1"
+ ];
return Process.run(command, args).then((result) {
if (result.exitCode != 0) {
_logEvent("Could not disable pop-up blocking for safari");
@@ -301,12 +313,13 @@
return directory.exists().then((exists) {
if (exists) {
_logEvent("Deleting ${paths.current}");
- return directory.delete(recursive: true)
- .then((_) => deleteIfExists(paths))
- .catchError((error) {
- _logEvent("Failure trying to delete ${paths.current}: $error");
- return false;
- });
+ return directory
+ .delete(recursive: true)
+ .then((_) => deleteIfExists(paths))
+ .catchError((error) {
+ _logEvent("Failure trying to delete ${paths.current}: $error");
+ return false;
+ });
} else {
_logEvent("${paths.current} is not present");
return deleteIfExists(paths);
@@ -379,10 +392,12 @@
return getVersion().then((version) {
_logEvent("Got version: $version");
return Directory.systemTemp.createTemp().then((userDir) {
- _cleanup = () { userDir.deleteSync(recursive: true); };
+ _cleanup = () {
+ userDir.deleteSync(recursive: true);
+ };
_createLaunchHTML(userDir.path, url);
var args = ["${userDir.path}/launch.html"];
- return startBrowser(_binary, args);
+ return startBrowserProcess(_binary, args);
});
}).catchError((error) {
_logEvent("Running $_binary --version failed with $error");
@@ -395,7 +410,6 @@
String toString() => "Safari";
}
-
class Chrome extends Browser {
String _version = "Version not found yet";
@@ -429,7 +443,6 @@
});
}
-
Future<bool> start(String url) {
_logEvent("Starting chrome browser on: $url");
// Get the version and log that.
@@ -438,11 +451,19 @@
_logEvent("Got version: $_version");
return Directory.systemTemp.createTemp().then((userDir) {
- _cleanup = () { userDir.deleteSync(recursive: true); };
- var args = ["--user-data-dir=${userDir.path}", url,
- "--disable-extensions", "--disable-popup-blocking",
- "--bwsi", "--no-first-run"];
- return startBrowser(_binary, args, environment: _getEnvironment());
+ _cleanup = () {
+ userDir.deleteSync(recursive: true);
+ };
+ var args = [
+ "--user-data-dir=${userDir.path}",
+ url,
+ "--disable-extensions",
+ "--disable-popup-blocking",
+ "--bwsi",
+ "--no-first-run"
+ ];
+ return startBrowserProcess(_binary, args,
+ environment: _getEnvironment());
});
}).catchError((e) {
_logEvent("Running $_binary --version failed with $e");
@@ -453,14 +474,14 @@
String toString() => "Chrome";
}
-
class SafariMobileSimulator extends Safari {
/**
* Directories where safari simulator stores state. We delete these if the
* deleteCache is set
*/
- static const List<String> CACHE_DIRECTORIES =
- const ["Library/Application Support/iPhone Simulator/7.1/Applications"];
+ static const List<String> CACHE_DIRECTORIES = const [
+ "Library/Application Support/iPhone Simulator/7.1/Applications"
+ ];
// Clears the cache if the static deleteCache flag is set.
// Returns false if the command to actually clear the cache did not complete.
@@ -476,33 +497,34 @@
return clearCache().then((success) {
if (!success) {
_logEvent("Could not clear cache, exiting");
- return false;
+ return false;
}
- var args = ["-SimulateApplication",
- "/Applications/Xcode.app/Contents/Developer/Platforms/"
- "iPhoneSimulator.platform/Developer/SDKs/"
- "iPhoneSimulator7.1.sdk/Applications/MobileSafari.app/"
- "MobileSafari",
- "-u", url];
- return startBrowser(_binary, args)
- .catchError((e) {
- _logEvent("Running $_binary --version failed with $e");
- return false;
- });
+ var args = [
+ "-SimulateApplication",
+ "/Applications/Xcode.app/Contents/Developer/Platforms/"
+ "iPhoneSimulator.platform/Developer/SDKs/"
+ "iPhoneSimulator7.1.sdk/Applications/MobileSafari.app/"
+ "MobileSafari",
+ "-u",
+ url
+ ];
+ return startBrowserProcess(_binary, args).catchError((e) {
+ _logEvent("Running $_binary --version failed with $e");
+ return false;
+ });
});
}
String toString() => "SafariMobileSimulator";
}
-
class Dartium extends Chrome {
final bool checkedMode;
Dartium(this.checkedMode);
Map<String, String> _getEnvironment() {
- var environment = new Map<String,String>.from(Platform.environment);
+ var environment = new Map<String, String>.from(Platform.environment);
// By setting this environment variable, dartium will forward "print()"
// calls in dart to the top-level javascript function "dartPrint()" if
// available.
@@ -518,10 +540,12 @@
class IE extends Browser {
Future<String> getVersion() {
- var args = ["query",
- "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer",
- "/v",
- "svcVersion"];
+ var args = [
+ "query",
+ "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer",
+ "/v",
+ "svcVersion"
+ ];
return Process.run("reg", args).then((result) {
if (result.exitCode == 0) {
// The string we get back looks like this:
@@ -543,27 +567,26 @@
var localAppData = Platform.environment['LOCALAPPDATA'];
Directory dir = new Directory("$localAppData\\Microsoft\\"
- "Internet Explorer\\Recovery");
- return dir.delete(recursive: true)
- .then((_) { return true; })
- .catchError((error) {
- _logEvent("Deleting recovery dir failed with $error");
- return false;
- });
+ "Internet Explorer\\Recovery");
+ return dir.delete(recursive: true).then((_) {
+ return true;
+ }).catchError((error) {
+ _logEvent("Deleting recovery dir failed with $error");
+ return false;
+ });
}
Future<bool> start(String url) {
_logEvent("Starting ie browser on: $url");
return clearCache().then((_) => getVersion()).then((version) {
_logEvent("Got version: $version");
- return startBrowser(_binary, [url]);
+ return startBrowserProcess(_binary, [url]);
});
}
+
String toString() => "IE";
-
}
-
class AndroidBrowserConfig {
final String name;
final String package;
@@ -572,20 +595,14 @@
AndroidBrowserConfig(this.name, this.package, this.activity, this.action);
}
-
final contentShellOnAndroidConfig = new AndroidBrowserConfig(
'ContentShellOnAndroid',
'org.chromium.content_shell_apk',
'.ContentShellActivity',
'android.intent.action.VIEW');
-
-final dartiumOnAndroidConfig = new AndroidBrowserConfig(
- 'DartiumOnAndroid',
- 'com.google.android.apps.chrome',
- '.Main',
- 'android.intent.action.VIEW');
-
+final dartiumOnAndroidConfig = new AndroidBrowserConfig('DartiumOnAndroid',
+ 'com.google.android.apps.chrome', '.Main', 'android.intent.action.VIEW');
class AndroidBrowser extends Browser {
final bool checkedMode;
@@ -597,8 +614,8 @@
}
Future<bool> start(String url) {
- var intent = new Intent(
- _config.action, _config.package, _config.activity, url);
+ var intent =
+ new Intent(_config.action, _config.package, _config.activity, url);
return _adbDevice.waitForBootCompleted().then((_) {
return _adbDevice.forceStop(_config.package);
}).then((_) {
@@ -630,14 +647,13 @@
}
void logBrowserInfoToTestBrowserOutput() {
- _testBrowserOutput.stdout.write(
- 'Android device id: ${_adbDevice.deviceId}\n');
+ _testBrowserOutput.stdout
+ .write('Android device id: ${_adbDevice.deviceId}\n');
}
String toString() => _config.name;
}
-
class AndroidChrome extends Browser {
static const String viewAction = 'android.intent.action.VIEW';
static const String mainAction = 'android.intent.action.MAIN';
@@ -646,14 +662,13 @@
static const String firefoxPackage = 'org.mozilla.firefox';
static const String turnScreenOnPackage = 'com.google.dart.turnscreenon';
- AndroidEmulator _emulator;
AdbDevice _adbDevice;
AndroidChrome(this._adbDevice);
Future<bool> start(String url) {
- var browserIntent = new Intent(
- viewAction, browserPackage, '.BrowserActivity', url);
+ var browserIntent =
+ new Intent(viewAction, browserPackage, '.BrowserActivity', url);
var chromeIntent = new Intent(viewAction, chromePackage, '.Main', url);
var firefoxIntent = new Intent(viewAction, firefoxPackage, '.App', url);
var turnScreenOnIntent =
@@ -702,14 +717,13 @@
}
void logBrowserInfoToTestBrowserOutput() {
- _testBrowserOutput.stdout.write(
- 'Android device id: ${_adbDevice.deviceId}\n');
+ _testBrowserOutput.stdout
+ .write('Android device id: ${_adbDevice.deviceId}\n');
}
String toString() => "chromeOnAndroid";
}
-
class Firefox extends Browser {
static const String enablePopUp =
'user_pref("dom.disable_open_during_load", false);';
@@ -741,13 +755,19 @@
return Directory.systemTemp.createTemp().then((userDir) {
_createPreferenceFile(userDir.path);
- _cleanup = () { userDir.deleteSync(recursive: true); };
- var args = ["-profile", "${userDir.path}",
- "-no-remote", "-new-instance", url];
- var environment = new Map<String,String>.from(Platform.environment);
+ _cleanup = () {
+ userDir.deleteSync(recursive: true);
+ };
+ var args = [
+ "-profile",
+ "${userDir.path}",
+ "-no-remote",
+ "-new-instance",
+ url
+ ];
+ var environment = new Map<String, String>.from(Platform.environment);
environment["MOZ_CRASHREPORTER_DISABLE"] = "1";
- return startBrowser(_binary, args, environment: environment);
-
+ return startBrowserProcess(_binary, args, environment: environment);
});
}).catchError((e) {
_logEvent("Running $_binary --version failed with $e");
@@ -758,11 +778,10 @@
String toString() => "Firefox";
}
-
/**
* Describes the current state of a browser used for testing.
*/
-class BrowserTestingStatus {
+class BrowserStatus {
Browser browser;
BrowserTest currentTest;
@@ -772,12 +791,11 @@
BrowserTest lastTest;
bool timeout = false;
Timer nextTestTimeout;
- Stopwatch timeSinceRestart = new Stopwatch();
+ Stopwatch timeSinceRestart = new Stopwatch()..start();
- BrowserTestingStatus(Browser this.browser);
+ BrowserStatus(Browser this.browser);
}
-
/**
* Describes a single test to be run in the browser.
*/
@@ -805,12 +823,9 @@
id = _idCounter++;
}
- String toJSON() => JSON.encode({'url': url,
- 'id': id,
- 'isHtmlTest': false});
+ String toJSON() => JSON.encode({'url': url, 'id': id, 'isHtmlTest': false});
}
-
/**
* Describes a test with a custom HTML page to be run in the browser.
*/
@@ -818,15 +833,16 @@
List<String> expectedMessages;
HtmlTest(url, doneCallback, timeout, this.expectedMessages)
- : super(url, doneCallback, timeout) { }
+ : super(url, doneCallback, timeout) {}
- String toJSON() => JSON.encode({'url': url,
- 'id': id,
- 'isHtmlTest': true,
- 'expectedMessages': expectedMessages});
+ String toJSON() => JSON.encode({
+ 'url': url,
+ 'id': id,
+ 'isHtmlTest': true,
+ 'expectedMessages': expectedMessages
+ });
}
-
/* Describes the output of running the test in a browser */
class BrowserTestOutput {
final Duration delayUntilTestStarted;
@@ -837,149 +853,157 @@
final BrowserOutput browserOutput;
final bool didTimeout;
- BrowserTestOutput(
- this.delayUntilTestStarted, this.duration, this.lastKnownMessage,
- this.browserOutput, {this.didTimeout: false});
+ BrowserTestOutput(this.delayUntilTestStarted, this.duration,
+ this.lastKnownMessage, this.browserOutput,
+ {this.didTimeout: false});
}
-/**
- * Encapsulates all the functionality for running tests in browsers.
- * The interface is rather simple. After starting, the runner tests
- * are simply added to the queue and a the supplied callbacks are called
- * whenever a test completes.
- */
+/// Encapsulates all the functionality for running tests in browsers.
+/// Tests are added to the queue and the supplied callbacks are called
+/// when a test completes.
+/// BrowserTestRunner starts up to maxNumBrowser instances of the browser,
+/// to run the tests, starting them sequentially, as needed, so only
+/// one is starting up at a time.
+/// BrowserTestRunner starts a BrowserTestingServer, which serves a
+/// driver page to the browsers, serves tests, and receives results and
+/// requests back from the browsers.
class BrowserTestRunner {
static const int MAX_NEXT_TEST_TIMEOUTS = 10;
static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 60);
static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60);
+ /// If the queue was recently empty, don't start another browser.
+ static const Duration MIN_NONEMPTY_QUEUE_TIME = const Duration(seconds: 1);
+
final Map configuration;
+ BrowserTestingServer testingServer;
final String localIp;
String browserName;
- final int maxNumBrowsers;
+ int maxNumBrowsers;
bool checkedMode;
+ int numBrowsers = 0;
// Used to send back logs from the browser (start, stop etc)
Function logger;
- int browserIdCount = 0;
+ int browserIdCounter = 1;
+
+ bool testingServerStarted = false;
bool underTermination = false;
int numBrowserGetTestTimeouts = 0;
-
+ DateTime lastEmptyTestQueueTime = new DateTime.now();
+ String _currentStartingBrowserId;
List<BrowserTest> testQueue = new List<BrowserTest>();
- Map<String, BrowserTestingStatus> browserStatus =
- new Map<String, BrowserTestingStatus>();
+ Map<String, BrowserStatus> browserStatus = new Map<String, BrowserStatus>();
var adbDeviceMapping = new Map<String, AdbDevice>();
+ List<AdbDevice> idleAdbDevices;
+
// This cache is used to guarantee that we never see double reporting.
// If we do we need to provide developers with this information.
// We don't add urls to the cache until we have run it.
Map<int, String> testCache = new Map<int, String>();
+
Map<int, String> doubleReportingOutputs = new Map<int, String>();
+ List<String> timedOut = [];
- BrowserTestingServer testingServer;
+ // We will start a new browser when the test queue hasn't been empty
+ // recently, we have fewer than maxNumBrowsers browsers, and there is
+ // no other browser instance currently starting up.
+ bool get queueWasEmptyRecently {
+ return testQueue.isEmpty ||
+ new DateTime.now().difference(lastEmptyTestQueueTime) <
+ MIN_NONEMPTY_QUEUE_TIME;
+ }
- /**
- * The TestRunner takes the testingServer in as a constructor parameter in
- * case we wish to have a testing server with different behavior (such as the
- * case for performance testing.
- */
- BrowserTestRunner(this.configuration,
- this.localIp,
- this.browserName,
- this.maxNumBrowsers,
- {BrowserTestingServer this.testingServer}) {
+ // While a browser is starting, but has not requested its first test, its
+ // browserId is stored in _currentStartingBrowserId.
+ // When no browser is currently starting, _currentStartingBrowserId is null.
+ bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null;
+ void markCurrentlyStarting(String id) {
+ _currentStartingBrowserId = id;
+ }
+
+ void markNotCurrentlyStarting(String id) {
+ if (_currentStartingBrowserId == id) _currentStartingBrowserId = null;
+ }
+
+ // If [browserName] doesn't support opening new windows, we use new iframes
+ // instead.
+ bool get useIframe =>
+ !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName);
+
+ /// The optional testingServer parameter allows callers to pass in
+ /// a testing server with different behavior than the default
+ /// BrowserTestServer. The url handlers of the testingServer are
+ /// overwritten, so an existing handler can't be shared between instances.
+ BrowserTestRunner(
+ this.configuration, this.localIp, this.browserName, this.maxNumBrowsers,
+ {BrowserTestingServer this.testingServer}) {
checkedMode = configuration['checked'];
+ if (browserName == 'ff') browserName = 'firefox';
}
- Future<bool> start() {
- // If [browserName] doesn't support opening new windows, we use new iframes
- // instead.
- bool useIframe =
- !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName);
+ Future start() async {
if (testingServer == null) {
- testingServer = new BrowserTestingServer(
- configuration, localIp, useIframe);
+ testingServer =
+ new BrowserTestingServer(configuration, localIp, useIframe);
}
- return testingServer.start().then((_) {
- testingServer.testDoneCallBack = handleResults;
- testingServer.testStatusUpdateCallBack = handleStatusUpdate;
- testingServer.testStartedCallBack = handleStarted;
- testingServer.nextTestCallBack = getNextTest;
- return getBrowsers().then((browsers) {
- var futures = [];
- for (var browser in browsers) {
- var url = testingServer.getDriverUrl(browser.id);
- var future = browser.start(url).then((success) {
- if (success) {
- var status = new BrowserTestingStatus(browser);
- browserStatus[browser.id] = status;
- status.nextTestTimeout = createNextTestTimer(status);
- status.timeSinceRestart.start();
- }
- return success;
- });
- futures.add(future);
- }
- return Future.wait(futures).then((values) {
- return !values.contains(false);
- });
- });
- });
+ await testingServer.start();
+ testingServer
+ ..testDoneCallBack = handleResults
+ ..testStatusUpdateCallBack = handleStatusUpdate
+ ..testStartedCallBack = handleStarted
+ ..nextTestCallBack = getNextTest;
+ if (browserName == 'chromeOnAndroid') {
+ var idbNames = await AdbHelper.listDevices();
+ idleAdbDevices = new List.from(idbNames.map((id) => new AdbDevice(id)));
+ maxNumBrowsers = min(maxNumBrowsers, idleAdbDevices.length);
+ }
+ testingServerStarted = true;
+ requestBrowser();
}
- Future<List<Browser>> getBrowsers() {
- // TODO(kustermann): This is a hackisch way to accomplish it and should
- // be encapsulated
- var browsersCompleter = new Completer();
- var androidBrowserCreationMapping = {
- 'chromeOnAndroid' : (AdbDevice device) => new AndroidChrome(device),
- 'ContentShellOnAndroid' : (AdbDevice device) => new AndroidBrowser(
- device,
- contentShellOnAndroidConfig,
- checkedMode,
- configuration['drt']),
- 'DartiumOnAndroid' : (AdbDevice device) => new AndroidBrowser(
- device,
- dartiumOnAndroidConfig,
- checkedMode,
- configuration['dartium']),
- };
- if (androidBrowserCreationMapping.containsKey(browserName)) {
- AdbHelper.listDevices().then((deviceIds) {
- if (deviceIds.length > 0) {
- var browsers = [];
- for (int i = 0; i < deviceIds.length; i++) {
- var id = "BROWSER$i";
- var device = new AdbDevice(deviceIds[i]);
- adbDeviceMapping[id] = device;
- var browser = androidBrowserCreationMapping[browserName](device);
- browsers.add(browser);
- // We store this in case we need to kill the browser.
- browser.id = id;
- }
- browsersCompleter.complete(browsers);
- } else {
- throw new StateError("No android devices found.");
- }
- });
+ /// requestBrowser() is called whenever we might want to start an additional
+ /// browser instance.
+ /// It is called when starting the BrowserTestRunner, and whenever a browser
+ /// is killed, whenever a new test is enqueued, or whenever a browser
+ /// finishes a test.
+ /// So we are guaranteed that this will always eventually be called, as long
+ /// as the test queue isn't empty.
+ void requestBrowser() {
+ if (!testingServerStarted) return;
+ if (underTermination) return;
+ if (numBrowsers == maxNumBrowsers) return;
+ if (aBrowserIsCurrentlyStarting) return;
+ if (numBrowsers > 0 && queueWasEmptyRecently) return;
+ createBrowser();
+ }
+
+ String getNextBrowserId() => "BROWSER${browserIdCounter++}";
+
+ void createBrowser() {
+ final String id = getNextBrowserId();
+ final String url = testingServer.getDriverUrl(id);
+ Browser browser;
+ if (browserName == 'chromeOnAndroid') {
+ AdbDevice device = idleAdbDevices.removeLast();
+ adbDeviceMapping[id] = device;
+ browser = new AndroidChrome(device);
} else {
- var browsers = [];
- for (int i = 0; i < maxNumBrowsers; i++) {
- var id = "BROWSER$browserIdCount";
- browserIdCount++;
- var browser = getInstance();
- browsers.add(browser);
- // We store this in case we need to kill the browser.
- browser.id = id;
- }
- browsersCompleter.complete(browsers);
+ String path = Locations.getBrowserLocation(browserName, configuration);
+ browser = new Browser.byName(browserName, path, checkedMode);
+ browser.logger = logger;
}
- return browsersCompleter.future;
+ browser.id = id;
+ markCurrentlyStarting(id);
+ final status = new BrowserStatus(browser);
+ browserStatus[id] = status;
+ numBrowsers++;
+ status.nextTestTimeout = createNextTestTimer(status);
+ browser.start(url);
}
- var timedOut = [];
-
void handleResults(String browserId, String output, int testId) {
var status = browserStatus[browserId];
if (testCache.containsKey(testId)) {
@@ -997,11 +1021,11 @@
if (status.currentTest.id != testId) {
print("Expected test id ${status.currentTest.id} for"
- "${status.currentTest.url}");
+ "${status.currentTest.url}");
print("Got test id ${testId}");
print("Last test id was ${status.lastTest.id} for "
- "${status.currentTest.url}");
- throw("This should never happen, wrong test id");
+ "${status.currentTest.url}");
+ throw ("This should never happen, wrong test id");
}
testCache[testId] = status.currentTest.url;
@@ -1050,12 +1074,11 @@
}
}
- void handleTimeout(BrowserTestingStatus status) {
+ void handleTimeout(BrowserStatus status) {
// We simply kill the browser and starts up a new one!
// We could be smarter here, but it does not seems like it is worth it.
if (status.timeout) {
- DebugLogger.error(
- "Got test timeout for an already restarting browser");
+ DebugLogger.error("Got test timeout for an already restarting browser");
return;
}
status.timeout = true;
@@ -1084,63 +1107,24 @@
// We don't want to start a new browser if we are terminating.
if (underTermination) return;
- restartBrowser(id);
+ removeBrowser(id);
+ requestBrowser();
});
}
- void restartBrowser(String id) {
- if (browserName.contains('OnAndroid')) {
- DebugLogger.info("Restarting browser $id");
- }
- var browser;
- var new_id = id;
+ /// Remove a browser that has closed from our data structures that track
+ /// open browsers. Check if we want to replace it with a new browser.
+ void removeBrowser(String id) {
if (browserName == 'chromeOnAndroid') {
- browser = new AndroidChrome(adbDeviceMapping[id]);
- } else if (browserName == 'ContentShellOnAndroid') {
- browser = new AndroidBrowser(adbDeviceMapping[id],
- contentShellOnAndroidConfig,
- checkedMode,
- configuration['drt']);
- } else if (browserName == 'DartiumOnAndroid') {
- browser = new AndroidBrowser(adbDeviceMapping[id],
- dartiumOnAndroidConfig,
- checkedMode,
- configuration['dartium']);
- } else {
- browserStatus.remove(id);
- browser = getInstance();
- new_id = "BROWSER$browserIdCount";
- browserIdCount++;
+ idleAdbDevices.add(adbDeviceMapping.remove(id));
}
- browser.id = new_id;
- var status = new BrowserTestingStatus(browser);
- browserStatus[new_id] = status;
- status.nextTestTimeout = createNextTestTimer(status);
- status.timeSinceRestart.start();
- browser.start(testingServer.getDriverUrl(new_id)).then((success) {
- // We may have started terminating in the mean time.
- if (underTermination) {
- if (status.nextTestTimeout != null) {
- status.nextTestTimeout.cancel();
- status.nextTestTimeout = null;
- }
- browser.close().then((success) {
- // We should never hit this, print it out.
- if (!success) {
- print("Could not kill browser ($id) started due to timeout");
- }
- });
- return;
- }
- if (!success) {
- // TODO(ricow): Handle this better.
- print("This is bad, should never happen, could not start browser");
- exit(1);
- }
- });
+ markNotCurrentlyStarting(id);
+ browserStatus.remove(id);
+ --numBrowsers;
}
BrowserTest getNextTest(String browserId) {
+ markNotCurrentlyStarting(browserId);
var status = browserStatus[browserId];
if (status == null) return null;
if (status.nextTestTimeout != null) {
@@ -1152,13 +1136,10 @@
// We are currently terminating this browser, don't start a new test.
if (status.timeout) return null;
- // Restart content_shell and dartium on Android if they have been
+ // Restart Internet Explorer if it has been
// running for longer than RESTART_BROWSER_INTERVAL. The tests have
// had flaky timeouts, and this may help.
- if ((browserName == 'ContentShellOnAndroid' ||
- browserName == 'DartiumOnAndroid' ||
- browserName == 'ie10' ||
- browserName == 'ie11') &&
+ if ((browserName == 'ie10' || browserName == 'ie11') &&
status.timeSinceRestart.elapsed > RESTART_BROWSER_INTERVAL) {
var id = status.browser.id;
// Reset stopwatch so we don't trigger again before restarting.
@@ -1166,13 +1147,20 @@
status.browser.close().then((_) {
// We don't want to start a new browser if we are terminating.
if (underTermination) return;
- restartBrowser(id);
+ removeBrowser(id);
+ requestBrowser();
});
// Don't send a test to the browser we are restarting.
return null;
}
BrowserTest test = testQueue.removeLast();
+ // If our queue isn't empty, try starting more browsers
+ if (testQueue.isEmpty) {
+ lastEmptyTestQueueTime = new DateTime.now();
+ } else {
+ requestBrowser();
+ }
if (status.currentTest == null) {
status.currentTest = test;
status.currentTest.lastKnownMessage = '';
@@ -1196,26 +1184,27 @@
// browser, since a new test is being started.
status.browser.resetTestBrowserOutput();
status.browser.logBrowserInfoToTestBrowserOutput();
- if (browserName.contains('OnAndroid')) {
- DebugLogger.info("Browser $browserId getting test ${test.url}");
- }
-
return test;
}
- Timer createTimeoutTimer(BrowserTest test, BrowserTestingStatus status) {
- return new Timer(new Duration(seconds: test.timeout),
- () { handleTimeout(status); });
+ /// Creates a timer that is active while a test is running on a browser.
+ Timer createTimeoutTimer(BrowserTest test, BrowserStatus status) {
+ return new Timer(new Duration(seconds: test.timeout), () {
+ handleTimeout(status);
+ });
}
- Timer createNextTestTimer(BrowserTestingStatus status) {
- return new Timer(BrowserTestRunner.NEXT_TEST_TIMEOUT,
- () { handleNextTestTimeout(status); });
+ /// Creates a timer that is active while no test is running on the
+ /// browser. It has finished one test, and it has not requested a new test.
+ Timer createNextTestTimer(BrowserStatus status) {
+ return new Timer(BrowserTestRunner.NEXT_TEST_TIMEOUT, () {
+ handleNextTestTimeout(status);
+ });
}
void handleNextTestTimeout(status) {
- DebugLogger.warning(
- "Browser timed out before getting next test. Restarting");
+ DebugLogger
+ .warning("Browser timed out before getting next test. Restarting");
if (status.timeout) return;
numBrowserGetTestTimeouts++;
if (numBrowserGetTestTimeouts >= MAX_NEXT_TEST_TIMEOUTS) {
@@ -1224,12 +1213,16 @@
terminate().then((_) => exit(1));
} else {
status.timeout = true;
- status.browser.close().then((_) => restartBrowser(status.browser.id));
+ status.browser.close().then((_) {
+ removeBrowser(status.browser.id);
+ requestBrowser();
+ });
}
}
- void queueTest(BrowserTest test) {
+ void enqueueTest(BrowserTest test) {
testQueue.add(test);
+ requestBrowser();
}
void printDoubleReportingTests() {
@@ -1252,44 +1245,30 @@
}
}
- Future<bool> terminate() {
+ // TODO(26191): Call a unified fatalError(), that shuts down all subprocesses.
+ // This just kills the browsers in this BrowserTestRunner instance.
+ Future terminate() async {
var browsers = [];
underTermination = true;
testingServer.underTermination = true;
- for (BrowserTestingStatus status in browserStatus.values) {
+ for (BrowserStatus status in browserStatus.values) {
browsers.add(status.browser);
if (status.nextTestTimeout != null) {
status.nextTestTimeout.cancel();
status.nextTestTimeout = null;
}
}
- // Success if all the browsers closed successfully.
- bool success = true;
- Future closeBrowser(Browser b) {
- return b.close().then((bool closeSucceeded) {
- if (!closeSucceeded) {
- success = false;
- }
- });
+ for (Browser b in browsers) {
+ await b.close();
}
- return Future.forEach(browsers, closeBrowser).then((_) {
- testingServer.errorReportingServer.close();
- printDoubleReportingTests();
- return success;
- });
- }
-
- Browser getInstance() {
- if (browserName == 'ff') browserName = 'firefox';
- var path = Locations.getBrowserLocation(browserName, configuration);
- var browser = new Browser.byName(browserName, path, checkedMode);
- browser.logger = logger;
- return browser;
+ testingServer.errorReportingServer.close();
+ printDoubleReportingTests();
}
}
class BrowserTestingServer {
final Map configuration;
+
/// Interface of the testing server:
///
/// GET /driver/BROWSER_ID -- This will get the driver page to fetch
@@ -1326,9 +1305,10 @@
Future start() {
var test_driver_error_port = configuration['test_driver_error_port'];
- return HttpServer.bind(localIp, test_driver_error_port)
- .then(setupErrorServer)
- .then(setupDispatchingServer);
+ return HttpServer
+ .bind(localIp, test_driver_error_port)
+ .then(setupErrorServer)
+ .then(setupDispatchingServer);
}
void setupErrorServer(HttpServer server) {
@@ -1336,18 +1316,20 @@
void errorReportingHandler(HttpRequest request) {
StringBuffer buffer = new StringBuffer();
request.transform(UTF8.decoder).listen((data) {
- buffer.write(data);
- }, onDone: () {
- String back = buffer.toString();
- request.response.headers.set("Access-Control-Allow-Origin", "*");
- request.response.done.catchError((error) {
- DebugLogger.error("Error getting error from browser"
- "on uri ${request.uri.path}: $error");
- });
- request.response.close();
- DebugLogger.error("Error from browser on : "
- "${request.uri.path}, data: $back");
- }, onError: (error) { print(error); });
+ buffer.write(data);
+ }, onDone: () {
+ String back = buffer.toString();
+ request.response.headers.set("Access-Control-Allow-Origin", "*");
+ request.response.done.catchError((error) {
+ DebugLogger.error("Error getting error from browser"
+ "on uri ${request.uri.path}: $error");
+ });
+ request.response.close();
+ DebugLogger.error("Error from browser on : "
+ "${request.uri.path}, data: $back");
+ }, onError: (error) {
+ print(error);
+ });
}
void errorHandler(e) {
if (!underTermination) print("Error occured in httpserver: $e");
@@ -1358,58 +1340,56 @@
void setupDispatchingServer(_) {
DispatchingServer server = configuration['_servers_'].server;
void noCache(request) {
- request.response.headers.set("Cache-Control",
- "no-cache, no-store, must-revalidate");
+ request.response.headers
+ .set("Cache-Control", "no-cache, no-store, must-revalidate");
}
- int testId(request) =>
- int.parse(request.uri.queryParameters["id"]);
+ int testId(request) => int.parse(request.uri.queryParameters["id"]);
String browserId(request, prefix) =>
request.uri.path.substring(prefix.length + 1);
-
server.addHandler(reportPath, (HttpRequest request) {
noCache(request);
- handleReport(request, browserId(request, reportPath),
- testId(request), isStatusUpdate: false);
+ handleReport(request, browserId(request, reportPath), testId(request),
+ isStatusUpdate: false);
});
server.addHandler(statusUpdatePath, (HttpRequest request) {
noCache(request);
- handleReport(request, browserId(request, statusUpdatePath),
- testId(request), isStatusUpdate: true);
+ handleReport(
+ request, browserId(request, statusUpdatePath), testId(request),
+ isStatusUpdate: true);
});
server.addHandler(startedPath, (HttpRequest request) {
noCache(request);
- handleStarted(request, browserId(request, startedPath),
- testId(request));
+ handleStarted(request, browserId(request, startedPath), testId(request));
});
makeSendPageHandler(String prefix) => (HttpRequest request) {
- noCache(request);
- var textResponse = "";
- if (prefix == driverPath) {
- textResponse = getDriverPage(browserId(request, prefix));
- request.response.headers.set('Content-Type', 'text/html');
- }
- if (prefix == nextTestPath) {
- textResponse = getNextTest(browserId(request, prefix));
- request.response.headers.set('Content-Type', 'text/plain');
- }
- request.response.write(textResponse);
- request.listen((_) {}, onDone: request.response.close);
- request.response.done.catchError((error) {
- if (!underTermination) {
- print("URI ${request.uri}");
- print("Textresponse $textResponse");
- throw "Error returning content to browser: $error";
- }
- });
- };
+ noCache(request);
+ var textResponse = "";
+ if (prefix == driverPath) {
+ textResponse = getDriverPage(browserId(request, prefix));
+ request.response.headers.set('Content-Type', 'text/html');
+ }
+ if (prefix == nextTestPath) {
+ textResponse = getNextTest(browserId(request, prefix));
+ request.response.headers.set('Content-Type', 'text/plain');
+ }
+ request.response.write(textResponse);
+ request.listen((_) {}, onDone: request.response.close);
+ request.response.done.catchError((error) {
+ if (!underTermination) {
+ print("URI ${request.uri}");
+ print("Textresponse $textResponse");
+ throw "Error returning content to browser: $error";
+ }
+ });
+ };
server.addHandler(driverPath, makeSendPageHandler(driverPath));
server.addHandler(nextTestPath, makeSendPageHandler(nextTestPath));
}
void handleReport(HttpRequest request, String browserId, var testId,
- {bool isStatusUpdate}) {
+ {bool isStatusUpdate}) {
StringBuffer buffer = new StringBuffer();
request.transform(UTF8.decoder).listen((data) {
buffer.write(data);
@@ -1422,7 +1402,9 @@
testDoneCallBack(browserId, back, testId);
}
// TODO(ricow): We should do something smart if we get an error here.
- }, onError: (error) { DebugLogger.error("$error"); });
+ }, onError: (error) {
+ DebugLogger.error("$error");
+ });
}
void handleStarted(HttpRequest request, String browserId, var testId) {
@@ -1436,7 +1418,9 @@
String back = buffer.toString();
request.response.close();
testStartedCallBack(browserId, back, testId);
- }, onError: (error) { DebugLogger.error("$error"); });
+ }, onError: (error) {
+ DebugLogger.error("$error");
+ });
}
String getNextTest(String browserId) {
@@ -1452,7 +1436,7 @@
String getDriverUrl(String browserId) {
if (errorReportingServer == null) {
print("Bad browser testing server, you are not started yet. Can't "
- "produce driver url");
+ "produce driver url");
exit(1);
// This should never happen - exit immediately;
}
@@ -1460,7 +1444,6 @@
return "http://$localIp:$port/driver/$browserId";
}
-
String getDriverPage(String browserId) {
var errorReportingUrl =
"http://$localIp:${errorReportingServer.port}/$browserId";
diff --git a/tools/testing/dart/browser_perf_testing/pubspec.yaml b/tools/testing/dart/browser_perf_testing/pubspec.yaml
deleted file mode 100644
index b033e13..0000000
--- a/tools/testing/dart/browser_perf_testing/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: browser_perf_testing
-version: 0.0.1
-author: Dart Team <misc@dartlang.org>
-description: Framework for running performance benchmarks in the browser with our testing framework.
-homepage: http://www.dartlang.org
-dependencies:
- path: any
- args: any
-dev_dependencies:
-environment:
diff --git a/tools/testing/dart/browser_test.dart b/tools/testing/dart/browser_test.dart
index 63d8de0..1236b55 100644
--- a/tools/testing/dart/browser_test.dart
+++ b/tools/testing/dart/browser_test.dart
@@ -6,9 +6,7 @@
import 'path.dart';
-String getHtmlContents(String title,
- String scriptType,
- Path sourceScript) {
+String getHtmlContents(String title, String scriptType, Path sourceScript) {
return """
<!DOCTYPE html>
<html>
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index d826263..9118fc8 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -22,21 +22,33 @@
import "test_suite.dart";
import "test_configurations.dart";
-const List<String> COMMON_ARGUMENTS =
- const <String>['--report', '--progress=diff', 'co19'];
+const List<String> COMMON_ARGUMENTS = const <String>[
+ '--report',
+ '--progress=diff',
+ 'co19'
+];
const List<List<String>> COMMAND_LINES = const <List<String>>[
- const <String>['-mrelease,debug', '-rvm', '-cnone'],
- const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
- const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
- const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
- const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
- '--minified'],
- const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
- '--checked'],
- const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk',
- '--checked'],
- const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk'],
+ const <String>['-mrelease,debug', '-rvm', '-cnone'],
+ const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
+ const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
+ const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
+ const <String>[
+ '-mrelease',
+ '-rd8,jsshell',
+ '-cdart2js',
+ '--use-sdk',
+ '--minified'
+ ],
+ const <String>[
+ '-mrelease',
+ '-rd8,jsshell',
+ '-cdart2js',
+ '--use-sdk',
+ '--checked'
+ ],
+ const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk', '--checked'],
+ const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk'],
];
void main(List<String> args) {
@@ -55,4 +67,3 @@
testConfigurations(configurations);
}
}
-
diff --git a/tools/testing/dart/co19_test_config.dart b/tools/testing/dart/co19_test_config.dart
index 813038d..c331f93 100644
--- a/tools/testing/dart/co19_test_config.dart
+++ b/tools/testing/dart/co19_test_config.dart
@@ -11,15 +11,14 @@
RegExp _testRegExp = new RegExp(r"t[0-9]{2}.dart$");
Co19TestSuite(Map configuration)
- : super(configuration,
- "co19",
- new Path("tests/co19/src"),
- ["tests/co19/co19-co19.status",
- "tests/co19/co19-analyzer.status",
- "tests/co19/co19-analyzer2.status",
- "tests/co19/co19-runtime.status",
- "tests/co19/co19-dart2js.status",
- "tests/co19/co19-dartium.status"]);
+ : super(configuration, "co19", new Path("tests/co19/src"), [
+ "tests/co19/co19-co19.status",
+ "tests/co19/co19-analyzer.status",
+ "tests/co19/co19-analyzer2.status",
+ "tests/co19/co19-runtime.status",
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartium.status"
+ ]);
bool isTestFile(String filename) => _testRegExp.hasMatch(filename);
bool get listRecursively => true;
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 5c8d41d..7b1e5f6 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -4,20 +4,13 @@
library compiler_configuration;
-import 'dart:io' show
- Platform;
+import 'dart:io' show Platform;
-import 'runtime_configuration.dart' show
- RuntimeConfiguration;
+import 'runtime_configuration.dart' show RuntimeConfiguration;
-import 'test_runner.dart' show
- Command,
- CommandBuilder,
- CompilationCommand;
+import 'test_runner.dart' show Command, CommandBuilder, CompilationCommand;
-import 'test_suite.dart' show
- TestInformation,
- TestUtils;
+import 'test_suite.dart' show TestInformation, TestUtils;
/// Grouping of a command with its expected result.
class CommandArtifact {
@@ -35,9 +28,7 @@
Uri nativeDirectoryToUri(String nativePath) {
Uri uri = new Uri.file(nativePath);
String path = uri.path;
- return (path == '' || path.endsWith('/'))
- ? uri
- : Uri.parse('$uri/');
+ return (path == '' || path.endsWith('/')) ? uri : Uri.parse('$uri/');
}
abstract class CompilerConfiguration {
@@ -61,36 +52,48 @@
bool useSdk = configuration['use_sdk'];
bool isCsp = configuration['csp'];
bool useCps = configuration['cps_ir'];
+ // TODO(26060): Remove the browser multiplier when issue resolved.
+ bool isBrowser = configuration['browser'];
switch (compiler) {
case 'dart2analyzer':
return new AnalyzerCompilerConfiguration(
- isDebug: isDebug, isChecked: isChecked,
- isHostChecked: isHostChecked, useSdk: useSdk);
+ isDebug: isDebug,
+ isChecked: isChecked,
+ isHostChecked: isHostChecked,
+ useSdk: useSdk);
case 'dart2js':
return new Dart2jsCompilerConfiguration(
- isDebug: isDebug, isChecked: isChecked,
- isHostChecked: isHostChecked, useCps: useCps, useSdk: useSdk,
- isCsp: isCsp, extraDart2jsOptions:
+ isDebug: isDebug,
+ isChecked: isChecked,
+ isHostChecked: isHostChecked,
+ useCps: useCps,
+ useSdk: useSdk,
+ isCsp: isCsp,
+ isBrowser: isBrowser,
+ extraDart2jsOptions:
TestUtils.getExtraOptions(configuration, 'dart2js_options'));
case 'dart2app':
return new Dart2AppSnapshotCompilerConfiguration(
isDebug: isDebug, isChecked: isChecked);
case 'precompiler':
return new PrecompilerCompilerConfiguration(
- isDebug: isDebug, isChecked: isChecked,
+ isDebug: isDebug,
+ isChecked: isChecked,
arch: configuration['arch']);
case 'none':
return new NoneCompilerConfiguration(
- isDebug: isDebug, isChecked: isChecked,
- isHostChecked: isHostChecked, useSdk: useSdk);
+ isDebug: isDebug,
+ isChecked: isChecked,
+ isHostChecked: isHostChecked,
+ useSdk: useSdk);
default:
throw "Unknown compiler '$compiler'";
}
}
- CompilerConfiguration._subclass({
- this.isDebug: false,
+ CompilerConfiguration._subclass(
+ {this.isDebug: false,
this.isChecked: false,
this.isHostChecked: false,
this.useSdk: false});
@@ -126,9 +129,7 @@
}
List<String> computeCompilerArguments(vmOptions, sharedOptions, args) {
- return new List<String>()
- ..addAll(sharedOptions)
- ..addAll(args);
+ return new List<String>()..addAll(sharedOptions)..addAll(args);
}
List<String> computeRuntimeArguments(
@@ -145,15 +146,13 @@
/// The "none" compiler.
class NoneCompilerConfiguration extends CompilerConfiguration {
-
- NoneCompilerConfiguration({
- bool isDebug,
- bool isChecked,
- bool isHostChecked,
- bool useSdk})
+ NoneCompilerConfiguration(
+ {bool isDebug, bool isChecked, bool isHostChecked, bool useSdk})
: super._subclass(
- isDebug: isDebug, isChecked: isChecked,
- isHostChecked: isHostChecked, useSdk: useSdk);
+ isDebug: isDebug,
+ isChecked: isChecked,
+ isHostChecked: isHostChecked,
+ useSdk: useSdk);
bool get hasCompiler => false;
@@ -171,9 +170,9 @@
args.add('--enable_type_checks');
}
return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(originalArguments);
+ ..addAll(vmOptions)
+ ..addAll(sharedOptions)
+ ..addAll(originalArguments);
}
}
@@ -183,15 +182,13 @@
static Map<String, List<Uri>> _bootstrapDependenciesCache =
new Map<String, List<Uri>>();
- Dart2xCompilerConfiguration(
- this.moniker,
- {bool isDebug,
- bool isChecked,
- bool isHostChecked,
- bool useSdk})
+ Dart2xCompilerConfiguration(this.moniker,
+ {bool isDebug, bool isChecked, bool isHostChecked, bool useSdk})
: super._subclass(
- isDebug: isDebug, isChecked: isChecked,
- isHostChecked: isHostChecked, useSdk: useSdk);
+ isDebug: isDebug,
+ isChecked: isChecked,
+ isHostChecked: isHostChecked,
+ useSdk: useSdk);
String computeCompilerPath(String buildDir) {
var prefix = 'sdk/bin';
@@ -219,17 +216,24 @@
arguments.add('--out=$outputFileName');
return commandBuilder.getCompilationCommand(
- moniker, outputFileName, !useSdk,
+ moniker,
+ outputFileName,
+ !useSdk,
bootstrapDependencies(buildDir),
computeCompilerPath(buildDir),
- arguments, environmentOverrides);
+ arguments,
+ environmentOverrides);
}
List<Uri> bootstrapDependencies(String buildDir) {
if (!useSdk) return const <Uri>[];
- return _bootstrapDependenciesCache.putIfAbsent(buildDir, () =>
- [Uri.base.resolveUri(nativeDirectoryToUri(buildDir))
- .resolve('dart-sdk/bin/snapshots/dart2js.dart.snapshot')]);
+ return _bootstrapDependenciesCache.putIfAbsent(
+ buildDir,
+ () => [
+ Uri.base
+ .resolveUri(nativeDirectoryToUri(buildDir))
+ .resolve('dart-sdk/bin/snapshots/dart2js.dart.snapshot')
+ ]);
}
}
@@ -237,29 +241,33 @@
class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
final bool isCsp;
final bool useCps;
+ final bool isBrowser;
final List<String> extraDart2jsOptions;
// We cache the extended environment to save memory.
static Map<String, String> cpsFlagCache;
static Map<String, String> environmentOverridesCacheObject;
- Dart2jsCompilerConfiguration({
- bool isDebug,
+ Dart2jsCompilerConfiguration(
+ {bool isDebug,
bool isChecked,
bool isHostChecked,
bool useSdk,
bool this.useCps,
bool this.isCsp,
+ bool this.isBrowser,
this.extraDart2jsOptions})
- : super(
- 'dart2js',
- isDebug: isDebug, isChecked: isChecked,
- isHostChecked: isHostChecked, useSdk: useSdk);
+ : super('dart2js',
+ isDebug: isDebug,
+ isChecked: isChecked,
+ isHostChecked: isHostChecked,
+ useSdk: useSdk);
int computeTimeoutMultiplier() {
int multiplier = 1;
if (isDebug) multiplier *= 4;
if (isChecked) multiplier *= 2;
if (isHostChecked) multiplier *= 16;
+ if (isBrowser) multiplier *= 2; // TODO(26060): Remove when issue fixed.
return multiplier;
}
@@ -271,16 +279,10 @@
Map<String, String> environmentOverrides) {
List compilerArguments = new List.from(arguments)
..addAll(extraDart2jsOptions);
- return new CommandArtifact(
- <Command>[
- this.computeCompilationCommand(
- '$tempDir/out.js',
- buildDir,
- CommandBuilder.instance,
- compilerArguments,
- environmentOverrides)],
- '$tempDir/out.js',
- 'application/javascript');
+ return new CommandArtifact(<Command>[
+ this.computeCompilationCommand('$tempDir/out.js', buildDir,
+ CommandBuilder.instance, compilerArguments, environmentOverrides)
+ ], '$tempDir/out.js', 'application/javascript');
}
List<String> computeRuntimeArguments(
@@ -291,25 +293,22 @@
List<String> sharedOptions,
List<String> originalArguments,
CommandArtifact artifact) {
- Uri sdk = useSdk ?
- nativeDirectoryToUri(buildDir).resolve('dart-sdk/') :
- nativeDirectoryToUri(TestUtils.dartDir.toNativePath()).resolve('sdk/');
- Uri preambleDir = sdk.resolve(
- 'lib/_internal/js_runtime/lib/preambles/');
+ Uri sdk = useSdk
+ ? nativeDirectoryToUri(buildDir).resolve('dart-sdk/')
+ : nativeDirectoryToUri(TestUtils.dartDir.toNativePath())
+ .resolve('sdk/');
+ Uri preambleDir = sdk.resolve('lib/_internal/js_runtime/lib/preambles/');
return runtimeConfiguration.dart2jsPreambles(preambleDir)
- ..add(artifact.filename);
+ ..add(artifact.filename);
}
}
-
class PrecompilerCompilerConfiguration extends CompilerConfiguration {
final String arch;
- PrecompilerCompilerConfiguration({
- bool isDebug,
- bool isChecked,
- String arch})
- : super._subclass(isDebug: isDebug, isChecked: isChecked), arch = arch;
+ PrecompilerCompilerConfiguration({bool isDebug, bool isChecked, String arch})
+ : super._subclass(isDebug: isDebug, isChecked: isChecked),
+ arch = arch;
int computeTimeoutMultiplier() {
int multiplier = 2;
@@ -324,28 +323,14 @@
CommandBuilder commandBuilder,
List arguments,
Map<String, String> environmentOverrides) {
- return new CommandArtifact(
- <Command>[
- this.computeCompilationCommand(
- tempDir,
- buildDir,
- CommandBuilder.instance,
- arguments,
- environmentOverrides),
- this.computeAssembleCommand(
- tempDir,
- buildDir,
- CommandBuilder.instance,
- arguments,
- environmentOverrides),
- this.computeRemoveAssemblyCommand(
- tempDir,
- buildDir,
- CommandBuilder.instance,
- arguments,
- environmentOverrides)],
- '$tempDir',
- 'application/dart-precompiled');
+ return new CommandArtifact(<Command>[
+ this.computeCompilationCommand(tempDir, buildDir, CommandBuilder.instance,
+ arguments, environmentOverrides),
+ this.computeAssembleCommand(tempDir, buildDir, CommandBuilder.instance,
+ arguments, environmentOverrides),
+ this.computeRemoveAssemblyCommand(tempDir, buildDir,
+ CommandBuilder.instance, arguments, environmentOverrides)
+ ], '$tempDir', 'application/dart-precompiled');
}
CompilationCommand computeCompilationCommand(
@@ -359,10 +344,8 @@
args.add("--gen-precompiled-snapshot=$tempDir");
args.addAll(arguments);
- return commandBuilder.getCompilationCommand(
- 'precompiler', tempDir, !useSdk,
- bootstrapDependencies(buildDir),
- exec, args, environmentOverrides);
+ return commandBuilder.getCompilationCommand('precompiler', tempDir, !useSdk,
+ bootstrapDependencies(buildDir), exec, args, environmentOverrides);
}
CompilationCommand computeAssembleCommand(
@@ -401,16 +384,16 @@
}
var exec = cc;
- var args = [shared,
- cc_flags,
- '-o',
- '$tempDir/$libname',
- '$tempDir/precompiled.S'];
+ var args = [
+ shared,
+ cc_flags,
+ '-o',
+ '$tempDir/$libname',
+ '$tempDir/precompiled.S'
+ ];
- return commandBuilder.getCompilationCommand(
- 'assemble', tempDir, !useSdk,
- bootstrapDependencies(buildDir),
- exec, args, environmentOverrides);
+ return commandBuilder.getCompilationCommand('assemble', tempDir, !useSdk,
+ bootstrapDependencies(buildDir), exec, args, environmentOverrides);
}
// This step reduces the amount of space needed to run the precompilation
@@ -425,32 +408,35 @@
var args = ['$tempDir/precompiled.S'];
return commandBuilder.getCompilationCommand(
- 'remove_assembly', tempDir, !useSdk,
+ 'remove_assembly',
+ tempDir,
+ !useSdk,
bootstrapDependencies(buildDir),
- exec, args, environmentOverrides);
+ exec,
+ args,
+ environmentOverrides);
}
List<String> filterVmOptions(List<String> vmOptions) {
var filtered = new List.from(vmOptions);
filtered.removeWhere(
- (option) => option.startsWith("--optimization-counter-threshold"));
+ (option) => option.startsWith("--optimization-counter-threshold"));
filtered.removeWhere(
- (option) => option.startsWith("--optimization_counter_threshold"));
+ (option) => option.startsWith("--optimization_counter_threshold"));
return filtered;
}
- List<String> computeCompilerArguments(vmOptions,
- sharedOptions,
- originalArguments) {
+ List<String> computeCompilerArguments(
+ vmOptions, sharedOptions, originalArguments) {
List<String> args = [];
if (isChecked) {
args.add('--enable_asserts');
args.add('--enable_type_checks');
}
return args
- ..addAll(filterVmOptions(vmOptions))
- ..addAll(sharedOptions)
- ..addAll(originalArguments);
+ ..addAll(filterVmOptions(vmOptions))
+ ..addAll(sharedOptions)
+ ..addAll(originalArguments);
}
List<String> computeRuntimeArguments(
@@ -467,17 +453,14 @@
args.add('--enable_type_checks');
}
return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(originalArguments);
+ ..addAll(vmOptions)
+ ..addAll(sharedOptions)
+ ..addAll(originalArguments);
}
}
-
class Dart2AppSnapshotCompilerConfiguration extends CompilerConfiguration {
- Dart2AppSnapshotCompilerConfiguration({
- bool isDebug,
- bool isChecked})
+ Dart2AppSnapshotCompilerConfiguration({bool isDebug, bool isChecked})
: super._subclass(isDebug: isDebug, isChecked: isChecked);
int computeTimeoutMultiplier() {
@@ -494,16 +477,10 @@
List arguments,
Map<String, String> environmentOverrides) {
String outputName = computeOutputName(tempDir);
- return new CommandArtifact(
- <Command>[
- this.computeCompilationCommand(
- outputName,
- buildDir,
- CommandBuilder.instance,
- arguments,
- environmentOverrides)],
- outputName,
- 'application/dart-snapshot');
+ return new CommandArtifact(<Command>[
+ this.computeCompilationCommand(outputName, buildDir,
+ CommandBuilder.instance, arguments, environmentOverrides)
+ ], outputName, 'application/dart-snapshot');
}
String computeOutputName(String tempDir) {
@@ -523,23 +500,26 @@
args.addAll(arguments);
return commandBuilder.getCompilationCommand(
- 'dart2snapshot', outputName, !useSdk,
+ 'dart2snapshot',
+ outputName,
+ !useSdk,
bootstrapDependencies(buildDir),
- exec, args, environmentOverrides);
+ exec,
+ args,
+ environmentOverrides);
}
- List<String> computeCompilerArguments(vmOptions,
- sharedOptions,
- originalArguments) {
+ List<String> computeCompilerArguments(
+ vmOptions, sharedOptions, originalArguments) {
List<String> args = [];
if (isChecked) {
args.add('--enable_asserts');
args.add('--enable_type_checks');
}
return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(originalArguments);
+ ..addAll(vmOptions)
+ ..addAll(sharedOptions)
+ ..addAll(originalArguments);
}
List<String> computeRuntimeArguments(
@@ -556,22 +536,20 @@
args.add('--enable_type_checks');
}
return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(originalArguments);
+ ..addAll(vmOptions)
+ ..addAll(sharedOptions)
+ ..addAll(originalArguments);
}
}
-
class AnalyzerCompilerConfiguration extends CompilerConfiguration {
AnalyzerCompilerConfiguration(
- {bool isDebug,
- bool isChecked,
- bool isHostChecked,
- bool useSdk})
+ {bool isDebug, bool isChecked, bool isHostChecked, bool useSdk})
: super._subclass(
- isDebug: isDebug, isChecked: isChecked,
- isHostChecked: isHostChecked, useSdk: useSdk);
+ isDebug: isDebug,
+ isChecked: isChecked,
+ isHostChecked: isHostChecked,
+ useSdk: useSdk);
int computeTimeoutMultiplier() {
return 4;
@@ -605,14 +583,12 @@
if (isChecked) {
arguments.add('--enable_type_checks');
}
- return new CommandArtifact(
- <Command>[
- commandBuilder.getAnalysisCommand(
- 'dart2analyzer', computeCompilerPath(buildDir), arguments,
- environmentOverrides,
- flavor: 'dart2analyzer')],
- null, null); // Since this is not a real compilation, no artifacts are
- // produced.
+ return new CommandArtifact(<Command>[
+ commandBuilder.getAnalysisCommand('dart2analyzer',
+ computeCompilerPath(buildDir), arguments, environmentOverrides,
+ flavor: 'dart2analyzer')
+ ], null, null); // Since this is not a real compilation, no artifacts are
+ // produced.
}
List<String> computeRuntimeArguments(
diff --git a/tools/testing/dart/dependency_graph.dart b/tools/testing/dart/dependency_graph.dart
index 1de7b9e..abdcf50 100644
--- a/tools/testing/dart/dependency_graph.dart
+++ b/tools/testing/dart/dependency_graph.dart
@@ -7,7 +7,6 @@
import 'dart:async';
import 'utils.dart';
-
/*
* [Graph] represents a datastructure for representing an DAG (directed acyclic
* graph). Each node in the graph is in a given [NodeState] and can have data
@@ -114,12 +113,12 @@
class NodeState extends UniqueObject {
static NodeState Initialized = new NodeState._("Initialized");
- static NodeState Waiting = new NodeState._("Waiting");
- static NodeState Enqueuing = new NodeState._("Enqueuing");
- static NodeState Processing = new NodeState._("Running");
- static NodeState Successful = new NodeState._("Successful");
- static NodeState Failed = new NodeState._("Failed");
- static NodeState UnableToRun = new NodeState._("UnableToRun");
+ static NodeState Waiting = new NodeState._("Waiting");
+ static NodeState Enqueuing = new NodeState._("Enqueuing");
+ static NodeState Processing = new NodeState._("Running");
+ static NodeState Successful = new NodeState._("Successful");
+ static NodeState Failed = new NodeState._("Failed");
+ static NodeState UnableToRun = new NodeState._("UnableToRun");
final String name;
diff --git a/tools/testing/dart/drt_updater.dart b/tools/testing/dart/drt_updater.dart
index 3f34885..ee5a628 100644
--- a/tools/testing/dart/drt_updater.dart
+++ b/tools/testing/dart/drt_updater.dart
@@ -28,7 +28,11 @@
if (!isActive) {
isActive = true;
print('Updating $name.');
- onUpdated = [() {updated = true;} ];
+ onUpdated = [
+ () {
+ updated = true;
+ }
+ ];
_updatingProcess = Process.run('python', _getUpdateCommand);
_updatingProcess.then(_onUpdatedHandler).catchError((e) {
print("Error starting $script process: $e");
@@ -57,7 +61,7 @@
print(result.stderr);
exit(1);
}
- for (var callback in onUpdated ) callback();
+ for (var callback in onUpdated) callback();
}
}
@@ -69,17 +73,15 @@
if (runtime == 'drt' && configuration['drt'] == '') {
// Download the default content shell from Google Storage.
if (_contentShellUpdater == null) {
- _contentShellUpdater = new _DartiumUpdater('Content Shell',
- 'tools/get_archive.py',
- 'drt');
+ _contentShellUpdater =
+ new _DartiumUpdater('Content Shell', 'tools/get_archive.py', 'drt');
}
return _contentShellUpdater;
} else if (runtime == 'dartium' && configuration['dartium'] == '') {
// Download the default Dartium from Google Storage.
if (_dartiumUpdater == null) {
- _dartiumUpdater = new _DartiumUpdater('Dartium Chrome',
- 'tools/get_archive.py',
- 'dartium');
+ _dartiumUpdater = new _DartiumUpdater(
+ 'Dartium Chrome', 'tools/get_archive.py', 'dartium');
}
return _dartiumUpdater;
} else {
diff --git a/tools/testing/dart/html_test.dart b/tools/testing/dart/html_test.dart
index 0f69eed..dfa555f 100644
--- a/tools/testing/dart/html_test.dart
+++ b/tools/testing/dart/html_test.dart
@@ -31,15 +31,15 @@
var match = htmlAnnotation.firstMatch(contents);
if (match == null) return null;
var annotation = JSON.decode(match[1]);
- if (annotation is! Map || annotation['expectedMessages'] is! List ||
+ if (annotation is! Map ||
+ annotation['expectedMessages'] is! List ||
annotation['scripts'] is! List) {
DebugLogger.warning("File $filename does not have expected annotation."
" Should have {'scripts':[...], 'expectedMessages':[...]}");
return null;
}
return new HtmlTestInformation(new Path(filename),
- annotation['expectedMessages'],
- annotation['scripts']);
+ annotation['expectedMessages'], annotation['scripts']);
}
String getContents(HtmlTestInformation info, bool compileToJS) {
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 1cfdb65..429ddeac 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -7,11 +7,10 @@
import 'dart:async';
import 'dart:io';
-import 'dart:convert' show
- HtmlEscape;
+import 'dart:convert' show HtmlEscape;
import 'path.dart';
-import 'test_suite.dart'; // For TestUtils.
+import 'test_suite.dart'; // For TestUtils.
// TODO(efortuna): Rewrite to not use the args library and simply take an
// expected number of arguments, so test.dart doesn't rely on the args library?
// See discussion on https://codereview.chromium.org/11931025/.
@@ -23,9 +22,8 @@
Map<String, Function> _handlers = new Map<String, Function>();
Function _notFound;
- DispatchingServer(this.server,
- void onError(e),
- void this._notFound(HttpRequest request)) {
+ DispatchingServer(
+ this.server, void onError(e), void this._notFound(HttpRequest request)) {
server.listen(_dispatchRequest, onError: onError);
}
@@ -46,8 +44,6 @@
}
}
-
-
/// Interface of the HTTP server:
///
/// /echo: This will stream the data received in the request stream back
@@ -77,37 +73,37 @@
TestUtils.setDartDirUri(Platform.script.resolve('../../..'));
/** Convenience method for local testing. */
var parser = new ArgParser();
- parser.addOption('port', abbr: 'p',
+ parser.addOption('port',
+ abbr: 'p',
help: 'The main server port we wish to respond to requests.',
defaultsTo: '0');
- parser.addOption('crossOriginPort', abbr: 'c',
+ parser.addOption('crossOriginPort',
+ abbr: 'c',
help: 'A different port that accepts request from the main server port.',
defaultsTo: '0');
- parser.addFlag('help', abbr: 'h', negatable: false,
- help: 'Print this usage information.');
+ parser.addFlag('help',
+ abbr: 'h', negatable: false, help: 'Print this usage information.');
parser.addOption('build-directory', help: 'The build directory to use.');
parser.addOption('package-root', help: 'The package root to use.');
- parser.addOption('network', help: 'The network interface to use.',
- defaultsTo: '0.0.0.0');
- parser.addFlag('csp', help: 'Use Content Security Policy restrictions.',
- defaultsTo: false);
- parser.addOption('runtime', help: 'The runtime we are using (for csp flags).',
- defaultsTo: 'none');
+ parser.addOption('network',
+ help: 'The network interface to use.', defaultsTo: '0.0.0.0');
+ parser.addFlag('csp',
+ help: 'Use Content Security Policy restrictions.', defaultsTo: false);
+ parser.addOption('runtime',
+ help: 'The runtime we are using (for csp flags).', defaultsTo: 'none');
var args = parser.parse(arguments);
if (args['help']) {
print(parser.getUsage());
} else {
var servers = new TestingServers(new Path(args['build-directory']),
- args['csp'],
- args['runtime'],
- null,
- args['package-root']);
+ args['csp'], args['runtime'], null, args['package-root']);
var port = int.parse(args['port']);
var crossOriginPort = int.parse(args['crossOriginPort']);
- servers.startServers(args['network'],
- port: port,
- crossOriginPort: crossOriginPort).then((_) {
+ servers
+ .startServers(args['network'],
+ port: port, crossOriginPort: crossOriginPort)
+ .then((_) {
DebugLogger.info('Server listening on port ${servers.port}');
DebugLogger.info('Server listening on port ${servers.crossOriginPort}');
});
@@ -138,16 +134,16 @@
final String runtime;
DispatchingServer _server;
- TestingServers(Path buildDirectory,
- this.useContentSecurityPolicy,
- [String this.runtime = 'none', String dartDirectory,
- String packageRoot]) {
+ TestingServers(Path buildDirectory, this.useContentSecurityPolicy,
+ [String this.runtime = 'none',
+ String dartDirectory,
+ String packageRoot]) {
_buildDirectory = TestUtils.absolutePath(buildDirectory);
- _dartDirectory = dartDirectory == null ? TestUtils.dartDir
- : new Path(dartDirectory);
- _packageRoot = packageRoot == null ?
- _buildDirectory.append('packages') :
- new Path(packageRoot);
+ _dartDirectory =
+ dartDirectory == null ? TestUtils.dartDir : new Path(dartDirectory);
+ _packageRoot = packageRoot == null
+ ? _buildDirectory.append('packages')
+ : new Path(packageRoot);
}
int get port => _serverList[0].port;
@@ -166,8 +162,7 @@
return _startHttpServer(host, port: port).then((server) {
_server = server;
return _startHttpServer(host,
- port: crossOriginPort,
- allowedPort:_serverList[0].port);
+ port: crossOriginPort, allowedPort: _serverList[0].port);
});
}
@@ -178,8 +173,8 @@
var buildDirectory = _buildDirectory.toNativePath();
var csp = useContentSecurityPolicy ? '--csp ' : '';
return '$dart $script -p $port -c $crossOriginPort $csp'
- '--build-directory=$buildDirectory --runtime=$runtime '
- '--package-root=$_packageRoot';
+ '--build-directory=$buildDirectory --runtime=$runtime '
+ '--package-root=$_packageRoot';
}
void stopServers() {
@@ -208,12 +203,11 @@
});
}
- void _handleFileOrDirectoryRequest(HttpRequest request,
- int allowedPort) {
+ void _handleFileOrDirectoryRequest(HttpRequest request, int allowedPort) {
// Enable browsers to cache file/directory responses.
var response = request.response;
- response.headers.set("Cache-Control",
- "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
+ response.headers
+ .set("Cache-Control", "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
var path = _getFilePathFromRequestPath(request.uri.path);
if (path != null) {
var file = new File(path.toNativePath());
@@ -235,9 +229,11 @@
});
} else {
if (request.uri.path == '/') {
- var entries = [new _Entry('root_dart', 'root_dart/'),
- new _Entry('root_build', 'root_build/'),
- new _Entry('echo', 'echo')];
+ var entries = [
+ new _Entry('root_dart', 'root_dart/'),
+ new _Entry('root_build', 'root_build/'),
+ new _Entry('echo', 'echo')
+ ];
_sendDirectoryListing(entries, request, response);
} else {
_sendNotFound(request);
@@ -285,12 +281,10 @@
var relativePath;
if (pathSegments[0] == PREFIX_BUILDDIR) {
basePath = _buildDirectory;
- relativePath = new Path(
- pathSegments.skip(1).join('/'));
+ relativePath = new Path(pathSegments.skip(1).join('/'));
} else if (pathSegments[0] == PREFIX_DARTDIR) {
basePath = _dartDirectory;
- relativePath = new Path(
- pathSegments.skip(1).join('/'));
+ relativePath = new Path(pathSegments.skip(1).join('/'));
}
var packagesIndex = pathSegments.indexOf('packages');
if (packagesIndex != -1) {
@@ -309,24 +303,21 @@
var completer = new Completer();
var entries = [];
- directory.list().listen(
- (FileSystemEntity fse) {
- var filename = new Path(fse.path).filename;
- if (fse is File) {
- entries.add(new _Entry(filename, filename));
- } else if (fse is Directory) {
- entries.add(new _Entry(filename, '$filename/'));
- }
- },
- onDone: () {
- completer.complete(entries);
- });
+ directory.list().listen((FileSystemEntity fse) {
+ var filename = new Path(fse.path).filename;
+ if (fse is File) {
+ entries.add(new _Entry(filename, filename));
+ } else if (fse is Directory) {
+ entries.add(new _Entry(filename, '$filename/'));
+ }
+ }, onDone: () {
+ completer.complete(entries);
+ });
return completer.future;
}
- void _sendDirectoryListing(List<_Entry> entries,
- HttpRequest request,
- HttpResponse response) {
+ void _sendDirectoryListing(
+ List<_Entry> entries, HttpRequest request, HttpResponse response) {
response.headers.set('Content-Type', 'text/html');
var header = '''<!DOCTYPE html>
<html>
@@ -344,7 +335,6 @@
</body>
</html>''';
-
entries.sort();
response.write(header);
for (var entry in entries) {
@@ -360,26 +350,21 @@
});
}
- void _sendFileContent(HttpRequest request,
- HttpResponse response,
- int allowedPort,
- Path path,
- File file) {
+ void _sendFileContent(HttpRequest request, HttpResponse response,
+ int allowedPort, Path path, File file) {
if (allowedPort != -1) {
var headerOrigin = request.headers.value('Origin');
var allowedOrigin;
if (headerOrigin != null) {
var origin = Uri.parse(headerOrigin);
// Allow loading from http://*:$allowedPort in browsers.
- allowedOrigin =
- '${origin.scheme}://${origin.host}:${allowedPort}';
+ allowedOrigin = '${origin.scheme}://${origin.host}:${allowedPort}';
} else {
// IE10 appears to be bugged and is not sending the Origin header
// when making CORS requests to the same domain but different port.
allowedOrigin = '*';
}
-
response.headers.set("Access-Control-Allow-Origin", allowedOrigin);
response.headers.set('Access-Control-Allow-Credentials', 'true');
} else {
@@ -392,8 +377,10 @@
// whereas Firefox and IE10 use X-Content-Security-Policy. Safari
// still uses the WebKit- prefixed version.
var content_header_value = "script-src 'self'; object-src 'self'";
- for (var header in ["Content-Security-Policy",
- "X-Content-Security-Policy"]) {
+ for (var header in [
+ "Content-Security-Policy",
+ "X-Content-Security-Policy"
+ ]) {
response.headers.set(header, content_header_value);
}
if (const ["safari"].contains(runtime)) {
@@ -426,7 +413,7 @@
}
if (!isHarmlessPath(request.uri.path)) {
DebugLogger.warning('HttpServer: could not find file for request path: '
- '"${request.uri.path}"');
+ '"${request.uri.path}"');
}
var response = request.response;
response.statusCode = HttpStatus.NOT_FOUND;
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index 005cdc0..d39bc9a 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -61,27 +61,28 @@
// ddd /// 07: static type warning, dynamic type error
// fff
-void ExtractTestsFromMultitest(Path filePath,
- Map<String, String> tests,
- Map<String, Set<String>> outcomes) {
+void ExtractTestsFromMultitest(Path filePath, Map<String, String> tests,
+ Map<String, Set<String>> outcomes) {
// Read the entire file into a byte buffer and transform it to a
// String. This will treat the file as ascii but the only parts
// we are interested in will be ascii in any case.
List bytes = new File(filePath.toNativePath()).readAsBytesSync();
String contents = decodeUtf8(bytes);
int first_newline = contents.indexOf('\n');
- final String line_separator =
- (first_newline == 0 || contents[first_newline - 1] != '\r')
- ? '\n'
- : '\r\n';
+ final String line_separator = (first_newline == 0 ||
+ contents[first_newline - 1] != '\r') ? '\n' : '\r\n';
List<String> lines = contents.split(line_separator);
if (lines.last == '') lines.removeLast();
bytes = null;
contents = null;
- Set<String> validMultitestOutcomes = new Set<String>.from(
- ['ok', 'compile-time error', 'runtime error',
- 'static type warning', 'dynamic type error',
- 'checked mode compile-time error']);
+ Set<String> validMultitestOutcomes = new Set<String>.from([
+ 'ok',
+ 'compile-time error',
+ 'runtime error',
+ 'static type warning',
+ 'dynamic type error',
+ 'checked mode compile-time error'
+ ]);
// Create the set of multitests, which will have a new test added each
// time we see a multitest line with a new key.
@@ -96,8 +97,8 @@
lineCount++;
var annotation = new _Annotation.from(line);
if (annotation != null) {
- testsAsLines.putIfAbsent(annotation.key,
- () => new List<String>.from(testsAsLines["none"]));
+ testsAsLines.putIfAbsent(
+ annotation.key, () => new List<String>.from(testsAsLines["none"]));
// Add line to test with annotation.key as key, empty line to the rest.
for (var key in testsAsLines.keys) {
testsAsLines[key].add(annotation.key == key ? line : "");
@@ -172,8 +173,8 @@
var annotation = new _Annotation();
annotation.key = parts[0];
annotation.rest = parts[1];
- annotation.outcomesList = annotation.rest.split(',')
- .map((s) => s.trim()).toList();
+ annotation.outcomesList =
+ annotation.rest.split(',').map((s) => s.trim()).toList();
return annotation;
}
}
@@ -219,8 +220,8 @@
return foundImports;
}
-Future doMultitest(Path filePath, String outputDir, Path suiteDir,
- CreateTest doTest) {
+Future doMultitest(
+ Path filePath, String outputDir, Path suiteDir, CreateTest doTest) {
void writeFile(String filepath, String content) {
final File file = new File(filepath);
@@ -254,8 +255,8 @@
TestUtils.mkdirRecursive(targetDir, importDir);
}
// Copy file.
- futureCopies.add(TestUtils.copyFile(sourceDir.join(importPath),
- targetDir.join(importPath)));
+ futureCopies.add(TestUtils.copyFile(
+ sourceDir.join(importPath), targetDir.join(importPath)));
}
// Wait until all imports are copied before scheduling test cases.
@@ -272,21 +273,17 @@
bool isNegativeIfChecked = outcome.contains('dynamic type error');
bool hasCompileErrorIfChecked =
outcome.contains('checked mode compile-time error');
- doTest(multitestFilename,
- filePath,
- hasCompileError,
- hasRuntimeErrors,
- isNegativeIfChecked: isNegativeIfChecked,
- hasCompileErrorIfChecked: hasCompileErrorIfChecked,
- hasStaticWarning: hasStaticWarning,
- multitestKey: key);
+ doTest(multitestFilename, filePath, hasCompileError, hasRuntimeErrors,
+ isNegativeIfChecked: isNegativeIfChecked,
+ hasCompileErrorIfChecked: hasCompileErrorIfChecked,
+ hasStaticWarning: hasStaticWarning,
+ multitestKey: key);
}
return null;
});
}
-
Path CreateMultitestDirectory(String outputDir, Path suiteDir) {
Directory generatedTestDir = new Directory('$outputDir/generated_tests');
if (!new Directory(outputDir).existsSync()) {
diff --git a/tools/testing/dart/path.dart b/tools/testing/dart/path.dart
index 1e1bf7d..a3d35aa 100644
--- a/tools/testing/dart/path.dart
+++ b/tools/testing/dart/path.dart
@@ -13,9 +13,12 @@
final bool isWindowsShare;
Path(String source)
- : _path = _clean(source), isWindowsShare = _isWindowsShare(source);
+ : _path = _clean(source),
+ isWindowsShare = _isWindowsShare(source);
- Path.raw(String source) : _path = source, isWindowsShare = false;
+ Path.raw(String source)
+ : _path = source,
+ isWindowsShare = false;
Path._internal(String this._path, bool this.isWindowsShare);
@@ -58,8 +61,7 @@
// Throws exception if an impossible case is reached.
if (base.isAbsolute != isAbsolute ||
base.isWindowsShare != isWindowsShare) {
- throw new ArgumentError(
- "Invalid case of Path.relativeTo(base):\n"
+ throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
" Path and base must both be relative, or both absolute.\n"
" Arguments: $_path.relativeTo($base)");
}
@@ -72,29 +74,26 @@
bool pathHasDrive =
_path.length >= 4 && _path[2] == ':' && _path[3] == '/';
if (baseHasDrive && pathHasDrive) {
- int baseDrive = basePath.codeUnitAt(1) | 32; // Convert to uppercase.
+ int baseDrive = basePath.codeUnitAt(1) | 32; // Convert to uppercase.
if (baseDrive >= 'a'.codeUnitAt(0) &&
baseDrive <= 'z'.codeUnitAt(0) &&
baseDrive == (_path.codeUnitAt(1) | 32)) {
- if(basePath[1] != _path[1]) {
+ if (basePath[1] != _path[1]) {
// Replace the drive letter in basePath with that from _path.
basePath = '/${_path[1]}:/${basePath.substring(4)}';
base = new Path(basePath);
}
} else {
- throw new ArgumentError(
- "Invalid case of Path.relativeTo(base):\n"
+ throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
" Base path and target path are on different Windows drives.\n"
" Arguments: $_path.relativeTo($base)");
}
} else if (baseHasDrive != pathHasDrive) {
- throw new ArgumentError(
- "Invalid case of Path.relativeTo(base):\n"
+ throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
" Base path must start with a drive letter if and "
"only if target path does.\n"
" Arguments: $_path.relativeTo($base)");
}
-
}
if (_path.startsWith(basePath)) {
if (_path == basePath) return new Path('.');
@@ -125,8 +124,7 @@
final segments = new List<String>();
if (common < baseSegments.length && baseSegments[common] == '..') {
- throw new ArgumentError(
- "Invalid case of Path.relativeTo(base):\n"
+ throw new ArgumentError("Invalid case of Path.relativeTo(base):\n"
" Base path has more '..'s than path does.\n"
" Arguments: $_path.relativeTo($base)");
}
@@ -140,12 +138,11 @@
segments.add('.');
}
if (hasTrailingSeparator) {
- segments.add('');
+ segments.add('');
}
return new Path(segments.join('/'));
}
-
Path join(Path further) {
if (further.isAbsolute) {
throw new ArgumentError(
@@ -175,19 +172,19 @@
// Contains no segments that are '.'.
// Absolute paths have no segments that are '..'.
// All '..' segments of a relative path are at the beginning.
- if (isEmpty) return false; // The canonical form of '' is '.'.
+ if (isEmpty) return false; // The canonical form of '' is '.'.
if (_path == '.') return true;
- List segs = _path.split('/'); // Don't mask the getter 'segments'.
- if (segs[0] == '') { // Absolute path
- segs[0] = null; // Faster than removeRange().
- } else { // A canonical relative path may start with .. segments.
- for (int pos = 0;
- pos < segs.length && segs[pos] == '..';
- ++pos) {
+ List segs = _path.split('/'); // Don't mask the getter 'segments'.
+ if (segs[0] == '') {
+ // Absolute path
+ segs[0] = null; // Faster than removeRange().
+ } else {
+ // A canonical relative path may start with .. segments.
+ for (int pos = 0; pos < segs.length && segs[pos] == '..'; ++pos) {
segs[pos] = null;
}
}
- if (segs.last == '') segs.removeLast(); // Path ends with /.
+ if (segs.last == '') segs.removeLast(); // Path ends with /.
// No remaining segments can be ., .., or empty.
return !segs.any((s) => s == '' || s == '.' || s == '..');
}
@@ -196,10 +193,7 @@
bool isAbs = isAbsolute;
List segs = segments();
String drive;
- if (isAbs &&
- !segs.isEmpty &&
- segs[0].length == 2 &&
- segs[0][1] == ':') {
+ if (isAbs && !segs.isEmpty && segs[0].length == 2 && segs[0][1] == ':') {
drive = segs[0];
segs.removeRange(0, 1);
}
diff --git a/tools/testing/dart/record_and_replay.dart b/tools/testing/dart/record_and_replay.dart
index 68e67ce..022c35d 100644
--- a/tools/testing/dart/record_and_replay.dart
+++ b/tools/testing/dart/record_and_replay.dart
@@ -52,7 +52,7 @@
var _cwd;
TestCaseRecorder(this._outputPath) {
- _cwd = Directory.current.path;
+ _cwd = Directory.current.path;
}
void nextCommand(ProcessCommand command, int timeout) {
@@ -63,11 +63,11 @@
var arguments = makePathsRelativeToDart(_cwd, command.arguments);
var commandExecution = {
- 'name' : command.displayName,
- 'command' : {
- 'timeout_limit' : timeout,
- 'executable' : command.executable,
- 'arguments' : arguments,
+ 'name': command.displayName,
+ 'command': {
+ 'timeout_limit': timeout,
+ 'executable': command.executable,
+ 'arguments': arguments,
},
};
_recordedCommandInvocations.add(commandExecution);
@@ -86,7 +86,7 @@
var _cwd;
TestCaseOutputArchive() {
- _cwd = Directory.current.path;
+ _cwd = Directory.current.path;
}
void loadFromPath(Path recordingPath) {
@@ -95,7 +95,7 @@
_commandOutputRecordings = {};
for (var commandRecording in commandRecordings) {
var key = _indexKey(commandRecording['command']['executable'],
- commandRecording['command']['arguments'].join(' '));
+ commandRecording['command']['arguments'].join(' '));
_commandOutputRecordings[key] = commandRecording['command_output'];
}
}
@@ -111,13 +111,13 @@
var command_output = _commandOutputRecordings[key];
if (command_output == null) {
print("Sorry, but there is no command output for ${command.displayName}"
- " ($command)");
+ " ($command)");
exit(42);
}
double seconds = command_output['duration'];
- var duration = new Duration(seconds: seconds.round(),
- milliseconds: (seconds/1000).round());
+ var duration = new Duration(
+ seconds: seconds.round(), milliseconds: (seconds / 1000).round());
var commandOutput = createCommandOutput(
command,
command_output['exit_code'],
@@ -133,4 +133,3 @@
return "${executable}__$arguments";
}
}
-
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index 55cf8fe..8766322 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -4,17 +4,13 @@
library runtime_configuration;
-import 'compiler_configuration.dart' show
- CommandArtifact;
+import 'compiler_configuration.dart' show CommandArtifact;
// TODO(ahe): Remove this import, we can precompute all the values required
// from TestSuite once the refactoring is complete.
-import 'test_suite.dart' show
- TestSuite;
+import 'test_suite.dart' show TestSuite;
-import 'test_runner.dart' show
- Command,
- CommandBuilder;
+import 'test_runner.dart' show Command, CommandBuilder;
// TODO(ahe): I expect this class will become abstract very soon.
class RuntimeConfiguration {
@@ -68,10 +64,8 @@
RuntimeConfiguration._subclass();
- int computeTimeoutMultiplier({
- String mode,
- bool isChecked: false,
- String arch}) {
+ int computeTimeoutMultiplier(
+ {String mode, bool isChecked: false, String arch}) {
return 1;
}
@@ -90,8 +84,7 @@
/// The 'none' runtime configuration.
class NoneRuntimeConfiguration extends RuntimeConfiguration {
- NoneRuntimeConfiguration()
- : super._subclass();
+ NoneRuntimeConfiguration() : super._subclass();
List<Command> computeRuntimeCommands(
TestSuite suite,
@@ -106,8 +99,7 @@
class CommandLineJavaScriptRuntime extends RuntimeConfiguration {
final String moniker;
- CommandLineJavaScriptRuntime(this.moniker)
- : super._subclass();
+ CommandLineJavaScriptRuntime(this.moniker) : super._subclass();
void checkArtifact(CommandArtifact artifact) {
String type = artifact.mimeType;
@@ -119,8 +111,7 @@
/// Chrome/V8-based development shell (d8).
class D8RuntimeConfiguration extends CommandLineJavaScriptRuntime {
- D8RuntimeConfiguration()
- : super('d8');
+ D8RuntimeConfiguration() : super('d8');
List<Command> computeRuntimeCommands(
TestSuite suite,
@@ -131,8 +122,9 @@
// TODO(ahe): Avoid duplication of this method between d8 and jsshell.
checkArtifact(artifact);
return <Command>[
- commandBuilder.getJSCommandlineCommand(
- moniker, suite.d8FileName, arguments, environmentOverrides)];
+ commandBuilder.getJSCommandlineCommand(
+ moniker, suite.d8FileName, arguments, environmentOverrides)
+ ];
}
List<String> dart2jsPreambles(Uri preambleDir) {
@@ -142,8 +134,7 @@
/// Firefox/SpiderMonkey-based development shell (jsshell).
class JsshellRuntimeConfiguration extends CommandLineJavaScriptRuntime {
- JsshellRuntimeConfiguration()
- : super('jsshell');
+ JsshellRuntimeConfiguration() : super('jsshell');
List<Command> computeRuntimeCommands(
TestSuite suite,
@@ -153,8 +144,9 @@
Map<String, String> environmentOverrides) {
checkArtifact(artifact);
return <Command>[
- commandBuilder.getJSCommandlineCommand(
- moniker, suite.jsShellFileName, arguments, environmentOverrides)];
+ commandBuilder.getJSCommandlineCommand(
+ moniker, suite.jsShellFileName, arguments, environmentOverrides)
+ ];
}
List<String> dart2jsPreambles(Uri preambleDir) {
@@ -164,20 +156,17 @@
/// Common runtime configuration for runtimes based on the Dart VM.
class DartVmRuntimeConfiguration extends RuntimeConfiguration {
- DartVmRuntimeConfiguration()
- : super._subclass();
+ DartVmRuntimeConfiguration() : super._subclass();
- int computeTimeoutMultiplier({
- String mode,
- bool isChecked: false,
- String arch}) {
+ int computeTimeoutMultiplier(
+ {String mode, bool isChecked: false, String arch}) {
int multiplier = 1;
switch (arch) {
case 'simarm':
case 'arm':
case 'simarmv6':
case 'armv6':
- case' simarmv5te':
+ case ' simarmv5te':
case 'armv5te':
case 'simmips':
case 'mips':
@@ -195,16 +184,14 @@
/// Runtime configuration for Content Shell. We previously used a similar
/// program named Dump Render Tree, hence the name.
class DrtRuntimeConfiguration extends DartVmRuntimeConfiguration {
- int computeTimeoutMultiplier({
- String mode,
- bool isChecked: false,
- String arch}) {
+ int computeTimeoutMultiplier(
+ {String mode, bool isChecked: false, String arch}) {
return 4 // Allow additional time for browser testing to run.
// TODO(ahe): We might need to distinquish between DRT for running
// JavaScript and Dart code. I'm not convinced the inherited timeout
// multiplier is relevant for JavaScript.
- * super.computeTimeoutMultiplier(
- mode: mode, isChecked: isChecked);
+ *
+ super.computeTimeoutMultiplier(mode: mode, isChecked: isChecked);
}
}
@@ -224,8 +211,9 @@
String executable = suite.configuration['noopt']
? suite.dartVmNooptBinaryFileName
: suite.dartVmBinaryFileName;
- return <Command>[commandBuilder.getVmCommand(
- executable, arguments, environmentOverrides)];
+ return <Command>[
+ commandBuilder.getVmCommand(executable, arguments, environmentOverrides)
+ ];
}
}
@@ -246,10 +234,10 @@
augmentedArgs.add("--run-full-snapshot=${artifact.filename}");
augmentedArgs.addAll(arguments);
- return <Command>[commandBuilder.getVmCommand(
- suite.dartVmProductBinaryFileName,
- augmentedArgs,
- environmentOverrides)];
+ return <Command>[
+ commandBuilder.getVmCommand(suite.dartVmProductBinaryFileName,
+ augmentedArgs, environmentOverrides)
+ ];
}
}
@@ -270,10 +258,10 @@
augmentedArgs.add("--run-precompiled-snapshot=${artifact.filename}");
augmentedArgs.addAll(arguments);
- return <Command>[commandBuilder.getVmCommand(
- suite.dartPrecompiledBinaryFileName,
- augmentedArgs,
- environmentOverrides)];
+ return <Command>[
+ commandBuilder.getVmCommand(suite.dartPrecompiledBinaryFileName,
+ augmentedArgs, environmentOverrides)
+ ];
}
}
diff --git a/tools/testing/dart/status_expression.dart b/tools/testing/dart/status_expression.dart
index 5cd0a34..c5b0b80 100644
--- a/tools/testing/dart/status_expression.dart
+++ b/tools/testing/dart/status_expression.dart
@@ -49,13 +49,11 @@
static const String OR = "||";
}
-
class Tokenizer {
String expression;
List<String> tokens;
- Tokenizer(String this.expression)
- : tokens = new List<String>();
+ Tokenizer(String this.expression) : tokens = new List<String>();
// Tokens are : "(", ")", "$", ",", "&&", "||", "==", "!=", and (maximal) \w+.
static final testRegexp =
@@ -71,17 +69,14 @@
}
}
-
abstract class BooleanExpression {
bool evaluate(Map<String, String> environment);
}
-
abstract class SetExpression {
Set<String> evaluate(Map<String, String> environment);
}
-
class Comparison implements BooleanExpression {
TermVariable left;
TermConstant right;
@@ -90,15 +85,14 @@
Comparison(this.left, this.right, this.negate);
bool evaluate(environment) {
- return
- negate != (left.termValue(environment) == right.termValue(environment));
+ return negate !=
+ (left.termValue(environment) == right.termValue(environment));
}
String toString() =>
"(\$${left.name} ${negate ? '!=' : '=='} ${right.value})";
}
-
class TermVariable {
String name;
@@ -107,15 +101,13 @@
String termValue(environment) {
var value = environment[name];
if (value == null) {
- throw new ExprEvaluationException(
- "Could not find '$name' in environment "
+ throw new ExprEvaluationException("Could not find '$name' in environment "
"while evaluating status file expression.");
}
return value.toString();
}
}
-
class TermConstant {
String value;
@@ -124,7 +116,6 @@
String termValue(environment) => value;
}
-
class BooleanVariable implements BooleanExpression {
TermVariable variable;
@@ -134,7 +125,6 @@
String toString() => "(bool \$${variable.name})";
}
-
class BooleanOperation implements BooleanExpression {
String op;
BooleanExpression left;
@@ -142,13 +132,12 @@
BooleanOperation(this.op, this.left, this.right);
- bool evaluate(environment) => (op == Token.AND) ?
- left.evaluate(environment) && right.evaluate(environment) :
- left.evaluate(environment) || right.evaluate(environment);
+ bool evaluate(environment) => (op == Token.AND)
+ ? left.evaluate(environment) && right.evaluate(environment)
+ : left.evaluate(environment) || right.evaluate(environment);
String toString() => "($left $op $right)";
}
-
class SetUnion implements SetExpression {
SetExpression left;
SetExpression right;
@@ -166,19 +155,18 @@
String toString() => "($left || $right)";
}
-
class SetIf implements SetExpression {
SetExpression left;
BooleanExpression right;
SetIf(this.left, this.right);
- Set<String> evaluate(environment) => right.evaluate(environment) ?
- left.evaluate(environment) : new Set<String>();
+ Set<String> evaluate(environment) => right.evaluate(environment)
+ ? left.evaluate(environment)
+ : new Set<String>();
String toString() => "($left if $right)";
}
-
class SetConstant implements SetExpression {
String value;
@@ -188,7 +176,6 @@
String toString() => value;
}
-
// An iterator that allows peeking at the current token.
class Scanner {
List<String> tokens;
@@ -207,7 +194,6 @@
}
}
-
class ExpressionParser {
Scanner scanner;
@@ -217,7 +203,7 @@
SetExpression parseSetUnion() {
SetExpression left = parseSetIf();
- while (scanner.hasMore() && scanner.current == Token.UNION){
+ while (scanner.hasMore() && scanner.current == Token.UNION) {
scanner.advance();
SetExpression right = parseSetIf();
left = new SetUnion(left, right);
@@ -237,7 +223,7 @@
SetExpression parseSetOr() {
SetExpression left = parseSetAtomic();
- while (scanner.hasMore() && scanner.current == Token.OR){
+ while (scanner.hasMore() && scanner.current == Token.OR) {
scanner.advance();
SetExpression right = parseSetAtomic();
left = new SetUnion(left, right);
@@ -245,7 +231,6 @@
return left;
}
-
SetExpression parseSetAtomic() {
if (scanner.current == Token.LEFT_PAREN) {
scanner.advance();
@@ -327,4 +312,3 @@
}
}
}
-
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index 8c32e6e..8fa9bb7 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -25,8 +25,7 @@
static Expectation MISSING_COMPILETIME_ERROR =
byName('MissingCompileTimeError');
static Expectation STATIC_WARNING = byName('StaticWarning');
- static Expectation MISSING_STATIC_WARNING =
- byName('MissingStaticWarning');
+ static Expectation MISSING_STATIC_WARNING = byName('MissingStaticWarning');
static Expectation PUB_GET_ERROR = byName('PubGetError');
// "meta expectations"
@@ -46,7 +45,7 @@
}
// Keep a map of all possible Expectation objects, initialized lazily.
- static Map<String, Expectation> _AllExpectations;
+ static Map<String, Expectation> _AllExpectations;
static void _initialize() {
if (_AllExpectations == null) {
_AllExpectations = new Map<String, Expectation>();
@@ -89,9 +88,9 @@
final bool isMetaExpectation;
Expectation._(prettyName,
- {Expectation this.group: null,
- bool this.isMetaExpectation: false})
- : prettyName = prettyName, name = prettyName.toLowerCase();
+ {Expectation this.group: null, bool this.isMetaExpectation: false})
+ : prettyName = prettyName,
+ name = prettyName.toLowerCase();
bool canBeOutcomeOf(Expectation expectation) {
Expectation outcome = this;
@@ -107,7 +106,6 @@
String toString() => prettyName;
}
-
final RegExp SplitComment = new RegExp("^([^#]*)(#.*)?\$");
final RegExp HeaderPattern = new RegExp(r"^\[([^\]]+)\]");
final RegExp RulePattern = new RegExp(r"\s*([^: ]*)\s*:(.*)");
@@ -129,7 +127,8 @@
final int lineNumber;
Section.always(this.statusFile, this.lineNumber)
- : condition = null, testRules = new List<TestRule>();
+ : condition = null,
+ testRules = new List<TestRule>();
Section(this.statusFile, this.condition, this.lineNumber)
: testRules = new List<TestRule>();
@@ -141,18 +140,16 @@
}
}
-Future<TestExpectations> ReadTestExpectations(List<String> statusFilePaths,
- Map environment) {
+Future<TestExpectations> ReadTestExpectations(
+ List<String> statusFilePaths, Map environment) {
var testExpectations = new TestExpectations();
return Future.wait(statusFilePaths.map((String statusFile) {
- return ReadTestExpectationsInto(
- testExpectations, statusFile, environment);
+ return ReadTestExpectationsInto(testExpectations, statusFile, environment);
})).then((_) => testExpectations);
}
-Future ReadTestExpectationsInto(TestExpectations expectations,
- String statusFilePath,
- environment) {
+Future ReadTestExpectationsInto(
+ TestExpectations expectations, String statusFilePath, environment) {
var completer = new Completer();
List<Section> sections = new List<Section>();
@@ -179,14 +176,11 @@
}
int lineNumber = 0;
Stream<String> lines =
- file.openRead()
- .transform(UTF8.decoder)
- .transform(new LineSplitter());
+ file.openRead().transform(UTF8.decoder).transform(new LineSplitter());
Section currentSection = new Section.always(statusFile, -1);
sections.add(currentSection);
-
lines.listen((String line) {
lineNumber++;
Match match = SplitComment.firstMatch(line);
@@ -225,34 +219,28 @@
if (issueString == null) issueString = match[2];
}
int issue = issueString != null ? int.parse(issueString) : null;
- currentSection.testRules.add(
- new TestRule(name, expression, issue, lineNumber));
+ currentSection.testRules
+ .add(new TestRule(name, expression, issue, lineNumber));
return;
}
print("unmatched line: $line");
- },
- onDone: onDone);
+ }, onDone: onDone);
}
-
class TestRule {
String name;
SetExpression expression;
int issue;
int lineNumber;
- TestRule(this.name,
- this.expression,
- this.issue,
- this.lineNumber);
+ TestRule(this.name, this.expression, this.issue, this.lineNumber);
bool get hasIssue => issue != null;
String toString() => 'TestRule($name, $expression, $issue)';
}
-
class TestExpectations {
// Only create one copy of each Set<Expectation>.
// We just use .toString as a key, so we may make a few
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index 5841052..0f5e37b 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -6,78 +6,78 @@
import 'dart:convert';
List<Map> LINUX_COMBINATIONS = [
- {
- 'runtimes' : ['none'],
- 'modes' : ['release'],
- 'archs' : ['x64'],
- 'compiler' : 'dart2analyzer'
- },
- {
- 'runtimes' : ['vm'],
- 'modes' : ['debug', 'release'],
- 'archs' : ['ia32', 'x64', 'simarm', 'simmips'],
- 'compiler' : 'none'
- },
- {
- 'runtimes' : ['d8', 'jsshell', 'chrome', 'ff'],
- 'modes' : ['release'],
- 'archs' : ['ia32'],
- 'compiler' : 'dart2js'
- },
- {
- 'runtimes' : ['dartium'],
- 'modes' : ['release', 'debug'],
- 'archs' : ['ia32'],
- 'compiler' : 'none'
- },
+ {
+ 'runtimes': ['none'],
+ 'modes': ['release'],
+ 'archs': ['x64'],
+ 'compiler': 'dart2analyzer'
+ },
+ {
+ 'runtimes': ['vm'],
+ 'modes': ['debug', 'release'],
+ 'archs': ['ia32', 'x64', 'simarm', 'simmips'],
+ 'compiler': 'none'
+ },
+ {
+ 'runtimes': ['d8', 'jsshell', 'chrome', 'ff'],
+ 'modes': ['release'],
+ 'archs': ['ia32'],
+ 'compiler': 'dart2js'
+ },
+ {
+ 'runtimes': ['dartium'],
+ 'modes': ['release', 'debug'],
+ 'archs': ['ia32'],
+ 'compiler': 'none'
+ },
];
List<Map> MACOS_COMBINATIONS = [
- {
- 'runtimes' : ['vm'],
- 'modes' : ['debug', 'release'],
- 'archs' : ['ia32', 'x64'],
- 'compiler' : 'none'
- },
- {
- 'runtimes' : ['safari', 'safarimobilesim'],
- 'modes' : ['release'],
- 'archs' : ['ia32'],
- 'compiler' : 'dart2js'
- },
- {
- 'runtimes' : ['dartium'],
- 'modes' : ['release', 'debug'],
- 'archs' : ['ia32'],
- 'compiler' : 'none'
- },
+ {
+ 'runtimes': ['vm'],
+ 'modes': ['debug', 'release'],
+ 'archs': ['ia32', 'x64'],
+ 'compiler': 'none'
+ },
+ {
+ 'runtimes': ['safari', 'safarimobilesim'],
+ 'modes': ['release'],
+ 'archs': ['ia32'],
+ 'compiler': 'dart2js'
+ },
+ {
+ 'runtimes': ['dartium'],
+ 'modes': ['release', 'debug'],
+ 'archs': ['ia32'],
+ 'compiler': 'none'
+ },
];
List<Map> WINDOWS_COMBINATIONS = [
- {
- 'runtimes' : ['vm'],
- 'modes' : ['debug', 'release'],
- 'archs' : ['ia32', 'x64'],
- 'compiler' : 'none'
- },
- {
- 'runtimes' : ['chrome', 'ff', 'ie11', 'ie10'],
- 'modes' : ['release'],
- 'archs' : ['ia32'],
- 'compiler' : 'dart2js'
- },
- {
- 'runtimes' : ['dartium'],
- 'modes' : ['release', 'debug'],
- 'archs' : ['ia32'],
- 'compiler' : 'none'
- },
+ {
+ 'runtimes': ['vm'],
+ 'modes': ['debug', 'release'],
+ 'archs': ['ia32', 'x64'],
+ 'compiler': 'none'
+ },
+ {
+ 'runtimes': ['chrome', 'ff', 'ie11', 'ie10'],
+ 'modes': ['release'],
+ 'archs': ['ia32'],
+ 'compiler': 'dart2js'
+ },
+ {
+ 'runtimes': ['dartium'],
+ 'modes': ['release', 'debug'],
+ 'archs': ['ia32'],
+ 'compiler': 'none'
+ },
];
Map<String, List<Map>> COMBINATIONS = {
- 'linux' : LINUX_COMBINATIONS,
- 'windows' : WINDOWS_COMBINATIONS,
- 'macos' : MACOS_COMBINATIONS
+ 'linux': LINUX_COMBINATIONS,
+ 'windows': WINDOWS_COMBINATIONS,
+ 'macos': MACOS_COMBINATIONS
};
List<Map> getCombinations() {
@@ -165,8 +165,15 @@
for (var runtime in combination['runtimes']) {
var compiler = combination['compiler'];
- var args = ['tools/test.py', '-m$mode', '-c$compiler', '-r$runtime',
- '-a$arch', '--report-in-json', '--use-sdk'];
+ var args = [
+ 'tools/test.py',
+ '-m$mode',
+ '-c$compiler',
+ '-r$runtime',
+ '-a$arch',
+ '--report-in-json',
+ '--use-sdk'
+ ];
var result = Process.runSync('python', args);
if (result.exitCode != 0) {
print(result.stdout);
@@ -202,7 +209,7 @@
for (var key in keys) {
var value = map[key];
values.add(value);
- var pct = 100*(value/total);
+ var pct = 100 * (value / total);
values.add('${pct.toStringAsFixed(3)}%');
}
diff --git a/tools/testing/dart/summary_report.dart b/tools/testing/dart/summary_report.dart
index 2f740b5..e62f772 100644
--- a/tools/testing/dart/summary_report.dart
+++ b/tools/testing/dart/summary_report.dart
@@ -37,7 +37,7 @@
.any((expectation) => expectation.canBeOutcomeOf(Expectation.FAIL));
bool containsPass = expectations.contains(Expectation.PASS);
bool containsSkip = expectations
- .any((expectation) => expectation.canBeOutcomeOf(Expectation.SKIP));
+ .any((expectation) => expectation.canBeOutcomeOf(Expectation.SKIP));
bool containsSkipByDesign =
expectations.contains(Expectation.SKIP_BY_DESIGN);
bool containsCrash = expectations.contains(Expectation.CRASH);
@@ -100,19 +100,19 @@
}
Map<String, int> get values => {
- 'total': _total,
- 'skippedOther': skippedOther,
- 'skippedByDesign': _skippedByDesign,
- 'pass': _pass,
- 'noCrash': _noCrash,
- 'flakyCrash': _flakyCrash,
- 'failOk': _failOk,
- 'fail': _fail,
- 'crash': _crash,
- 'timeout': _timeout,
- 'compileErrorSkip': _compileErrorSkip,
- 'bogus': bogus
- };
+ 'total': _total,
+ 'skippedOther': skippedOther,
+ 'skippedByDesign': _skippedByDesign,
+ 'pass': _pass,
+ 'noCrash': _noCrash,
+ 'flakyCrash': _flakyCrash,
+ 'failOk': _failOk,
+ 'fail': _fail,
+ 'crash': _crash,
+ 'timeout': _timeout,
+ 'compileErrorSkip': _compileErrorSkip,
+ 'bogus': bogus
+ };
String get report => """Total: $_total tests
* $_skipped tests will be skipped ($_skippedByDesign skipped by design)
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index c7d4a09..ff48273 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -26,27 +26,27 @@
* moved to here, if possible.
*/
final TEST_SUITE_DIRECTORIES = [
- new Path('pkg'),
- new Path('third_party/pkg_tested'),
- new Path('runtime/tests/vm'),
- new Path('runtime/observatory/tests/service'),
- new Path('samples'),
- new Path('samples-dev'),
- new Path('tests/benchmark_smoke'),
- new Path('tests/chrome'),
- new Path('tests/compiler/dart2js'),
- new Path('tests/compiler/dart2js_extra'),
- new Path('tests/compiler/dart2js_native'),
- new Path('tests/corelib'),
- new Path('tests/html'),
- new Path('tests/isolate'),
- new Path('tests/language'),
- new Path('tests/lib'),
- new Path('tests/standalone'),
- new Path('tests/try'),
- new Path('tests/utils'),
- new Path('utils/tests/css'),
- new Path('utils/tests/peg'),
+ new Path('pkg'),
+ new Path('third_party/pkg_tested'),
+ new Path('runtime/tests/vm'),
+ new Path('runtime/observatory/tests/service'),
+ new Path('samples'),
+ new Path('samples-dev'),
+ new Path('tests/benchmark_smoke'),
+ new Path('tests/chrome'),
+ new Path('tests/compiler/dart2js'),
+ new Path('tests/compiler/dart2js_extra'),
+ new Path('tests/compiler/dart2js_native'),
+ new Path('tests/corelib'),
+ new Path('tests/html'),
+ new Path('tests/isolate'),
+ new Path('tests/language'),
+ new Path('tests/lib'),
+ new Path('tests/standalone'),
+ new Path('tests/try'),
+ new Path('tests/utils'),
+ new Path('utils/tests/css'),
+ new Path('utils/tests/peg'),
];
void testConfigurations(List<Map> configurations) {
@@ -72,13 +72,15 @@
if (recordingPath != null && recordingOutputPath != null) {
print("Fatal: Can't have the '--record_to_file' and '--replay_from_file'"
- "at the same time. Exiting ...");
+ "at the same time. Exiting ...");
exit(1);
}
- if (!firstConf['append_logs']) {
- var files = [new File(TestUtils.flakyFileName()),
- new File(TestUtils.testOutcomeFileName())];
+ if (!firstConf['append_logs']) {
+ var files = [
+ new File(TestUtils.flakyFileName()),
+ new File(TestUtils.testOutcomeFileName())
+ ];
for (var file in files) {
if (file.existsSync()) {
file.deleteSync();
@@ -86,18 +88,21 @@
}
}
- DebugLogger.init(firstConf['write_debug_log'] ?
- TestUtils.debugLogfile() : null, append: firstConf['append_logs']);
+ DebugLogger.init(
+ firstConf['write_debug_log'] ? TestUtils.debugLogfile() : null,
+ append: firstConf['append_logs']);
// Print the configurations being run by this execution of
// test.dart. However, don't do it if the silent progress indicator
// is used. This is only needed because of the junit tests.
if (progressIndicator != 'silent') {
- List output_words = configurations.length > 1 ?
- ['Test configurations:'] : ['Test configuration:'];
+ List output_words = configurations.length > 1
+ ? ['Test configurations:']
+ : ['Test configuration:'];
for (Map conf in configurations) {
List settings = ['compiler', 'runtime', 'mode', 'arch']
- .map((name) => conf[name]).toList();
+ .map((name) => conf[name])
+ .toList();
if (conf['checked']) settings.add('checked');
if (conf['noopt']) settings.add('noopt');
output_words.add(settings.join('_'));
@@ -114,9 +119,9 @@
var maxBrowserProcesses = maxProcesses;
if (configurations.length > 1 &&
(configurations[0]['test_server_port'] != 0 ||
- configurations[0]['test_server_cross_origin_port'] != 0)) {
+ configurations[0]['test_server_cross_origin_port'] != 0)) {
print("If the http server ports are specified, only one configuration"
- " may be run at a time");
+ " may be run at a time");
exit(1);
}
for (var conf in configurations) {
@@ -127,11 +132,12 @@
// The http server is available on window.location.port, and a second
// server for cross-domain tests can be found by calling
// getCrossOriginPortNumber().
- var servers = new TestingServers(new Path(TestUtils.buildDir(conf)),
- useContentSecurityPolicy,
- conf['runtime'],
- null,
- conf['package_root']);
+ var servers = new TestingServers(
+ new Path(TestUtils.buildDir(conf)),
+ useContentSecurityPolicy,
+ conf['runtime'],
+ null,
+ conf['package_root']);
serverFutures.add(servers.startServers(conf['local_ip'],
port: conf['test_server_port'],
crossOriginPort: conf['test_server_cross_origin_port']));
@@ -158,7 +164,7 @@
// for mobile safari simultainiously.
maxBrowserProcesses = 1;
} else if (conf['runtime'] == 'chrome' &&
- Platform.operatingSystem == 'macos') {
+ Platform.operatingSystem == 'macos') {
// Chrome on mac results in random timeouts.
// Issue: https://github.com/dart-lang/sdk/issues/23891
// This change does not fix the problem.
@@ -180,8 +186,8 @@
if (key == 'co19') {
testSuites.add(new Co19TestSuite(conf));
} else if (conf['compiler'] == 'none' &&
- conf['runtime'] == 'vm' &&
- key == 'vm') {
+ conf['runtime'] == 'vm' &&
+ key == 'vm') {
// vm tests contain both cc tests (added here) and dart tests (added
// in [TEST_SUITE_DIRECTORIES]).
testSuites.add(new VMTestSuite(conf));
@@ -190,17 +196,17 @@
testSuites.add(new AnalyzeLibraryTestSuite(conf));
}
} else if (conf['compiler'] == 'none' &&
- conf['runtime'] == 'vm' &&
- key == 'pkgbuild') {
+ conf['runtime'] == 'vm' &&
+ key == 'pkgbuild') {
if (!conf['use_repository_packages'] &&
!conf['use_public_packages']) {
print("You need to use either --use-repository-packages or "
- "--use-public-packages with the pkgbuild test suite!");
+ "--use-public-packages with the pkgbuild test suite!");
exit(1);
}
if (!conf['use_sdk']) {
print("Running the 'pkgbuild' test suite requires "
- "passing the '--use-sdk' to test.py");
+ "passing the '--use-sdk' to test.py");
exit(1);
}
testSuites.add(
@@ -211,8 +217,8 @@
for (final testSuiteDir in TEST_SUITE_DIRECTORIES) {
final name = testSuiteDir.filename;
if (selectors.containsKey(name)) {
- testSuites.add(
- new StandardTestSuite.forDirectory(conf, testSuiteDir));
+ testSuites
+ .add(new StandardTestSuite.forDirectory(conf, testSuiteDir));
}
}
}
@@ -252,9 +258,8 @@
var printFailureSummary = progressIndicator != 'buildbot';
eventListener.add(new TestFailurePrinter(printFailureSummary, formatter));
}
- eventListener.add(progressIndicatorFromName(progressIndicator,
- startTime,
- formatter));
+ eventListener.add(
+ progressIndicatorFromName(progressIndicator, startTime, formatter));
if (printTiming) {
eventListener.add(new TimingPrinter(startTime));
}
@@ -279,16 +284,17 @@
void startProcessQueue() {
// [firstConf] is needed here, since the ProcessQueue needs to know the
// settings of 'noBatch' and 'local_ip'
- new ProcessQueue(firstConf,
- maxProcesses,
- maxBrowserProcesses,
- startTime,
- testSuites,
- eventListener,
- allTestsFinished,
- verbose,
- recordingPath,
- recordingOutputPath);
+ new ProcessQueue(
+ firstConf,
+ maxProcesses,
+ maxBrowserProcesses,
+ startTime,
+ testSuites,
+ eventListener,
+ allTestsFinished,
+ verbose,
+ recordingPath,
+ recordingOutputPath);
}
// Start all the HTTP servers required before starting the process queue.
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 26d5249..9cbd3c2 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -11,10 +11,22 @@
import "compiler_configuration.dart" show CompilerConfiguration;
import "runtime_configuration.dart" show RuntimeConfiguration;
-const List<String> defaultTestSelectors =
- const ['samples', 'standalone', 'corelib', 'co19', 'language',
- 'isolate', 'vm', 'html', 'benchmark_smoke',
- 'utils', 'lib', 'pkg', 'analyze_library', 'service'];
+const List<String> defaultTestSelectors = const [
+ 'samples',
+ 'standalone',
+ 'corelib',
+ 'co19',
+ 'language',
+ 'isolate',
+ 'vm',
+ 'html',
+ 'benchmark_smoke',
+ 'utils',
+ 'lib',
+ 'pkg',
+ 'analyze_library',
+ 'service'
+];
/**
* Specification of a single test option.
@@ -23,12 +35,9 @@
* the Map returned from the [TestOptionParser] parse method.
*/
class _TestOptionSpecification {
- _TestOptionSpecification(this.name,
- this.description,
- this.keys,
- this.values,
- this.defaultValue,
- {this.type : 'string'});
+ _TestOptionSpecification(
+ this.name, this.description, this.keys, this.values, this.defaultValue,
+ {this.type: 'string'});
String name;
String description;
List<String> keys;
@@ -45,16 +54,12 @@
* Creates a test options parser initialized with the known options.
*/
TestOptionsParser() {
- _options =
- [ new _TestOptionSpecification(
- 'mode',
- 'Mode in which to run the tests',
- ['-m', '--mode'],
- ['all', 'debug', 'release', 'product'],
- 'debug'),
- new _TestOptionSpecification(
- 'compiler',
- '''Specify any compilation step (if needed).
+ _options = [
+ new _TestOptionSpecification('mode', 'Mode in which to run the tests',
+ ['-m', '--mode'], ['all', 'debug', 'release', 'product'], 'debug'),
+ new _TestOptionSpecification(
+ 'compiler',
+ '''Specify any compilation step (if needed).
none: Do not compile the Dart code (run native Dart code on the VM).
(only valid with the following runtimes: vm, drt)
@@ -69,14 +74,13 @@
dart2app: Compile the Dart code into an app snapshot before running the test
(only valid with the following runtimes: dart_product)''',
- ['-c', '--compiler'],
- ['none', 'precompiler', 'dart2js', 'dart2analyzer',
- 'dart2app'],
- 'none'),
- // TODO(antonm): fix the option drt.
- new _TestOptionSpecification(
- 'runtime',
- '''Where the tests should be run.
+ ['-c', '--compiler'],
+ ['none', 'precompiler', 'dart2js', 'dart2analyzer', 'dart2app'],
+ 'none'),
+ // TODO(antonm): fix the option drt.
+ new _TestOptionSpecification(
+ 'runtime',
+ '''Where the tests should be run.
vm: Run Dart code on the standalone dart vm.
dart_precompiled: Run a precompiled snapshot on a variant of the standalone
@@ -103,372 +107,325 @@
none: No runtime, compile only (for example, used for dart2analyzer static
analysis tests).''',
- ['-r', '--runtime'],
- ['vm', 'dart_precompiled', 'dart_product',
- 'd8', 'jsshell', 'drt', 'dartium',
- 'ff', 'firefox',
- 'chrome', 'safari', 'ie9', 'ie10', 'ie11', 'opera',
- 'chromeOnAndroid', 'safarimobilesim',
- 'ContentShellOnAndroid', 'DartiumOnAndroid', 'none'],
- 'vm'),
- new _TestOptionSpecification(
- 'arch',
- 'The architecture to run tests for',
- ['-a', '--arch'],
- ['all', 'ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64', 'mips',
- 'simarm', 'simarmv6', 'simarmv5te', 'simarm64', 'simmips'],
- 'x64'),
- new _TestOptionSpecification(
- 'system',
- 'The operating system to run tests on',
- ['-s', '--system'],
- ['linux', 'macos', 'windows'],
- Platform.operatingSystem),
- new _TestOptionSpecification(
- 'checked',
- 'Run tests in checked mode',
- ['--checked'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'host_checked',
- 'Run compiler in checked mode',
- ['--host-checked'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'minified',
- 'Enable minification in the compiler',
- ['--minified'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'csp',
- 'Run tests under Content Security Policy restrictions',
- ['--csp'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'cps_ir',
- 'Run the compiler with the cps based backend',
- ['--cps-ir'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'noopt',
- 'Run an in-place precompilation',
- ['--noopt'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'timeout',
- 'Timeout in seconds',
- ['-t', '--timeout'],
- [],
- -1,
- type: 'int'),
- new _TestOptionSpecification(
- 'progress',
- 'Progress indication mode',
- ['-p', '--progress'],
- ['compact', 'color', 'line', 'verbose',
- 'silent', 'status', 'buildbot', 'diff'],
- 'compact'),
- new _TestOptionSpecification(
- 'failure-summary',
- 'Print failure summary at the end',
- ['--failure-summary'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'step_name',
- 'Step name for use by -pbuildbot',
- ['--step_name'],
- [],
- null),
- new _TestOptionSpecification(
- 'report',
- 'Print a summary report of the number of tests, by expectation',
- ['--report'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'tasks',
- 'The number of parallel tasks to run',
- ['-j', '--tasks'],
- [],
- Platform.numberOfProcessors,
- type: 'int'),
- new _TestOptionSpecification(
- 'shards',
- 'The number of instances that the tests will be sharded over',
- ['--shards'],
- [],
- 1,
- type: 'int'),
- new _TestOptionSpecification(
- 'shard',
- 'The index of this instance when running in sharded mode',
- ['--shard'],
- [],
- 1,
- type: 'int'),
- new _TestOptionSpecification(
- 'help',
- 'Print list of options',
- ['-h', '--help'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'verbose',
- 'Verbose output',
- ['-v', '--verbose'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'list',
- 'List tests only, do not run them',
- ['--list'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'report_in_json',
- 'When doing list, output result summary in json only.',
- ['--report-in-json'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'time',
- 'Print timing information after running tests',
- ['--time'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'dart',
- 'Path to dart executable',
- ['--dart'],
- [],
- ''),
- new _TestOptionSpecification(
- 'drt', // TODO(antonm): fix the option name.
- 'Path to content shell executable',
- ['--drt'],
- [],
- ''),
- new _TestOptionSpecification(
- 'dartium',
- 'Path to Dartium Chrome executable',
- ['--dartium'],
- [],
- ''),
- new _TestOptionSpecification(
- 'firefox',
- 'Path to firefox browser executable',
- ['--firefox'],
- [],
- ''),
- new _TestOptionSpecification(
- 'chrome',
- 'Path to chrome browser executable',
- ['--chrome'],
- [],
- ''),
- new _TestOptionSpecification(
- 'safari',
- 'Path to safari browser executable',
- ['--safari'],
- [],
- ''),
- new _TestOptionSpecification(
- 'use_sdk',
- '''Use compiler or runtime from the SDK.
+ ['-r', '--runtime'],
+ [
+ 'vm',
+ 'dart_precompiled',
+ 'dart_product',
+ 'd8',
+ 'jsshell',
+ 'drt',
+ 'dartium',
+ 'ff',
+ 'firefox',
+ 'chrome',
+ 'safari',
+ 'ie9',
+ 'ie10',
+ 'ie11',
+ 'opera',
+ 'chromeOnAndroid',
+ 'safarimobilesim',
+ 'ContentShellOnAndroid',
+ 'DartiumOnAndroid',
+ 'none'
+ ],
+ 'vm'),
+ new _TestOptionSpecification(
+ 'arch',
+ 'The architecture to run tests for',
+ ['-a', '--arch'],
+ [
+ 'all',
+ 'ia32',
+ 'x64',
+ 'arm',
+ 'armv6',
+ 'armv5te',
+ 'arm64',
+ 'mips',
+ 'simarm',
+ 'simarmv6',
+ 'simarmv5te',
+ 'simarm64',
+ 'simmips'
+ ],
+ 'x64'),
+ new _TestOptionSpecification(
+ 'system',
+ 'The operating system to run tests on',
+ ['-s', '--system'],
+ ['linux', 'macos', 'windows'],
+ Platform.operatingSystem),
+ new _TestOptionSpecification(
+ 'checked', 'Run tests in checked mode', ['--checked'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification('host_checked',
+ 'Run compiler in checked mode', ['--host-checked'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification('minified',
+ 'Enable minification in the compiler', ['--minified'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'csp',
+ 'Run tests under Content Security Policy restrictions',
+ ['--csp'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'cps_ir',
+ 'Run the compiler with the cps based backend',
+ ['--cps-ir'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'noopt', 'Run an in-place precompilation', ['--noopt'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'timeout', 'Timeout in seconds', ['-t', '--timeout'], [], -1,
+ type: 'int'),
+ new _TestOptionSpecification(
+ 'progress',
+ 'Progress indication mode',
+ ['-p', '--progress'],
+ [
+ 'compact',
+ 'color',
+ 'line',
+ 'verbose',
+ 'silent',
+ 'status',
+ 'buildbot',
+ 'diff'
+ ],
+ 'compact'),
+ new _TestOptionSpecification('failure-summary',
+ 'Print failure summary at the end', ['--failure-summary'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification('step_name',
+ 'Step name for use by -pbuildbot', ['--step_name'], [], null),
+ new _TestOptionSpecification(
+ 'report',
+ 'Print a summary report of the number of tests, by expectation',
+ ['--report'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'tasks',
+ 'The number of parallel tasks to run',
+ ['-j', '--tasks'],
+ [],
+ Platform.numberOfProcessors,
+ type: 'int'),
+ new _TestOptionSpecification(
+ 'shards',
+ 'The number of instances that the tests will be sharded over',
+ ['--shards'],
+ [],
+ 1,
+ type: 'int'),
+ new _TestOptionSpecification(
+ 'shard',
+ 'The index of this instance when running in sharded mode',
+ ['--shard'],
+ [],
+ 1,
+ type: 'int'),
+ new _TestOptionSpecification(
+ 'help', 'Print list of options', ['-h', '--help'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'verbose', 'Verbose output', ['-v', '--verbose'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'list', 'List tests only, do not run them', ['--list'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'report_in_json',
+ 'When doing list, output result summary in json only.',
+ ['--report-in-json'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification('time',
+ 'Print timing information after running tests', ['--time'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'dart', 'Path to dart executable', ['--dart'], [], ''),
+ new _TestOptionSpecification(
+ 'drt', // TODO(antonm): fix the option name.
+ 'Path to content shell executable',
+ ['--drt'],
+ [],
+ ''),
+ new _TestOptionSpecification('dartium',
+ 'Path to Dartium Chrome executable', ['--dartium'], [], ''),
+ new _TestOptionSpecification('firefox',
+ 'Path to firefox browser executable', ['--firefox'], [], ''),
+ new _TestOptionSpecification(
+ 'chrome', 'Path to chrome browser executable', ['--chrome'], [], ''),
+ new _TestOptionSpecification(
+ 'safari', 'Path to safari browser executable', ['--safari'], [], ''),
+ new _TestOptionSpecification(
+ 'use_sdk',
+ '''Use compiler or runtime from the SDK.
Normally, the compiler or runtimes in PRODUCT_DIR is tested, with this
option, the compiler or runtime in PRODUCT_DIR/dart-sdk/bin is tested.
Note: currently only implemented for dart2js.''',
- ['--use-sdk'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'use_public_packages',
- 'For tests using packages: Use pub.dartlang.org packages '
- 'instead the ones in the repository.',
- ['--use-public-packages'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'use_repository_packages',
- 'For tests using packages: Use pub.dartlang.org packages '
- 'but use overrides for the packages available in the '
- 'repository.',
- ['--use-repository-packages'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'build_directory',
- 'The name of the build directory, where products are placed.',
- ['--build-directory'],
- [],
- ''),
- new _TestOptionSpecification(
- 'noBatch',
- 'Do not run tests in batch mode',
- ['-n', '--nobatch'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'dart2js_batch',
- 'Run dart2js tests in batch mode',
- ['--dart2js-batch'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'append_logs',
- 'Do not delete old logs but rather append to them.',
- ['--append_logs'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'write_debug_log',
- 'Don\'t write debug messages to stdout but rather to a logfile.',
- ['--write-debug-log'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'write_test_outcome_log',
- 'Write the outcome of all tests executed to a '
- '"${TestUtils.flakyFileName()}" file.',
- ['--write-test-outcome-log'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'clear_browser_cache',
- 'Browser specific clearing of caches(i.e., delete it).',
- ['--clear_browser_cache'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'copy_coredumps',
- 'If we see a crash that we did not expect, copy the core dumps. '
- 'to /tmp',
- ['--copy-coredumps'],
- [],
- false,
- type: 'bool'),
- new _TestOptionSpecification(
- 'local_ip',
- 'IP address the http servers should listen on.'
- 'This address is also used for browsers to connect.',
- ['--local_ip'],
- [],
- '127.0.0.1'),
- new _TestOptionSpecification(
- 'test_server_port',
- 'Port for test http server.',
- ['--test_server_port'],
- [],
- 0,
- type: 'int'),
- new _TestOptionSpecification(
- 'test_server_cross_origin_port',
- 'Port for test http server cross origin.',
- ['--test_server_cross_origin_port'],
- [],
- 0,
- type: 'int'),
- new _TestOptionSpecification(
- 'test_driver_port',
- 'Port for http test driver server.',
- ['--test_driver_port'],
- [],
- 0,
- type: 'int'),
- new _TestOptionSpecification(
- 'test_driver_error_port',
- 'Port for http test driver server errors.',
- ['--test_driver_error_port'],
- [],
- 0,
- type: 'int'),
- new _TestOptionSpecification(
- 'record_to_file',
- 'Records all the commands that need to be executed and writes it '
- 'out to a file.',
- ['--record_to_file'],
- [],
- null),
- new _TestOptionSpecification(
- 'replay_from_file',
- 'Records all the commands that need to be executed and writes it '
- 'out to a file.',
- ['--replay_from_file'],
- [],
- null),
- new _TestOptionSpecification(
- 'builder_tag',
- 'Machine specific options that is not captured by the regular '
- 'test options. Used to be able to make sane updates to the '
- 'status files.',
- ['--builder-tag'],
- [],
- ''),
- new _TestOptionSpecification(
- 'vm_options',
- 'Extra options to send to the vm when running',
- ['--vm-options'],
- [],
- null),
- new _TestOptionSpecification(
- 'dart2js_options',
- 'Extra options for dart2js compilation step',
- ['--dart2js-options'],
- [],
- null),
- new _TestOptionSpecification(
- 'suite_dir',
- 'Additional directory to add to the testing matrix',
- ['--suite-dir'],
- [],
- null),
- new _TestOptionSpecification(
- 'package_root',
- 'The package root to use for testing.',
- ['--package-root'],
- [],
- null),
- new _TestOptionSpecification(
- 'exclude_suite',
- 'Exclude suites from default selector, only works when no'
- ' selector has been specified on the command line',
- ['--exclude-suite'],
- defaultTestSelectors,
- null),];
+ ['--use-sdk'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'use_public_packages',
+ 'For tests using packages: Use pub.dartlang.org packages '
+ 'instead the ones in the repository.',
+ ['--use-public-packages'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'use_repository_packages',
+ 'For tests using packages: Use pub.dartlang.org packages '
+ 'but use overrides for the packages available in the '
+ 'repository.',
+ ['--use-repository-packages'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'build_directory',
+ 'The name of the build directory, where products are placed.',
+ ['--build-directory'],
+ [],
+ ''),
+ new _TestOptionSpecification('noBatch', 'Do not run tests in batch mode',
+ ['-n', '--nobatch'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification('dart2js_batch',
+ 'Run dart2js tests in batch mode', ['--dart2js-batch'], [], false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'append_logs',
+ 'Do not delete old logs but rather append to them.',
+ ['--append_logs'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'write_debug_log',
+ 'Don\'t write debug messages to stdout but rather to a logfile.',
+ ['--write-debug-log'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'write_test_outcome_log',
+ 'Write the outcome of all tests executed to a '
+ '"${TestUtils.flakyFileName()}" file.',
+ ['--write-test-outcome-log'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'clear_browser_cache',
+ 'Browser specific clearing of caches(i.e., delete it).',
+ ['--clear_browser_cache'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'copy_coredumps',
+ 'If we see a crash that we did not expect, copy the core dumps. '
+ 'to /tmp',
+ ['--copy-coredumps'],
+ [],
+ false,
+ type: 'bool'),
+ new _TestOptionSpecification(
+ 'local_ip',
+ 'IP address the http servers should listen on.'
+ 'This address is also used for browsers to connect.',
+ ['--local_ip'],
+ [],
+ '127.0.0.1'),
+ new _TestOptionSpecification('test_server_port',
+ 'Port for test http server.', ['--test_server_port'], [], 0,
+ type: 'int'),
+ new _TestOptionSpecification(
+ 'test_server_cross_origin_port',
+ 'Port for test http server cross origin.',
+ ['--test_server_cross_origin_port'],
+ [],
+ 0,
+ type: 'int'),
+ new _TestOptionSpecification('test_driver_port',
+ 'Port for http test driver server.', ['--test_driver_port'], [], 0,
+ type: 'int'),
+ new _TestOptionSpecification(
+ 'test_driver_error_port',
+ 'Port for http test driver server errors.',
+ ['--test_driver_error_port'],
+ [],
+ 0,
+ type: 'int'),
+ new _TestOptionSpecification(
+ 'record_to_file',
+ 'Records all the commands that need to be executed and writes it '
+ 'out to a file.',
+ ['--record_to_file'],
+ [],
+ null),
+ new _TestOptionSpecification(
+ 'replay_from_file',
+ 'Records all the commands that need to be executed and writes it '
+ 'out to a file.',
+ ['--replay_from_file'],
+ [],
+ null),
+ new _TestOptionSpecification(
+ 'builder_tag',
+ 'Machine specific options that is not captured by the regular '
+ 'test options. Used to be able to make sane updates to the '
+ 'status files.',
+ ['--builder-tag'],
+ [],
+ ''),
+ new _TestOptionSpecification(
+ 'vm_options',
+ 'Extra options to send to the vm when running',
+ ['--vm-options'],
+ [],
+ null),
+ new _TestOptionSpecification(
+ 'dart2js_options',
+ 'Extra options for dart2js compilation step',
+ ['--dart2js-options'],
+ [],
+ null),
+ new _TestOptionSpecification(
+ 'suite_dir',
+ 'Additional directory to add to the testing matrix',
+ ['--suite-dir'],
+ [],
+ null),
+ new _TestOptionSpecification('package_root',
+ 'The package root to use for testing.', ['--package-root'], [], null),
+ new _TestOptionSpecification(
+ 'exclude_suite',
+ 'Exclude suites from default selector, only works when no'
+ ' selector has been specified on the command line',
+ ['--exclude-suite'],
+ defaultTestSelectors,
+ null),
+ ];
}
-
/**
* Parse a list of strings as test options.
*
@@ -541,7 +498,6 @@
continue;
}
-
// Multiple uses of a flag are an error, because there is no
// naturally correct way to handle conflicting options.
if (configuration.containsKey(spec.name)) {
@@ -586,18 +542,33 @@
List<Map> expandedConfigs = _expandConfigurations(configuration);
List<Map> result = expandedConfigs.where(_isValidConfig).toList();
for (var config in result) {
- config['_reproducing_arguments_'] =
- _constructReproducingCommandArguments(config);
+ config['_reproducing_arguments_'] =
+ _constructReproducingCommandArguments(config);
}
return result.isEmpty ? null : result;
}
// For printing out reproducing command lines, we don't want to add these
// options.
- Set<String> _blacklistedOptions = new Set<String>.from([
- 'progress', 'failure-summary', 'step_name', 'report', 'tasks', 'verbose',
- 'time', 'dart', 'drt', 'dartium', 'firefox', 'chrome', 'safari',
- 'build_directory', 'append_logs', 'local_ip', 'shard', 'shards',
+ Set<String> _blacklistedOptions = new Set<String>.from([
+ 'progress',
+ 'failure-summary',
+ 'step_name',
+ 'report',
+ 'tasks',
+ 'verbose',
+ 'time',
+ 'dart',
+ 'drt',
+ 'dartium',
+ 'firefox',
+ 'chrome',
+ 'safari',
+ 'build_directory',
+ 'append_logs',
+ 'local_ip',
+ 'shard',
+ 'shards',
]);
List<String> _constructReproducingCommandArguments(Map config) {
@@ -648,9 +619,22 @@
// runs test.py -c dart2js -r drt,none the dart2js_none and
// dart2js_drt will be duplicating work. If later we don't need 'none'
// with dart2js, we should remove it from here.
- validRuntimes = const ['d8', 'jsshell', 'drt', 'none', 'dartium',
- 'ff', 'chrome', 'safari', 'ie9', 'ie10', 'ie11',
- 'opera', 'chromeOnAndroid', 'safarimobilesim'];
+ validRuntimes = const [
+ 'd8',
+ 'jsshell',
+ 'drt',
+ 'none',
+ 'dartium',
+ 'ff',
+ 'chrome',
+ 'safari',
+ 'ie9',
+ 'ie10',
+ 'ie11',
+ 'opera',
+ 'chromeOnAndroid',
+ 'safarimobilesim'
+ ];
break;
case 'dart2analyzer':
validRuntimes = const ['none'];
@@ -662,8 +646,13 @@
validRuntimes = const ['dart_precompiled'];
break;
case 'none':
- validRuntimes = const ['vm', 'drt', 'dartium',
- 'ContentShellOnAndroid', 'DartiumOnAndroid'];
+ validRuntimes = const [
+ 'vm',
+ 'drt',
+ 'dartium',
+ 'ContentShellOnAndroid',
+ 'DartiumOnAndroid'
+ ];
break;
}
if (!validRuntimes.contains(config['runtime'])) {
@@ -680,13 +669,13 @@
if (config['shard'] < 1 || config['shard'] > config['shards']) {
isValid = false;
print("Error: shard index is ${config['shard']} out of "
- "${config['shards']} shards");
+ "${config['shards']} shards");
}
if (config['use_repository_packages'] && config['use_public_packages']) {
isValid = false;
print("Cannot have both --use-repository-packages and "
- "--use-public-packages");
+ "--use-public-packages");
}
return isValid;
@@ -743,7 +732,7 @@
// in that test suite. If no selectors are explicitly given use
// the default suite patterns.
var selectors = configuration['selectors'];
- if (selectors is !Map) {
+ if (selectors is! Map) {
if (selectors == null) {
if (configuration['suite_dir'] != null) {
var suite_path = new Path(configuration['suite_dir']);
@@ -752,8 +741,9 @@
selectors = new List.from(defaultTestSelectors);
}
- var exclude_suites = configuration['exclude_suite'] != null ?
- configuration['exclude_suite'].split(',') : [];
+ var exclude_suites = configuration['exclude_suite'] != null
+ ? configuration['exclude_suite'].split(',')
+ : [];
for (var exclude in exclude_suites) {
if (selectors.contains(exclude)) {
selectors.remove(exclude);
@@ -777,7 +767,7 @@
}
if (selectorMap.containsKey(suite)) {
print("Error: '$suite/$pattern'. Only one test selection"
- " pattern is allowed to start with '$suite/'");
+ " pattern is allowed to start with '$suite/'");
exit(1);
}
selectorMap[suite] = new RegExp(pattern);
@@ -816,8 +806,8 @@
if (configuration['timeout'] == -1) {
int compilerMulitiplier =
new CompilerConfiguration(configuration).computeTimeoutMultiplier();
- int runtimeMultiplier =
- new RuntimeConfiguration(configuration).computeTimeoutMultiplier(
+ int runtimeMultiplier = new RuntimeConfiguration(configuration)
+ .computeTimeoutMultiplier(
mode: configuration['mode'],
isChecked: configuration['checked'],
arch: configuration['arch']);
@@ -847,7 +837,6 @@
return result;
}
-
/**
* Print out usage information.
*/
@@ -864,7 +853,8 @@
print('${option.name}: ${option.description}.');
for (var name in option.keys) {
assert(name.startsWith('-'));
- var buffer = new StringBuffer();;
+ var buffer = new StringBuffer();
+ ;
buffer.write(name);
if (option.type == 'bool') {
assert(option.values.isEmpty);
@@ -891,7 +881,6 @@
}
}
-
/**
* Find the test option specification for a given option key.
*/
@@ -905,6 +894,5 @@
exit(1);
}
-
List<_TestOptionSpecification> _options;
}
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 0fbb767..3fdfbf3 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -61,19 +61,19 @@
}
}
-
List<String> _buildFailureOutput(TestCase test,
- [Formatter formatter = const Formatter()]) {
-
+ [Formatter formatter = const Formatter()]) {
List<String> getLinesWithoutCarriageReturn(List<int> output) {
- return decodeUtf8(output).replaceAll('\r\n', '\n')
- .replaceAll('\r', '\n').split('\n');
+ return decodeUtf8(output)
+ .replaceAll('\r\n', '\n')
+ .replaceAll('\r', '\n')
+ .split('\n');
}
List<String> output = new List<String>();
output.add('');
output.add(formatter.failed('FAILED: ${test.configurationString}'
- ' ${test.displayName}'));
+ ' ${test.displayName}'));
StringBuffer expected = new StringBuffer();
expected.write('Expected: ');
for (var expectation in test.expectedOutcomes) {
@@ -82,8 +82,8 @@
output.add(expected.toString());
output.add('Actual: ${test.result}');
if (!test.lastCommandOutput.hasTimedOut) {
- if (test.commandOutputs.length != test.commands.length
- && !test.expectCompileError) {
+ if (test.commandOutputs.length != test.commands.length &&
+ !test.expectCompileError) {
output.add('Unexpected compile-time error.');
} else {
if (test.expectCompileError) {
@@ -123,8 +123,7 @@
}
if (test is BrowserTestCase) {
// Additional command for rerunning the steps locally after the fact.
- var command =
- test.configuration["_servers_"].httpServerCommandline();
+ var command = test.configuration["_servers_"].httpServerCommandline();
output.add('');
output.add('To retest, run: $command');
}
@@ -152,20 +151,19 @@
}
String _buildSummaryEnd(int failedTests) {
- if (failedTests == 0) {
- return '\n===\n=== All tests succeeded\n===\n';
- } else {
- var pluralSuffix = failedTests != 1 ? 's' : '';
- return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n';
- }
+ if (failedTests == 0) {
+ return '\n===\n=== All tests succeeded\n===\n';
+ } else {
+ var pluralSuffix = failedTests != 1 ? 's' : '';
+ return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n';
+ }
}
-
class EventListener {
- void testAdded() { }
- void done(TestCase test) { }
- void allTestsKnown() { }
- void allDone() { }
+ void testAdded() {}
+ void done(TestCase test) {}
+ void allTestsKnown() {}
+ void allDone() {}
}
class ExitCodeSetter extends EventListener {
@@ -226,10 +224,22 @@
* },
*/
- static final INTERESTED_CONFIGURATION_PARAMETERS =
- ['mode', 'arch', 'compiler', 'runtime', 'checked', 'host_checked',
- 'minified', 'csp', 'system', 'vm_options', 'use_sdk',
- 'use_repository_packages', 'use_public_packages', 'builder_tag'];
+ static final INTERESTED_CONFIGURATION_PARAMETERS = [
+ 'mode',
+ 'arch',
+ 'compiler',
+ 'runtime',
+ 'checked',
+ 'host_checked',
+ 'minified',
+ 'csp',
+ 'system',
+ 'vm_options',
+ 'use_sdk',
+ 'use_repository_packages',
+ 'use_public_packages',
+ 'builder_tag'
+ ];
IOSink _sink;
@@ -248,22 +258,20 @@
for (var command in test.commands) {
var output = test.commandOutputs[command];
if (output != null) {
- double duration = output.time.inMicroseconds/1000.0;
+ double duration = output.time.inMicroseconds / 1000.0;
totalDuration += duration;
- commandResults.add({
- 'name': command.displayName,
- 'duration': duration,
- });
+ commandResults
+ .add({'name': command.displayName, 'duration': duration,});
}
}
_writeTestOutcomeRecord({
- 'name' : name,
- 'configuration' : configuration,
- 'test_result' : {
- 'outcome' : outcome,
- 'expected_outcomes' : expectations,
- 'duration' : totalDuration,
- 'command_results' : commandResults,
+ 'name': name,
+ 'configuration': configuration,
+ 'test_result': {
+ 'outcome': outcome,
+ 'expected_outcomes': expectations,
+ 'duration': totalDuration,
+ 'command_results': commandResults,
},
});
}
@@ -281,7 +289,6 @@
}
}
-
class UnexpectedCrashDumpArchiver extends EventListener {
void done(TestCase test) {
if (test.unexpectedOutput && test.result == Expectation.CRASH) {
@@ -294,19 +301,20 @@
var binBaseName = new Path(binName).filename;
if (binFile.existsSync()) {
var tmpPath = new Path(Directory.systemTemp.path);
- var dir = new Path(TestUtils.mkdirRecursive(tmpPath,
- new Path('coredump_${test.lastCommandOutput.pid}')).path);
+ var dir = new Path(TestUtils
+ .mkdirRecursive(
+ tmpPath, new Path('coredump_${test.lastCommandOutput.pid}'))
+ .path);
TestUtils.copyFile(new Path(name), dir.append(name));
TestUtils.copyFile(new Path(binName), dir.append(binBaseName));
print("\nCopied core dump and binary for unexpected crash to: "
- "$dir");
+ "$dir");
}
}
}
}
}
-
class SummaryPrinter extends EventListener {
final bool jsonOnly;
@@ -323,7 +331,6 @@
}
}
-
class TimingPrinter extends EventListener {
final _command2testCases = new Map<Command, List<TestCase>>();
final _commandOutputs = new Set<CommandOutput>();
@@ -357,8 +364,8 @@
}).join(', ');
print('${commandOutput.time} - '
- '${command.displayName} - '
- '$testCasesDescription');
+ '${command.displayName} - '
+ '$testCasesDescription');
}
}
}
@@ -377,7 +384,6 @@
_printFailureSummary();
}
-
void _printFailureOutput(TestCase test) {
String status = '${test.displayName}: ${test.result}';
List<String> configs =
@@ -405,12 +411,11 @@
runtimeToConfiguration.putIfAbsent(runtime, () => <String>[]);
runtimeConfigs.add(config);
}
- runtimeToConfiguration.forEach((String runtime,
- List<String> runtimeConfigs) {
+ runtimeToConfiguration
+ .forEach((String runtime, List<String> runtimeConfigs) {
runtimeConfigs.sort((a, b) => a.compareTo(b));
- List<String> statuses =
- groupedStatuses.putIfAbsent('$runtime: $runtimeConfigs',
- () => <String>[]);
+ List<String> statuses = groupedStatuses.putIfAbsent(
+ '$runtime: $runtimeConfigs', () => <String>[]);
statuses.add(status);
});
});
@@ -432,15 +437,14 @@
void done(TestCase test) {
for (var commandOutput in test.commandOutputs.values) {
- if (commandOutput.compilationSkipped)
- _skippedCompilations++;
+ if (commandOutput.compilationSkipped) _skippedCompilations++;
}
}
void allDone() {
if (_skippedCompilations > 0) {
print('\n$_skippedCompilations compilations were skipped because '
- 'the previous output was already up to date\n');
+ 'the previous output was already up to date\n');
}
}
}
@@ -460,24 +464,23 @@
static Stream<Directory> getLeftOverTemporaryDirectories() {
var regExp = _getTemporaryDirectoryRegexp();
- return Directory.systemTemp.list().where(
- (FileSystemEntity fse) {
- if (fse is Directory) {
- if (regExp.hasMatch(new Path(fse.path).filename)) {
- return true;
- }
- }
- return false;
- });
+ return Directory.systemTemp.list().where((FileSystemEntity fse) {
+ if (fse is Directory) {
+ if (regExp.hasMatch(new Path(fse.path).filename)) {
+ return true;
+ }
+ }
+ return false;
+ });
}
void allDone() {
getLeftOverTemporaryDirectories().length.then((int count) {
if (count > MIN_NUMBER_OF_TEMP_DIRS) {
DebugLogger.warning("There are ${count} directories "
- "in the system tempdir "
- "('${Directory.systemTemp.path}')! "
- "Maybe left over directories?\n");
+ "in the system tempdir "
+ "('${Directory.systemTemp.path}')! "
+ "Maybe left over directories?\n");
}
}).catchError((error) {
DebugLogger.warning("Could not list temp directories, got: $error");
@@ -495,15 +498,13 @@
}
}
-
class TestFailurePrinter extends EventListener {
bool _printSummary;
var _formatter;
var _failureSummary = <String>[];
- var _failedTests= 0;
+ var _failedTests = 0;
- TestFailurePrinter(this._printSummary,
- [this._formatter = const Formatter()]);
+ TestFailurePrinter(this._printSummary, [this._formatter = const Formatter()]);
void done(TestCase test) {
if (test.unexpectedOutput) {
@@ -538,8 +539,9 @@
class ProgressIndicator extends EventListener {
ProgressIndicator(this._startTime);
-
- void testAdded() { _foundTests++; }
+ void testAdded() {
+ _foundTests++;
+ }
void done(TestCase test) {
if (test.unexpectedOutput) {
@@ -566,8 +568,7 @@
}
abstract class CompactIndicator extends ProgressIndicator {
- CompactIndicator(DateTime startTime)
- : super(startTime);
+ CompactIndicator(DateTime startTime) : super(startTime);
void allDone() {
if (_failedTests > 0) {
@@ -582,7 +583,6 @@
void _printProgress();
}
-
class CompactProgressIndicator extends CompactIndicator {
Formatter _formatter;
@@ -595,18 +595,15 @@
var passedPadded = _pad(_passedTests.toString(), 5);
var failedPadded = _pad(_failedTests.toString(), 5);
Duration d = (new DateTime.now()).difference(_startTime);
- var progressLine =
- '\r[${_timeString(d)} | $progressPadded% | '
+ var progressLine = '\r[${_timeString(d)} | $progressPadded% | '
'+${_formatter.passed(passedPadded)} | '
'-${_formatter.failed(failedPadded)}]';
stdout.write(progressLine);
}
}
-
class VerboseProgressIndicator extends ProgressIndicator {
- VerboseProgressIndicator(DateTime startTime)
- : super(startTime);
+ VerboseProgressIndicator(DateTime startTime) : super(startTime);
void _printDoneProgress(TestCase test) {
var status = 'pass';
@@ -617,7 +614,6 @@
}
}
-
class BuildbotProgressIndicator extends ProgressIndicator {
static String stepName;
var _failureSummary = <String>[];
@@ -657,10 +653,8 @@
}
}
-
-EventListener progressIndicatorFromName(String name,
- DateTime startTime,
- Formatter formatter) {
+EventListener progressIndicatorFromName(
+ String name, DateTime startTime, Formatter formatter) {
switch (name) {
case 'compact':
return new CompactProgressIndicator(startTime, formatter);
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 0fe9f18..0d64136 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -39,10 +39,14 @@
// Some IO tests use these variables and get confused if the host environment
// variables are inherited so they are excluded.
-const List<String> EXCLUDED_ENVIRONMENT_VARIABLES =
- const ['http_proxy', 'https_proxy', 'no_proxy',
- 'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY'];
-
+const List<String> EXCLUDED_ENVIRONMENT_VARIABLES = const [
+ 'http_proxy',
+ 'https_proxy',
+ 'no_proxy',
+ 'HTTP_PROXY',
+ 'HTTPS_PROXY',
+ 'NO_PROXY'
+];
/** A command executed as a step in a test case. */
class Command {
@@ -70,7 +74,8 @@
return _cachedHashCode;
}
- operator ==(other) => identical(this, other) ||
+ operator ==(other) =>
+ identical(this, other) ||
(runtimeType == other.runtimeType && _equal(other));
void _buildHashCode(HashCodeBuilder builder) {
@@ -78,8 +83,7 @@
}
bool _equal(Command other) =>
- hashCode == other.hashCode &&
- displayName == other.displayName;
+ hashCode == other.hashCode && displayName == other.displayName;
String toString() => reproductionCommand;
@@ -99,10 +103,8 @@
/** Working directory for the command */
final String workingDirectory;
- ProcessCommand._(String displayName, this.executable,
- this.arguments,
- [this.environmentOverrides = null,
- this.workingDirectory = null])
+ ProcessCommand._(String displayName, this.executable, this.arguments,
+ [this.environmentOverrides = null, this.workingDirectory = null])
: super._(displayName) {
if (io.Platform.operatingSystem == 'windows') {
// Windows can't handle the first command if it is a .bat file or the like
@@ -130,11 +132,12 @@
String get reproductionCommand {
var env = new StringBuffer();
environmentOverrides.forEach((key, value) =>
- (io.Platform.operatingSystem == 'windows') ?
- env.write('set $key=${escapeCommandLineArgument(value)} & ') :
- env.write('$key=${escapeCommandLineArgument(value)} '));
+ (io.Platform.operatingSystem == 'windows')
+ ? env.write('set $key=${escapeCommandLineArgument(value)} & ')
+ : env.write('$key=${escapeCommandLineArgument(value)} '));
var command = ([executable]..addAll(arguments))
- .map(escapeCommandLineArgument).join(' ');
+ .map(escapeCommandLineArgument)
+ .join(' ');
if (workingDirectory != null) {
command = "$command (working directory: $workingDirectory)";
}
@@ -149,13 +152,14 @@
final bool _neverSkipCompilation;
final List<Uri> _bootstrapDependencies;
- CompilationCommand._(String displayName,
- this._outputFile,
- this._neverSkipCompilation,
- this._bootstrapDependencies,
- String executable,
- List<String> arguments,
- Map<String, String> environmentOverrides)
+ CompilationCommand._(
+ String displayName,
+ this._outputFile,
+ this._neverSkipCompilation,
+ this._bootstrapDependencies,
+ String executable,
+ List<String> arguments,
+ Map<String, String> environmentOverrides)
: super._(displayName, executable, arguments, environmentOverrides);
Future<bool> get outputIsUpToDate {
@@ -181,8 +185,8 @@
return readDepsFile("$_outputFile.deps").then((dependencies) {
if (dependencies != null) {
dependencies.addAll(_bootstrapDependencies);
- var jsOutputLastModified = TestUtils.lastModifiedCache.getLastModified(
- new Uri(scheme: 'file', path: _outputFile));
+ var jsOutputLastModified = TestUtils.lastModifiedCache
+ .getLastModified(new Uri(scheme: 'file', path: _outputFile));
if (jsOutputLastModified != null) {
for (var dependency in dependencies) {
var dependencyLastModified =
@@ -220,37 +224,36 @@
AddFlagsKey(this.flags, this.env);
// Just use object identity for environment map
bool operator ==(other) =>
- other is AddFlagsKey && flags == other.flags && env == other.env;
+ other is AddFlagsKey && flags == other.flags && env == other.env;
int get hashCode => flags.hashCode ^ env.hashCode;
}
class ContentShellCommand extends ProcessCommand {
- ContentShellCommand._(String executable,
- String htmlFile,
- List<String> options,
- List<String> dartFlags,
- Map<String, String> environmentOverrides)
- : super._("content_shell",
- executable,
- _getArguments(options, htmlFile),
- _getEnvironment(environmentOverrides, dartFlags));
+ ContentShellCommand._(
+ String executable,
+ String htmlFile,
+ List<String> options,
+ List<String> dartFlags,
+ Map<String, String> environmentOverrides)
+ : super._("content_shell", executable, _getArguments(options, htmlFile),
+ _getEnvironment(environmentOverrides, dartFlags));
// Cache the modified environments in a map from the old environment and
// the string of Dart flags to the new environment. Avoid creating new
// environment object for each command object.
- static Map<AddFlagsKey, Map> environments =
- new Map<AddFlagsKey, Map>();
+ static Map<AddFlagsKey, Map> environments = new Map<AddFlagsKey, Map>();
static Map _getEnvironment(Map env, List<String> dartFlags) {
var needDartFlags = dartFlags != null && dartFlags.length > 0;
if (needDartFlags) {
if (env == null) {
- env = const { };
+ env = const {};
}
var flags = dartFlags.join(' ');
- return environments.putIfAbsent(new AddFlagsKey(flags, env),
+ return environments.putIfAbsent(
+ new AddFlagsKey(flags, env),
() => new Map.from(env)
- ..addAll({'DART_FLAGS': flags, 'DART_FORWARDING_PRINT': '1'}));
+ ..addAll({'DART_FLAGS': flags, 'DART_FORWARDING_PRINT': '1'}));
}
return env;
}
@@ -270,11 +273,10 @@
final Map configuration;
final bool retry;
- BrowserTestCommand._(String _browser,
- this.url,
- this.configuration,
- this.retry)
- : super._(_browser), browser = _browser;
+ BrowserTestCommand._(
+ String _browser, this.url, this.configuration, this.retry)
+ : super._(_browser),
+ browser = _browser;
void _buildHashCode(HashCodeBuilder builder) {
super._buildHashCode(builder);
@@ -292,10 +294,12 @@
retry == other.retry;
String get reproductionCommand {
- var parts = [io.Platform.resolvedExecutable,
- 'tools/testing/dart/launch_browser.dart',
- browser,
- url];
+ var parts = [
+ io.Platform.resolvedExecutable,
+ 'tools/testing/dart/launch_browser.dart',
+ browser,
+ url
+ ];
return parts.map(escapeCommandLineArgument).join(' ');
}
@@ -304,11 +308,8 @@
class BrowserHtmlTestCommand extends BrowserTestCommand {
List<String> expectedMessages;
- BrowserHtmlTestCommand._(String browser,
- String url,
- Map configuration,
- this.expectedMessages,
- bool retry)
+ BrowserHtmlTestCommand._(String browser, String url, Map configuration,
+ this.expectedMessages, bool retry)
: super._(browser, url, configuration, retry);
void _buildHashCode(HashCodeBuilder builder) {
@@ -324,11 +325,8 @@
class AnalysisCommand extends ProcessCommand {
final String flavor;
- AnalysisCommand._(this.flavor,
- String displayName,
- String executable,
- List<String> arguments,
- Map<String, String> environmentOverrides)
+ AnalysisCommand._(this.flavor, String displayName, String executable,
+ List<String> arguments, Map<String, String> environmentOverrides)
: super._(displayName, executable, arguments, environmentOverrides);
void _buildHashCode(HashCodeBuilder builder) {
@@ -337,40 +335,34 @@
}
bool _equal(AnalysisCommand other) =>
- super._equal(other) &&
- flavor == other.flavor;
+ super._equal(other) && flavor == other.flavor;
}
class VmCommand extends ProcessCommand {
- VmCommand._(String executable,
- List<String> arguments,
- Map<String,String> environmentOverrides)
+ VmCommand._(String executable, List<String> arguments,
+ Map<String, String> environmentOverrides)
: super._("vm", executable, arguments, environmentOverrides);
}
class JSCommandlineCommand extends ProcessCommand {
- JSCommandlineCommand._(String displayName,
- String executable,
- List<String> arguments,
- [Map<String, String> environmentOverrides = null])
- : super._(displayName,
- executable,
- arguments,
- environmentOverrides);
+ JSCommandlineCommand._(
+ String displayName, String executable, List<String> arguments,
+ [Map<String, String> environmentOverrides = null])
+ : super._(displayName, executable, arguments, environmentOverrides);
}
class PubCommand extends ProcessCommand {
final String command;
- PubCommand._(String pubCommand,
- String pubExecutable,
- String pubspecYamlDirectory,
- String pubCacheDirectory)
- : super._('pub_$pubCommand',
- new io.File(pubExecutable).absolute.path,
- [pubCommand],
- {'PUB_CACHE' : pubCacheDirectory},
- pubspecYamlDirectory), command = pubCommand;
+ PubCommand._(String pubCommand, String pubExecutable,
+ String pubspecYamlDirectory, String pubCacheDirectory)
+ : super._(
+ 'pub_$pubCommand',
+ new io.File(pubExecutable).absolute.path,
+ [pubCommand],
+ {'PUB_CACHE': pubCacheDirectory},
+ pubspecYamlDirectory),
+ command = pubCommand;
void _buildHashCode(HashCodeBuilder builder) {
super._buildHashCode(builder);
@@ -378,8 +370,7 @@
}
bool _equal(PubCommand other) =>
- super._equal(other) &&
- command == other.command;
+ super._equal(other) && command == other.command;
}
/* [ScriptCommand]s are executed by dart code. */
@@ -394,7 +385,7 @@
final String _destinationDirectory;
CleanDirectoryCopyCommand._(this._sourceDirectory, this._destinationDirectory)
- : super._('dir_copy');
+ : super._('dir_copy');
String get reproductionCommand =>
"Copying '$_sourceDirectory' to '$_destinationDirectory'.";
@@ -440,10 +431,9 @@
String _destinationFile;
Map<String, Map> _dependencyOverrides;
- ModifyPubspecYamlCommand._(this._pubspecYamlFile,
- this._destinationFile,
- this._dependencyOverrides)
- : super._("modify_pubspec") {
+ ModifyPubspecYamlCommand._(
+ this._pubspecYamlFile, this._destinationFile, this._dependencyOverrides)
+ : super._("modify_pubspec") {
assert(_pubspecYamlFile.endsWith("pubspec.yaml"));
assert(_destinationFile.endsWith("pubspec.yaml"));
}
@@ -455,9 +445,9 @@
Future<ScriptCommandOutputImpl> run() {
var watch = new Stopwatch()..start();
- var pubspecLockFile =
- _destinationFile.substring(0, _destinationFile.length - ".yaml".length)
- + ".lock";
+ var pubspecLockFile = _destinationFile.substring(
+ 0, _destinationFile.length - ".yaml".length) +
+ ".lock";
var file = new io.File(_pubspecYamlFile);
var destinationFile = new io.File(_destinationFile);
@@ -465,15 +455,14 @@
return file.readAsString().then((String yamlString) {
var dependencyOverrideSection = new StringBuffer();
if (_dependencyOverrides.isNotEmpty) {
- dependencyOverrideSection.write(
- "\n"
+ dependencyOverrideSection.write("\n"
"# This section was autogenerated by test.py!\n"
"dependency_overrides:\n");
_dependencyOverrides.forEach((String packageName, Map override) {
dependencyOverrideSection.write(" $packageName:\n");
override.forEach((overrideKey, overrideValue) {
- dependencyOverrideSection.write(
- " $overrideKey: $overrideValue\n");
+ dependencyOverrideSection
+ .write(" $overrideKey: $overrideValue\n");
});
});
}
@@ -529,9 +518,9 @@
}
var link = new io.Link(_link);
- return link.exists()
- .then((bool exists) { if (exists) return link.delete(); })
- .then((_) => link.create(_target));
+ return link.exists().then((bool exists) {
+ if (exists) return link.delete();
+ }).then((_) => link.create(_target));
}).then((_) {
return new ScriptCommandOutputImpl(
this, Expectation.PASS, "", watch.elapsed);
@@ -548,9 +537,7 @@
}
bool _equal(MakeSymlinkCommand other) =>
- super._equal(other) &&
- _link == other._link &&
- _target == other._target;
+ super._equal(other) && _link == other._link && _target == other._target;
}
class CommandBuilder {
@@ -566,45 +553,46 @@
_cleared = true;
}
- ContentShellCommand getContentShellCommand(String executable,
- String htmlFile,
- List<String> options,
- List<String> dartFlags,
- Map<String, String> environment) {
+ ContentShellCommand getContentShellCommand(
+ String executable,
+ String htmlFile,
+ List<String> options,
+ List<String> dartFlags,
+ Map<String, String> environment) {
ContentShellCommand command = new ContentShellCommand._(
executable, htmlFile, options, dartFlags, environment);
return _getUniqueCommand(command);
}
- BrowserTestCommand getBrowserTestCommand(String browser,
- String url,
- Map configuration,
- bool retry) {
+ BrowserTestCommand getBrowserTestCommand(
+ String browser, String url, Map configuration, bool retry) {
var command = new BrowserTestCommand._(browser, url, configuration, retry);
return _getUniqueCommand(command);
}
- BrowserHtmlTestCommand getBrowserHtmlTestCommand(String browser,
- String url,
- Map configuration,
- List<String> expectedMessages,
- bool retry) {
+ BrowserHtmlTestCommand getBrowserHtmlTestCommand(String browser, String url,
+ Map configuration, List<String> expectedMessages, bool retry) {
var command = new BrowserHtmlTestCommand._(
browser, url, configuration, expectedMessages, retry);
return _getUniqueCommand(command);
}
- CompilationCommand getCompilationCommand(String displayName,
- outputFile,
- neverSkipCompilation,
- List<Uri> bootstrapDependencies,
- String executable,
- List<String> arguments,
- Map<String, String> environment) {
- var command =
- new CompilationCommand._(
- displayName, outputFile, neverSkipCompilation,
- bootstrapDependencies, executable, arguments, environment);
+ CompilationCommand getCompilationCommand(
+ String displayName,
+ outputFile,
+ neverSkipCompilation,
+ List<Uri> bootstrapDependencies,
+ String executable,
+ List<String> arguments,
+ Map<String, String> environment) {
+ var command = new CompilationCommand._(
+ displayName,
+ outputFile,
+ neverSkipCompilation,
+ bootstrapDependencies,
+ executable,
+ arguments,
+ environment);
return _getUniqueCommand(command);
}
@@ -616,41 +604,36 @@
return _getUniqueCommand(command);
}
- VmCommand getVmCommand(String executable,
- List<String> arguments,
- Map<String, String> environmentOverrides) {
+ VmCommand getVmCommand(String executable, List<String> arguments,
+ Map<String, String> environmentOverrides) {
var command = new VmCommand._(executable, arguments, environmentOverrides);
return _getUniqueCommand(command);
}
Command getJSCommandlineCommand(String displayName, executable, arguments,
- [environment = null]) {
- var command = new JSCommandlineCommand._(displayName, executable, arguments,
- environment);
+ [environment = null]) {
+ var command = new JSCommandlineCommand._(
+ displayName, executable, arguments, environment);
return _getUniqueCommand(command);
}
Command getProcessCommand(String displayName, executable, arguments,
- [environment = null, workingDirectory = null]) {
- var command = new ProcessCommand._(displayName, executable, arguments,
- environment, workingDirectory);
+ [environment = null, workingDirectory = null]) {
+ var command = new ProcessCommand._(
+ displayName, executable, arguments, environment, workingDirectory);
return _getUniqueCommand(command);
}
Command getCopyCommand(String sourceDirectory, String destinationDirectory) {
- var command = new CleanDirectoryCopyCommand._(sourceDirectory,
- destinationDirectory);
+ var command =
+ new CleanDirectoryCopyCommand._(sourceDirectory, destinationDirectory);
return _getUniqueCommand(command);
}
- Command getPubCommand(String pubCommand,
- String pubExecutable,
- String pubspecYamlDirectory,
- String pubCacheDirectory) {
- var command = new PubCommand._(pubCommand,
- pubExecutable,
- pubspecYamlDirectory,
- pubCacheDirectory);
+ Command getPubCommand(String pubCommand, String pubExecutable,
+ String pubspecYamlDirectory, String pubCacheDirectory) {
+ var command = new PubCommand._(
+ pubCommand, pubExecutable, pubspecYamlDirectory, pubCacheDirectory);
return _getUniqueCommand(command);
}
@@ -659,7 +642,7 @@
}
Command getModifyPubspecCommand(String pubspecYamlFile, Map depsOverrides,
- {String destinationFile: null}) {
+ {String destinationFile: null}) {
if (destinationFile == null) destinationFile = pubspecYamlFile;
return _getUniqueCommand(new ModifyPubspecYamlCommand._(
pubspecYamlFile, destinationFile, depsOverrides));
@@ -716,7 +699,8 @@
* compiling multiple sources that are run in isolation.
*/
List<Command> commands;
- Map<Command, CommandOutput> commandOutputs = new Map<Command,CommandOutput>();
+ Map<Command, CommandOutput> commandOutputs =
+ new Map<Command, CommandOutput>();
Map configuration;
String displayName;
@@ -724,19 +708,16 @@
int hash = 0;
Set<Expectation> expectedOutcomes;
- TestCase(this.displayName,
- this.commands,
- this.configuration,
- this.expectedOutcomes,
- {isNegative: false,
- TestInformation info: null}) {
+ TestCase(this.displayName, this.commands, this.configuration,
+ this.expectedOutcomes,
+ {isNegative: false, TestInformation info: null}) {
if (isNegative || displayName.contains("negative_test")) {
_expectations |= IS_NEGATIVE;
}
if (info != null) {
_setExpectations(info);
- hash = info.originTestPath.relativeTo(TestUtils.dartDir)
- .toString().hashCode;
+ hash =
+ info.originTestPath.relativeTo(TestUtils.dartDir).toString().hashCode;
}
}
@@ -777,8 +758,8 @@
CommandOutput get lastCommandOutput {
if (commandOutputs.length == 0) {
throw new Exception("CommandOutputs is empty, maybe no command was run? ("
- "displayName: '$displayName', "
- "configurationString: '$configurationString')");
+ "displayName: '$displayName', "
+ "configurationString: '$configurationString')");
}
return commandOutputs[commands[commandOutputs.length - 1]];
}
@@ -786,8 +767,8 @@
Command get lastCommandExecuted {
if (commandOutputs.length == 0) {
throw new Exception("CommandOutputs is empty, maybe no command was run? ("
- "displayName: '$displayName', "
- "configurationString: '$configurationString')");
+ "displayName: '$displayName', "
+ "configurationString: '$configurationString')");
}
return commands[commandOutputs.length - 1];
}
@@ -815,34 +796,34 @@
}
bool get isFlaky {
- if (expectedOutcomes.contains(Expectation.SKIP) ||
- expectedOutcomes.contains(Expectation.SKIP_BY_DESIGN)) {
- return false;
- }
+ if (expectedOutcomes.contains(Expectation.SKIP) ||
+ expectedOutcomes.contains(Expectation.SKIP_BY_DESIGN)) {
+ return false;
+ }
- return expectedOutcomes
- .where((expectation) => !expectation.isMetaExpectation).length > 1;
+ return expectedOutcomes
+ .where((expectation) => !expectation.isMetaExpectation)
+ .length >
+ 1;
}
bool get isFinished {
return commandOutputs.length > 0 &&
(!lastCommandOutput.successful ||
- commands.length == commandOutputs.length);
+ commands.length == commandOutputs.length);
}
}
-
/**
* BrowserTestCase has an extra compilation command that is run in a separate
* process, before the regular test is run as in the base class [TestCase].
* If the compilation command fails, then the rest of the test is not run.
*/
class BrowserTestCase extends TestCase {
-
- BrowserTestCase(displayName, commands, configuration,
- expectedOutcomes, info, isNegative, this._testingUrl)
- : super(displayName, commands, configuration,
- expectedOutcomes, isNegative: isNegative, info: info);
+ BrowserTestCase(displayName, commands, configuration, expectedOutcomes, info,
+ isNegative, this._testingUrl)
+ : super(displayName, commands, configuration, expectedOutcomes,
+ isNegative: isNegative, info: info);
String _testingUrl;
@@ -858,14 +839,13 @@
return testOutput.contains("unittest-suite-success");
}
- Expectation _negateOutcomeIfIncompleteAsyncTest(Expectation outcome,
- String testOutput) {
+ Expectation _negateOutcomeIfIncompleteAsyncTest(
+ Expectation outcome, String testOutput) {
// If this is an asynchronous test and the asynchronous operation didn't
// complete successfully, it's outcome is Expectation.FAIL.
// TODO: maybe we should introduce a AsyncIncomplete marker or so
if (outcome == Expectation.PASS) {
- if (_isAsyncTest(testOutput) &&
- !_isAsyncTestSuccessful(testOutput)) {
+ if (_isAsyncTest(testOutput) && !_isAsyncTestSuccessful(testOutput)) {
return Expectation.FAIL;
}
}
@@ -930,14 +910,15 @@
bool alreadyPrintedWarning = false;
// TODO(kustermann): Remove testCase from this class.
- CommandOutputImpl(Command this.command,
- int this.exitCode,
- bool this.timedOut,
- List<int> this.stdout,
- List<int> this.stderr,
- Duration this.time,
- bool this.compilationSkipped,
- int this.pid) {
+ CommandOutputImpl(
+ Command this.command,
+ int this.exitCode,
+ bool this.timedOut,
+ List<int> this.stdout,
+ List<int> this.stderr,
+ Duration this.time,
+ bool this.compilationSkipped,
+ int this.pid) {
diagnostics = [];
}
@@ -991,8 +972,8 @@
return testCase.isNegative ? !didFail(testCase) : didFail(testCase);
}
- Expectation _negateOutcomeIfNegativeTest(Expectation outcome,
- bool isNegative) {
+ Expectation _negateOutcomeIfNegativeTest(
+ Expectation outcome, bool isNegative) {
if (!isNegative) return outcome;
if (outcome.canBeOutcomeOf(Expectation.FAIL)) {
@@ -1012,21 +993,9 @@
bool _failedBecauseOfMissingXDisplay;
BrowserCommandOutputImpl(
- command,
- exitCode,
- timedOut,
- stdout,
- stderr,
- time,
- compilationSkipped) :
- super(command,
- exitCode,
- timedOut,
- stdout,
- stderr,
- time,
- compilationSkipped,
- 0) {
+ command, exitCode, timedOut, stdout, stderr, time, compilationSkipped)
+ : super(command, exitCode, timedOut, stdout, stderr, time,
+ compilationSkipped, 0) {
_failedBecauseOfMissingXDisplay = _didFailBecauseOfMissingXDisplay();
if (_failedBecauseOfMissingXDisplay) {
DebugLogger.warning("Warning: Test failure because of missing XDisplay");
@@ -1128,7 +1097,7 @@
}
if (!containsFail && !containsPass) {
DebugLogger.warning("Test had neither 'FAIL' nor 'PASS' in stdout. "
- "($command)");
+ "($command)");
return true;
}
if (containsFail) {
@@ -1137,43 +1106,31 @@
assert(containsPass);
if (exitCode != 0) {
var message = "All tests passed, but exitCode != 0. "
- "Actual exitcode: $exitCode. "
- "($command)";
+ "Actual exitcode: $exitCode. "
+ "($command)";
DebugLogger.warning(message);
diagnostics.add(message);
}
return (!hasCrashed &&
- exitCode != 0 &&
- (!isWindows || exitCode != WHITELISTED_CONTENTSHELL_EXITCODE));
+ exitCode != 0 &&
+ (!isWindows || exitCode != WHITELISTED_CONTENTSHELL_EXITCODE));
}
DebugLogger.warning("Couldn't find 'Content-Type: text/plain' in output. "
- "($command).");
+ "($command).");
return true;
}
}
class HTMLBrowserCommandOutputImpl extends BrowserCommandOutputImpl {
- HTMLBrowserCommandOutputImpl(
- command,
- exitCode,
- timedOut,
- stdout,
- stderr,
- time,
- compilationSkipped) :
- super(command,
- exitCode,
- timedOut,
- stdout,
- stderr,
- time,
- compilationSkipped);
+ HTMLBrowserCommandOutputImpl(
+ command, exitCode, timedOut, stdout, stderr, time, compilationSkipped)
+ : super(command, exitCode, timedOut, stdout, stderr, time,
+ compilationSkipped);
bool didFail(TestCase testCase) {
return _getOutcome() != Expectation.PASS;
}
-
bool get _browserTestFailure {
// We should not need to convert back and forward.
var output = decodeUtf8(super.stdout);
@@ -1183,10 +1140,16 @@
}
class BrowserTestJsonResult {
- static const ALLOWED_TYPES =
- const ['sync_exception', 'window_onerror', 'script_onerror',
- 'window_compilationerror', 'print', 'message_received', 'dom',
- 'debug'];
+ static const ALLOWED_TYPES = const [
+ 'sync_exception',
+ 'window_onerror',
+ 'script_onerror',
+ 'window_compilationerror',
+ 'print',
+ 'message_received',
+ 'dom',
+ 'debug'
+ ];
final Expectation outcome;
final String htmlDom;
@@ -1198,7 +1161,7 @@
void validate(String assertion, bool value) {
if (!value) {
throw "InvalidFormat sent from browser driving page: $assertion:\n\n"
- "$content";
+ "$content";
}
}
@@ -1218,12 +1181,11 @@
var value = entry['value'];
var timestamp = entry['timestamp'];
- validate("'type' of an entry must be a String",
- type is String);
+ validate("'type' of an entry must be a String", type is String);
validate("'type' has to be in $ALLOWED_TYPES.",
- ALLOWED_TYPES.contains(type));
- validate("'timestamp' of an entry must be a number",
- timestamp is num);
+ ALLOWED_TYPES.contains(type));
+ validate(
+ "'timestamp' of an entry must be a number", timestamp is num);
messagesByType[type].add(value);
}
@@ -1238,7 +1200,7 @@
return new BrowserTestJsonResult(
_getOutcome(messagesByType), dom, events);
}
- } catch(error) {
+ } catch (error) {
// If something goes wrong, we know the content was not in the correct
// JSON format. So we can't parse it.
// The caller is responsible for falling back to the old way of
@@ -1275,11 +1237,11 @@
// the unittest implementation posts these messages using
// "window.postMessage()" instead of the normal "print()" them.
- var isAsyncTest = searchForMsg(['print', 'message_received'],
- 'unittest-suite-wait-for-done');
+ var isAsyncTest = searchForMsg(
+ ['print', 'message_received'], 'unittest-suite-wait-for-done');
var isAsyncSuccess =
searchForMsg(['print', 'message_received'], 'unittest-suite-success') ||
- searchForMsg(['print', 'message_received'], 'unittest-suite-done');
+ searchForMsg(['print', 'message_received'], 'unittest-suite-done');
if (isAsyncTest) {
if (isAsyncSuccess) {
@@ -1301,22 +1263,23 @@
}
class BrowserControllerTestOutcome extends CommandOutputImpl
- with UnittestSuiteMessagesMixin {
+ with UnittestSuiteMessagesMixin {
BrowserTestOutput _result;
Expectation _rawOutcome;
- factory BrowserControllerTestOutcome(Command command,
- BrowserTestOutput result) {
+ factory BrowserControllerTestOutcome(
+ Command command, BrowserTestOutput result) {
void validate(String assertion, bool value) {
if (!value) {
throw "InvalidFormat sent from browser driving page: $assertion:\n\n"
- "${result.lastKnownMessage}";
+ "${result.lastKnownMessage}";
}
}
String indent(String string, int numSpaces) {
var spaces = new List.filled(numSpaces, ' ').join('');
- return string.replaceAll('\r\n', '\n')
+ return string
+ .replaceAll('\r\n', '\n')
.split('\n')
.map((line) => "$spaces$line")
.join('\n');
@@ -1344,13 +1307,13 @@
if (result.didTimeout) {
if (result.delayUntilTestStarted != null) {
stderr = "This test timed out. The delay until the test actually "
- "started was: ${result.delayUntilTestStarted}.";
+ "started was: ${result.delayUntilTestStarted}.";
} else {
// TODO(ricow/kustermann) as soon as we record the state periodically,
// we will have more information and can remove this warning.
stderr = "This test has not notified test.py that it started running. "
- "This could be a bug in test.py! "
- "Please contact ricow/whesse";
+ "This could be a bug in test.py! "
+ "Please contact ricow/whesse";
}
}
@@ -1360,8 +1323,7 @@
stdout = "message:\n${indent(result.lastKnownMessage, 2)}\n\n";
}
- stderr =
- '$stderr\n\n'
+ stderr = '$stderr\n\n'
'BrowserOutput while running the test (* EXPERIMENTAL *):\n'
'BrowserOutput.stdout:\n'
'${indent(result.browserOutput.stdout.toString(), 2)}\n'
@@ -1369,20 +1331,23 @@
'${indent(result.browserOutput.stderr.toString(), 2)}\n'
'\n';
return new BrowserControllerTestOutcome._internal(
- command, result, outcome, encodeUtf8(stdout), encodeUtf8(stderr));
+ command, result, outcome, encodeUtf8(stdout), encodeUtf8(stderr));
}
BrowserControllerTestOutcome._internal(
- Command command, BrowserTestOutput result, this._rawOutcome,
- List<int> stdout, List<int> stderr)
+ Command command,
+ BrowserTestOutput result,
+ this._rawOutcome,
+ List<int> stdout,
+ List<int> stderr)
: super(command, 0, result.didTimeout, stdout, stderr, result.duration,
- false, 0) {
+ false, 0) {
_result = result;
}
Expectation result(TestCase testCase) {
// Handle timeouts first
- if (_result.didTimeout) return Expectation.TIMEOUT;
+ if (_result.didTimeout) return Expectation.TIMEOUT;
// Multitests are handled specially
if (testCase.hasRuntimeError) {
@@ -1394,7 +1359,6 @@
}
}
-
class AnalysisCommandOutputImpl extends CommandOutputImpl {
// An error line has 8 fields that look like:
// ERROR|COMPILER|MISSING_SOURCE|file:/tmp/t.dart|15|1|24|Missing source.
@@ -1403,21 +1367,10 @@
final int FILENAME = 3;
final int FORMATTED_ERROR = 7;
- AnalysisCommandOutputImpl(command,
- exitCode,
- timedOut,
- stdout,
- stderr,
- time,
- compilationSkipped) :
- super(command,
- exitCode,
- timedOut,
- stdout,
- stderr,
- time,
- compilationSkipped,
- 0);
+ AnalysisCommandOutputImpl(
+ command, exitCode, timedOut, stdout, stderr, time, compilationSkipped)
+ : super(command, exitCode, timedOut, stdout, stderr, time,
+ compilationSkipped, 0);
Expectation result(TestCase testCase) {
// TODO(kustermann): If we run the analyzer not in batch mode, make sure
@@ -1455,9 +1408,8 @@
return Expectation.STATIC_WARNING;
}
- assert (errors.length == 0 && warnings.length == 0);
- assert (!testCase.hasCompileError &&
- !testCase.hasStaticWarning);
+ assert(errors.length == 0 && warnings.length == 0);
+ assert(!testCase.hasCompileError && !testCase.hasStaticWarning);
return Expectation.PASS;
}
@@ -1468,7 +1420,7 @@
StringBuffer field = new StringBuffer();
List<String> result = [];
bool escaped = false;
- for (var i = 0 ; i < line.length; i++) {
+ for (var i = 0; i < line.length; i++) {
var c = line[i];
if (!escaped && c == '\\') {
escaped = true;
@@ -1503,13 +1455,12 @@
}
class VmCommandOutputImpl extends CommandOutputImpl
- with UnittestSuiteMessagesMixin {
+ with UnittestSuiteMessagesMixin {
static const DART_VM_EXITCODE_COMPILE_TIME_ERROR = 254;
static const DART_VM_EXITCODE_UNCAUGHT_EXCEPTION = 255;
VmCommandOutputImpl(Command command, int exitCode, bool timedOut,
- List<int> stdout, List<int> stderr, Duration time,
- int pid)
+ List<int> stdout, List<int> stderr, Duration time, int pid)
: super(command, exitCode, timedOut, stdout, stderr, time, false, pid);
Expectation result(TestCase testCase) {
@@ -1553,11 +1504,16 @@
class CompilationCommandOutputImpl extends CommandOutputImpl {
static const DART2JS_EXITCODE_CRASH = 253;
- CompilationCommandOutputImpl(Command command, int exitCode, bool timedOut,
- List<int> stdout, List<int> stderr, Duration time,
+ CompilationCommandOutputImpl(
+ Command command,
+ int exitCode,
+ bool timedOut,
+ List<int> stdout,
+ List<int> stderr,
+ Duration time,
bool compilationSkipped)
: super(command, exitCode, timedOut, stdout, stderr, time,
- compilationSkipped, 0);
+ compilationSkipped, 0);
Expectation result(TestCase testCase) {
// Handle general crash/timeout detection.
@@ -1596,7 +1552,7 @@
}
class JsCommandlineOutputImpl extends CommandOutputImpl
- with UnittestSuiteMessagesMixin {
+ with UnittestSuiteMessagesMixin {
JsCommandlineOutputImpl(Command command, int exitCode, bool timedOut,
List<int> stdout, List<int> stderr, Duration time)
: super(command, exitCode, timedOut, stdout, stderr, time, false, 0);
@@ -1620,7 +1576,7 @@
class PubCommandOutputImpl extends CommandOutputImpl {
PubCommandOutputImpl(PubCommand command, int exitCode, bool timedOut,
List<int> stdout, List<int> stderr, Duration time)
- : super(command, exitCode, timedOut, stdout, stderr, time, false, 0);
+ : super(command, exitCode, timedOut, stdout, stderr, time, false, 0);
Expectation result(TestCase testCase) {
// Handle crashes and timeouts first
@@ -1641,8 +1597,8 @@
final Expectation _result;
ScriptCommandOutputImpl(ScriptCommand command, this._result,
- String scriptExecutionInformation, Duration time)
- : super(command, 0, false, [], [], time, false, 0) {
+ String scriptExecutionInformation, Duration time)
+ : super(command, 0, false, [], [], time, false, 0) {
var lines = scriptExecutionInformation.split("\n");
diagnostics.addAll(lines);
}
@@ -1652,29 +1608,20 @@
bool get canRunDependendCommands => _result == Expectation.PASS;
bool get successful => _result == Expectation.PASS;
-
}
-CommandOutput createCommandOutput(Command command,
- int exitCode,
- bool timedOut,
- List<int> stdout,
- List<int> stderr,
- Duration time,
- bool compilationSkipped,
- [int pid = 0]) {
+CommandOutput createCommandOutput(Command command, int exitCode, bool timedOut,
+ List<int> stdout, List<int> stderr, Duration time, bool compilationSkipped,
+ [int pid = 0]) {
if (command is ContentShellCommand) {
return new BrowserCommandOutputImpl(
- command, exitCode, timedOut, stdout, stderr,
- time, compilationSkipped);
+ command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
} else if (command is BrowserTestCommand) {
return new HTMLBrowserCommandOutputImpl(
- command, exitCode, timedOut, stdout, stderr,
- time, compilationSkipped);
+ command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
} else if (command is AnalysisCommand) {
return new AnalysisCommandOutputImpl(
- command, exitCode, timedOut, stdout, stderr,
- time, compilationSkipped);
+ command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
} else if (command is VmCommand) {
return new VmCommandOutputImpl(
command, exitCode, timedOut, stdout, stderr, time, pid);
@@ -1694,12 +1641,10 @@
command, exitCode, timedOut, stdout, stderr, time);
}
- return new CommandOutputImpl(
- command, exitCode, timedOut, stdout, stderr,
+ return new CommandOutputImpl(command, exitCode, timedOut, stdout, stderr,
time, compilationSkipped, pid);
}
-
/**
* An OutputLog records the output from a test, but truncates it if
* it is longer than MAX_HEAD characters, and just keeps the head and
@@ -1734,10 +1679,9 @@
}
}
- List<int> _truncatedTail() =>
- tail.length > TAIL_LENGTH ?
- tail.sublist(tail.length - TAIL_LENGTH) :
- tail;
+ List<int> _truncatedTail() => tail.length > TAIL_LENGTH
+ ? tail.sublist(tail.length - TAIL_LENGTH)
+ : tail;
List<int> toList() {
if (complete == null) {
@@ -1751,7 +1695,8 @@
*****************************************************************************
-""".codeUnits);
+"""
+ .codeUnits);
complete.addAll(_truncatedTail());
} else if (tail != null) {
complete.addAll(tail);
@@ -1801,11 +1746,10 @@
_commandComplete(0);
} else {
var processEnvironment = _createProcessEnvironment();
- Future processFuture =
- io.Process.start(command.executable,
- command.arguments,
- environment: processEnvironment,
- workingDirectory: command.workingDirectory);
+ Future processFuture = io.Process.start(
+ command.executable, command.arguments,
+ environment: processEnvironment,
+ workingDirectory: command.workingDirectory);
processFuture.then((io.Process process) {
StreamSubscription stdoutSubscription =
_drainStream(process.stdout, stdout);
@@ -1871,14 +1815,14 @@
});
}
- Future.wait([stdoutCompleter.future,
- stderrCompleter.future]).then((_) {
+ Future.wait([stdoutCompleter.future, stderrCompleter.future]).then(
+ (_) {
_commandComplete(exitCode);
});
});
- timeoutTimer = new Timer(new Duration(seconds: timeout),
- timeoutHandler);
+ timeoutTimer =
+ new Timer(new Duration(seconds: timeout), timeoutHandler);
}).catchError((e) {
// TODO(floitsch): should we try to report the stacktrace?
print("Process error:");
@@ -1912,8 +1856,8 @@
return commandOutput;
}
- StreamSubscription _drainStream(Stream<List<int>> source,
- OutputLog destination) {
+ StreamSubscription _drainStream(
+ Stream<List<int>> source, OutputLog destination) {
return source.listen(destination.add);
}
@@ -1957,7 +1901,7 @@
BatchRunnerProcess();
Future<CommandOutput> runCommand(String runnerType, ProcessCommand command,
- int timeout, List<String> arguments) {
+ int timeout, List<String> arguments) {
assert(_completer == null);
assert(!_currentlyRunning);
@@ -2011,15 +1955,14 @@
_status = null;
_stdoutCompleter = new Completer();
_stderrCompleter = new Completer();
- _timer = new Timer(new Duration(seconds: timeout),
- _timeoutHandler);
+ _timer = new Timer(new Duration(seconds: timeout), _timeoutHandler);
var line = _createArgumentsLine(_arguments, timeout);
_process.stdin.write(line);
_stdoutSubscription.resume();
_stderrSubscription.resume();
- Future.wait([_stdoutCompleter.future,
- _stderrCompleter.future]).then((_) => _reportResult());
+ Future.wait([_stdoutCompleter.future, _stderrCompleter.future]).then(
+ (_) => _reportResult());
}
String _createArgumentsLine(List<String> arguments, int timeout) {
@@ -2034,13 +1977,14 @@
var exitCode = 0;
if (outcome == "CRASH") exitCode = CRASHING_BROWSER_EXITCODE;
if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1;
- var output = createCommandOutput(_command,
- exitCode,
- (outcome == "TIMEOUT"),
- _testStdout.toList(),
- _testStderr.toList(),
- new DateTime.now().difference(_startTime),
- false);
+ var output = createCommandOutput(
+ _command,
+ exitCode,
+ (outcome == "TIMEOUT"),
+ _testStdout.toList(),
+ _testStderr.toList(),
+ new DateTime.now().difference(_startTime),
+ false);
assert(_completer != null);
_completer.complete(output);
_completer = null;
@@ -2055,7 +1999,8 @@
_stdoutSubscription.cancel();
_stderrSubscription.cancel();
_startProcess(_reportResult);
- } else { // No active test case running.
+ } else {
+ // No active test case running.
_process = null;
}
}
@@ -2077,16 +2022,13 @@
environment[key] = _processEnvironmentOverrides[key];
}
}
- Future processFuture = io.Process.start(executable,
- arguments,
- environment: environment);
+ Future processFuture =
+ io.Process.start(executable, arguments, environment: environment);
processFuture.then((io.Process p) {
_process = p;
var _stdoutStream =
- _process.stdout
- .transform(UTF8.decoder)
- .transform(new LineSplitter());
+ _process.stdout.transform(UTF8.decoder).transform(new LineSplitter());
_stdoutSubscription = _stdoutStream.listen((String line) {
if (line.startsWith('>>> TEST')) {
_status = line;
@@ -2107,9 +2049,7 @@
_stdoutSubscription.pause();
var _stderrStream =
- _process.stderr
- .transform(UTF8.decoder)
- .transform(new LineSplitter());
+ _process.stderr.transform(UTF8.decoder).transform(new LineSplitter());
_stderrSubscription = _stderrStream.listen((String line) {
if (line.startsWith('>>> EOF STDERR')) {
_stderrSubscription.pause();
@@ -2156,7 +2096,6 @@
}
}
-
/**
* [TestCaseEnqueuer] takes a list of TestSuites, generates TestCases and
* builds a dependency graph of all commands in every TestSuite.
@@ -2223,7 +2162,6 @@
}
}
-
/*
* [CommandEnqueuer] will
* - change node.state to NodeState.Enqueuing as soon as all dependencies have
@@ -2232,11 +2170,15 @@
* have a state of NodeState.Failed/NodeState.UnableToRun.
*/
class CommandEnqueuer {
- static final INIT_STATES = [dgraph.NodeState.Initialized,
- dgraph.NodeState.Waiting];
- static final FINISHED_STATES = [dgraph.NodeState.Successful,
- dgraph.NodeState.Failed,
- dgraph.NodeState.UnableToRun];
+ static final INIT_STATES = [
+ dgraph.NodeState.Initialized,
+ dgraph.NodeState.Waiting
+ ];
+ static final FINISHED_STATES = [
+ dgraph.NodeState.Successful,
+ dgraph.NodeState.Failed,
+ dgraph.NodeState.UnableToRun
+ ];
final dgraph.Graph _graph;
CommandEnqueuer(this._graph) {
@@ -2248,9 +2190,9 @@
});
eventCondition((e) => e is dgraph.StateChangedEvent).listen((event) {
- if ([dgraph.NodeState.Waiting,
- dgraph.NodeState.Processing].contains(event.from)) {
- if (FINISHED_STATES.contains(event.to)){
+ if ([dgraph.NodeState.Waiting, dgraph.NodeState.Processing]
+ .contains(event.from)) {
+ if (FINISHED_STATES.contains(event.to)) {
for (var dependendNode in event.node.neededFor) {
_changeNodeStateIfNecessary(dependendNode);
}
@@ -2263,16 +2205,17 @@
// changed it's state.
void _changeNodeStateIfNecessary(dgraph.Node node) {
if (INIT_STATES.contains(node.state)) {
- bool anyDependenciesUnsuccessful = node.dependencies.any(
- (dep) => [dgraph.NodeState.Failed,
- dgraph.NodeState.UnableToRun].contains(dep.state));
+ bool anyDependenciesUnsuccessful = node.dependencies.any((dep) => [
+ dgraph.NodeState.Failed,
+ dgraph.NodeState.UnableToRun
+ ].contains(dep.state));
var newState = dgraph.NodeState.Waiting;
if (anyDependenciesUnsuccessful) {
newState = dgraph.NodeState.UnableToRun;
} else {
- bool allDependenciesSuccessful = node.dependencies.every(
- (dep) => dep.state == dgraph.NodeState.Successful);
+ bool allDependenciesSuccessful = node.dependencies
+ .every((dep) => dep.state == dgraph.NodeState.Successful);
if (allDependenciesSuccessful) {
newState = dgraph.NodeState.Enqueuing;
@@ -2304,8 +2247,8 @@
final TestCaseEnqueuer enqueuer;
final Queue<Command> _runQueue = new Queue<Command>();
- final _commandOutputStream = new StreamController<CommandOutput>(sync: true);
- final _completer = new Completer();
+ final _commandOutputStream = new StreamController<CommandOutput>(sync: true);
+ final _completer = new Completer();
int _numProcesses = 0;
int _maxProcesses;
@@ -2314,23 +2257,23 @@
bool _finishing = false;
bool _verbose = false;
- CommandQueue(this.graph, this.enqueuer, this.executor,
- this._maxProcesses, this._maxBrowserProcesses, this._verbose) {
+ CommandQueue(this.graph, this.enqueuer, this.executor, this._maxProcesses,
+ this._maxBrowserProcesses, this._verbose) {
var eventCondition = graph.events.where;
eventCondition((event) => event is dgraph.StateChangedEvent)
.listen((event) {
- if (event.to == dgraph.NodeState.Enqueuing) {
- assert(event.from == dgraph.NodeState.Initialized ||
- event.from == dgraph.NodeState.Waiting);
- graph.changeState(event.node, dgraph.NodeState.Processing);
- var command = event.node.userData;
- if (event.node.dependencies.length > 0) {
- _runQueue.addFirst(command);
- } else {
- _runQueue.add(command);
- }
- Timer.run(() => _tryRunNextCommand());
- }
+ if (event.to == dgraph.NodeState.Enqueuing) {
+ assert(event.from == dgraph.NodeState.Initialized ||
+ event.from == dgraph.NodeState.Waiting);
+ graph.changeState(event.node, dgraph.NodeState.Processing);
+ var command = event.node.userData;
+ if (event.node.dependencies.length > 0) {
+ _runQueue.addFirst(command);
+ } else {
+ _runQueue.add(command);
+ }
+ Timer.run(() => _tryRunNextCommand());
+ }
});
// We're finished if the graph is sealed and all nodes are in a finished
// state (Successful, Failed or UnableToRun).
@@ -2374,8 +2317,8 @@
// If a command is part of many TestCases we set the timeout to be
// the maximum over all [TestCase.timeout]s. At some point, we might
// eliminate [TestCase.timeout] completely and move it to [Command].
- int timeout = testCases.map((TestCase test) => test.timeout)
- .fold(0, math.max);
+ int timeout =
+ testCases.map((TestCase test) => test.timeout).fold(0, math.max);
if (_verbose) {
print('Running "${command.displayName}" command: $command');
@@ -2422,7 +2365,7 @@
print("CommandQueue state:");
print(" Processes: used: $_numProcesses max: $_maxProcesses");
print(" BrowserProcesses: used: $_numBrowserProcesses "
- "max: $_maxBrowserProcesses");
+ "max: $_maxBrowserProcesses");
print(" Finishing: $_finishing");
print(" Queue (length = ${_runQueue.length}):");
for (var command in _runQueue) {
@@ -2431,7 +2374,6 @@
}
}
-
/*
* [CommandExecutor] is responsible for executing commands. It will make sure
* that the the following two constraints are satisfied
@@ -2494,7 +2436,7 @@
return _runCommand(command, timeout).then((CommandOutput output) {
if (retriesLeft > 0 && shouldRetryCommand(output)) {
DebugLogger.warning("Rerunning Command: ($retriesLeft "
- "attempt(s) remains) [cmd: $command]");
+ "attempt(s) remains) [cmd: $command]");
return runCommand(retriesLeft - 1);
} else {
return new Future.value(output);
@@ -2545,8 +2487,8 @@
var completer = new Completer<CommandOutput>();
var callback = (BrowserTestOutput output) {
- completer.complete(
- new BrowserControllerTestOutcome(browserCommand, output));
+ completer
+ .complete(new BrowserControllerTestOutcome(browserCommand, output));
};
BrowserTest browserTest;
@@ -2558,40 +2500,32 @@
}
_getBrowserTestRunner(browserCommand.browser, browserCommand.configuration)
.then((testRunner) {
- testRunner.queueTest(browserTest);
+ testRunner.enqueueTest(browserTest);
});
return completer.future;
}
- Future<BrowserTestRunner> _getBrowserTestRunner(String browser,
- Map configuration) {
+ Future<BrowserTestRunner> _getBrowserTestRunner(
+ String browser, Map configuration) async {
var localIp = globalConfiguration['local_ip'];
- var num_browsers = maxBrowserProcesses;
if (_browserTestRunners[configuration] == null) {
var testRunner = new BrowserTestRunner(
- configuration, localIp, browser, num_browsers);
+ configuration, localIp, browser, maxBrowserProcesses);
if (globalConfiguration['verbose']) {
testRunner.logger = DebugLogger.info;
}
_browserTestRunners[configuration] = testRunner;
- return testRunner.start().then((started) {
- if (started) {
- return testRunner;
- }
- print("Issue starting browser test runner");
- io.exit(1);
- });
+ await testRunner.start();
}
- return new Future.value(_browserTestRunners[configuration]);
+ return _browserTestRunners[configuration];
}
}
class RecordingCommandExecutor implements CommandExecutor {
TestCaseRecorder _recorder;
- RecordingCommandExecutor(Path path)
- : _recorder = new TestCaseRecorder(path);
+ RecordingCommandExecutor(Path path) : _recorder = new TestCaseRecorder(path);
Future<CommandOutput> runCommand(node, ProcessCommand command, int timeout) {
assert(node.dependencies.length == 0);
@@ -2613,8 +2547,7 @@
if (environment == null) return true;
return environment.length == 0 ||
(environment.length == 1 &&
- environment.containsKey("DART_CONFIGURATION"));
-
+ environment.containsKey("DART_CONFIGURATION"));
}
}
@@ -2650,7 +2583,7 @@
// "xvfb-run" issue 7564, try re-running the test.
bool containsFailureMsg(String line) {
return line.contains(MESSAGE_CANNOT_OPEN_DISPLAY) ||
- line.contains(MESSAGE_FAILED_TO_RUN_COMMAND);
+ line.contains(MESSAGE_FAILED_TO_RUN_COMMAND);
}
if (stdout.any(containsFailureMsg) || stderr.any(containsFailureMsg)) {
return true;
@@ -2678,8 +2611,10 @@
* closed.
*/
class TestCaseCompleter {
- static final COMPLETED_STATES = [dgraph.NodeState.Failed,
- dgraph.NodeState.Successful];
+ static final COMPLETED_STATES = [
+ dgraph.NodeState.Failed,
+ dgraph.NodeState.Successful
+ ];
final dgraph.Graph graph;
final TestCaseEnqueuer enqueuer;
final CommandQueue commandQueue;
@@ -2707,26 +2642,26 @@
// changes.
eventCondition((event) => event is dgraph.StateChangedEvent)
.listen((dgraph.StateChangedEvent event) {
- if (event.from == dgraph.NodeState.Processing &&
- !finishedRemainingTestCases ) {
- var command = event.node.userData;
+ if (event.from == dgraph.NodeState.Processing &&
+ !finishedRemainingTestCases) {
+ var command = event.node.userData;
- assert(COMPLETED_STATES.contains(event.to));
- assert(_outputs[command] != null);
+ assert(COMPLETED_STATES.contains(event.to));
+ assert(_outputs[command] != null);
- _completeTestCasesIfPossible(enqueuer.command2testCases[command]);
- _checkDone();
- }
+ _completeTestCasesIfPossible(enqueuer.command2testCases[command]);
+ _checkDone();
+ }
});
// Listen also for GraphSealedEvent's. If there is not a single node in the
// graph, we still want to finish after the graph was sealed.
eventCondition((event) => event is dgraph.GraphSealedEvent)
.listen((dgraph.GraphSealedEvent event) {
- if (!_closed && enqueuer.remainingTestCases.isEmpty) {
- _controller.close();
- _closed = true;
- }
+ if (!_closed && enqueuer.remainingTestCases.isEmpty) {
+ _controller.close();
+ _closed = true;
+ }
});
}
@@ -2770,7 +2705,6 @@
}
}
-
class ProcessQueue {
Map _globalConfiguration;
@@ -2778,32 +2712,28 @@
final dgraph.Graph _graph = new dgraph.Graph();
List<EventListener> _eventListener;
- ProcessQueue(this._globalConfiguration,
- maxProcesses,
- maxBrowserProcesses,
- DateTime startTime,
- testSuites,
- this._eventListener,
- this._allDone,
- [bool verbose = false,
- String recordingOutputFile,
- String recordedInputFile]) {
+ ProcessQueue(this._globalConfiguration, maxProcesses, maxBrowserProcesses,
+ DateTime startTime, testSuites, this._eventListener, this._allDone,
+ [bool verbose = false,
+ String recordingOutputFile,
+ String recordedInputFile]) {
void setupForListing(TestCaseEnqueuer testCaseEnqueuer) {
- _graph.events.where((event) => event is dgraph.GraphSealedEvent)
- .listen((dgraph.GraphSealedEvent event) {
- var testCases = new List.from(testCaseEnqueuer.remainingTestCases);
- testCases.sort((a, b) => a.displayName.compareTo(b.displayName));
+ _graph.events
+ .where((event) => event is dgraph.GraphSealedEvent)
+ .listen((dgraph.GraphSealedEvent event) {
+ var testCases = new List.from(testCaseEnqueuer.remainingTestCases);
+ testCases.sort((a, b) => a.displayName.compareTo(b.displayName));
- print("\nGenerating all matching test cases ....\n");
+ print("\nGenerating all matching test cases ....\n");
- for (TestCase testCase in testCases) {
- eventFinishedTestCase(testCase);
- print("${testCase.displayName} "
- "Expectations: ${testCase.expectedOutcomes.join(', ')} "
- "Configuration: '${testCase.configurationString}'");
- }
- eventAllTestsKnown();
- });
+ for (TestCase testCase in testCases) {
+ eventFinishedTestCase(testCase);
+ print("${testCase.displayName} "
+ "Expectations: ${testCase.expectedOutcomes.join(', ')} "
+ "Configuration: '${testCase.configurationString}'");
+ }
+ eventAllTestsKnown();
+ });
}
var testCaseEnqueuer;
@@ -2825,17 +2755,18 @@
cancelDebugTimer();
_debugTimer = new Timer(debugTimerDuration, () {
print("The debug timer of test.dart expired. Please report this issue"
- " to ricow/whesse and provide the following information:");
+ " to ricow/whesse and provide the following information:");
print("");
print("Graph is sealed: ${_graph.isSealed}");
print("");
_graph.DumpCounts();
print("");
var unfinishedNodeStates = [
- dgraph.NodeState.Initialized,
- dgraph.NodeState.Waiting,
- dgraph.NodeState.Enqueuing,
- dgraph.NodeState.Processing];
+ dgraph.NodeState.Initialized,
+ dgraph.NodeState.Waiting,
+ dgraph.NodeState.Enqueuing,
+ dgraph.NodeState.Processing
+ ];
for (var nodeState in unfinishedNodeStates) {
if (_graph.stateCount(nodeState) > 0) {
@@ -2849,7 +2780,7 @@
print(" Command: $command");
for (var testCase in testCases) {
print(" Enqueued by: ${testCase.configurationString} "
- "-- ${testCase.displayName}");
+ "-- ${testCase.displayName}");
}
print("");
}
@@ -2870,9 +2801,10 @@
// When the graph building is finished, notify event listeners.
_graph.events
- .where((event) => event is dgraph.GraphSealedEvent).listen((event) {
- eventAllTestsKnown();
- });
+ .where((event) => event is dgraph.GraphSealedEvent)
+ .listen((event) {
+ eventAllTestsKnown();
+ });
// Queue commands as they become "runnable"
var commandEnqueuer = new CommandEnqueuer(_graph);
@@ -2890,30 +2822,27 @@
// Run "runnable commands" using [executor] subject to
// maxProcesses/maxBrowserProcesses constraint
- commandQueue = new CommandQueue(
- _graph, testCaseEnqueuer, executor, maxProcesses, maxBrowserProcesses,
- verbose);
+ commandQueue = new CommandQueue(_graph, testCaseEnqueuer, executor,
+ maxProcesses, maxBrowserProcesses, verbose);
// Finish test cases when all commands were run (or some failed)
var testCaseCompleter =
new TestCaseCompleter(_graph, testCaseEnqueuer, commandQueue);
- testCaseCompleter.finishedTestCases.listen(
- (TestCase finishedTestCase) {
- resetDebugTimer();
+ testCaseCompleter.finishedTestCases.listen((TestCase finishedTestCase) {
+ resetDebugTimer();
- // If we're recording, we don't report any TestCases to listeners.
- if (!recording) {
- eventFinishedTestCase(finishedTestCase);
- }
- },
- onDone: () {
- // Wait until the commandQueue/execturo is done (it may need to stop
- // batch runners, browser controllers, ....)
- commandQueue.done.then((_) {
- cancelDebugTimer();
- eventAllTestsDone();
- });
- });
+ // If we're recording, we don't report any TestCases to listeners.
+ if (!recording) {
+ eventFinishedTestCase(finishedTestCase);
+ }
+ }, onDone: () {
+ // Wait until the commandQueue/execturo is done (it may need to stop
+ // batch runners, browser controllers, ....)
+ commandQueue.done.then((_) {
+ cancelDebugTimer();
+ eventAllTestsDone();
+ });
+ });
resetDebugTimer();
}
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index fd06d20..d288da8 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -27,21 +27,18 @@
import "utils.dart";
import "http_server.dart" show PREFIX_BUILDDIR, PREFIX_DARTDIR;
-import "compiler_configuration.dart" show
- CommandArtifact,
- CompilerConfiguration;
+import "compiler_configuration.dart"
+ show CommandArtifact, CompilerConfiguration;
-import "runtime_configuration.dart" show
- RuntimeConfiguration;
+import "runtime_configuration.dart" show RuntimeConfiguration;
import 'browser_test.dart';
-
RegExp multiHtmlTestGroupRegExp = new RegExp(r"\s*[^/]\s*group\('[^,']*");
RegExp multiHtmlTestRegExp = new RegExp(r"useHtmlIndividualConfiguration()");
// Require at least one non-space character before '///'
RegExp multiTestRegExp = new RegExp(r"\S *"
- r"/// \w+:(.*)");
+ r"/// \w+:(.*)");
RegExp dartExtension = new RegExp(r'\.dart$');
/**
@@ -49,14 +46,12 @@
*/
typedef bool Predicate<T>(T arg);
-typedef void CreateTest(Path filePath,
- Path originTestPath,
- bool hasCompileError,
- bool hasRuntimeError,
- {bool isNegativeIfChecked,
- bool hasCompileErrorIfChecked,
- bool hasStaticWarning,
- String multitestKey});
+typedef void CreateTest(Path filePath, Path originTestPath,
+ bool hasCompileError, bool hasRuntimeError,
+ {bool isNegativeIfChecked,
+ bool hasCompileErrorIfChecked,
+ bool hasStaticWarning,
+ String multitestKey});
typedef void VoidFunction();
@@ -74,7 +69,6 @@
return completer.future;
}
-
/** A completer that waits until all added [Future]s complete. */
// TODO(rnystrom): Copied from web_components. Remove from here when it gets
// added to dart:core. (See #6626.)
@@ -116,7 +110,6 @@
Future<List> get future => _completer.future;
}
-
/**
* A TestSuite represents a collection of tests. It creates a [TestCase]
* object for each test to be run, and passes the test cases to a callback.
@@ -132,10 +125,10 @@
Map<String, String> _environmentOverrides;
TestSuite(this.configuration, this.suiteName) {
- TestUtils.buildDir(configuration); // Sets configuration_directory.
+ TestUtils.buildDir(configuration); // Sets configuration_directory.
if (configuration['configuration_directory'] != null) {
_environmentOverrides = {
- 'DART_CONFIGURATION' : configuration['configuration_directory']
+ 'DART_CONFIGURATION': configuration['configuration_directory']
};
}
}
@@ -359,13 +352,14 @@
.append(testUniqueName);
TestUtils.mkdirRecursive(new Path('.'), generatedTestPath);
- return new File(generatedTestPath.toNativePath()).absolute.path
+ return new File(generatedTestPath.toNativePath())
+ .absolute
+ .path
.replaceAll('\\', '/');
}
- String buildTestCaseDisplayName(Path suiteDir,
- Path originTestPath,
- {String multitestName: ""}) {
+ String buildTestCaseDisplayName(Path suiteDir, Path originTestPath,
+ {String multitestName: ""}) {
Path testNamePath = originTestPath.relativeTo(suiteDir);
var directory = testNamePath.directoryPath;
var filenameWithoutExt = testNamePath.filenameWithoutExtension;
@@ -391,10 +385,10 @@
var checked = configuration['checked'] ? '-checked' : '';
var minified = configuration['minified'] ? '-minified' : '';
var sdk = configuration['use_sdk'] ? '-sdk' : '';
- var packages = configuration['use_public_packages']
- ? '-public_packages' : '';
+ var packages =
+ configuration['use_public_packages'] ? '-public_packages' : '';
var dirName = "${configuration['compiler']}-${configuration['runtime']}"
- "$checked$minified$packages$sdk";
+ "$checked$minified$packages$sdk";
return createGeneratedTestDirectoryHelper(
"tests", dirName, testPath, optionsName);
}
@@ -404,10 +398,10 @@
var minified = configuration['minified'] ? '-minified' : '';
var csp = configuration['csp'] ? '-csp' : '';
var sdk = configuration['use_sdk'] ? '-sdk' : '';
- var packages = configuration['use_public_packages']
- ? '-public_packages' : '';
+ var packages =
+ configuration['use_public_packages'] ? '-public_packages' : '';
var dirName = "${configuration['compiler']}"
- "$checked$minified$csp$packages$sdk";
+ "$checked$minified$csp$packages$sdk";
return createGeneratedTestDirectoryHelper(
"compilations", dirName, testPath, "");
}
@@ -415,14 +409,16 @@
String createPubspecCheckoutDirectory(Path directoryOfPubspecYaml) {
var sdk = configuration['use_sdk'] ? '-sdk' : '';
var pkg = configuration['use_public_packages']
- ? 'public_packages' : 'repo_packages';
+ ? 'public_packages'
+ : 'repo_packages';
return createGeneratedTestDirectoryHelper(
"pubspec_checkouts", '$pkg$sdk', directoryOfPubspecYaml, "");
}
String createPubPackageBuildsDirectory(Path directoryOfPubspecYaml) {
var pkg = configuration['use_public_packages']
- ? 'public_packages' : 'repo_packages';
+ ? 'public_packages'
+ : 'repo_packages';
return createGeneratedTestDirectoryHelper(
"pub_package_builds", pkg, directoryOfPubspecYaml, "");
}
@@ -434,19 +430,20 @@
var dir = new Directory(path.toNativePath());
return dir.exists().then((var exist) {
if (!exist) return [];
- return dir.list(recursive: false)
- .where((fse) => fse is Directory)
- .map((Directory directory) {
- var fullPath = directory.absolute.path;
- var packageName = new Path(fullPath).filename;
- if (isValid(packageName)) {
- return [packageName, path.append(packageName).toNativePath()];
- }
- return null;
- })
- .where((name) => name != null)
- .toList();
- });
+ return dir
+ .list(recursive: false)
+ .where((fse) => fse is Directory)
+ .map((Directory directory) {
+ var fullPath = directory.absolute.path;
+ var packageName = new Path(fullPath).filename;
+ if (isValid(packageName)) {
+ return [packageName, path.append(packageName).toNativePath()];
+ }
+ return null;
+ })
+ .where((name) => name != null)
+ .toList();
+ });
}
Future<Map> discoverPackagesInRepository() {
@@ -522,28 +519,25 @@
Map buildPubspecDependencyOverrides(Map packageDirectories) {
Map overrides = {};
packageDirectories.forEach((String packageName, String fullPath) {
- overrides[packageName] = { 'path' : fullPath };
+ overrides[packageName] = {'path': fullPath};
});
return overrides;
}
-
}
-
Future<Iterable<String>> ccTestLister(String runnerPath) {
return Process.run(runnerPath, ["--list"]).then((ProcessResult result) {
if (result.exitCode != 0) {
throw "Failed to list tests: '$runnerPath --list'. "
- "Process exited with ${result.exitCode}";
+ "Process exited with ${result.exitCode}";
}
return result.stdout
- .split('\n')
- .map((line) => line.trim())
- .where((name) => name.length > 0);
+ .split('\n')
+ .map((line) => line.trim())
+ .where((name) => name.length > 0);
});
}
-
/**
* A specialized [TestSuite] that runs tests written in C to unit test
* the Dart virtual machine and its API.
@@ -559,11 +553,9 @@
final String dartDir;
List<String> statusFilePaths;
- CCTestSuite(Map configuration,
- String suiteName,
- String runnerName,
- this.statusFilePaths,
- {this.testPrefix: ''})
+ CCTestSuite(Map configuration, String suiteName, String runnerName,
+ this.statusFilePaths,
+ {this.testPrefix: ''})
: super(configuration, suiteName),
dartDir = TestUtils.dartDir.toNativePath() {
// For running the tests we use the given '$runnerName' binary
@@ -585,8 +577,7 @@
// "suiteName/testName" for cc tests.
String constructedName = '$suiteName/$testPrefix$testName';
- var expectations = testExpectations.expectations(
- '$testPrefix$testName');
+ var expectations = testExpectations.expectations('$testPrefix$testName');
var args = TestUtils.standardOptions(configuration);
args.add(testName);
@@ -616,7 +607,6 @@
}
}
-
class TestInformation {
Path filePath;
Path originTestPath;
@@ -628,27 +618,36 @@
bool hasStaticWarning;
String multitestKey;
- TestInformation(this.filePath, this.originTestPath, this.optionsFromFile,
- this.hasCompileError, this.hasRuntimeError,
- this.isNegativeIfChecked, this.hasCompileErrorIfChecked,
- this.hasStaticWarning,
- {this.multitestKey: ''}) {
+ TestInformation(
+ this.filePath,
+ this.originTestPath,
+ this.optionsFromFile,
+ this.hasCompileError,
+ this.hasRuntimeError,
+ this.isNegativeIfChecked,
+ this.hasCompileErrorIfChecked,
+ this.hasStaticWarning,
+ {this.multitestKey: ''}) {
assert(filePath.isAbsolute);
}
}
-
class HtmlTestInformation extends TestInformation {
List<String> expectedMessages;
List<String> scripts;
HtmlTestInformation(Path filePath, this.expectedMessages, this.scripts)
- : super(filePath, filePath,
- {'isMultitest': false, 'isMultiHtmlTest': false},
- false, false, false, false, false) {}
+ : super(
+ filePath,
+ filePath,
+ {'isMultitest': false, 'isMultiHtmlTest': false},
+ false,
+ false,
+ false,
+ false,
+ false) {}
}
-
/**
* A standard [TestSuite] implementation that searches for tests in a
* directory, and creates [TestCase]s that compile and/or run them.
@@ -664,12 +663,9 @@
final extraVmOptions;
List<Uri> _dart2JsBootstrapDependencies;
- StandardTestSuite(Map configuration,
- String suiteName,
- Path suiteDirectory,
- this.statusFilePaths,
- {this.isTestFilePredicate,
- bool recursive: false})
+ StandardTestSuite(Map configuration, String suiteName, Path suiteDirectory,
+ this.statusFilePaths,
+ {this.isTestFilePredicate, bool recursive: false})
: super(configuration, suiteName),
dartDir = TestUtils.dartDir,
listRecursively = recursive,
@@ -678,11 +674,14 @@
if (!useSdk) {
_dart2JsBootstrapDependencies = [];
} else {
- var snapshotPath = TestUtils.absolutePath(new Path(buildDir).join(
- new Path('dart-sdk/bin/snapshots/'
- 'utils_wrapper.dart.snapshot'))).toString();
- _dart2JsBootstrapDependencies =
- [new Uri(scheme: 'file', path: snapshotPath)];
+ var snapshotPath = TestUtils
+ .absolutePath(
+ new Path(buildDir).join(new Path('dart-sdk/bin/snapshots/'
+ 'utils_wrapper.dart.snapshot')))
+ .toString();
+ _dart2JsBootstrapDependencies = [
+ new Uri(scheme: 'file', path: snapshotPath)
+ ];
}
}
@@ -715,14 +714,14 @@
*/
factory StandardTestSuite.forDirectory(Map configuration, Path directory) {
var name = directory.filename;
- var status_paths = ['$directory/$name.status',
- '$directory/.status',
- '$directory/${name}_dart2js.status',
- '$directory/${name}_analyzer2.status'];
+ var status_paths = [
+ '$directory/$name.status',
+ '$directory/.status',
+ '$directory/${name}_dart2js.status',
+ '$directory/${name}_analyzer2.status'
+ ];
- return new StandardTestSuite(configuration,
- name, directory,
- status_paths,
+ return new StandardTestSuite(configuration, name, directory, status_paths,
isTestFilePredicate: (filename) => filename.endsWith('_test.dart'),
recursive: true);
}
@@ -823,11 +822,12 @@
}
void enqueueDirectory(Directory dir, FutureGroup group) {
- var lister = dir.list(recursive: listRecursively)
+ var lister = dir
+ .list(recursive: listRecursively)
.where((fse) => fse is File)
.forEach((File f) {
- enqueueFile(f.path, group);
- });
+ enqueueFile(f.path, group);
+ });
group.add(lister);
}
@@ -835,8 +835,8 @@
if (isHtmlTestFile(filename)) {
var info = htmlTest.getInformation(filename);
if (info == null) {
- DebugLogger.error(
- "HtmlTest $filename does not contain required annotations");
+ DebugLogger
+ .error("HtmlTest $filename does not contain required annotations");
return;
}
cachedTests.add(info);
@@ -852,11 +852,9 @@
if (optionsFromFile['isMultitest']) {
group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase));
} else {
- createTestCase(filePath,
- filePath,
- optionsFromFile['hasCompileError'],
- optionsFromFile['hasRuntimeError'],
- hasStaticWarning: optionsFromFile['hasStaticWarning']);
+ createTestCase(filePath, filePath, optionsFromFile['hasCompileError'],
+ optionsFromFile['hasRuntimeError'],
+ hasStaticWarning: optionsFromFile['hasStaticWarning']);
}
}
@@ -864,15 +862,13 @@
final existsCache = TestUtils.existsCache;
Path root = TestUtils.dartDir;
- assert ("$filePath".startsWith("$root"));
+ assert("$filePath".startsWith("$root"));
// We start with the parent directory of [filePath] and go up until
// the root directory (excluding the root).
- List<String> segments =
- filePath.directoryPath.relativeTo(root).segments();
+ List<String> segments = filePath.directoryPath.relativeTo(root).segments();
while (segments.length > 0) {
- var pubspecYamlPath =
- new Path(segments.join('/')).append('pubspec.yaml');
+ var pubspecYamlPath = new Path(segments.join('/')).append('pubspec.yaml');
if (existsCache.doesFileExist(pubspecYamlPath.toNativePath())) {
return root.join(pubspecYamlPath);
}
@@ -884,7 +880,7 @@
void enqueueTestCaseFromTestInformation(TestInformation info) {
String testName = buildTestCaseDisplayName(suiteDir, info.originTestPath,
multitestName:
- info.optionsFromFile['isMultitest'] ? info.multitestKey : "");
+ info.optionsFromFile['isMultitest'] ? info.multitestKey : "");
Set<Expectation> expectations = testExpectations.expectations(testName);
if (info is HtmlTestInformation) {
enqueueHtmlTest(info, testName, expectations);
@@ -898,8 +894,7 @@
var packageDir = pubspecYamlFile.directoryPath;
var packageName = packageDir.filename;
- var checkoutDirectory =
- createPubspecCheckoutDirectory(packageDir);
+ var checkoutDirectory = createPubspecCheckoutDirectory(packageDir);
var modifiedYamlFile = new Path(checkoutDirectory).append("pubspec.yaml");
var pubCacheDirectory = new Path(checkoutDirectory).append("pub-cache");
var newPackageRoot = new Path(checkoutDirectory).append("packages");
@@ -919,8 +914,8 @@
// NOTE: We make a link in the package-root to pkg/expect, since
// 'package:expect' is not available on pub.dartlang.org!
var expectLink = newPackageRoot.append('expect');
- var expectLinkTarget = TestUtils.dartDir
- .append('pkg').append('expect').append('lib');
+ var expectLinkTarget =
+ TestUtils.dartDir.append('pkg').append('expect').append('lib');
// Generate dependency overrides if we use repository packages.
var packageDirectories = {};
@@ -951,10 +946,7 @@
commands.add(CommandBuilder.instance.getMakeSymlinkCommand(
expectLink.toNativePath(), expectLinkTarget.toNativePath()));
- return {
- 'commands' : commands,
- 'package-root' : newPackageRoot,
- };
+ return {'commands': commands, 'package-root': newPackageRoot,};
}
// If this test is inside a package, we will check if there is a
@@ -1003,24 +995,21 @@
baseCommands, packageRoot, info, testName, expectations);
}
} else {
- enqueueStandardTest(
- baseCommands, info, testName, expectations);
+ enqueueStandardTest(baseCommands, info, testName, expectations);
}
}
- void enqueueStandardTest(List<Command> baseCommands,
- TestInformation info,
- String testName,
- Set<Expectation> expectations) {
- var commonArguments = commonArgumentsFromFile(info.filePath,
- info.optionsFromFile);
+ void enqueueStandardTest(List<Command> baseCommands, TestInformation info,
+ String testName, Set<Expectation> expectations) {
+ var commonArguments =
+ commonArgumentsFromFile(info.filePath, info.optionsFromFile);
List<List<String>> vmOptionsList = getVmOptions(info.optionsFromFile);
assert(!vmOptionsList.isEmpty);
for (var vmOptionsVarient = 0;
- vmOptionsVarient < vmOptionsList.length;
- vmOptionsVarient++) {
+ vmOptionsVarient < vmOptionsList.length;
+ vmOptionsVarient++) {
var vmOptions = vmOptionsList[vmOptionsVarient];
var allVmOptions = vmOptions;
if (!extraVmOptions.isEmpty) {
@@ -1028,15 +1017,11 @@
}
var commands = []..addAll(baseCommands);
- commands.addAll(makeCommands(info, vmOptionsVarient,
- allVmOptions, commonArguments));
- enqueueNewTestCase(
- new TestCase('$suiteName/$testName',
- commands,
- configuration,
- expectations,
- isNegative: isNegative(info),
- info: info));
+ commands.addAll(
+ makeCommands(info, vmOptionsVarient, allVmOptions, commonArguments));
+ enqueueNewTestCase(new TestCase(
+ '$suiteName/$testName', commands, configuration, expectations,
+ isNegative: isNegative(info), info: info));
}
}
@@ -1054,10 +1039,8 @@
return negative;
}
- List<Command> makeCommands(TestInformation info,
- int vmOptionsVarient,
- var vmOptions,
- var args) {
+ List<Command> makeCommands(
+ TestInformation info, int vmOptionsVarient, var vmOptions, var args) {
List<Command> commands = <Command>[];
CompilerConfiguration compilerConfiguration =
new CompilerConfiguration(configuration);
@@ -1066,10 +1049,8 @@
List<String> compileTimeArguments = <String>[];
String tempDir;
if (compilerConfiguration.hasCompiler) {
- compileTimeArguments =
- compilerConfiguration.computeCompilerArguments(vmOptions,
- sharedOptions,
- args);
+ compileTimeArguments = compilerConfiguration.computeCompilerArguments(
+ vmOptions, sharedOptions, args);
// Avoid doing this for analyzer.
var path = info.filePath;
if (vmOptionsVarient != 0) {
@@ -1101,38 +1082,38 @@
runtimeConfiguration,
buildDir,
info,
- vmOptions, sharedOptions, args,
+ vmOptions,
+ sharedOptions,
+ args,
compilationArtifact);
return commands
- ..addAll(
- runtimeConfiguration.computeRuntimeCommands(
- this,
- CommandBuilder.instance,
- compilationArtifact,
- runtimeArguments,
- environmentOverrides));
+ ..addAll(runtimeConfiguration.computeRuntimeCommands(
+ this,
+ CommandBuilder.instance,
+ compilationArtifact,
+ runtimeArguments,
+ environmentOverrides));
}
CreateTest makeTestCaseCreator(Map optionsFromFile) {
- return (Path filePath,
- Path originTestPath,
- bool hasCompileError,
- bool hasRuntimeError,
- {bool isNegativeIfChecked: false,
- bool hasCompileErrorIfChecked: false,
- bool hasStaticWarning: false,
- String multitestKey}) {
+ return (Path filePath, Path originTestPath, bool hasCompileError,
+ bool hasRuntimeError,
+ {bool isNegativeIfChecked: false,
+ bool hasCompileErrorIfChecked: false,
+ bool hasStaticWarning: false,
+ String multitestKey}) {
// Cache the test information for each test case.
- var info = new TestInformation(filePath,
- originTestPath,
- optionsFromFile,
- hasCompileError,
- hasRuntimeError,
- isNegativeIfChecked,
- hasCompileErrorIfChecked,
- hasStaticWarning,
- multitestKey: multitestKey);
+ var info = new TestInformation(
+ filePath,
+ originTestPath,
+ optionsFromFile,
+ hasCompileError,
+ hasRuntimeError,
+ isNegativeIfChecked,
+ hasCompileErrorIfChecked,
+ hasStaticWarning,
+ multitestKey: multitestKey);
cachedTests.add(info);
enqueueTestCaseFromTestInformation(info);
};
@@ -1179,15 +1160,16 @@
if (subtestName != null) {
parameters['group'] = subtestName;
}
- return new Uri(scheme: 'http',
- host: configuration['local_ip'],
- port: serverPort,
- path: pathComponent,
- queryParameters: parameters);
+ return new Uri(
+ scheme: 'http',
+ host: configuration['local_ip'],
+ port: serverPort,
+ path: pathComponent,
+ queryParameters: parameters);
}
- void _createWrapperFile(String dartWrapperFilename,
- Path localDartLibraryFilename) {
+ void _createWrapperFile(
+ String dartWrapperFilename, Path localDartLibraryFilename) {
File file = new File(dartWrapperFilename);
RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE);
@@ -1210,12 +1192,8 @@
* subTestName, Set<String>> if we are running a browser multi-test (one
* compilation and many browser runs).
*/
- void enqueueBrowserTest(
- List<Command> baseCommands,
- Path packageRoot,
- TestInformation info,
- String testName,
- expectations) {
+ void enqueueBrowserTest(List<Command> baseCommands, Path packageRoot,
+ TestInformation info, String testName, expectations) {
RegExp badChars = new RegExp('[-=/]');
List VmOptionsList = getVmOptions(info.optionsFromFile);
bool multipleOptions = VmOptionsList.length > 1;
@@ -1223,18 +1201,11 @@
String optionsName =
multipleOptions ? vmOptions.join('-').replaceAll(badChars, '') : '';
String tempDir = createOutputDirectory(info.filePath, optionsName);
- enqueueBrowserTestWithOptions(
- baseCommands,
- packageRoot,
- info,
- testName,
- expectations,
- vmOptions,
- tempDir);
+ enqueueBrowserTestWithOptions(baseCommands, packageRoot, info, testName,
+ expectations, vmOptions, tempDir);
}
}
-
void enqueueBrowserTestWithOptions(
List<Command> baseCommands,
Path packageRoot,
@@ -1337,13 +1308,8 @@
}
if (compiler != 'none') {
- commands.add(
- _compileCommand(
- dartWrapperFilename,
- compiledDartWrapperFilename,
- compiler,
- tempDir,
- optionsFromFile));
+ commands.add(_compileCommand(dartWrapperFilename,
+ compiledDartWrapperFilename, compiler, tempDir, optionsFromFile));
}
// some tests require compiling multiple input scripts.
@@ -1354,13 +1320,8 @@
Path fromPath = filePath.directoryPath.join(namePath);
if (compiler != 'none') {
assert(namePath.extension == 'dart');
- commands.add(
- _compileCommand(
- fromPath.toNativePath(),
- '$tempDir/$fileName.js',
- compiler,
- tempDir,
- optionsFromFile));
+ commands.add(_compileCommand(fromPath.toNativePath(),
+ '$tempDir/$fileName.js', compiler, tempDir, optionsFromFile));
}
if (compiler == 'none') {
// For the tests that require multiple input scripts but are not
@@ -1371,13 +1332,12 @@
}
}
-
// Variables for browser multi-tests.
bool multitest = info.optionsFromFile['isMultiHtmlTest'];
List<String> subtestNames =
multitest ? info.optionsFromFile['subtestNames'] : [null];
for (String subtestName in subtestNames) {
- // Construct the command that executes the browser test
+ // Construct the command that executes the browser test
List<Command> commandSet = new List<Command>.from(commands);
var htmlPath_subtest = _createUrlPathFromFile(new Path(htmlPath));
@@ -1400,42 +1360,29 @@
dartFlags.addAll(vmOptions);
}
- commandSet.add(
- CommandBuilder.instance.getContentShellCommand(
- contentShellFilename,
- fullHtmlPath,
- contentShellOptions,
- dartFlags,
- environmentOverrides));
+ commandSet.add(CommandBuilder.instance.getContentShellCommand(
+ contentShellFilename,
+ fullHtmlPath,
+ contentShellOptions,
+ dartFlags,
+ environmentOverrides));
} else {
- commandSet.add(
- CommandBuilder.instance.getBrowserTestCommand(
- runtime,
- fullHtmlPath,
- configuration,
- !isNegative(info)));
+ commandSet.add(CommandBuilder.instance.getBrowserTestCommand(
+ runtime, fullHtmlPath, configuration, !isNegative(info)));
}
// Create BrowserTestCase and queue it.
var fullTestName = multitest ? '$testName/$subtestName' : testName;
var expectation = multitest ? expectations[fullTestName] : expectations;
- var testCase = new BrowserTestCase(
- '$suiteName/$fullTestName',
- commandSet,
- configuration,
- expectation,
- info,
- isNegative(info),
- fullHtmlPath);
+ var testCase = new BrowserTestCase('$suiteName/$fullTestName', commandSet,
+ configuration, expectation, info, isNegative(info), fullHtmlPath);
enqueueNewTestCase(testCase);
}
}
void enqueueHtmlTest(
- HtmlTestInformation info,
- String testName,
- expectations) {
+ HtmlTestInformation info, String testName, expectations) {
final String compiler = configuration['compiler'];
final String runtime = configuration['runtime'];
// Html tests work only with the browser controller.
@@ -1475,19 +1422,15 @@
Uri script = testUri.resolveUri(uri);
Uri copiedScript = tempUri.resolveUri(uri);
if (compiler == 'none' || scriptPath.endsWith('.js')) {
- new File.fromUri(copiedScript).writeAsStringSync(
- new File.fromUri(script).readAsStringSync());
+ new File.fromUri(copiedScript)
+ .writeAsStringSync(new File.fromUri(script).readAsStringSync());
} else {
var destination = copiedScript.toFilePath();
if (compileToJS) {
destination = destination.replaceFirst(dartExtension, '.js');
}
- commands.add(_compileCommand(
- script.toFilePath(),
- destination,
- compiler,
- tempDir,
- info.optionsFromFile));
+ commands.add(_compileCommand(script.toFilePath(), destination,
+ compiler, tempDir, info.optionsFromFile));
}
}
}
@@ -1496,28 +1439,18 @@
var htmlPath = _createUrlPathFromFile(new Path(htmlFile.toFilePath()));
var fullHtmlPath = _getUriForBrowserTest(htmlPath, null).toString();
- commands.add(CommandBuilder.instance.getBrowserHtmlTestCommand(
- runtime,
- fullHtmlPath,
- configuration,
- info.expectedMessages,
- !isNegative(info)));
+ commands.add(CommandBuilder.instance.getBrowserHtmlTestCommand(runtime,
+ fullHtmlPath, configuration, info.expectedMessages, !isNegative(info)));
String testDisplayName = '$suiteName/$testName';
- var testCase = new BrowserTestCase(
- testDisplayName,
- commands,
- configuration,
- expectations,
- info,
- isNegative(info),
- fullHtmlPath);
+ var testCase = new BrowserTestCase(testDisplayName, commands, configuration,
+ expectations, info, isNegative(info), fullHtmlPath);
enqueueNewTestCase(testCase);
return;
}
/** Helper to create a compilation command for a single input file. */
- Command _compileCommand(String inputFile, String outputFile,
- String compiler, String dir, optionsFromFile) {
+ Command _compileCommand(String inputFile, String outputFile, String compiler,
+ String dir, optionsFromFile) {
assert(compiler == 'dart2js');
List<String> args;
if (compilerPath.endsWith('.dart')) {
@@ -1527,8 +1460,7 @@
args = [];
}
args.addAll(TestUtils.standardOptions(configuration));
- String packageRoot =
- packageRootArgument(optionsFromFile['packageRoot']);
+ String packageRoot = packageRootArgument(optionsFromFile['packageRoot']);
if (packageRoot != null) args.add(packageRoot);
String packages = packagesArgument(optionsFromFile['packages']);
if (packages != null) args.add(packages);
@@ -1537,22 +1469,31 @@
List<String> options = optionsFromFile['sharedOptions'];
if (options != null) args.addAll(options);
return CommandBuilder.instance.getCompilationCommand(
- compiler, outputFile, !useSdk,
- dart2JsBootstrapDependencies, compilerPath, args, environmentOverrides);
+ compiler,
+ outputFile,
+ !useSdk,
+ dart2JsBootstrapDependencies,
+ compilerPath,
+ args,
+ environmentOverrides);
}
/** Helper to create a Polymer deploy command for a single HTML file. */
- Command _polymerDeployCommand(String inputFile, String outputDir,
- optionsFromFile) {
+ Command _polymerDeployCommand(
+ String inputFile, String outputDir, optionsFromFile) {
List<String> args = [];
String packageRoot = packageRootArgument(optionsFromFile['packageRoot']);
if (packageRoot != null) args.add(packageRoot);
String packages = packagesArgument(optionsFromFile['packages']);
if (packages != null) args.add(packages);
- args..add('package:polymer/deploy.dart')
- ..add('--test')..add(inputFile)
- ..add('--out')..add(outputDir)
- ..add('--file-filter')..add('.svn');
+ args
+ ..add('package:polymer/deploy.dart')
+ ..add('--test')
+ ..add(inputFile)
+ ..add('--out')
+ ..add(outputDir)
+ ..add('--file-filter')
+ ..add('.svn');
if (configuration['csp']) args.add('--csp');
return CommandBuilder.instance.getProcessCommand(
@@ -1568,14 +1509,14 @@
return 'text/javascript';
default:
print('Non-web runtime, so no scriptType for: '
- '${configuration["compiler"]}');
+ '${configuration["compiler"]}');
exit(1);
return null;
}
}
bool get hasRuntime {
- switch(configuration['runtime']) {
+ switch (configuration['runtime']) {
case 'none':
return false;
default:
@@ -1614,7 +1555,7 @@
if (configuration["compiler"] == "dart2analyzer" &&
(filePath.filename.contains("dart2js") ||
- filePath.directoryPath.segments().last.contains('html_common'))) {
+ filePath.directoryPath.segments().last.contains('html_common'))) {
args.add("--use-dart2js-libraries");
}
@@ -1733,8 +1674,8 @@
RegExp packagesRegExp = new RegExp(r"// Packages=(.*)");
RegExp isolateStubsRegExp = new RegExp(r"// IsolateStubs=(.*)");
// TODO(gram) Clean these up once the old directives are not supported.
- RegExp domImportRegExp =
- new RegExp(r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
+ RegExp domImportRegExp = new RegExp(
+ r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
multiLine: true);
var bytes = new File(filePath.toNativePath()).readAsBytesSync();
@@ -1813,34 +1754,43 @@
List<String> subtestNames = [];
Iterator matchesIter =
multiHtmlTestGroupRegExp.allMatches(contents).iterator;
- while(matchesIter.moveNext() && isMultiHtmlTest) {
+ while (matchesIter.moveNext() && isMultiHtmlTest) {
String fullMatch = matchesIter.current.group(0);
subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
}
- return { "vmOptions": result,
- "sharedOptions": sharedOptions == null ? [] : sharedOptions,
- "dartOptions": dartOptions,
- "packageRoot": packageRoot,
- "packages": packages,
- "hasCompileError": false,
- "hasRuntimeError": false,
- "hasStaticWarning" : false,
- "otherScripts": otherScripts,
- "isMultitest": isMultitest,
- "isMultiHtmlTest": isMultiHtmlTest,
- "subtestNames": subtestNames,
- "isolateStubs": isolateStubs,
- "containsDomImport": containsDomImport };
+ return {
+ "vmOptions": result,
+ "sharedOptions": sharedOptions == null ? [] : sharedOptions,
+ "dartOptions": dartOptions,
+ "packageRoot": packageRoot,
+ "packages": packages,
+ "hasCompileError": false,
+ "hasRuntimeError": false,
+ "hasStaticWarning": false,
+ "otherScripts": otherScripts,
+ "isMultitest": isMultitest,
+ "isMultiHtmlTest": isMultiHtmlTest,
+ "subtestNames": subtestNames,
+ "isolateStubs": isolateStubs,
+ "containsDomImport": containsDomImport
+ };
}
List<List<String>> getVmOptions(Map optionsFromFile) {
var COMPILERS = const ['none', 'precompiler', 'dart2app'];
- var RUNTIMES = const ['none', 'dart_precompiled', 'dart_product', 'vm',
- 'drt', 'dartium',
- 'ContentShellOnAndroid', 'DartiumOnAndroid'];
+ var RUNTIMES = const [
+ 'none',
+ 'dart_precompiled',
+ 'dart_product',
+ 'vm',
+ 'drt',
+ 'dartium',
+ 'ContentShellOnAndroid',
+ 'DartiumOnAndroid'
+ ];
var needsVmOptions = COMPILERS.contains(configuration['compiler']) &&
- RUNTIMES.contains(configuration['runtime']);
+ RUNTIMES.contains(configuration['runtime']);
if (!needsVmOptions) return [[]];
final vmOptions = optionsFromFile['vmOptions'];
return vmOptions;
@@ -1861,8 +1811,8 @@
* environment variables, configuration files, etc.
*/
Map readOptionsFromCo19File(Path filePath) {
- String contents = decodeUtf8(new File(filePath.toNativePath())
- .readAsBytesSync());
+ String contents =
+ decodeUtf8(new File(filePath.toNativePath()).readAsBytesSync());
bool hasCompileError = contents.contains("@compile-error");
bool hasRuntimeError = contents.contains("@runtime-error");
@@ -1876,7 +1826,7 @@
"packageRoot": null,
"hasCompileError": hasCompileError,
"hasRuntimeError": hasRuntimeError,
- "hasStaticWarning" : hasStaticWarning,
+ "hasStaticWarning": hasStaticWarning,
"otherScripts": <String>[],
"isMultitest": isMultitest,
"isMultiHtmlTest": false,
@@ -1887,54 +1837,46 @@
}
}
-
/// Used for testing packages in on off settings, i.e., we pass in the actual
/// directory that we want to test.
class PKGTestSuite extends StandardTestSuite {
-
PKGTestSuite(Map configuration, Path directoryPath)
- : super(configuration,
- directoryPath.filename,
- directoryPath,
- ["$directoryPath/.status"],
- isTestFilePredicate: (f) => f.endsWith('_test.dart'),
- recursive: true);
+ : super(configuration, directoryPath.filename, directoryPath,
+ ["$directoryPath/.status"],
+ isTestFilePredicate: (f) => f.endsWith('_test.dart'),
+ recursive: true);
- void enqueueBrowserTest(List<Command> baseCommands,
- Path packageRoot,
- TestInformation info,
- String testName,
- expectations) {
- String runtime = configuration['runtime'];
- Path filePath = info.filePath;
- Path dir = filePath.directoryPath;
- String nameNoExt = filePath.filenameWithoutExtension;
- Path customHtmlPath = dir.append('$nameNoExt.html');
- File customHtml = new File(customHtmlPath.toNativePath());
- if (!customHtml.existsSync()) {
- super.enqueueBrowserTest(baseCommands, packageRoot,
- info, testName, expectations);
- } else {
- Path relativeHtml = customHtmlPath.relativeTo(TestUtils.dartDir);
- List<Command> commands = []..addAll(baseCommands);
- var fullPath = _createUrlPathFromFile(customHtmlPath);
+ void enqueueBrowserTest(List<Command> baseCommands, Path packageRoot,
+ TestInformation info, String testName, expectations) {
+ String runtime = configuration['runtime'];
+ Path filePath = info.filePath;
+ Path dir = filePath.directoryPath;
+ String nameNoExt = filePath.filenameWithoutExtension;
+ Path customHtmlPath = dir.append('$nameNoExt.html');
+ File customHtml = new File(customHtmlPath.toNativePath());
+ if (!customHtml.existsSync()) {
+ super.enqueueBrowserTest(
+ baseCommands, packageRoot, info, testName, expectations);
+ } else {
+ Path relativeHtml = customHtmlPath.relativeTo(TestUtils.dartDir);
+ List<Command> commands = []..addAll(baseCommands);
+ var fullPath = _createUrlPathFromFile(customHtmlPath);
- commands.add(CommandBuilder.instance.getBrowserTestCommand(
- runtime, fullPath, configuration, !isNegative(info)));
- String testDisplayName = '$suiteName/$testName';
- enqueueNewTestCase(new BrowserTestCase(testDisplayName,
- commands,
- configuration,
- expectations,
- info,
- isNegative(info),
- relativeHtml.toNativePath()));
-
- }
+ commands.add(CommandBuilder.instance.getBrowserTestCommand(
+ runtime, fullPath, configuration, !isNegative(info)));
+ String testDisplayName = '$suiteName/$testName';
+ enqueueNewTestCase(new BrowserTestCase(
+ testDisplayName,
+ commands,
+ configuration,
+ expectations,
+ info,
+ isNegative(info),
+ relativeHtml.toNativePath()));
}
+ }
}
-
/// A DartcCompilationTestSuite will run dartc on all of the tests.
///
/// Usually, the result of a dartc run is determined by the output of
@@ -1942,15 +1884,13 @@
class DartcCompilationTestSuite extends StandardTestSuite {
List<String> _testDirs;
- DartcCompilationTestSuite(Map configuration,
- String suiteName,
- String directoryPath,
- List<String> this._testDirs,
- List<String> expectations)
- : super(configuration,
- suiteName,
- new Path(directoryPath),
- expectations);
+ DartcCompilationTestSuite(
+ Map configuration,
+ String suiteName,
+ String directoryPath,
+ List<String> this._testDirs,
+ List<String> expectations)
+ : super(configuration, suiteName, new Path(directoryPath), expectations);
List<String> additionalOptions(Path filePath) {
return ['--fatal-warnings', '--fatal-type-errors'];
@@ -1970,14 +1910,10 @@
}
}
-
class AnalyzeLibraryTestSuite extends DartcCompilationTestSuite {
AnalyzeLibraryTestSuite(Map configuration)
- : super(configuration,
- 'analyze_library',
- 'sdk',
- ['lib'],
- ['tests/lib/analyzer/analyze_library.status']);
+ : super(configuration, 'analyze_library', 'sdk', ['lib'],
+ ['tests/lib/analyzer/analyze_library.status']);
List<String> additionalOptions(Path filePath, {bool showSdkWarnings}) {
var options = super.additionalOptions(filePath);
@@ -1996,24 +1932,25 @@
bool get listRecursively => true;
}
-
class PkgBuildTestSuite extends TestSuite {
final String statusFilePath;
PkgBuildTestSuite(Map configuration, String suiteName, this.statusFilePath)
: super(configuration, suiteName) {
- assert(configuration['use_sdk']);;
+ assert(configuration['use_sdk']);
+ ;
}
void forEachTest(void onTest(TestCase testCase), _, [void onDone()]) {
bool fileExists(Path path) => new File(path.toNativePath()).existsSync();
- bool dirExists(Path path)
- => new Directory(path.toNativePath()).existsSync();
+ bool dirExists(Path path) =>
+ new Directory(path.toNativePath()).existsSync();
- enqueueTestCases(Map<String, String> localPackageDirectories,
- Map<String, String> localSampleDirectories,
- TestExpectations testExpectations) {
+ enqueueTestCases(
+ Map<String, String> localPackageDirectories,
+ Map<String, String> localSampleDirectories,
+ TestExpectations testExpectations) {
enqueueTestCase(String packageName, String directory) {
var absoluteDirectoryPath = new Path(directory);
@@ -2022,8 +1959,7 @@
return;
}
- var directoryPath =
- absoluteDirectoryPath.relativeTo(TestUtils.dartDir);
+ var directoryPath = absoluteDirectoryPath.relativeTo(TestUtils.dartDir);
var testName = "$directoryPath";
var displayName = '$suiteName/$testName';
var packageName = directoryPath.filename;
@@ -2055,10 +1991,10 @@
var commands = new List<Command>();
commands.add(
CommandBuilder.instance.getCopyCommand(directory, checkoutDir));
- commands.add(CommandBuilder.instance.getModifyPubspecCommand(
- pubspecYamlFile, dependencyOverrides));
- commands.add(CommandBuilder.instance.getPubCommand(
- "get", pubPath, checkoutDir, cacheDir));
+ commands.add(CommandBuilder.instance
+ .getModifyPubspecCommand(pubspecYamlFile, dependencyOverrides));
+ commands.add(CommandBuilder.instance
+ .getPubCommand("get", pubPath, checkoutDir, cacheDir));
bool containsWebDirectory = dirExists(directoryPath.append('web'));
bool containsBuildDartFile =
@@ -2067,23 +2003,29 @@
var dartBinary = new File(dartVmBinaryFileName).absolute.path;
commands.add(CommandBuilder.instance.getProcessCommand(
- "custom_build", dartBinary, ['build.dart'],
- {'PUB_CACHE': cacheDir}, checkoutDir));
+ "custom_build",
+ dartBinary,
+ ['build.dart'],
+ {'PUB_CACHE': cacheDir},
+ checkoutDir));
// We only try to deploy the application if it's a webapp.
if (containsWebDirectory) {
commands.add(CommandBuilder.instance.getProcessCommand(
- "custom_deploy", dartBinary, ['build.dart', '--deploy'],
- {'PUB_CACHE': cacheDir}, checkoutDir));
+ "custom_deploy",
+ dartBinary,
+ ['build.dart', '--deploy'],
+ {'PUB_CACHE': cacheDir},
+ checkoutDir));
}
- } else if (containsWebDirectory) {
- commands.add(CommandBuilder.instance.getPubCommand(
- "build", pubPath, checkoutDir, cacheDir));
+ } else if (containsWebDirectory) {
+ commands.add(CommandBuilder.instance
+ .getPubCommand("build", pubPath, checkoutDir, cacheDir));
}
// Enqueue TestCase
- var testCase = new TestCase(displayName,
- commands, configuration, testExpectations.expectations(testName));
+ var testCase = new TestCase(displayName, commands, configuration,
+ testExpectations.expectations(testName));
enqueueNewTestCase(testCase);
}
@@ -2097,10 +2039,13 @@
doTest = onTest;
List<String> statusFiles = [
- TestUtils.dartDir.join(new Path(statusFilePath)).toNativePath()];
+ TestUtils.dartDir.join(new Path(statusFilePath)).toNativePath()
+ ];
ReadTestExpectations(statusFiles, configuration).then((expectations) {
- Future.wait([discoverPackagesInRepository(),
- discoverSamplesInRepository()]).then((List results) {
+ Future.wait([
+ discoverPackagesInRepository(),
+ discoverSamplesInRepository()
+ ]).then((List results) {
Map packageDirectories = results[0];
Map sampleDirectories = results[1];
enqueueTestCases(packageDirectories, sampleDirectories, expectations);
@@ -2109,7 +2054,6 @@
}
}
-
class LastModifiedCache {
Map<String, DateTime> _cache = <String, DateTime>{};
@@ -2135,7 +2079,6 @@
}
}
-
class ExistsCache {
Map<String, bool> _cache = <String, bool>{};
@@ -2152,7 +2095,6 @@
}
}
-
class TestUtils {
/**
* Any script using TestUtils must set dartDirUri to a file:// URI
@@ -2162,13 +2104,13 @@
dartDirUri = uri;
dartDir = new Path(uri.toFilePath());
}
+
static Random rand = new Random.secure();
static Uri dartDirUri;
static Path dartDir;
static LastModifiedCache lastModifiedCache = new LastModifiedCache();
static ExistsCache existsCache = new ExistsCache();
- static Path currentWorkingDirectory =
- new Path(Directory.current.path);
+ static Path currentWorkingDirectory = new Path(Directory.current.path);
/**
* Generates a random number.
@@ -2210,7 +2152,8 @@
* Assumes that the directory for [dest] already exists.
*/
static Future copyFile(Path source, Path dest) {
- return new File(source.toNativePath()).openRead()
+ return new File(source.toNativePath())
+ .openRead()
.pipe(new File(dest.toNativePath()).openWrite());
}
@@ -2240,13 +2183,14 @@
var native_path = new Path(path).toNativePath();
// Running this in a shell sucks, but rmdir is not part of the standard
// path.
- return Process.run('rmdir', ['/s', '/q', native_path], runInShell: true)
- .then((ProcessResult result) {
- if (result.exitCode != 0) {
- throw new Exception('Can\'t delete path $native_path. '
- 'This path might be too long');
- }
- });
+ return Process
+ .run('rmdir', ['/s', '/q', native_path], runInShell: true)
+ .then((ProcessResult result) {
+ if (result.exitCode != 0) {
+ throw new Exception('Can\'t delete path $native_path. '
+ 'This path might be too long');
+ }
+ });
} else {
var dir = new Directory(path);
return dir.delete(recursive: true);
@@ -2259,8 +2203,8 @@
var minified = configuration['minified'] ? '-minified' : '';
var csp = configuration['csp'] ? '-csp' : '';
var sdk = configuration['use_sdk'] ? '-sdk' : '';
- var packages = configuration['use_public_packages']
- ? '-public_packages' : '';
+ var packages =
+ configuration['use_public_packages'] ? '-public_packages' : '';
var dirName = "${configuration['compiler']}"
"$checked$minified$csp$packages$sdk";
String generatedPath = "${TestUtils.buildDir(configuration)}"
@@ -2328,8 +2272,7 @@
args.add("--categories=all");
}
}
- if ((compiler == "dart2js") &&
- configuration["minified"]) {
+ if ((compiler == "dart2js") && configuration["minified"]) {
args.add("--minify");
}
if (compiler == "dart2js" && configuration["csp"]) {
@@ -2415,7 +2358,7 @@
var crossDir = new Directory(new Path('$outDir$cross').toNativePath());
if (normalDir.existsSync() && crossDir.existsSync()) {
throw "You can't have both $normalDir and $crossDir, we don't know which"
- " binary to use";
+ " binary to use";
}
if (crossDir.existsSync()) {
return cross;
@@ -2468,7 +2411,6 @@
"tests_co19_src_WebPlatformTest_html_semantics_embedded-content_"
"media-elements_": "co19_media_elements",
"tests_co19_src_WebPlatformTest_html_semantics_": "co19_semantics_",
-
"tests_co19_src_WebPlatformTest_html-templates_additions-to-"
"the-steps-to-clone-a-node_": "co19_htmltemplates_clone_",
"tests_co19_src_WebPlatformTest_html-templates_definitions_"
@@ -2486,7 +2428,6 @@
"tests_co19_src_WebPlatformTest_html-templates_template-element"
"_template-": "co19_htmltemplates_element-",
"tests_co19_src_WebPlatformTest_html-templates_": "co19_htmltemplate_",
-
"tests_co19_src_WebPlatformTest_shadow-dom_shadow-trees_":
"co19_shadow-trees_",
"tests_co19_src_WebPlatformTest_shadow-dom_elements-and-dom-objects_":
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index d000994..fd2245e 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -14,7 +14,7 @@
const Duration MAX_STDIO_DELAY = const Duration(seconds: 30);
String MAX_STDIO_DELAY_PASSED_MESSAGE =
-"""Not waiting for stdout/stderr from subprocess anymore
+ """Not waiting for stdout/stderr from subprocess anymore
($MAX_STDIO_DELAY passed). Please note that this could be an indicator
that there is a hanging process which we were unable to kill.""";
@@ -46,6 +46,7 @@
// if (trace != null) msg += "\nStackTrace: $trace";
return msg;
}
+
static void info(String msg, [error]) {
msg = _formatErrorMessage(msg, error);
_print("$_datetime Info: $msg");
@@ -88,13 +89,12 @@
if (newLine) buffer.write("\n");
}
- prettifyJsonInternal(
- Object obj, {bool indentation: true, bool newLine: true}) {
+ prettifyJsonInternal(Object obj,
+ {bool indentation: true, bool newLine: true}) {
if (obj is List) {
addString("[", indentation: indentation);
currentIndentation += shiftWidth;
for (var item in obj) {
-
prettifyJsonInternal(item, indentation: indentation, newLine: false);
addString(",", indentation: false);
}
@@ -119,7 +119,6 @@
return buffer.toString();
}
-
/**
* [areByteArraysEqual] compares a range of bytes from [buffer1] with a
* range of bytes from [buffer2].
@@ -129,9 +128,8 @@
* [offset2]).
* Otherwise [false] is returned.
*/
-bool areByteArraysEqual(List<int> buffer1, int offset1,
- List<int> buffer2, int offset2,
- int count) {
+bool areByteArraysEqual(
+ List<int> buffer1, int offset1, List<int> buffer2, int offset2, int count) {
if ((offset1 + count) > buffer1.length ||
(offset2 + count) > buffer2.length) {
return false;
@@ -151,7 +149,7 @@
* Returns [true] if [pattern] was found in [data].
* Otherwise [false] is returned.
*/
-int findBytes(List<int> data, List<int> pattern, [int startPos=0]) {
+int findBytes(List<int> data, List<int> pattern, [int startPos = 0]) {
// TODO(kustermann): Use one of the fast string-matching algorithms!
for (int i = startPos; i < (data.length - pattern.length); i++) {
bool found = true;
@@ -180,47 +178,47 @@
}
class Locations {
- static String getBrowserLocation(String browserName,
- Map globalConfiguration) {
+ static String getBrowserLocation(
+ String browserName, Map globalConfiguration) {
var location = globalConfiguration[browserName];
if (location != null && location != '') {
return location;
}
var browserLocations = {
- 'firefox': const {
- 'windows': 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
- 'linux': 'firefox',
- 'macos': '/Applications/Firefox.app/Contents/MacOS/firefox'
- },
- 'chrome': const {
- 'windows':
+ 'firefox': const {
+ 'windows': 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
+ 'linux': 'firefox',
+ 'macos': '/Applications/Firefox.app/Contents/MacOS/firefox'
+ },
+ 'chrome': const {
+ 'windows':
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
- 'macos':
- '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
- 'linux': 'google-chrome'
- },
- 'dartium': const {
- 'windows': 'client\\tests\\dartium\\chrome.exe',
- 'macos': 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium',
- 'linux': 'client/tests/dartium/chrome'
- },
- 'safari': const {
- 'macos': '/Applications/Safari.app/Contents/MacOS/Safari'
- },
- 'safarimobilesim': const {
- 'macos': '/Applications/Xcode.app/Contents/Developer/Platforms/'
- 'iPhoneSimulator.platform/Developer/Applications/'
- 'iPhone Simulator.app/Contents/MacOS/iPhone Simulator'
- },
- 'ie9': const {
- 'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
- },
- 'ie10': const {
- 'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
- },
- 'ie11': const {
- 'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
- }};
+ 'macos': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
+ 'linux': 'google-chrome'
+ },
+ 'dartium': const {
+ 'windows': 'client\\tests\\dartium\\chrome.exe',
+ 'macos': 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium',
+ 'linux': 'client/tests/dartium/chrome'
+ },
+ 'safari': const {
+ 'macos': '/Applications/Safari.app/Contents/MacOS/Safari'
+ },
+ 'safarimobilesim': const {
+ 'macos': '/Applications/Xcode.app/Contents/Developer/Platforms/'
+ 'iPhoneSimulator.platform/Developer/Applications/'
+ 'iPhone Simulator.app/Contents/MacOS/iPhone Simulator'
+ },
+ 'ie9': const {
+ 'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
+ },
+ 'ie10': const {
+ 'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
+ },
+ 'ie11': const {
+ 'windows': 'C:\\Program Files\\Internet Explorer\\iexplore.exe'
+ }
+ };
browserLocations['ff'] = browserLocations['firefox'];
assert(browserLocations[browserName] != null);
@@ -246,12 +244,15 @@
int _value = 0;
void add(Object object) {
- _value = ((_value * 31) ^ object.hashCode) & 0x3FFFFFFF;
+ _value = ((_value * 31) ^ object.hashCode) & 0x3FFFFFFF;
}
void addJson(Object object) {
- if (object == null || object is num || object is String ||
- object is Uri || object is bool) {
+ if (object == null ||
+ object is num ||
+ object is String ||
+ object is Uri ||
+ object is bool) {
add(object);
} else if (object is List) {
object.forEach(addJson);
@@ -304,7 +305,7 @@
final int _hashCode;
int get hashCode => _hashCode;
- operator==(other) => other is UniqueObject && _hashCode == other._hashCode;
+ operator ==(other) => other is UniqueObject && _hashCode == other._hashCode;
UniqueObject() : _hashCode = ++_nextId;
}
diff --git a/tools/testing/dart/vm_test_config.dart b/tools/testing/dart/vm_test_config.dart
index 9fdf36b..9cadd4fc 100644
--- a/tools/testing/dart/vm_test_config.dart
+++ b/tools/testing/dart/vm_test_config.dart
@@ -8,9 +8,7 @@
class VMTestSuite extends CCTestSuite {
VMTestSuite(Map configuration)
- : super(configuration,
- "vm",
- "run_vm_tests",
- ["runtime/tests/vm/vm.status"],
- testPrefix: 'cc/');
+ : super(
+ configuration, "vm", "run_vm_tests", ["runtime/tests/vm/vm.status"],
+ testPrefix: 'cc/');
}