@malloydata/malloy-tests 0.0.304 → 0.0.305

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/package.json CHANGED
@@ -21,14 +21,14 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@jest/globals": "^29.4.3",
24
- "@malloydata/db-bigquery": "0.0.304",
25
- "@malloydata/db-duckdb": "0.0.304",
26
- "@malloydata/db-postgres": "0.0.304",
27
- "@malloydata/db-snowflake": "0.0.304",
28
- "@malloydata/db-trino": "0.0.304",
29
- "@malloydata/malloy": "0.0.304",
30
- "@malloydata/malloy-tag": "0.0.304",
31
- "@malloydata/render": "0.0.304",
24
+ "@malloydata/db-bigquery": "0.0.305",
25
+ "@malloydata/db-duckdb": "0.0.305",
26
+ "@malloydata/db-postgres": "0.0.305",
27
+ "@malloydata/db-snowflake": "0.0.305",
28
+ "@malloydata/db-trino": "0.0.305",
29
+ "@malloydata/malloy": "0.0.305",
30
+ "@malloydata/malloy-tag": "0.0.305",
31
+ "@malloydata/render": "0.0.305",
32
32
  "events": "^3.3.0",
33
33
  "jsdom": "^22.1.0",
34
34
  "luxon": "^2.4.0",
@@ -38,5 +38,5 @@
38
38
  "@types/jsdom": "^21.1.1",
39
39
  "@types/luxon": "^2.4.0"
40
40
  },
41
- "version": "0.0.304"
41
+ "version": "0.0.305"
42
42
  }
@@ -485,21 +485,20 @@ expressionModels.forEach((x, databaseName) => {
485
485
  });
486
486
 
487
487
  it(`works using unary minus in calculate block - ${databaseName}`, async () => {
488
- const result = await expressionModel
489
- .loadQuery(
490
- `run: state_facts -> {
491
- group_by: first_letter is substr(state, 1, 1)
492
- aggregate: states_with_first_letter_ish is round(count() / 2) * 2
493
- calculate:
494
- r is rank()
495
- neg_r is -r
496
- }`
497
- )
498
- .run();
499
- expect(result.data.path(0, 'neg_r').value).toBe(-1);
500
- expect(result.data.path(1, 'neg_r').value).toBe(-1);
501
- expect(result.data.path(2, 'neg_r').value).toBe(-3);
502
- expect(result.data.path(3, 'neg_r').value).toBe(-3);
488
+ await expect(`
489
+ run: state_facts -> {
490
+ group_by: first_letter is substr(state, 1, 1)
491
+ aggregate: states_with_first_letter_ish is round(count() / 2) * 2
492
+ calculate:
493
+ r is rank()
494
+ neg_r is -r
495
+ }`).matchesRows(
496
+ expressionModel,
497
+ {neg_r: -1},
498
+ {neg_r: -1},
499
+ {neg_r: -3},
500
+ {neg_r: -3}
501
+ );
503
502
  });
504
503
 
