From 8fb0ba09b2394bc4a6b770b57c689eef22bf6797 Mon Sep 17 00:00:00 2001 From: Claire Sarsam Date: Thu, 12 Jan 2017 09:58:59 -0700 Subject: [PATCH] Address CR feedback Revert formatting/content changes that shouldn't have been merged in --- lib/src/component/resize_sensor.dart | 7 +- .../component_declaration/component_base.dart | 32 +++--- .../component_declaration/flux_component.dart | 82 ++++++++------ .../transformer_helpers.dart | 46 +++----- lib/src/util/document_event_helper_util.dart | 16 --- lib/src/util/js_util.dart | 14 --- lib/src/util/react_wrappers.dart | 6 -- lib/src/util/rem_util.dart | 1 + lib/src/util/test_mode.dart | 1 + .../handler_precedence.dart | 4 +- .../flux_component_test/store_handlers.dart | 4 +- .../accessor_mixin_integration_test.dart | 6 +- .../util/handler_chain_util_test.dart | 100 ------------------ test/over_react/util/rem_util_test.dart | 38 ++++--- 14 files changed, 115 insertions(+), 242 deletions(-) delete mode 100644 lib/src/util/document_event_helper_util.dart delete mode 100644 lib/src/util/js_util.dart diff --git a/lib/src/component/resize_sensor.dart b/lib/src/component/resize_sensor.dart index 4749d3b12..df120969f 100644 --- a/lib/src/component/resize_sensor.dart +++ b/lib/src/component/resize_sensor.dart @@ -15,6 +15,7 @@ /// Thanks! /// https://github.com/marcj/css-element-queries/blob/master/src/ResizeSensor.js library resize_sensor; + import 'dart:collection'; import 'dart:html'; @@ -78,7 +79,6 @@ class ResizeSensorComponent extends UiComponent { Element _expandSensorChildRef; Element _expandSensorRef; - Element _collapseSensorChildRef; Element _collapseSensorRef; @override @@ -111,10 +111,7 @@ class ResizeSensorComponent extends UiComponent { ..key = 'expandSensor' )(expandSensorChild); - var collapseSensorChild = (Dom.div() - ..ref = (ref) { _collapseSensorChildRef = ref; } - ..style = _collapseSensorChildStyle - )(); + var collapseSensorChild = (Dom.div()..style = _collapseSensorChildStyle)(); var collapseSensor = (Dom.div() ..className = 'resize-sensor-collapse' diff --git a/lib/src/component_declaration/component_base.dart b/lib/src/component_declaration/component_base.dart index b4458cb77..4362a06ab 100644 --- a/lib/src/component_declaration/component_base.dart +++ b/lib/src/component_declaration/component_base.dart @@ -86,20 +86,14 @@ typedef TProps UiFactory([Map backingProps]); /// For use as a Function variable type when the `backingProps` argument is not required. typedef TProps BuilderOnlyUiFactory(); -typedef dynamic _RefTypedef(String ref); - -/// The basis for a over_react component, extending [react.Component]. (Successor to [BaseComponent]). +/// The basis for a over_react component. /// /// Includes support for strongly-typed props and utilities for prop and CSS classname forwarding. +/// +/// Extends [react.Component]. +/// +/// Related: [UiStatefulComponent] abstract class UiComponent extends react.Component { - /// Returns the component of the specified [ref]. - /// > `react.Component` if it is a Dart component - /// > DOM node if it is a DOM component. - /// - /// Overridden for strong typing. - @override - _RefTypedef get ref => super.ref; - /// The props for the non-forwarding props defined in this component. Iterable get consumedProps => null; @@ -131,12 +125,12 @@ abstract class UiComponent extends react.Component { void validateRequiredProps(Map appliedProps) { consumedProps?.forEach((ConsumedProps consumedProps) { consumedProps.props.forEach((PropDescriptor prop) { - if (!prop.isRequired) return; - if (prop.isNullable && appliedProps.containsKey(prop.key)) return; - if (!prop.isNullable && appliedProps[prop.key] != null) return; + if (!prop.isRequired) return; + if (prop.isNullable && appliedProps.containsKey(prop.key)) return; + if (!prop.isNullable && appliedProps[prop.key] != null) return; - throw new PropError.required(prop.key, prop.errorMessage); - }); + throw new PropError.required(prop.key, prop.errorMessage); + }); }); } @@ -203,11 +197,11 @@ abstract class UiComponent extends react.Component { // ---------------------------------------------------------------------- } -/// /// The basis for a stateful over_react component. +/// The basis for a stateful over_react component. /// /// Includes support for strongly-typed props and state and utilities for prop and CSS classname forwarding. /// -/// Extends [react.Component] +/// Extends [react.Component]. /// /// Related: [UiComponent] abstract class UiStatefulComponent extends UiComponent { @@ -240,10 +234,12 @@ abstract class UiStatefulComponent super.state = value; /// Returns a typed state object backed by the specified [stateMap]. + /// /// Required to properly instantiate the generic [TState] class. TState typedStateFactory(Map stateMap); /// Returns a typed state object backed by a new Map. + /// /// Convenient for use with [getInitialState] and [setState]. TState newState() => typedStateFactory({}); diff --git a/lib/src/component_declaration/flux_component.dart b/lib/src/component_declaration/flux_component.dart index 0bdc7a71e..09d1c938a 100644 --- a/lib/src/component_declaration/flux_component.dart +++ b/lib/src/component_declaration/flux_component.dart @@ -1,3 +1,17 @@ +// Copyright 2016 Workiva Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + library over_react.component_declaration.flux_component; import 'dart:async'; @@ -21,13 +35,13 @@ abstract class FluxUiProps extends UiProps { ActionsT get actions => props[_actionsPropKey] as ActionsT; // ignore: avoid_as set actions(ActionsT value) => props[_actionsPropKey] = value; - /// The prop defined by [StoresT]. This object should either be an - /// instance of [Store] or should provide access to one or more [Store]s. + /// The prop defined by [StoresT]. + /// + /// This object should either be an instance of [Store] or should provide access to one or more [Store]s. /// - /// **Instead of storing state within this component via [setState], it is - /// recommended that data be pulled directly from these stores.** This ensures - /// that the data being used is always up to date and leaves the state - /// management logic to the stores. + /// __Instead of storing state within this component via `setState`, it is recommended that data be + /// pulled directly from these stores.__ This ensures that the data being used is always up to date + /// and leaves the state management logic to the stores. /// /// If this component only needs data from a single [Store], then [StoresT] /// should be an instance of [Store]. This allows the default implementation @@ -36,28 +50,30 @@ abstract class FluxUiProps extends UiProps { /// If this component needs data from multiple [Store] instances, then /// [StoresT] should be a class that provides access to these multiple stores. /// Then, you can explicitly select the [Store] instances that should be - /// listened to by overriding [redrawOn]. + /// listened to by overriding [_FluxComponentMixin.redrawOn]. StoresT get store => props[_storePropKey] as StoresT; // ignore: avoid_as set store(StoresT value) => props[_storePropKey] = value; } /// Builds on top of [UiComponent], adding w_flux integration, much like the [FluxComponent] in w_flux. /// -/// Flux components are responsible for rendering application views and turning -/// user interactions and events into [Action]s. Flux components can use data -/// from one or many [Store] instances to define the resulting component. +/// * Flux components are responsible for rendering application views and turning +/// user interactions and events into [Action]s. +/// * Flux components can use data from one or many [Store] instances to define +/// the resulting component. /// -/// Use with the over_react transformer via the `@Component()` ([Component]) annotation. +/// Use with the over_react transformer via the `@Component()` ([annotations.Component]) annotation. abstract class FluxUiComponent extends UiComponent with _FluxComponentMixin, BatchedRedraws {} -/// Builds on top of [StatefulUiComponent], adding w_flux integration, much like the [FluxComponent] in w_flux. +/// Builds on top of [UiStatefulComponent], adding `w_flux` integration, much like the [FluxComponent] in w_flux. /// -/// Flux components are responsible for rendering application views and turning -/// user interactions and events into [Action]s. Flux components can use data -/// from one or many [Store] instances to define the resulting component. +/// * Flux components are responsible for rendering application views and turning +/// user interactions and events into [Action]s. +/// * Flux components can use data from one or many [Store] instances to define +/// the resulting component. /// -/// Use with the over_react transformer via the `@Component()` ([Component]) annotation. +/// Use with the over_react transformer via the `@Component()` ([annotations.Component]) annotation. abstract class FluxUiStatefulComponent extends UiStatefulComponent with _FluxComponentMixin, BatchedRedraws {} @@ -68,15 +84,19 @@ abstract class FluxUiStatefulComponent implements BatchedRedraws { TProps get props; - /// List of store subscriptions created when the component mounts. These - /// subscriptions are canceled when the component is unmounted. + /// List of store subscriptions created when the component mounts. + /// + /// These subscriptions are canceled when the component is unmounted. List _subscriptions = []; - componentWillMount() { - // Subscribe to all applicable stores. Stores returned by `redrawOn()` will - // have their triggers mapped directly to this components redraw function. - // Stores included in the `getStoreHandlers()` result will be listened to - // and wired up to their respective handlers. + void componentWillMount() { + /// Subscribe to all applicable stores. + /// + /// [Store]s returned by [redrawOn] will have their triggers mapped directly to this components + /// redraw function. + /// + /// [Store]s included in the [getStoreHandlers] result will be listened to and wired up to their + /// respective handlers. Map handlers = new Map.fromIterable(redrawOn(), value: (_) => (_) => redraw())..addAll(getStoreHandlers()); @@ -86,8 +106,8 @@ abstract class _FluxComponentMixin implements Batche }); } - componentWillUnmount() { - // ensure that unmounted components don't batch render + void componentWillUnmount() { + // Ensure that unmounted components don't batch render shouldBatchRedraw = false; // Cancel all store subscriptions. @@ -99,6 +119,7 @@ abstract class _FluxComponentMixin implements Batche } /// Define the list of [Store] instances that this component should listen to. + /// /// When any of the returned [Store]s update their state, this component will /// redraw. /// @@ -121,8 +142,9 @@ abstract class _FluxComponentMixin implements Batche } /// If you need more fine-grained control over store trigger handling, - /// override this method to return a Map of stores to handlers. Whenever a - /// store in the returned map triggers, the respective handler will be called. + /// override this method to return a Map of stores to handlers. + /// + /// Whenever a store in the returned map triggers, the respective handler will be called. /// /// Handlers defined here take precedence over the [redrawOn] handling. /// If possible, however, [redrawOn] should be used instead of this in order @@ -132,9 +154,9 @@ abstract class _FluxComponentMixin implements Batche return {}; } - /// Register a [subscription] that should be canceled when the component - /// unmounts. Cancellation will be handled automatically by - /// [componentWillUnmount]. + /// Register a [subscription] that should be canceled when the component unmounts. + /// + /// Cancellation will be handled automatically by [componentWillUnmount]. void addSubscription(StreamSubscription subscription) { _subscriptions.add(subscription); } diff --git a/lib/src/component_declaration/transformer_helpers.dart b/lib/src/component_declaration/transformer_helpers.dart index 4ea5159ba..2973c62ad 100644 --- a/lib/src/component_declaration/transformer_helpers.dart +++ b/lib/src/component_declaration/transformer_helpers.dart @@ -21,8 +21,6 @@ export './annotations.dart'; export './component_base.dart' hide UiComponent, UiStatefulComponent, UiProps, UiState; -typedef dynamic _RefTypedef(String ref); - // ---------------------------------------------------------------------- // Helpers and extras consumable by generated code and consumers of // generated code. @@ -88,32 +86,22 @@ class GeneratedClass { } -/// The basis for a over_react component, extending [react.Component]. (Successor to [BaseComponent]). -/// -/// Includes support for strongly-typed props and utilities for prop and CSS classname forwarding. +/// See: [component_base.UiComponent] /// -/// Use with the over_react transformer via the `@Component()` ([Component]) annotation. +/// Use with the over_react transformer via the `@Component()` ([annotations.Component]) annotation. abstract class UiComponent extends component_base.UiComponent with GeneratedClass { /// This class should not be instantiated directly, and throws an error to indicate this. UiComponent() { _throwIfNotGenerated(); } - /// Returns the component of the specified [ref]. - /// > `react.Component` if it is a Dart component - /// > DOM node if it is a DOM component. - /// - /// Overridden for strong typing. - @override - _RefTypedef get ref => super.ref; - - /// The default consumed props, taken from the keys generated in the associated @[Props] class. + /// The default consumed props, taken from the keys generated in the associated @[annotations.Props] class. @toBeGenerated Iterable get $defaultConsumedProps => throw new UngeneratedError(member: #$defaultConsumedProps); /// The keys for the non-forwarding props defined in this component. /// - /// For generated components, this defaults to the keys generated in the associated @[Props] class + /// For generated components, this defaults to the keys generated in the associated @[annotations.Props] class /// if this getter is not overridden. @override Iterable get consumedProps => $defaultConsumedProps; @@ -126,11 +114,9 @@ abstract class UiComponent extends component_base.UiComp } -/// The basis for a stateful over_react component, extending [react.Component]. (Successor to [BaseComponentWithState]). -/// -/// Includes support for strongly-typed props and state and utilities for prop and CSS classname forwarding. +/// See: [component_base.UiStatefulComponent] /// -/// Use with the over_react transformer via the `@Component()` ([Component]) annotation. +/// Use with the over_react transformer via the `@Component()` ([annotations.Component]) annotation. abstract class UiStatefulComponent extends component_base.UiStatefulComponent with GeneratedClass { /// This class should not be instantiated directly, and throws an error to indicate this. @@ -138,32 +124,26 @@ abstract class UiStatefulComponent `react.Component` if it is a Dart component - /// > DOM node if it is a DOM component. - /// - /// Overridden for strong typing. - @override - _RefTypedef get ref => super.ref; - - /// The default consumed prop keys, taken from the keys generated in the associated @[Props] class. + /// The default consumed prop keys, taken from the keys generated in the associated @[annotations.Props] class. @toBeGenerated Iterable get $defaultConsumedProps => throw new UngeneratedError(member: #$defaultConsumedProps); /// The keys for the non-forwarding props defined in this component. /// - /// For generated components, this defaults to the keys generated in the associated @[Props] class + /// For generated components, this defaults to the keys generated in the associated @[annotations.Props] class /// if this getter is not overridden. @override Iterable get consumedProps => $defaultConsumedProps; /// Returns a typed props object backed by the specified [propsMap]. + /// /// Required to properly instantiate the generic [TProps] class. @override @toBeGenerated TProps typedPropsFactory(Map propsMap) => throw new UngeneratedError(member: #typedPropsFactory); /// Returns a typed state object backed by the specified [stateMap]. + /// /// Required to properly instantiate the generic [TState] class. @override @toBeGenerated TState typedStateFactory(Map stateMap) => throw new UngeneratedError(member: #typedStateFactory); } @@ -171,10 +151,10 @@ abstract class UiStatefulComponent _document; - static set document(html.HtmlDocument value) { - // TODO add `.fromEnvironment` check for warning when not testing. - _document = value; - } -} diff --git a/lib/src/util/js_util.dart b/lib/src/util/js_util.dart deleted file mode 100644 index 57e30f963..000000000 --- a/lib/src/util/js_util.dart +++ /dev/null @@ -1,14 +0,0 @@ -library over_react.js_util; - -import 'dart:js'; - -/// [Global JavaScript Array Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) -JsObject jsArray = context['Array']; - -/// Store a helper reference to the global [jsArray]'s [`slice` method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) -JsObject arrayProtoSlice = jsArray['prototype']['slice']; - -/// Converts the Array-like [object] to a [JsArray] using [arrayProtoSlice]. -JsArray convertToArray(JsObject object) { - return arrayProtoSlice.callMethod('apply', [object]); -} diff --git a/lib/src/util/react_wrappers.dart b/lib/src/util/react_wrappers.dart index c3b183c82..6d3fe162c 100644 --- a/lib/src/util/react_wrappers.dart +++ b/lib/src/util/react_wrappers.dart @@ -222,12 +222,6 @@ ReactElement cloneElement(ReactElement element, [Map props, Iterable children]) } } -/// Returns whether the React [instance] is mounted. -/// -/// Deprecated: Simply call `isMounted` on the [ReactComponent] instead. -@Deprecated('2.0.0') -bool isMounted(ReactComponent instance) => instance.isMounted(); - /// Returns the native Dart component associated with a React JS component instance, or null if the component is not Dart-based. react.Component getDartComponent(/* [1] */ instance) { if (instance is Element) { diff --git a/lib/src/util/rem_util.dart b/lib/src/util/rem_util.dart index 419f0ce6a..10dfd8ba0 100644 --- a/lib/src/util/rem_util.dart +++ b/lib/src/util/rem_util.dart @@ -21,6 +21,7 @@ import 'dart:html'; import 'package:over_react/over_react.dart'; import 'package:over_react/src/util/css_value_util.dart'; import 'package:react/react_dom.dart' as react_dom; + double _computeRootFontSize() { return new CssValue.parse(document.documentElement.getComputedStyle().fontSize).number.toDouble(); } diff --git a/lib/src/util/test_mode.dart b/lib/src/util/test_mode.dart index 6cc25b42a..11d81ec5d 100644 --- a/lib/src/util/test_mode.dart +++ b/lib/src/util/test_mode.dart @@ -13,6 +13,7 @@ // limitations under the License. library over_react.test_mode; + import 'package:over_react/src/component_declaration/component_base.dart' as component_base; /// Enables test mode. diff --git a/test/over_react/component_declaration/flux_component_test/handler_precedence.dart b/test/over_react/component_declaration/flux_component_test/handler_precedence.dart index 803f63ce3..28b182b7a 100644 --- a/test/over_react/component_declaration/flux_component_test/handler_precedence.dart +++ b/test/over_react/component_declaration/flux_component_test/handler_precedence.dart @@ -7,7 +7,7 @@ UiFactory TestHandlerPrecedence; class TestHandlerPrecedenceProps extends FluxUiProps {} @Component() -class TestHandlerPrecedenceComponent extends FluxUiComponent { +class TestHandlerPrecedenceComponent extends FluxUiComponent { int numberOfRedraws = 0; int numberOfHandlerCalls = 0; @@ -20,7 +20,7 @@ class TestHandlerPrecedenceComponent extends FluxUiComponent { @override getStoreHandlers() => {props.store.store1: increment}; - increment(_) { + increment(Store store) { numberOfHandlerCalls += 1; } diff --git a/test/over_react/component_declaration/flux_component_test/store_handlers.dart b/test/over_react/component_declaration/flux_component_test/store_handlers.dart index dd81431a7..04a42490b 100644 --- a/test/over_react/component_declaration/flux_component_test/store_handlers.dart +++ b/test/over_react/component_declaration/flux_component_test/store_handlers.dart @@ -7,7 +7,7 @@ UiFactory TestStoreHandlers; class TestStoreHandlersProps extends FluxUiProps {} @Component() -class TestStoreHandlersComponent extends FluxUiComponent { +class TestStoreHandlersComponent extends FluxUiComponent { int numberOfHandlerCalls = 0; @override @@ -16,7 +16,7 @@ class TestStoreHandlersComponent extends FluxUiComponent { @override getStoreHandlers() => {props.store: increment}; - increment(_) { + increment(Store store) { numberOfHandlerCalls += 1; } } diff --git a/test/over_react/component_declaration/transformer_integration_tests/accessor_mixin_integration_test.dart b/test/over_react/component_declaration/transformer_integration_tests/accessor_mixin_integration_test.dart index 877c8c28b..1cbda5cf7 100644 --- a/test/over_react/component_declaration/transformer_integration_tests/accessor_mixin_integration_test.dart +++ b/test/over_react/component_declaration/transformer_integration_tests/accessor_mixin_integration_test.dart @@ -50,7 +50,7 @@ main() { }); }); - group('generates prop getters/setters, when there is a custom key namespace, with', () { + group('generates prop getters/setters, when there is a custom key namespace, with', () { test('the custom namespace and the prop name as the key by default', () { var mixinsTest; @@ -81,7 +81,7 @@ main() { }); }); - group('@StateMixin()', () { + group('@StateMixin()', () { group('generates state getters/setters with', () { test('the state class name as a namespace and the state name as the key by default', () { var mixinsTest; @@ -112,7 +112,7 @@ main() { }); }); - group('generates state getters/setters, when there is a custom key namespace, with', () { + group('generates state getters/setters, when there is a custom key namespace, with', () { test('the custom namespace and the state name as the key by default', () { var mixinsTest; diff --git a/test/over_react/util/handler_chain_util_test.dart b/test/over_react/util/handler_chain_util_test.dart index ebb52a03a..6d445a809 100644 --- a/test/over_react/util/handler_chain_util_test.dart +++ b/test/over_react/util/handler_chain_util_test.dart @@ -279,106 +279,6 @@ main() { sharedTests(const CallbackUtil3Arg(), 3); }); }); - - group('React DOM event callback creation utility function', () { - callsBothFunctions(Function creator) { - bool calledA = false, calledB = false; - Function a = (event) => calledA = true; - Function b = (event) => calledB = true; - - var chainedCallback = creator(a, b); - var result = chainedCallback(null); - - expect(calledA, isTrue); - expect(calledB, isTrue); - - expect(result, isNull); - } - - callsFunctionsInOrder(Function creator) { - int counter = 1; - bool calledA = false, calledB = false; - Function a = (event) { - calledA = true; - expect(counter, equals(1)); - counter++; - }; - Function b = (event) { - calledB = true; - expect(counter, equals(2)); - }; - - var chainedCallback = creator(a, b); - chainedCallback(null); - - expect(calledA, isTrue); - expect(calledB, isTrue); - } - - returnsFalseWhenAReturnsFalse(Function creator) { - Function a = (event) => false; - Function b = (event) => true; - - var chainedCallback = creator(a, b); - var result = chainedCallback(null); - - expect(result, isFalse); - } - - returnsFalseWhenBReturnsFalse(Function creator) { - Function a = (event) => true; - Function b = (event) => false; - - var chainedCallback = creator(a, b); - var result = chainedCallback(null); - - expect(result, isFalse); - } - - returnsFalseWhenBothReturnFalse(Function creator) { - Function a = (event) => false; - Function b = (event) => false; - - var chainedCallback = creator(a, b); - var result = chainedCallback(null); - - expect(result, isFalse); - } - - returnsNullWhenNeitherReturnFalse(Function creator) { - Function a = (event) => true; - Function b = (event) => true; - - var chainedCallback = creator(a, b); - var result = chainedCallback(null); - - expect(result, isNull); - } - - handlesNullParameters(Function creator) { - bool flag = false; - Function callback = (event) => flag = true; - var chainedCallback, result; - - chainedCallback = creator(callback, null); - chainedCallback(null); - expect(flag, isTrue, reason: 'The first callback should be called when the second callback is null'); - - flag = false; - - chainedCallback = creator(null, callback); - chainedCallback(null); - expect(flag, isTrue, reason: 'The second callback should be called when the first callback is null'); - - chainedCallback = creator(null, null); - try { - result = chainedCallback(null); - expect(result, isNull); - } catch (exception) { - fail(exception); - } - } - }); }); } diff --git a/test/over_react/util/rem_util_test.dart b/test/over_react/util/rem_util_test.dart index e558b0d2e..f4d02d51b 100644 --- a/test/over_react/util/rem_util_test.dart +++ b/test/over_react/util/rem_util_test.dart @@ -167,18 +167,30 @@ main() { ); }); - test('throws when passed a CSS value string with a unit other than px/rem', () { - expect(() => toPx('1em'), allOf( - throwsArgumentError, - throwsA(hasToStringValue(contains('must be a rem num or a String px/rem value')))) - ); + group('throws when passed a CSS value string with a unit other than px/rem', () { + test('', () { + expect(() => toPx('1em'), allOf( + throwsArgumentError, + throwsA(hasToStringValue(contains('must be a rem num or a String px/rem value')))) + ); + }); + + test('unless `passThroughUnsupportedUnits` is true', () { + expect(toPx('1em', passThroughUnsupportedUnits: true), new CssValue.parse('1em')); + }); }); - test('throws when passed a CssValue instance with a unit other than px/rem', () { - expect(() => toPx(new CssValue.parse('1em')), allOf( - throwsArgumentError, - throwsA(hasToStringValue(contains('must be a rem num or a String px/rem value')))) - ); + group('throws when passed a CssValue instance with a unit other than px/rem', () { + test('', () { + expect(() => toPx(new CssValue.parse('1em')), allOf( + throwsArgumentError, + throwsA(hasToStringValue(contains('must be a rem num or a String px/rem value')))) + ); + }); + + test('unless `passThroughUnsupportedUnits` is true', () { + expect(toPx(new CssValue.parse('1em'), passThroughUnsupportedUnits: true), new CssValue.parse('1em')); + }); }); }); @@ -193,7 +205,7 @@ main() { 'correctly dispatches an event in resopnse to the first change', () async { expect(querySelector('#rem_change_sensor'), isNull); - var calls = []; + var calls = []; var listener = onRemChange.listen(calls.add); expect(querySelector('#rem_change_sensor'), isNotNull); @@ -210,7 +222,7 @@ main() { }); test('does not dispatch duplicate events when there are multiple listeners', () async { - var calls = []; + List calls = []; var listener1 = onRemChange.listen((_) {}); var listener2 = onRemChange.listen(calls.add); @@ -227,7 +239,7 @@ main() { }); test('does not dispatch events when recomputeRootFontSize is called and there is no change', () async { - var calls = []; + List calls = []; var listener = onRemChange.listen(calls.add); recomputeRootFontSize();