Skip to content

Commit a868fff

Browse files
committed
Add "built_value_test" library with matcher.
1 parent 04b5936 commit a868fff

File tree

14 files changed

+466
-9
lines changed

14 files changed

+466
-9
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 1.1.0
4+
5+
- Add "built_value_test" library. It provides a matcher which gives good mismatch messages for built_value instances.
6+
37
## 1.0.1
48

59
- Allow quiver 0.25.

benchmark/pubspec.yaml

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ environment:
1212
dependencies:
1313
browser: any
1414
built_collection: ^1.0.0
15-
built_value: ^1.0.1
15+
# built_value: ^1.0.1
16+
built_value:
17+
path: ../built_value
1618

1719
dev_dependencies:
1820
build: ^0.7.0
1921
build_runner: ^0.3.0
20-
built_value_generator: ^1.0.1
22+
# built_value_generator: ^1.0.1
23+
built_value_generator:
24+
path: ../built_value_generator
2125
source_gen: '>=0.5.0+03 <0.6.0'
2226
quiver: '>=0.21.0 <0.26.0'
2327
test: any

built_value_generator/pubspec.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ dependencies:
1414
analyzer: '>=0.29.0 <0.30.0'
1515
build: ^0.7.0
1616
built_collection: ^1.0.0
17-
built_value: ^1.0.1
17+
# built_value: ^1.0.1
18+
built_value:
19+
path: ../built_value
1820
meta: ^1.0.4
1921
source_gen: '>=0.5.0+03 <0.6.0'
2022
quiver: '>=0.21.0 <0.26.0'

built_value_test/LICENSE

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Copyright 2017, Google Inc. All rights reserved.
2+
3+
Redistribution and use in source and binary forms, with or without
4+
modification, are permitted provided that the following conditions are
5+
met:
6+
7+
* Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above
10+
copyright notice, this list of conditions and the following disclaimer
11+
in the documentation and/or other materials provided with the
12+
distribution.
13+
14+
* Neither the name of Google Inc. nor the names of its
15+
contributors may be used to endorse or promote products derived from
16+
this software without specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

built_value_test/lib/matcher.dart

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright (c) 2017, Google Inc. Please see the AUTHORS file for details.
2+
// All rights reserved. Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
import 'package:built_collection/built_collection.dart';
6+
import 'package:built_value/built_value.dart';
7+
import 'package:test/test.dart';
8+
9+
/// Returns a matcher that matches if the value is structurally equal to
10+
/// [expected].
11+
///
12+
/// Improves on a simple equality test by offering a detailed mismatch message.
13+
Matcher equalsBuilt(Built expected) => new _BuiltValueMatcher(expected);
14+
15+
/// Matcher for [Built] instances.
16+
///
17+
/// Converts instances to maps using [_CapturingToStringHelper] then compares
18+
/// using [equals], which does deep comparison on maps.
19+
class _BuiltValueMatcher implements Matcher {
20+
final Built _expected;
21+
final Matcher _delegate;
22+
23+
_BuiltValueMatcher(this._expected) : _delegate = equals(_toMap(_expected));
24+
25+
@override
26+
Description describe(Description description) =>
27+
_delegate.describe(description);
28+
29+
@override
30+
Description describeMismatch(dynamic item, Description mismatchDescription,
31+
Map matchState, bool verbose) {
32+
if (_expected.runtimeType != item.runtimeType)
33+
return mismatchDescription.add('is the wrong type');
34+
35+
return _delegate.describeMismatch(
36+
_toMap(item), mismatchDescription, matchState, verbose);
37+
}
38+
39+
@override
40+
bool matches(dynamic item, Map matchState) {
41+
if (_expected.runtimeType != item.runtimeType) return false;
42+
43+
return _delegate.matches(_toMap(item), matchState);
44+
}
45+
}
46+
47+
/// Converts a Built to a map.
48+
Map<String, Object> _toMap(Object built) {
49+
// Save the current newBuiltValueToStringHelper so we can restore it on
50+
// return.
51+
final previousNewBuiltValueToStringHelper = newBuiltValueToStringHelper;
52+
53+
// Create a ToStringHelper that will capture values instead of converting
54+
// them to String.
55+
final capturingToStringHelper = new _CapturingToStringHelper();
56+
newBuiltValueToStringHelper = (String className) {
57+
// Store the class name in the map, so we check types as well as fields
58+
// and values.
59+
capturingToStringHelper.map[r'$class'] = className;
60+
return capturingToStringHelper;
61+
};
62+
63+
// Call toString() on the value to do capture.
64+
built.toString();
65+
66+
// Reset to what it was on method entry.
67+
newBuiltValueToStringHelper = previousNewBuiltValueToStringHelper;
68+
69+
return capturingToStringHelper.map;
70+
}
71+
72+
/// Captures values in a Map instead of converting to a String.
73+
class _CapturingToStringHelper implements BuiltValueToStringHelper {
74+
final Map<String, Object> map = <String, Object>{};
75+
76+
@override
77+
void add(String field, Object value) {
78+
if (value is Built) {
79+
map[field] = _toMap(value);
80+
} else if (value is BuiltMap) {
81+
map[field] = value.asMap();
82+
} else {
83+
map[field] = value;
84+
}
85+
}
86+
}

