@@ -8,7 +8,6 @@ import 'package:build_runner_core/src/asset_graph/exceptions.dart';
88import 'package:build_runner_core/src/asset_graph/graph.dart' ;
99// ignore: implementation_imports
1010import 'package:build_runner_core/src/asset_graph/node.dart' ;
11- import 'package:package_config/package_config_types.dart' ;
1211import 'package:test/test.dart' ;
1312
1413final Matcher throwsCorruptedException = throwsA (
@@ -25,217 +24,50 @@ Matcher equalsAssetGraph(
2524class _AssetGraphMatcher extends Matcher {
2625 final AssetGraph _expected;
2726 final bool checkPreviousInputsDigest;
28-
29- const _AssetGraphMatcher (this ._expected, this .checkPreviousInputsDigest);
30-
31- @override
32- bool matches (dynamic item, Map <dynamic , dynamic > matchState) {
33- if (item is ! AssetGraph ) return false ;
34- var matches = true ;
35- if (item.allNodes.length != _expected.allNodes.length) matches = false ;
36- for (var node in item.allNodes) {
37- var expectedNode = _expected.get (node.id);
38- if (node.isDeleted != expectedNode? .isDeleted) {
39- matchState['IsDeleted of ${node .id }' ] = [
40- node.isDeleted,
41- expectedNode? .isDeleted,
42- ];
43- matches = false ;
44- }
45- if (node.runtimeType != expectedNode.runtimeType) {
46- matchState['RuntimeType' ] = [
47- node.runtimeType,
48- expectedNode.runtimeType,
49- ];
50- matches = false ;
51- }
52- if (expectedNode == null || expectedNode.id != node.id) {
53- matchState['AssetId' ] = [node.id, expectedNode! .id];
54- matches = false ;
55- }
56- if (! unorderedEquals (node.outputs).matches (expectedNode.outputs, {})) {
57- matchState['Outputs of ${node .id }' ] = [
58- node.outputs,
59- expectedNode.outputs,
60- ];
61- matches = false ;
62- }
63- if (! unorderedEquals (
64- node.primaryOutputs,
65- ).matches (expectedNode.primaryOutputs, {})) {
66- matchState['Primary outputs of ${node .id }' ] = [
67- node.primaryOutputs,
68- expectedNode.primaryOutputs,
69- ];
70- matches = false ;
71- }
72- if (! unorderedEquals (
73- node.anchorOutputs,
74- ).matches (expectedNode.anchorOutputs, {})) {
75- matchState['Anchor outputs of ${node .id }' ] = [
76- node.anchorOutputs,
77- expectedNode.anchorOutputs,
78- ];
79- matches = false ;
80- }
81- if (node.lastKnownDigest != expectedNode.lastKnownDigest) {
82- matchState['Digest of ${node .id }' ] = [
83- node.lastKnownDigest,
84- expectedNode.lastKnownDigest,
85- ];
86- matches = false ;
87- }
88- if (node.type == NodeType .generated) {
89- if (expectedNode.type == NodeType .generated) {
90- final configuration = node.generatedNodeConfiguration! ;
91- final expectedConfiguration =
92- expectedNode.generatedNodeConfiguration! ;
93-
94- if (configuration.primaryInput !=
95- expectedConfiguration.primaryInput) {
96- matchState['primaryInput of ${node .id }' ] = [
97- configuration.primaryInput,
98- expectedConfiguration.primaryInput,
99- ];
100- matches = false ;
101- }
102-
103- final state = node.generatedNodeState! ;
104- final expectedState = expectedNode.generatedNodeState! ;
105-
106- if (state.pendingBuildAction != expectedState.pendingBuildAction) {
107- matchState['pendingBuildAction of ${node .id }' ] = [
108- state.pendingBuildAction,
109- expectedState.pendingBuildAction,
110- ];
111- matches = false ;
112- }
113- if (! unorderedEquals (
114- state.inputs,
115- ).matches (expectedState.inputs, {})) {
116- matchState['Inputs of ${node .id }' ] = [
117- state.inputs,
118- expectedState.inputs,
119- ];
120- matches = false ;
121- }
122-
123- if (state.wasOutput != expectedState.wasOutput) {
124- matchState['wasOutput of ${node .id }' ] = [
125- state.wasOutput,
126- expectedState.wasOutput,
127- ];
128- matches = false ;
129- }
130- if (state.isFailure != expectedState.isFailure) {
131- matchState['isFailure of ${node .id }' ] = [
132- state.isFailure,
133- expectedState.isFailure,
134- ];
135- matches = false ;
136- }
137- if (checkPreviousInputsDigest &&
138- state.previousInputsDigest !=
139- expectedState.previousInputsDigest) {
140- matchState['previousInputDigest of ${node .id }' ] = [
141- state.previousInputsDigest,
142- expectedState.previousInputsDigest,
143- ];
144- matches = false ;
145- }
27+ final Matcher _matcher;
28+
29+ _AssetGraphMatcher (this ._expected, this .checkPreviousInputsDigest)
30+ : _matcher = equals (
31+ _graphToList (
32+ _expected,
33+ checkPreviousInputsDigest: checkPreviousInputsDigest,
34+ ),
35+ );
36+
37+ /// Converts [graph] to a list of [AssetNode] , sorted by ID, for comparison.
38+ ///
39+ /// If [checkPreviousInputsDigest] is false, removes `previousInputDigest`
40+ /// fields so they won't be compared.
41+ static List <AssetNode > _graphToList (
42+ AssetGraph graph, {
43+ required bool checkPreviousInputsDigest,
44+ }) {
45+ final result = < AssetNode > [];
46+ for (var node in graph.allNodes) {
47+ if (! checkPreviousInputsDigest) {
48+ if (node.type == NodeType .generated) {
49+ node = node.rebuild (
50+ (b) => b.generatedNodeState.previousInputsDigest = null ,
51+ );
14652 }
147- } else if (node.type == NodeType .glob) {
148- if (expectedNode.type == NodeType .glob) {
149- final state = node.globNodeState! ;
150- final expectedState = expectedNode.globNodeState! ;
151-
152- if (state.pendingBuildAction != expectedState.pendingBuildAction) {
153- matchState['pendingBuildAction of ${node .id }' ] = [
154- state.pendingBuildAction,
155- expectedState.pendingBuildAction,
156- ];
157- matches = false ;
158- }
159- if (! unorderedEquals (
160- state.inputs,
161- ).matches (expectedState.inputs, {})) {
162- matchState['Inputs of ${node .id }' ] = [
163- state.inputs,
164- expectedState.inputs,
165- ];
166- matches = false ;
167- }
168-
169- if (! unorderedEquals (
170- state.results,
171- ).matches (expectedState.results, {})) {
172- matchState['results of ${node .id }' ] = [
173- state.results,
174- expectedState.results,
175- ];
176- matches = false ;
177- }
178-
179- final configuration = node.globNodeConfiguration! ;
180- final expectedConfiguration = expectedNode.globNodeConfiguration! ;
181- if (configuration.glob != expectedConfiguration.glob) {
182- matchState['glob of ${node .id }' ] = [
183- configuration.glob,
184- expectedConfiguration.glob,
185- ];
186- matches = false ;
187- }
188- }
189- } else if (node.type == NodeType .postProcessAnchor) {
190- if (expectedNode.type == NodeType .postProcessAnchor) {
191- final nodeConfiguration = node.postProcessAnchorNodeConfiguration! ;
192- final expectedNodeConfiguration =
193- expectedNode.postProcessAnchorNodeConfiguration! ;
194- if (nodeConfiguration.actionNumber !=
195- expectedNodeConfiguration.actionNumber) {
196- matchState['actionNumber of ${node .id }' ] = [
197- nodeConfiguration.actionNumber,
198- expectedNodeConfiguration.actionNumber,
199- ];
200- matches = false ;
201- }
202- if (nodeConfiguration.builderOptionsId !=
203- expectedNodeConfiguration.builderOptionsId) {
204- matchState['builderOptionsId of ${node .id }' ] = [
205- nodeConfiguration.builderOptionsId,
206- expectedNodeConfiguration.builderOptionsId,
207- ];
208- matches = false ;
209- }
210- final nodeState = node.postProcessAnchorNodeState! ;
211- final expectedNodeState = expectedNode.postProcessAnchorNodeState! ;
212- if (checkPreviousInputsDigest &&
213- nodeState.previousInputsDigest !=
214- expectedNodeState.previousInputsDigest) {
215- matchState['previousInputsDigest of ${node .id }' ] = [
216- nodeState.previousInputsDigest,
217- expectedNodeState.previousInputsDigest,
218- ];
219- matches = false ;
220- }
221- if (nodeConfiguration.primaryInput !=
222- expectedNodeConfiguration.primaryInput) {
223- matchState['primaryInput of ${node .id }' ] = [
224- nodeConfiguration.primaryInput,
225- expectedNodeConfiguration.primaryInput,
226- ];
227- matches = false ;
228- }
53+ if (node.type == NodeType .postProcessAnchor) {
54+ node = node.rebuild (
55+ (b) => b..postProcessAnchorNodeState.previousInputsDigest = null ,
56+ );
22957 }
23058 }
59+ result.add (node);
23160 }
232- if (! equals (_expected.packageLanguageVersions).matches (
233- item.packageLanguageVersions,
234- matchState['packageLanguageVersions' ] = < String , LanguageVersion ? > {},
235- )) {
236- matches = false ;
237- }
238- return matches;
61+ return result..sort ((a, b) => a.id.toString ().compareTo (b.id.toString ()));
62+ }
63+
64+ @override
65+ bool matches (dynamic item, Map <dynamic , dynamic > matchState) {
66+ if (item is ! AssetGraph ) return false ;
67+ return _matcher.matches (
68+ _graphToList (item, checkPreviousInputsDigest: checkPreviousInputsDigest),
69+ matchState,
70+ );
23971 }
24072
24173 @override
@@ -248,13 +80,15 @@ class _AssetGraphMatcher extends Matcher {
24880 Description mismatchDescription,
24981 Map matchState,
25082 bool verbose,
251- ) {
252- matchState.forEach ((k, v) {
253- if (v is List ) {
254- mismatchDescription.add ('$k : got ${v [0 ]} but expected ${v [1 ]}' );
255- }
256- });
257-
258- return mismatchDescription;
259- }
83+ ) => _matcher.describeMismatch (
84+ item is AssetGraph
85+ ? _graphToList (
86+ item,
87+ checkPreviousInputsDigest: checkPreviousInputsDigest,
88+ )
89+ : '(not an AssetGraph!) $item ' ,
90+ mismatchDescription,
91+ matchState,
92+ verbose,
93+ );
26094}
0 commit comments