@malloydata/malloy 0.0.240-dev250311202829 → 0.0.240-dev250311214430
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/core.d.ts +1 -0
- package/dist/api/core.js +2 -1
- package/dist/lang/malloy-parse-info.d.ts +2 -10
- package/dist/lang/malloy-to-ast.d.ts +1 -0
- package/dist/lang/malloy-to-ast.js +9 -6
- package/dist/lang/malloy-to-stable-query.d.ts +76 -0
- package/dist/lang/malloy-to-stable-query.js +660 -0
- package/dist/lang/parse-log.d.ts +1 -0
- package/dist/lang/parse-malloy.d.ts +2 -9
- package/dist/lang/parse-malloy.js +7 -112
- package/dist/lang/parse-tree-walkers/model-annotation-walker.js +1 -1
- package/dist/lang/run-malloy-parser.d.ts +3 -0
- package/dist/lang/run-malloy-parser.js +53 -0
- package/dist/lang/syntax-errors/malloy-parser-error-listener.d.ts +4 -3
- package/dist/lang/syntax-errors/malloy-parser-error-listener.js +8 -4
- package/dist/lang/utils.d.ts +27 -1
- package/dist/lang/utils.js +78 -1
- package/package.json +3 -3
- package/dist/api/asynchronous.spec.d.ts +0 -1
- package/dist/api/asynchronous.spec.js +0 -240
- package/dist/api/sessioned.spec.d.ts +0 -1
- package/dist/api/sessioned.spec.js +0 -476
- package/dist/api/stateless.spec.d.ts +0 -1
- package/dist/api/stateless.spec.js +0 -400
- package/dist/lang/test/annotation.spec.d.ts +0 -14
- package/dist/lang/test/annotation.spec.js +0 -809
- package/dist/lang/test/composite-field-usage.spec.d.ts +0 -1
- package/dist/lang/test/composite-field-usage.spec.js +0 -261
- package/dist/lang/test/document-help-context-walker.spec.d.ts +0 -1
- package/dist/lang/test/document-help-context-walker.spec.js +0 -55
- package/dist/lang/test/document-symbol-walker.spec.d.ts +0 -1
- package/dist/lang/test/document-symbol-walker.spec.js +0 -209
- package/dist/lang/test/expressions.spec.d.ts +0 -1
- package/dist/lang/test/expressions.spec.js +0 -1181
- package/dist/lang/test/field-symbols.spec.d.ts +0 -1
- package/dist/lang/test/field-symbols.spec.js +0 -194
- package/dist/lang/test/find-table-path-walker.spec.d.ts +0 -1
- package/dist/lang/test/find-table-path-walker.spec.js +0 -50
- package/dist/lang/test/imports.spec.d.ts +0 -1
- package/dist/lang/test/imports.spec.js +0 -283
- package/dist/lang/test/lenses.spec.d.ts +0 -1
- package/dist/lang/test/lenses.spec.js +0 -384
- package/dist/lang/test/literals.spec.d.ts +0 -1
- package/dist/lang/test/literals.spec.js +0 -267
- package/dist/lang/test/locations.spec.d.ts +0 -1
- package/dist/lang/test/locations.spec.js +0 -679
- package/dist/lang/test/model-annotation-walker.spec.d.ts +0 -1
- package/dist/lang/test/model-annotation-walker.spec.js +0 -46
- package/dist/lang/test/model_serialization.spec.d.ts +0 -5
- package/dist/lang/test/model_serialization.spec.js +0 -116
- package/dist/lang/test/parameters.spec.d.ts +0 -1
- package/dist/lang/test/parameters.spec.js +0 -619
- package/dist/lang/test/parse.spec.d.ts +0 -1
- package/dist/lang/test/parse.spec.js +0 -893
- package/dist/lang/test/pretranslate.spec.d.ts +0 -1
- package/dist/lang/test/pretranslate.spec.js +0 -80
- package/dist/lang/test/query.spec.d.ts +0 -1
- package/dist/lang/test/query.spec.js +0 -1149
- package/dist/lang/test/source.spec.d.ts +0 -1
- package/dist/lang/test/source.spec.js +0 -570
- package/dist/lang/test/sql-block.spec.d.ts +0 -1
- package/dist/lang/test/sql-block.spec.js +0 -145
- package/dist/lang/test/syntax-errors.spec.d.ts +0 -1
- package/dist/lang/test/syntax-errors.spec.js +0 -142
- package/dist/model/utils.spec.d.ts +0 -1
- package/dist/model/utils.spec.js +0 -38
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import './parse-expects';
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
const test_translator_1 = require("./test-translator");
|
|
10
|
-
require("./parse-expects");
|
|
11
|
-
const composite_source_utils_1 = require("../../model/composite_source_utils");
|
|
12
|
-
function addPathToCompositeUsage(path, compositeUsage) {
|
|
13
|
-
var _a;
|
|
14
|
-
if (path.length === 0)
|
|
15
|
-
throw new Error('empty path');
|
|
16
|
-
if (path.length === 1) {
|
|
17
|
-
return {
|
|
18
|
-
fields: [...compositeUsage.fields, path[0]],
|
|
19
|
-
joinedUsage: compositeUsage.joinedUsage,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
return {
|
|
24
|
-
fields: compositeUsage.fields,
|
|
25
|
-
joinedUsage: {
|
|
26
|
-
...compositeUsage.joinedUsage,
|
|
27
|
-
[path[0]]: addPathToCompositeUsage(path.slice(1), (_a = compositeUsage.joinedUsage[path[0]]) !== null && _a !== void 0 ? _a : (0, composite_source_utils_1.emptyCompositeFieldUsage)()),
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function paths(paths) {
|
|
33
|
-
let cu = (0, composite_source_utils_1.emptyCompositeFieldUsage)();
|
|
34
|
-
for (const path of paths) {
|
|
35
|
-
cu = addPathToCompositeUsage(path, cu);
|
|
36
|
-
}
|
|
37
|
-
return cu;
|
|
38
|
-
}
|
|
39
|
-
describe('composite sources', () => {
|
|
40
|
-
describe('composite field usage', () => {
|
|
41
|
-
const m = (0, test_translator_1.model) `
|
|
42
|
-
##! experimental.composite_sources
|
|
43
|
-
source: x is compose(ab, ab) extend {
|
|
44
|
-
dimension: aif is ai + af
|
|
45
|
-
measure: ss is ai.sum()
|
|
46
|
-
measure: saiaf is ai.sum() { where: af > 1 }
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
source: y is compose(ab, ab) extend {
|
|
50
|
-
join_one: x on 1 = 1
|
|
51
|
-
}
|
|
52
|
-
`;
|
|
53
|
-
beforeAll(() => {
|
|
54
|
-
m.translator.translate();
|
|
55
|
-
});
|
|
56
|
-
test('looked up value', () => {
|
|
57
|
-
const mexpr = (0, test_translator_1.makeExprFunc)(m.translator.modelDef, 'y');
|
|
58
|
-
expect(mexpr `ai`).hasCompositeUsage(paths([['ai']]));
|
|
59
|
-
});
|
|
60
|
-
test('multiple values', () => {
|
|
61
|
-
const mexpr = (0, test_translator_1.makeExprFunc)(m.translator.modelDef, 'y');
|
|
62
|
-
expect(mexpr `ai + af`).hasCompositeUsage(paths([['ai'], ['af']]));
|
|
63
|
-
});
|
|
64
|
-
test('value plus constant', () => {
|
|
65
|
-
const mexpr = (0, test_translator_1.makeExprFunc)(m.translator.modelDef, 'y');
|
|
66
|
-
expect(mexpr `ai + 1`).hasCompositeUsage(paths([['ai']]));
|
|
67
|
-
});
|
|
68
|
-
test('join usage', () => {
|
|
69
|
-
const mexpr = (0, test_translator_1.makeExprFunc)(m.translator.modelDef, 'y');
|
|
70
|
-
expect(mexpr `x.ai + 1`).hasCompositeUsage(paths([['x', 'ai']]));
|
|
71
|
-
});
|
|
72
|
-
test('join usage complex', () => {
|
|
73
|
-
const mexpr = (0, test_translator_1.makeExprFunc)(m.translator.modelDef, 'y');
|
|
74
|
-
expect(mexpr `x.aif`).hasCompositeUsage(paths([
|
|
75
|
-
['x', 'ai'],
|
|
76
|
-
['x', 'af'],
|
|
77
|
-
]));
|
|
78
|
-
});
|
|
79
|
-
test('measure defined in composite source', () => {
|
|
80
|
-
const mexpr = (0, test_translator_1.makeExprFunc)(m.translator.modelDef, 'x');
|
|
81
|
-
expect(mexpr `ss`).hasCompositeUsage(paths([['ai']]));
|
|
82
|
-
});
|
|
83
|
-
test('measure with filter defined in composite source', () => {
|
|
84
|
-
const mexpr = (0, test_translator_1.makeExprFunc)(m.translator.modelDef, 'x');
|
|
85
|
-
expect(mexpr `saiaf`).hasCompositeUsage(paths([['ai'], ['af']]));
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
describe('composite source resolution and validation', () => {
|
|
89
|
-
test('compose fails on group_by that is relevant', () => {
|
|
90
|
-
expect(`
|
|
91
|
-
##! experimental.composite_sources
|
|
92
|
-
run: compose(
|
|
93
|
-
a extend { dimension: one is 1, two is 2 },
|
|
94
|
-
a extend { dimension: one is 1, three is 3 }
|
|
95
|
-
) -> {
|
|
96
|
-
group_by: one
|
|
97
|
-
group_by: three
|
|
98
|
-
group_by: ${'two'}
|
|
99
|
-
}
|
|
100
|
-
`).toLog((0, test_translator_1.errorMessage)('This operation uses composite field `two`, resulting in invalid usage of the composite source, as there is no composite input source which defines all of `one`, `three`, `two`'));
|
|
101
|
-
});
|
|
102
|
-
test('compose fails on filter that is relevant', () => {
|
|
103
|
-
expect(`
|
|
104
|
-
##! experimental.composite_sources
|
|
105
|
-
run: compose(
|
|
106
|
-
a extend { dimension: one is 1, two is 2 },
|
|
107
|
-
a extend { dimension: one is 1, three is 3 }
|
|
108
|
-
) -> {
|
|
109
|
-
group_by: one
|
|
110
|
-
group_by: three
|
|
111
|
-
where: ${'two = 2'}
|
|
112
|
-
}
|
|
113
|
-
`).toLog((0, test_translator_1.errorMessage)('This operation uses composite field `two`, resulting in invalid usage of the composite source, as there is no composite input source which defines all of `one`, `three`, `two`'));
|
|
114
|
-
});
|
|
115
|
-
test('compose fails in case where second field has overlap with first', () => {
|
|
116
|
-
expect(`
|
|
117
|
-
##! experimental.composite_sources
|
|
118
|
-
run: compose(
|
|
119
|
-
a extend { dimension: one is 1 },
|
|
120
|
-
a extend { dimension: two is 3 }
|
|
121
|
-
) -> {
|
|
122
|
-
group_by: one
|
|
123
|
-
group_by: ${'three is one + two'}
|
|
124
|
-
}
|
|
125
|
-
`).toLog((0, test_translator_1.errorMessage)('This operation uses composite field `two`, resulting in invalid usage of the composite source, as there is no composite input source which defines all of `one`, `two`'));
|
|
126
|
-
});
|
|
127
|
-
test('compose resolution succeeds nested', () => {
|
|
128
|
-
expect(`
|
|
129
|
-
##! experimental.composite_sources
|
|
130
|
-
run: compose(
|
|
131
|
-
compose(
|
|
132
|
-
a extend { dimension: one is 1, two is 2 },
|
|
133
|
-
a extend { dimension: one is 1, three is 3 }
|
|
134
|
-
),
|
|
135
|
-
a extend { dimension: one is 1, two is 2, three is 3 }
|
|
136
|
-
) -> {
|
|
137
|
-
group_by: one, two ${'three'}
|
|
138
|
-
}
|
|
139
|
-
`).toTranslate();
|
|
140
|
-
});
|
|
141
|
-
test('good composite field usage works', () => expect(`
|
|
142
|
-
##! experimental.composite_sources
|
|
143
|
-
run: compose(a, a extend { dimension: one is 1 }) -> { group_by: one }
|
|
144
|
-
`).toTranslate());
|
|
145
|
-
test('index on composite translates', () => expect(`
|
|
146
|
-
##! experimental.composite_sources
|
|
147
|
-
source: x is compose(
|
|
148
|
-
a extend { except: ai },
|
|
149
|
-
a
|
|
150
|
-
)
|
|
151
|
-
run: x -> { index: ai }
|
|
152
|
-
run: x -> { index: * }
|
|
153
|
-
`).toTranslate());
|
|
154
|
-
test('raw run of composite source fails', () => expect(`
|
|
155
|
-
##! experimental.composite_sources
|
|
156
|
-
run: compose(a extend { dimension: two is 2 }, a extend { dimension: one is 1 })
|
|
157
|
-
`).toLog((0, test_translator_1.errorMessage)('Cannot run this object as a query')));
|
|
158
|
-
test('composite source with parameter', () => {
|
|
159
|
-
expect(`
|
|
160
|
-
##! experimental { composite_sources parameters }
|
|
161
|
-
source: foo(param is 1) is compose(
|
|
162
|
-
a extend { dimension: x is param },
|
|
163
|
-
a extend { dimension: y is param + 1 }
|
|
164
|
-
)
|
|
165
|
-
run: foo(param is 2) -> { group_by: y }
|
|
166
|
-
`).toTranslate();
|
|
167
|
-
});
|
|
168
|
-
test('composite source does not include private field', () => {
|
|
169
|
-
expect(`
|
|
170
|
-
##! experimental { composite_sources access_modifiers }
|
|
171
|
-
source: foo is compose(
|
|
172
|
-
a extend {
|
|
173
|
-
private dimension: x is 1
|
|
174
|
-
},
|
|
175
|
-
a
|
|
176
|
-
)
|
|
177
|
-
run: foo -> { group_by: x }
|
|
178
|
-
`).toLog((0, test_translator_1.errorMessage)("'x' is not defined"));
|
|
179
|
-
});
|
|
180
|
-
test('composite source does not resolve to private field', () => {
|
|
181
|
-
expect(`
|
|
182
|
-
##! experimental { composite_sources access_modifiers }
|
|
183
|
-
source: foo is compose(
|
|
184
|
-
a extend {
|
|
185
|
-
private dimension: x is 1
|
|
186
|
-
dimension: y is 1
|
|
187
|
-
},
|
|
188
|
-
a extend { dimension: x is 1 }
|
|
189
|
-
)
|
|
190
|
-
run: foo -> { group_by: x, y }
|
|
191
|
-
`).toLog((0, test_translator_1.errorMessage)('This operation uses composite field `y`, resulting in invalid usage of the composite source, as there is no composite input source which defines all of `x`, `y`'));
|
|
192
|
-
});
|
|
193
|
-
test('composite source does include internal field', () => {
|
|
194
|
-
expect(`
|
|
195
|
-
##! experimental { composite_sources access_modifiers }
|
|
196
|
-
source: foo is compose(
|
|
197
|
-
a extend {
|
|
198
|
-
internal dimension: x is 1
|
|
199
|
-
},
|
|
200
|
-
a
|
|
201
|
-
) extend {
|
|
202
|
-
view: v is { group_by: x }
|
|
203
|
-
}
|
|
204
|
-
run: foo -> v
|
|
205
|
-
`).toTranslate();
|
|
206
|
-
});
|
|
207
|
-
test('access level mismatch in composite (before)', () => {
|
|
208
|
-
expect(`
|
|
209
|
-
##! experimental { composite_sources access_modifiers }
|
|
210
|
-
source: foo is compose(
|
|
211
|
-
a extend {
|
|
212
|
-
internal dimension: x is 1
|
|
213
|
-
},
|
|
214
|
-
a extend {
|
|
215
|
-
dimension: x is 1
|
|
216
|
-
}
|
|
217
|
-
)
|
|
218
|
-
run: foo -> { group_by: x }
|
|
219
|
-
`).toLog((0, test_translator_1.errorMessage)("'x' is internal"));
|
|
220
|
-
});
|
|
221
|
-
test('access level mismatch in composite (after)', () => {
|
|
222
|
-
expect(`
|
|
223
|
-
##! experimental { composite_sources access_modifiers }
|
|
224
|
-
source: foo is compose(
|
|
225
|
-
a extend {
|
|
226
|
-
dimension: x is 1
|
|
227
|
-
},
|
|
228
|
-
a extend {
|
|
229
|
-
internal dimension: x is 1
|
|
230
|
-
}
|
|
231
|
-
)
|
|
232
|
-
run: foo -> { group_by: x }
|
|
233
|
-
`).toLog((0, test_translator_1.errorMessage)("'x' is internal"));
|
|
234
|
-
});
|
|
235
|
-
test('array.each is okay', () => {
|
|
236
|
-
expect(`
|
|
237
|
-
##! experimental { composite_sources }
|
|
238
|
-
source: foo is compose(
|
|
239
|
-
a extend { dimension: x is 1 },
|
|
240
|
-
a extend { dimension: y is 2 }
|
|
241
|
-
) extend {
|
|
242
|
-
dimension: arr is [1, 2, 3]
|
|
243
|
-
}
|
|
244
|
-
run: foo -> { group_by: y, arr.each }
|
|
245
|
-
`).toTranslate();
|
|
246
|
-
});
|
|
247
|
-
test('timevalue extract okay', () => {
|
|
248
|
-
expect(`
|
|
249
|
-
##! experimental { composite_sources }
|
|
250
|
-
source: foo is compose(
|
|
251
|
-
a extend { dimension: x is 1 },
|
|
252
|
-
a extend { dimension: y is 2 }
|
|
253
|
-
) extend {
|
|
254
|
-
dimension: time is now
|
|
255
|
-
}
|
|
256
|
-
run: foo -> { group_by: y, time.day }
|
|
257
|
-
`).toTranslate();
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
});
|
|
261
|
-
//# sourceMappingURL=composite-field-usage.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2023 Google LLC
|
|
4
|
-
*
|
|
5
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
-
* a copy of this software and associated documentation files
|
|
7
|
-
* (the "Software"), to deal in the Software without restriction,
|
|
8
|
-
* including without limitation the rights to use, copy, modify, merge,
|
|
9
|
-
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
10
|
-
* and to permit persons to whom the Software is furnished to do so,
|
|
11
|
-
* subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be
|
|
14
|
-
* included in all copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
-
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
-
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
-
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
-
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
const test_translator_1 = require("./test-translator");
|
|
26
|
-
function testHelpContext(source, position, type, token) {
|
|
27
|
-
const doc = new test_translator_1.TestTranslator(source.code);
|
|
28
|
-
expect(doc.logger.hasErrors()).toBeFalsy();
|
|
29
|
-
const helpContext = doc.helpContext(position).helpContext;
|
|
30
|
-
expect(helpContext).toEqual({ type, token });
|
|
31
|
-
}
|
|
32
|
-
const source = `source: foo is DB.table('bar') extend {
|
|
33
|
-
where: bazz ~ 'biff'
|
|
34
|
-
query: foo is {
|
|
35
|
-
group_by: bazz
|
|
36
|
-
where: bop ~ 'blat'
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
query: bar {
|
|
41
|
-
group_by: bazz
|
|
42
|
-
}`;
|
|
43
|
-
test('Supports model properties', () => {
|
|
44
|
-
testHelpContext((0, test_translator_1.markSource) `${source}`, { line: 0, character: 1 }, 'model_property', 'source:');
|
|
45
|
-
testHelpContext((0, test_translator_1.markSource) `${source}`, { line: 8, character: 1 }, 'model_property', 'query:');
|
|
46
|
-
});
|
|
47
|
-
test('Supports source properties', () => {
|
|
48
|
-
testHelpContext((0, test_translator_1.markSource) `${source}`, { line: 1, character: 3 }, 'explore_property', 'where:');
|
|
49
|
-
testHelpContext((0, test_translator_1.markSource) `${source}`, { line: 2, character: 3 }, 'explore_property', 'query:');
|
|
50
|
-
});
|
|
51
|
-
test('Supports query properties', () => {
|
|
52
|
-
testHelpContext((0, test_translator_1.markSource) `${source}`, { line: 3, character: 5 }, 'query_property', 'group_by:');
|
|
53
|
-
testHelpContext((0, test_translator_1.markSource) `${source}`, { line: 4, character: 5 }, 'query_property', 'where:');
|
|
54
|
-
});
|
|
55
|
-
//# sourceMappingURL=document-help-context-walker.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2023 Google LLC
|
|
4
|
-
*
|
|
5
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
-
* a copy of this software and associated documentation files
|
|
7
|
-
* (the "Software"), to deal in the Software without restriction,
|
|
8
|
-
* including without limitation the rights to use, copy, modify, merge,
|
|
9
|
-
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
10
|
-
* and to permit persons to whom the Software is furnished to do so,
|
|
11
|
-
* subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be
|
|
14
|
-
* included in all copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
-
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
-
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
-
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
-
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
const test_translator_1 = require("./test-translator");
|
|
26
|
-
class MalloyExplore extends test_translator_1.TestTranslator {
|
|
27
|
-
constructor(src) {
|
|
28
|
-
super(src);
|
|
29
|
-
}
|
|
30
|
-
get symbols() {
|
|
31
|
-
const md = this.metadata();
|
|
32
|
-
return md.symbols || [];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
function testSymbol(source, name, type, path) {
|
|
36
|
-
const doc = new MalloyExplore(source.code);
|
|
37
|
-
let current = { children: doc.symbols };
|
|
38
|
-
path.forEach(segment => {
|
|
39
|
-
current = current.children[segment];
|
|
40
|
-
});
|
|
41
|
-
expect(doc.logger.hasErrors()).toBeFalsy();
|
|
42
|
-
expect(current).toMatchObject({
|
|
43
|
-
name,
|
|
44
|
-
range: source.locations[0].range,
|
|
45
|
-
type,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
function testLens(source, path) {
|
|
49
|
-
const doc = new MalloyExplore(source.code);
|
|
50
|
-
let current = {
|
|
51
|
-
children: doc.symbols,
|
|
52
|
-
};
|
|
53
|
-
path.forEach(segment => {
|
|
54
|
-
current = current.children[segment];
|
|
55
|
-
});
|
|
56
|
-
expect(doc.logger.hasErrors()).toBeFalsy();
|
|
57
|
-
const expectedLensRange = source.locations[0].range;
|
|
58
|
-
const expected = 'lensRange' in current && current.lensRange !== undefined
|
|
59
|
-
? { lensRange: expectedLensRange }
|
|
60
|
-
: { range: expectedLensRange };
|
|
61
|
-
expect(current).toMatchObject(expected);
|
|
62
|
-
}
|
|
63
|
-
test('source symbols are included', () => {
|
|
64
|
-
testSymbol((0, test_translator_1.markSource) `source: ${"flights is DB.table('my.table.flights')"}`, 'flights', 'explore', [0]);
|
|
65
|
-
});
|
|
66
|
-
test('query symbols are included', () => {
|
|
67
|
-
testSymbol((0, test_translator_1.markSource) `query: ${'flights_by_carrier is flights -> by_carrier'}`, 'flights_by_carrier', 'query', [0]);
|
|
68
|
-
});
|
|
69
|
-
test('run (def) symbols are included', () => {
|
|
70
|
-
testSymbol((0, test_translator_1.markSource) `run: ${'flights -> by_carrier'}`, 'unnamed_query', 'unnamed_query', [0]);
|
|
71
|
-
});
|
|
72
|
-
test('run (ref) symbols are included', () => {
|
|
73
|
-
testSymbol((0, test_translator_1.markSource) `query: by_carrier is flights -> by_carrier
|
|
74
|
-
run: ${'by_carrier'}`, 'unnamed_query', 'unnamed_query', [1]);
|
|
75
|
-
});
|
|
76
|
-
test('expression field defs are included', () => {
|
|
77
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
78
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
79
|
-
dimension: ${'one is 1'}
|
|
80
|
-
}
|
|
81
|
-
`, 'one', 'field', [0, 0]);
|
|
82
|
-
});
|
|
83
|
-
test('renamed fields are included', () => {
|
|
84
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
85
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
86
|
-
rename: ${'field_two is field_2'}
|
|
87
|
-
}
|
|
88
|
-
`, 'field_two', 'field', [0, 0]);
|
|
89
|
-
});
|
|
90
|
-
test('name only fields are included', () => {
|
|
91
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
92
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
93
|
-
dimension: ${'field_two is field_2'}
|
|
94
|
-
}
|
|
95
|
-
`, 'field_two', 'field', [0, 0]);
|
|
96
|
-
});
|
|
97
|
-
test('turtle fields are included', () => {
|
|
98
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
99
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
100
|
-
query: ${'my_turtle is { group_by: a }'}
|
|
101
|
-
}
|
|
102
|
-
`, 'my_turtle', 'query', [0, 0]);
|
|
103
|
-
});
|
|
104
|
-
test('turtle children fields are included', () => {
|
|
105
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
106
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
107
|
-
query: my_turtle is { group_by: ${'a'} }
|
|
108
|
-
}
|
|
109
|
-
`, 'a', 'field', [0, 0, 0]);
|
|
110
|
-
});
|
|
111
|
-
test('turtle children turtles are included', () => {
|
|
112
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
113
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
114
|
-
query: my_turtle is { nest: ${'inner_turtle is { group_by: a }'} }
|
|
115
|
-
}
|
|
116
|
-
`, 'inner_turtle', 'query', [0, 0, 0]);
|
|
117
|
-
});
|
|
118
|
-
test('refinement chain gets name correctly', () => {
|
|
119
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
120
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
121
|
-
query: my_turtle is { nest: ${'something + something_else'} }
|
|
122
|
-
}
|
|
123
|
-
`, 'something', 'query', [0, 0, 0]);
|
|
124
|
-
});
|
|
125
|
-
test('arrow in nest infers name correctly', () => {
|
|
126
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
127
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
128
|
-
query: my_turtle is { nest: ${'thingy -> something + something_else'} }
|
|
129
|
-
}
|
|
130
|
-
`, 'something', 'query', [0, 0, 0]);
|
|
131
|
-
});
|
|
132
|
-
test('join withs are included', () => {
|
|
133
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
134
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
135
|
-
join_one: ${'a is b with c'}
|
|
136
|
-
}
|
|
137
|
-
`, 'a', 'join', [0, 0]);
|
|
138
|
-
});
|
|
139
|
-
test('join ons are included', () => {
|
|
140
|
-
testSymbol((0, test_translator_1.markSource) `
|
|
141
|
-
source: flights is DB.table('my.table.flights') extend {
|
|
142
|
-
join_one: ${'a is b on c'}
|
|
143
|
-
}
|
|
144
|
-
`, 'a', 'join', [0, 0]);
|
|
145
|
-
});
|
|
146
|
-
test('source lenses go before block annotations when one source', () => {
|
|
147
|
-
testLens((0, test_translator_1.markSource) `${`# tag
|
|
148
|
-
# tag2
|
|
149
|
-
source:
|
|
150
|
-
# tag3
|
|
151
|
-
flights is DB.table('my.table.flights')`}`, [0]);
|
|
152
|
-
});
|
|
153
|
-
test('source lenses go before individual annotations when more than one source', () => {
|
|
154
|
-
testLens((0, test_translator_1.markSource) `# tag
|
|
155
|
-
source:
|
|
156
|
-
${`# tag2
|
|
157
|
-
flights is DB.table('my.table.flights')`}
|
|
158
|
-
|
|
159
|
-
flights2 is DB.table('my.table.flights')`, [0]);
|
|
160
|
-
});
|
|
161
|
-
test('query lenses go before block annotations when one source', () => {
|
|
162
|
-
testLens((0, test_translator_1.markSource) `${`# tag
|
|
163
|
-
# tag2
|
|
164
|
-
query:
|
|
165
|
-
# tag3
|
|
166
|
-
q is flights -> by_carrier`}`, [0]);
|
|
167
|
-
});
|
|
168
|
-
test('query lenses go before individual annotations when more than one source', () => {
|
|
169
|
-
testLens((0, test_translator_1.markSource) `# tag
|
|
170
|
-
query:
|
|
171
|
-
${`# tag2
|
|
172
|
-
q is flights -> by_carrier`}
|
|
173
|
-
|
|
174
|
-
q2 is flights -> by_carrier`, [0]);
|
|
175
|
-
});
|
|
176
|
-
test('anonymous query lenses go before block annotations', () => {
|
|
177
|
-
testLens((0, test_translator_1.markSource) `${`# tag
|
|
178
|
-
# tag2
|
|
179
|
-
query:
|
|
180
|
-
# tag3
|
|
181
|
-
flights -> by_carrier`}`, [0]);
|
|
182
|
-
});
|
|
183
|
-
test('run lenses go before block annotations', () => {
|
|
184
|
-
testLens((0, test_translator_1.markSource) `${`# tag
|
|
185
|
-
# tag2
|
|
186
|
-
run:
|
|
187
|
-
# tag3
|
|
188
|
-
flights -> by_carrier`}`, [0]);
|
|
189
|
-
});
|
|
190
|
-
test('multiline unnamed queries include last line', () => {
|
|
191
|
-
// The trailing } being in column 0 is significant
|
|
192
|
-
testLens((0, test_translator_1.markSource) `${`run: flights -> {
|
|
193
|
-
group_by: carrier
|
|
194
|
-
}`}`, [0]);
|
|
195
|
-
});
|
|
196
|
-
test('multiline named queries include last line', () => {
|
|
197
|
-
// The trailing } being in column 0 is significant
|
|
198
|
-
testLens((0, test_translator_1.markSource) `${`query: by_carrier is flights -> {
|
|
199
|
-
group_by: carrier
|
|
200
|
-
}`}`, [0]);
|
|
201
|
-
});
|
|
202
|
-
test('(regression) query does not use source block range', () => {
|
|
203
|
-
testLens((0, test_translator_1.markSource) `source: a is DB.table('b') extend {
|
|
204
|
-
query:
|
|
205
|
-
${'x is {select: *}'}
|
|
206
|
-
y is {select: *}
|
|
207
|
-
}`, [0, 0]);
|
|
208
|
-
});
|
|
209
|
-
//# sourceMappingURL=document-symbol-walker.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import './parse-expects';
|