built_value_test/pubspec.yaml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: built_value_test
2+
version: 1.1.0
3+
description: >
4+
Value types with builders, Dart classes as enums, and serialization.
5+
This library provides test support.
6+
authors:
7+
- David Morgan <davidmorgan@google.com>
8+
homepage: https://github.com/google/built_value.dart
9+
10+
environment:
11+
sdk: '>=1.8.0 <2.0.0'
12+
13+
dependencies:
14+
# built_value: ^1.0.0
15+
built_value:
16+
path: ../built_value
17+
built_collection: ^1.0.0
18+
collection: ^1.0.0
19+
quiver: '>=0.21.0 <0.26.0'
20+
21+
dev_dependencies:
22+
build: ^0.7.0
23+
build_runner: ^0.3.0
24+
# built_value_generator: ^1.0.1
25+
built_value_generator:
26+
path: ../built_value_generator
27+
source_gen: '>=0.5.0+03 <0.6.0'
28+
test: any
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) 2017, Google Inc. Please see the AUTHORS file for details.
2+
// All rights reserved. Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
import 'package:built_value/built_value.dart';
6+
import 'package:built_value_test/matcher.dart';
7+
import 'package:test/test.dart';
8+
import 'values.dart';
9+
10+
void main() {
11+
group('built_value matcher', () {
12+
test('matches if same', () {
13+
final value = new CompoundValue((b) => b
14+
..simpleValue.anInt = 3
15+
..string = 'str');
16+
17+
expect(value, equalsBuilt(value));
18+
});
19+
20+
test('reports if not same', () {
21+
final value = new CompoundValue((b) => b
22+
..simpleValue.anInt = 3
23+
..string = 'str');
24+
final otherValue = value.rebuild((b) => b..simpleValue.anInt = 5);
25+
26+
_expectMismatch(value, otherValue,
27+
"was <3> instead of <5> at location ['simpleValue']['anInt']");
28+
});
29+
30+
test('reports deep match on maps if not same', () {
31+
final value = new CompoundValue((b) => b
32+
..simpleValue.anInt = 3
33+
..simpleValue.map['foo'] = 3
34+
..simpleValue.map['bar'] = 4
35+
..string = 'str');
36+
final otherValue = value.rebuild((b) => b..simpleValue.map['bar'] = 5);
37+
38+
_expectMismatch(value, otherValue,
39+
"was <4> instead of <5> at location ['simpleValue']['map']['bar']");
40+
});
41+
42+
test('reports if the wrong type', () {
43+
final value = 42;
44+
final otherValue = new CompoundValue((b) => b..simpleValue.anInt = 5);
45+
46+
_expectMismatch(value, otherValue, 'is the wrong type');
47+
});
48+
});
49+
}
50+
51+
void _expectMismatch(
52+
Object value, Built otherValue, String expectedMismatchMessage) {
53+
try {
54+
expect(value, equalsBuilt(otherValue));
55+
} catch (exception) {
56+
expect(exception.toString(), contains(expectedMismatchMessage));
57+
return;
58+
}
59+
throw new StateError('Expected mismatch.');
60+
}

built_value_test/test/values.dart

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) 2017, Google Inc. Please see the AUTHORS file for details.
2+
// All rights reserved. Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
library values;
6+
7+
import 'package:built_collection/built_collection.dart';
8+
import 'package:built_value/built_value.dart';
9+
10+
part 'values.g.dart';
11+
12+
abstract class SimpleValue implements Built<SimpleValue, SimpleValueBuilder> {
13+
int get anInt;
14+
BuiltMap<String, int> get map;
15+
16+
factory SimpleValue([updates(SimpleValueBuilder b)]) = _$SimpleValue;
17+
SimpleValue._();
18+
}
19+
20+
abstract class CompoundValue
21+
implements Built<CompoundValue, CompoundValueBuilder> {
22+
SimpleValue get simpleValue;
23+
@nullable
24+
String get string;
25+
26+
factory CompoundValue([updates(CompoundValueBuilder b)]) = _$CompoundValue;
27+
CompoundValue._();
28+
}

0 commit comments

Comments
 (0)