Skip to content

Commit ab464b7

Browse files
committed
Added new properties to Test proto
1 parent e168207 commit ab464b7

File tree

3 files changed

+223
-7
lines changed

3 files changed

+223
-7
lines changed

core/actions/test.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { verifyObjectMatchesProto, VerifyProtoErrorBehaviour } from "df/common/protos";
22
import { ActionBuilder, INamedConfig, TableType } from "df/core/actions";
33
import { IncrementalTable } from "df/core/actions/incremental_table";
4-
import { Table } from "df/core/actions/table";
5-
import { View } from "df/core/actions/view";
4+
import { Table, TableContext } from "df/core/actions/table";
5+
import { View, ViewContext } from "df/core/actions/view";
66
import { Contextable, IActionContext, ITableContext, Resolvable } from "df/core/contextables";
77
import { Session } from "df/core/session";
88
import { targetStringifier } from "df/core/targets";
@@ -77,7 +77,8 @@ export class Test extends ActionBuilder<dataform.Test> {
7777

7878
/** @hidden We delay contextification until the final compile step, so hold these here for now. */
7979
public contextableInputs = new Map<string, Contextable<IActionContext, string>>();
80-
private contextableQuery: Contextable<IActionContext, string>;
80+
private inputToTargets = new Map<string, dataform.Target>();
81+
private contextableQuery: Contextable<IActionContext, string>;
8182
private datasetToTest: Resolvable;
8283

8384
/**
@@ -127,13 +128,20 @@ export class Test extends ActionBuilder<dataform.Test> {
127128
* Sets the input query to unit test against.
128129
*/
129130
public input(refName: string | string[], contextableQuery: Contextable<IActionContext, string>) {
131+
const target = resolvableAsTarget(toResolvable(refName));
132+
const inputName = targetStringifier.stringify(target);
130133
this.contextableInputs.set(
131-
targetStringifier.stringify(resolvableAsTarget(toResolvable(refName))),
134+
inputName,
132135
contextableQuery
133136
);
137+
this.inputToTargets.set(inputName, target);
134138
return this;
135139
}
136140

141+
public resolveSchema(resolveSchema: boolean) {
142+
this.proto.resolveSchema = resolveSchema;
143+
}
144+
137145
/**
138146
* Sets the expected output of the query to being tested against.
139147
*/
@@ -188,7 +196,34 @@ export class Test extends ActionBuilder<dataform.Test> {
188196
} else {
189197
const refReplacingContext = new RefReplacingContext(testContext);
190198
this.proto.testQuery = refReplacingContext.apply(dataset.contextableQuery);
199+
200+
// Set the test query with the fully qualified table references.
201+
if (dataset instanceof Table) {
202+
const tableContext = new TableContext(dataset);
203+
this.proto.query = tableContext.apply(dataset.contextableQuery);
204+
} else {
205+
const viewContext = new ViewContext(dataset);
206+
this.proto.query = viewContext.apply(dataset.contextableQuery);
207+
}
191208
}
209+
210+
// Build the inputs list with the fully qualified input names and the input query to mock each input.
211+
this.contextableInputs.forEach((inputContextable, inputName) => {
212+
const testInput = dataform.Test.TestInput.create();
213+
testInput.query = testContext.apply(inputContextable);
214+
testInput.target = this.applySessionToTarget(
215+
this.inputToTargets.get(inputName),
216+
this.session.projectConfig,
217+
this.getFileName(),
218+
{
219+
validateTarget: true
220+
});
221+
this.proto.inputs.push(testInput);
222+
});
223+
224+
// Add target property/
225+
this.proto.testTarget = dataset.getTarget();
226+
this.proto.resolveSchema = false;
192227
}
193228
this.proto.expectedOutputQuery = testContext.apply(this.contextableQuery);
194229

core/actions/test_test.ts

Lines changed: 174 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,176 @@
1-
import { suite } from "df/testing";
1+
import { expect } from "chai";
2+
import * as fs from "fs-extra";
3+
import * as path from "path";
24

