-
Notifications
You must be signed in to change notification settings - Fork 67
Expand file tree
/
Copy pathXmlScope.spec.ts
More file actions
182 lines (168 loc) · 7.45 KB
/
Copy pathXmlScope.spec.ts
File metadata and controls
182 lines (168 loc) · 7.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import { expect } from './chai-config.spec';
import { Position, Range } from 'vscode-languageserver';
import { DiagnosticMessages } from './DiagnosticMessages';
import type { XmlFile } from './files/XmlFile';
import { Program } from './Program';
import { expectDiagnostics, trim } from './testHelpers.spec';
import { standardizePath as s, util } from './util';
let rootDir = s`${process.cwd()}/rootDir`;
import { createSandbox } from 'sinon';
const sinon = createSandbox();
describe('XmlScope', () => {
let program: Program;
beforeEach(() => {
program = new Program({
rootDir: rootDir
});
sinon.restore();
});
afterEach(() => {
program.dispose();
sinon.restore();
});
describe('constructor', () => {
it('listens for attach/detach parent events', () => {
let parentXmlFile = program.setFile<XmlFile>('components/parent.xml', trim`
<?xml version="1.0" encoding="utf-8" ?>
<component name="Parent" extends="Scene">
</component>
`);
let scope = program.getScopeByName(parentXmlFile.pkgPath);
//should default to global scope
expect(scope.getParentScope()).to.equal(program.globalScope);
let childXmlFile = program.setFile<XmlFile>('components/child.xml', trim`
<?xml version="1.0" encoding="utf-8" ?>
<component name="Child" extends="Parent">
</component>
`);
let childScope = program.getComponentScope('Child')!;
program.validate();
// child should have found its parent
expect(childXmlFile.parentComponent).to.equal(parentXmlFile);
// child's parent scope should have found the parent scope
expect(childScope.getParentScope()).to.equal(program.getComponentScope('Parent'));
//remove the parent component
program.removeFile(`${rootDir}/components/parent.xml`);
program.validate();
//the child should know the parent no longer exists
expect(childXmlFile.parentComponent).not.to.exist;
//child's parent scope should be the global scope
expect(childScope.getParentScope()).to.equal(program.globalScope);
});
});
describe('getDefinition', () => {
it('finds parent file', () => {
let parentXmlFile = program.setFile('components/parent.xml', trim`
<?xml version="1.0" encoding="utf-8" ?>
<component name="ParentComponent">
</component>
`);
let childXmlFile = program.setFile('components/child.xml', trim`
<?xml version="1.0" encoding="utf-8" ?>
<component name="ChildComponent" extends="ParentComponent">
</component>
`);
const definition = program.getDefinition(childXmlFile.srcPath, Position.create(1, 48));
expect(definition).to.be.lengthOf(1);
expect((definition[0] as any).uri).to.equal(util.pathToUri(parentXmlFile.srcPath));
});
});
describe('getFiles', () => {
it('includes the xml file', () => {
let xmlFile = program.setFile('components/child.xml', trim`
<?xml version="1.0" encoding="utf-8" ?>
<component name="Child">
</component>
`);
program.validate();
expect(program.getComponentScope('Child')!.getOwnFiles()[0]).to.equal(xmlFile);
});
});
describe('validate', () => {
it('adds an error when an interface function cannot be found', () => {
program = new Program({ rootDir: rootDir });
program.setFile('components/child.xml', trim`
<?xml version="1.0" encoding="utf-8" ?>
<component name="child" extends="parent">
<interface>
<function name="func1" />
<function name="func2" />
<function id="func3" />
<function name="" />
<function name />
<field id="field1" type="string" onChange="func4" />
</interface>
<script uri="child.brs"/>
</component>
`);
program.setFile(s`components/child.brs`, `
sub func1()
end sub
`);
program.validate();
let childScope = program.getComponentScope('child')!;
expectDiagnostics(childScope, [{
...DiagnosticMessages.xmlFunctionNotFound('func2'),
range: Range.create(4, 24, 4, 29)
}, {
...DiagnosticMessages.xmlTagMissingAttribute('function', 'name'),
range: Range.create(5, 9, 5, 17)
}, {
...DiagnosticMessages.xmlTagMissingAttribute('function', 'name'),
range: Range.create(6, 9, 6, 17)
}, {
...DiagnosticMessages.xmlTagMissingAttribute('function', 'name'),
range: Range.create(7, 9, 7, 17)
}, { // syntax error expecting '=' but found '/>'
code: DiagnosticMessages.xmlGenericParseError('').code
}, { // onChange function
...DiagnosticMessages.xmlFunctionNotFound('func4'),
range: Range.create(8, 51, 8, 56)
}]);
});
it('adds an error when an interface field is invalid', () => {
program = new Program({ rootDir: rootDir });
program.setFile('components/child.xml', trim`
<?xml version="1.0" encoding="utf-8" ?>
<component name="child" extends="parent">
<interface>
<field id="field1" type="node" />
<field id="field2" type="no" />
<field id="field3" />
<field name="field4" type="str" />
<field id="field5" alias="other.field" />
<field id="" type="int" />
<field id />
</interface>
<script uri="child.brs"/>
</component>
`);
program.setFile(s`components/child.brs`, `
sub init()
end sub
`);
program.validate();
expectDiagnostics(program.getComponentScope('child')!, [{
...DiagnosticMessages.xmlInvalidFieldType('no'),
range: Range.create(4, 33, 4, 35)
}, {
...DiagnosticMessages.xmlTagMissingAttribute('field', 'type'),
range: Range.create(5, 9, 5, 14)
}, {
...DiagnosticMessages.xmlTagMissingAttribute('field', 'id'),
range: Range.create(6, 9, 6, 14)
}, {
...DiagnosticMessages.xmlTagMissingAttribute('field', 'id'),
range: Range.create(8, 9, 8, 14)
}, {
...DiagnosticMessages.xmlTagMissingAttribute('field', 'id'),
range: Range.create(9, 9, 9, 14)
}, {
...DiagnosticMessages.xmlTagMissingAttribute('field', 'type'),
range: Range.create(9, 9, 9, 14)
}, { // syntax error expecting '=' but found '/>'
code: DiagnosticMessages.xmlGenericParseError('').code
}]);
});
});
});