505
504
  it(`properly isolated nested calculations - ${databaseName}`, async () => {
@@ -0,0 +1,201 @@
1
+ /* eslint-disable no-console */
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
+
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+
27
+ import {RuntimeList, allDatabases} from '../../runtimes';
28
+ import {databasesFromEnvironmentOr} from '../../util';
29
+ import '../../util/db-jest-matchers';
30
+
31
+ const runtimes = new RuntimeList(databasesFromEnvironmentOr(allDatabases));
32
+
33
+ // // No prebuilt shared model, each test is complete. Makes debugging easier.
34
+ // function rootDbPath(databaseName: string) {
35
+ // return databaseName === 'bigquery' ? 'malloydata-org.' : '';
36
+ // }
37
+
38
+ afterAll(async () => {
39
+ await runtimes.closeAll();
40
+ });
41
+
42
+ runtimes.runtimeMap.forEach((runtime, databaseName) => {
43
+ // const q = runtime.getQuoter();
44
+
45
+ describe('limits', () => {
46
+ test('limit only', async () => {
47
+ await expect(`
48
+ run: ${databaseName}.table('malloytest.state_facts') -> {
49
+ group_by: popular_name
50
+ aggregate: c is count()
51
+ limit: 3
52
+ }
53
+ `).malloyResultMatches(runtime, [{}, {}, {}]);
54
+ });
55
+
56
+ test('limit nest one', async () => {
57
+ await expect(`
58
+ run: ${databaseName}.table('malloytest.state_facts') -> {
59
+ group_by: popular_name
60
+ aggregate: c is count()
61
+ limit: 3
62
+ nest: one is {
63
+ group_by: state
64
+ limit: 2
65
+ }
66
+ }
67
+ `).malloyResultMatches(runtime, [
68
+ {popular_name: 'Isabella', one: [{'state': 'AZ'}, {}]},
69
+ {},
70
+ {},
71
+ ]);
72
+ });
73
+
74
+ test('limit nest with having', async () => {
75
+ await expect(`
76
+ run: ${databaseName}.table('malloytest.state_facts') -> {
77
+ group_by: popular_name
78
+ aggregate: c is count()
79
+ having: c % 2 = 1
80
+ limit: 3
81
+ nest: one is {
82
+ group_by: state
83
+ limit: 2
84
+ }
85
+ }
86
+ `).malloyResultMatches(runtime, [
87
+ {popular_name: 'Sophia', one: [{'state': 'AK'}, {}]},
88
+ {},
89
+ {},
90
+ ]);
91
+ });
92
+
93
+ test('limit two nests with having', async () => {
94
+ await expect(`
95
+ run: ${databaseName}.table('malloytest.state_facts') -> {
96
+ nest: name is {
97
+ group_by: popular_name
98
+ aggregate: c is count()
99
+ having: c % 2 = 1
100
+ limit: 3
101
+ }
102
+ nest: by_state is {
103
+ group_by: state
104
+ limit: 2
105
+ }
106
+ }
107
+ `).malloyResultMatches(runtime, [
108
+ {
109
+ 'name': [{popular_name: 'Sophia'}, {}, {}],
110
+ 'by_state': [{'state': 'AK'}, {}],
111
+ },
112
+ ]);
113
+ });
114
+
115
+ test('limit 2 stage second with nest with having', async () => {
116
+ await expect(`
117
+ run: ${databaseName}.table('malloytest.state_facts') -> {
118
+ select: *
119
+ } -> {
120
+ group_by: popular_name
121
+ aggregate: c is count()
122
+ having: c % 2 = 1
123
+ limit: 3
124
+ nest: one is {
125
+ group_by: state
126
+ limit: 2
127
+ }
128
+ }
129
+ `).malloyResultMatches(runtime, [
130
+ {popular_name: 'Sophia', one: [{'state': 'AK'}, {}]},
131
+ {},
132
+ {},
133
+ ]);
134
+ });
135
+
136
+ test('limit index 2 stage', async () => {
137
+ await expect(`
138
+ //# test.debug
139
+ run: ${databaseName}.table('malloytest.state_facts') -> {
140
+ index: *
141
+ } -> {
142
+ group_by: fieldName
143
+ aggregate: cardinality is count(fieldValue)
144
+ limit: 2
145
+ nest: values is {
146
+ group_by: fieldValue
147
+ aggregate: weight is weight.sum()
148
+ limit: 3
149
+ }
150
+ }
151
+ `).malloyResultMatches(runtime, [
152
+ {fieldName: 'state', values: [{}, {}, {}]},
153
+ {
154
+ fieldName: 'popular_name',
155
+ values: [{fieldValue: 'Isabella', weight: 24}, {}, {}],
156
+ },
157
+ ]);
158
+ });
159
+ test('limit select - in pipeline', async () => {
160
+ await expect(`
161
+ //# test.debug
162
+ run: ${databaseName}.table('malloytest.state_facts') -> {
163
+ group_by: popular_name
164
+ aggregate: c is count()
165
+ having: c % 2 = 1
166
+ limit: 100
167
+ nest: one is {
168
+ group_by: state
169
+ limit: 2
170
+ }
171
+ } -> {
172
+ select: popular_name
173
+ limit: 2
174
+ }
175
+ `).malloyResultMatches(runtime, [{}, {}]);
176
+ });
177
+
178
+ test.when(
179
+ runtime.supportsNesting &&
180
+ runtime.dialect.supportsPipelinesInViews &&
181
+ databaseName !== 'trino'
182
+ )('limit select - nested pipeline', async () => {
183
+ await expect(`
184
+ //# test.debug
185
+ run: ${databaseName}.table('malloytest.state_facts') -> {
186
+ group_by: popular_name
187
+ aggregate: c is count()
188
+ having: c % 2 = 1
189
+ limit: 1
190
+ nest: one is {
191
+ group_by: state
192
+ limit: 20
193
+ } -> {
194
+ select: state
195
+ limit: 2
196
+ }
197
+ }
198
+ `).malloyResultMatches(runtime, [{one: [{}, {}]}]);
199
+ });
200
+ });
201
+ });
@@ -128,7 +128,7 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
128
128
  group_by: m is manufacturer
129
129
  aggregate: num_models is count()
130
130
  } extend {
131
- join_one: seats is
131
+ join_one: seats_join is
132
132
  aircraft_models->{
133
133
  group_by: m is manufacturer
134
134
  aggregate: total_seats is seats.sum()
@@ -137,7 +137,7 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
137
137
  select:
138
138
  m
139
139
  num_models
140
- seats.total_seats
140
+ seats_join.total_seats
141
141
  order_by: 2 desc
142
142
  limit: 1
143
143
  }
@@ -223,8 +223,7 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
223
223
  }
224
224
  );