3-
suite("test", () => {
4-
// This action currently has no unit tests!
5+
import { asPlainObject, suite, test } from "df/testing";
6+
import { TmpDirFixture } from "df/testing/fixtures";
7+
import {
8+
coreExecutionRequestFromPath,
9+
runMainInVm,
10+
VALID_WORKFLOW_SETTINGS_YAML
11+
} from "df/testing/run_core";
12+
13+
suite("test", ({ afterEach }) => {
14+
const tmpDirFixture = new TmpDirFixture(afterEach);
15+
16+
test(`test with no inputs`, () => {
17+
const projectDir = tmpDirFixture.createNewTmpDir();
18+
fs.writeFileSync(
19+
path.join(projectDir, "workflow_settings.yaml"),
20+
VALID_WORKFLOW_SETTINGS_YAML
21+
);
22+
fs.mkdirSync(path.join(projectDir, "definitions"));
23+
fs.writeFileSync(
24+
path.join(projectDir, "definitions/actions.yaml"),
25+
`
26+
actions:
27+
- table:
28+
filename: action.sql`
29+
);
30+
fs.writeFileSync(path.join(projectDir, "definitions/action.sql"), "SELECT 1");
31+
fs.writeFileSync(path.join(projectDir, "definitions/action_test.sqlx"),
32+
`
33+
config {
34+
type: "test",
35+
dataset: "action"
36+
}
37+
SELECT 1`);
38+
39+
const result = runMainInVm(coreExecutionRequestFromPath(projectDir));
40+
41+
expect(result.compile.compiledGraph.graphErrors.compilationErrors).deep.equals([]);
42+
expect(asPlainObject(result.compile.compiledGraph.tests)).deep.equals(
43+
asPlainObject([
44+
{
45+
// Original test properties
46+
name: "action_test",
47+
testQuery: "SELECT 1",
48+
expectedOutputQuery: "\n\nSELECT 1",
49+
fileName: "definitions/action_test.sqlx",
50+
51+
// New properties
52+
testTarget: {
53+
database: "defaultProject",
54+
schema: "defaultDataset",
55+
name: "action"
56+
},
57+
query: "SELECT 1",
58+
resolveSchema: false,
59+
}
60+
])
61+
);
62+
});
63+
64+
test(`test with multiple_inputs input`, () => {
65+
const projectDir = tmpDirFixture.createNewTmpDir();
66+
fs.writeFileSync(
67+
path.join(projectDir, "workflow_settings.yaml"),
68+
VALID_WORKFLOW_SETTINGS_YAML
69+
);
70+
fs.mkdirSync(path.join(projectDir, "definitions"));
71+
72+
// Add a declaration
73+
fs.writeFileSync(
74+
path.join(projectDir, "definitions/actions.yaml"),
75+
`
76+
actions:
77+
- declaration:
78+
name: a_declaration`
79+
);
80+
81+
// Add an action with a test, reads from declaration
82+
fs.writeFileSync(path.join(projectDir, "definitions/action1.sqlx"),
83+
`
84+
config {
85+
type: "table",
86+
}
87+
SELECT a,b,c FROM \${ref("a_declaration")}
88+
`);
89+
fs.writeFileSync(path.join(projectDir, "definitions/action1_test.sqlx"),
90+
`
91+
config {
92+
type: "test",
93+
dataset: "action1"
94+
}
95+
input "a_declaration" {
96+
SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d
97+
}
98+
SELECT 1 AS a, 2 AS b, 3 AS c`);
99+
100+
101+
// Add an action with a test, reads from previous action
102+
fs.writeFileSync(path.join(projectDir, "definitions/action2.sqlx"),
103+
`
104+
config {
105+
type: "table",
106+
}
107+
SELECT a,b FROM \${ref("action1")}
108+
`);
109+
fs.writeFileSync(path.join(projectDir, "definitions/action2_test.sqlx"),
110+
`
111+
config {
112+
type: "test",
113+
dataset: "action2"
114+
}
115+
input "action1" {
116+
SELECT 1 AS a, 2 AS b, 3 AS c
117+
}
118+
SELECT 1 AS a, 2 AS b`);
119+
120+
const result = runMainInVm(coreExecutionRequestFromPath(projectDir));
121+
122+
expect(result.compile.compiledGraph.graphErrors.compilationErrors).deep.equals([]);
123+
expect(asPlainObject(result.compile.compiledGraph.tests)).deep.equals(
124+
asPlainObject([
125+
{
126+
// Original test properties
127+
name: "action1_test",
128+
testQuery: "\n\nSELECT a,b,c FROM (\n SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d\n)\n ",
129+
expectedOutputQuery: "\n\n\nSELECT 1 AS a, 2 AS b, 3 AS c",
130+
fileName: "definitions/action1_test.sqlx",
131+
132+
// New properties
133+
testTarget: {
134+
database: "defaultProject",
135+
schema: "defaultDataset",
136+
name: "action1"
137+
},
138+
inputs: [{
139+
query: "\n SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d\n",
140+
target: {
141+
database: "defaultProject",
142+
schema: "defaultDataset",
143+
name: "a_declaration"
144+
}
145+
}],
146+
query: "\n\nSELECT a,b,c FROM `defaultProject.defaultDataset.a_declaration`\n ",
147+
resolveSchema: false,
148+
},
149+
{
150+
// Original test properties
151+
name: "action2_test",
152+
testQuery: "\n\nSELECT a,b FROM (\n SELECT 1 AS a, 2 AS b, 3 AS c\n)\n ",
153+
expectedOutputQuery: "\n\n\nSELECT 1 AS a, 2 AS b",
154+
fileName: "definitions/action2_test.sqlx",
155+
156+
// New properties
157+
testTarget: {
158+
database: "defaultProject",
159+
schema: "defaultDataset",
160+
name: "action2"
161+
},
162+
inputs: [{
163+
query: "\n SELECT 1 AS a, 2 AS b, 3 AS c\n",
164+
target: {
165+
database: "defaultProject",
166+
schema: "defaultDataset",
167+
name: "action1"
168+
}
169+
}],
170+
query: "\n\nSELECT a,b FROM `defaultProject.defaultDataset.action1`\n ",
171+
resolveSchema: false,
172+
}
173+
])
174+
);
175+
});
5176
});

protos/core.proto

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,16 @@ message Test {
264264

265265
// Generated.
266266
string file_name = 4;
267+
268+
Target test_target = 5;
269+
repeated TestInput inputs = 6;
270+
string query = 7;
271+
bool resolve_schema = 8;
272+
273+
message TestInput {
274+
Target target = 1;
275+
string query = 2;
276+
}
267277
}
268278

269279
message Notebook {

0 commit comments

Comments
 (0)