1+ const { expect } = require ( 'chai' ) ;
2+
3+
4+ function isDefined ( value ) {
5+ return typeof value !== 'undefined' ;
6+ }
7+
8+ function findVariable ( variables , expectedVariable ) {
9+ const {
10+ name,
11+ scope
12+ } = expectedVariable ;
13+
14+ const variable = variables . find (
15+ v => ( ! isDefined ( name ) || v . name === name ) && ( ! isDefined ( scope ) || v . scope ?. id === scope )
16+ ) ;
17+
18+ expect ( variable , `variable[name=${ name } , scope=${ scope } ]` ) . to . exist ;
19+
20+ return variable ;
21+ }
22+
23+ function assertVariableMatches ( variable , expectedVariable ) {
24+ const {
25+ name,
26+ type,
27+ detail,
28+ info,
29+ scope,
30+ isList,
31+ origin,
32+ entries
33+ } = expectedVariable ;
34+
35+ isDefined ( type ) && expect ( variable . type , `variable[name=${ name } ].type` ) . to . eql ( type ) ;
36+ isDefined ( info ) && expect ( variable . info , `variable[name=${ name } ].info` ) . to . eql ( info ) ;
37+ isDefined ( detail ) && expect ( variable . detail , `variable[name=${ name } ].detail` ) . to . eql ( detail ) ;
38+ isDefined ( scope ) && expect ( variable . scope . id , `variable[name=${ name } ].scope.id` ) . to . eql ( scope ) ;
39+ isDefined ( isList ) && expect ( ! ! variable . isList , `variable[name=${ name } ].isList` ) . to . eql ( ! ! isList ) ;
40+ isDefined ( entries ) && expect ( variable . entries , `variable[name=${ name } ].entries` ) . to . variableEqual ( entries ) ;
41+
42+ isDefined ( origin ) && origin . forEach ( ( expectedOrigin ) => {
43+ const foundOrigin = variable . origin . find ( o => o . id === expectedOrigin ) ;
44+ expect ( foundOrigin , `origin[name=${ expectedOrigin } ]` ) . to . exist ;
45+ } ) ;
46+
47+ isDefined ( origin ) && expect ( variable . origin . length , `variable[name=${ name } ].origin.length` ) . to . eql ( origin . length ) ;
48+ }
49+
50+ /**
51+ * Match variables against expected patterns,
52+ * return variables that were not matched.
53+ */
54+ function assertVariablesMatch ( variables , expectedVariables ) {
55+
56+ let remainingVariables = variables . slice ( ) ;
57+
58+ for ( const expectedVariable of expectedVariables ) {
59+ const variable = findVariable ( remainingVariables , expectedVariable ) ;
60+
61+ remainingVariables = remainingVariables . filter ( v => v !== variable ) ;
62+
63+ assertVariableMatches ( variable , expectedVariable ) ;
64+ }
65+
66+ return remainingVariables ;
67+ }
68+
69+ function variableAssertions ( chai , utils ) {
70+
71+ // use to verify that a list of variables
72+ // is complete, i.e. includes exactly the variables matched
73+ utils . addMethod ( chai . Assertion . prototype , 'variableEqual' , function ( expectedVariables ) {
74+ const variables = this . _obj ;
75+
76+ const remainingVariables = assertVariablesMatch ( variables , expectedVariables ) ;
77+
78+ expect ( remainingVariables . length , 'unmatched variables' ) . to . eql ( 0 ) ;
79+ } ) ;
80+
81+ // use to verify that a list of variables
82+ // includes a single or a list of variables (by pattern)
83+ utils . addMethod ( chai . Assertion . prototype , 'variableInclude' , function ( expectedVariables ) {
84+ const variables = this . _obj ;
85+
86+ if ( ! Array . isArray ( expectedVariables ) ) {
87+ expectedVariables = [ expectedVariables ] ;
88+ }
89+
90+ assertVariablesMatch ( variables , expectedVariables ) ;
91+ } ) ;
92+ }
93+
94+ module . exports = {
95+ variableAssertions
96+ } ;
0 commit comments