225
225
 
226
- // not sure how to solve this one yet, just check for > 4 rows
227
- it('All joins at the same level', async () => {
226
+ it('activates parent join when fields in leaf join are referenced', async () => {
228
227
  await expect(`
229
228
  source: flights is ${databaseName}.table('malloytest.flights') extend {
230
229
  join_one: aircraft is ${databaseName}.table('malloytest.aircraft')
@@ -238,14 +237,19 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
238
237
  aggregate: flight_count is count()
239
238
  limit: 5
240
239
  }
241
- `).malloyResultMatches(joinModel, [{}, {}, {}, {}, {}]);
240
+ `).malloyResultMatches(runtime, [{}, {}, {}, {}, {}]);
242
241
  });
243
242
 
243
+ // I don't know what join issue 440 was, there was a change of repos and that
244
+ // is no longer recorded anywhere. I suspect it was the indirect reference to
245
+ // the leaf join field. In a world where the join tree is built from fieldUsage
246
+ // that automatically works, but what is a problem is inferring the join tree
247
+ // from the ordering of usages. Inverting the "on" comparison in this test
248
+ // caused it to fail when the previous one passed.
244
249
  it('join issue440', async () => {
245
250
  await expect(`
246
- source: aircraft_models is ${databaseName}.table('malloytest.aircraft_models')
247
-
248
251
  source: aircraft is ${databaseName}.table('malloytest.aircraft')
252
+ source: aircraft_models is ${databaseName}.table('malloytest.aircraft_models')
249
253
 
250
254
  source: flights is ${databaseName}.table('malloytest.flights') extend {
251
255
  join_one: aircraft on aircraft.tail_num = tail_num
@@ -253,10 +257,10 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
253
257
  }
254
258
 
255
259
  run: flights-> {
256
- group_by: testingtwo is aircraft_models.model
257
- limit: 5
260
+ group_by: testtwo is aircraft_models.seats
261
+ limit: 1
258
262
  }
259
- `).malloyResultMatches(runtime, [{}, {}, {}, {}, {}]);
263
+ `).malloyResultMatches(runtime, [{}]);
260
264
  });
261
265
 
262
266
  it('join issue1092', async () => {
@@ -529,7 +529,7 @@ describe('airport_tests', () => {
529
529
  run: airports -> {
530
530
  group_by: county
531
531
  nest: stuff is {
532
- select: elevation
532
+ group_by: elevation
533
533
  order_by: 1 desc
534
534
  limit: 10
535
535
  }
package/src/runtimes.d.ts DELETED
@@ -1,53 +0,0 @@
1
- import type { Connection, MalloyQueryData, QueryDataRow, Result, RunSQLOptions, ModelCache } from '@malloydata/malloy';
2
- import { SingleConnectionRuntime, InMemoryURLReader, CacheManager } from '@malloydata/malloy';
3
- import { BigQueryConnection } from '@malloydata/db-bigquery';
4
- import { DuckDBConnection } from '@malloydata/db-duckdb';
5
- import { DuckDBWASMConnection } from '@malloydata/db-duckdb/wasm';
6
- import { SnowflakeConnection } from '@malloydata/db-snowflake';
7
- import { PooledPostgresConnection } from '@malloydata/db-postgres';
8
- import { MySQLConnection } from '@malloydata/db-mysql/src/mysql_connection';
9
- export declare class SnowflakeTestConnection extends SnowflakeConnection {
10
- runSQL(sqlCommand: string, options?: RunSQLOptions): Promise<MalloyQueryData>;
11
- }
12
- export declare class BigQueryTestConnection extends BigQueryConnection {
13
- runSQL(sqlCommand: string, options?: RunSQLOptions): Promise<MalloyQueryData>;
14
- }
15
- export declare class MySQLTestConnection extends MySQLConnection {
16
- runSQL(sqlCommand: string, options?: RunSQLOptions): Promise<MalloyQueryData>;
17
- }
18
- export declare class PostgresTestConnection extends PooledPostgresConnection {
19
- runSQL(sqlCommand: string, options?: RunSQLOptions): Promise<MalloyQueryData>;
20
- }
21
- export declare class DuckDBTestConnection extends DuckDBConnection {
22
- runSQL(sqlCommand: string, options?: RunSQLOptions): Promise<MalloyQueryData>;
23
- }
24
- export declare class DuckDBWASMTestConnection extends DuckDBWASMConnection {
25
- runSQL(sqlCommand: string, options?: RunSQLOptions): Promise<MalloyQueryData>;
26
- }
27
- export declare class TestCacheManager extends CacheManager {
28
- readonly _modelCache: ModelCache;
29
- constructor(_modelCache: ModelCache);
30
- }
31
- export declare class TestURLReader extends InMemoryURLReader {
32
- constructor();
33
- setFile(url: URL, contents: string): void;
34
- deleteFile(url: URL): void;
35
- }
36
- export declare function rows(qr: Result): QueryDataRow[];
37
- export declare function runtimeFor(dbName: string): SingleConnectionRuntime;
38
- export declare function testRuntimeFor(connection: Connection): SingleConnectionRuntime<Connection>;
39
- /**
40
- * All databases which should be tested by default. Experimental dialects
41
- * should not be in this list. Use MALLOY_DATABASE=dialect_name to test those
42
- */
43
- export declare const allDatabases: string[];
44
- type RuntimeDatabaseNames = (typeof allDatabases)[number];
45
- export declare class RuntimeList {
46
- runtimeMap: Map<string, SingleConnectionRuntime<Connection>>;
47
- runtimeList: Array<[string, SingleConnectionRuntime]>;
48
- constructor();
49
- constructor(databaseList: RuntimeDatabaseNames[]);
50
- constructor(externalConnections: SingleConnectionRuntime[]);
51
- closeAll(): Promise<void>;
52
- }
53
- export {};