Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core/actions/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,20 @@ export class Test extends ActionBuilder<dataform.Test> {
}
this.proto.expectedOutputQuery = testContext.apply(this.contextableQuery);

// Check if the test query and expected output query are non-empty.
if (!this.proto.testQuery.trim()) {
this.session.compileError(
new Error("Test query is empty."),
this.proto.fileName
);
}
if (!this.proto.expectedOutputQuery.trim()) {
this.session.compileError(
new Error("Expected query is empty."),
this.proto.fileName
);
}

return verifyObjectMatchesProto(
dataform.Test,
this.proto,
Expand Down
274 changes: 270 additions & 4 deletions core/actions/test_test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,271 @@
import { suite } from "df/testing";
// tslint:disable tsr-detect-non-literal-fs-filename
import { expect } from "chai";
import * as fs from "fs-extra";
import * as path from "path";

suite("test", () => {
// This action currently has no unit tests!
});
import { asPlainObject, suite, test } from "df/testing";
import { TmpDirFixture } from "df/testing/fixtures";
import {
coreExecutionRequestFromPath,
runMainInVm,
VALID_WORKFLOW_SETTINGS_YAML
} from "df/testing/run_core";

suite("test", ({ afterEach }) => {
const tmpDirFixture = new TmpDirFixture(afterEach);

test(`test with no inputs`, () => {
const projectDir = tmpDirFixture.createNewTmpDir();
const workflowSettingsPath = path.join(projectDir, "workflow_settings.yaml");
const definitionsDir = path.join(projectDir, "definitions");
const actionsYamlPath = path.join(definitionsDir, "actions.yaml");
const actionSqlPath = path.join(definitionsDir, "action.sql");
const actionTestSqlxPath = path.join(definitionsDir, "action_test.sqlx");

fs.writeFileSync(workflowSettingsPath, VALID_WORKFLOW_SETTINGS_YAML);
fs.mkdirSync(definitionsDir);
fs.writeFileSync(actionsYamlPath, `
actions:
- table:
filename: action.sql`
);
fs.writeFileSync(actionSqlPath, "SELECT 1");
fs.writeFileSync(actionTestSqlxPath, `
config {
type: "test",
dataset: "action"
}
SELECT 1`);

const result = runMainInVm(coreExecutionRequestFromPath(projectDir));

expect(result.compile.compiledGraph.graphErrors.compilationErrors).deep.equals([]);
expect(asPlainObject(result.compile.compiledGraph.tests)).deep.equals(
asPlainObject([
{
// Original test properties
name: "action_test",
testQuery: "SELECT 1",
expectedOutputQuery: "\n\nSELECT 1",
fileName: "definitions/action_test.sqlx",
}
])
);
expect(asPlainObject(result.compile.compiledGraph.tables)).deep.equals(
asPlainObject([
{
"target": {
"database": "defaultProject",
"name": "action",
"schema": "defaultDataset"
},
"canonicalTarget": {
"database": "defaultProject",
"name": "action",
"schema": "defaultDataset"
},
"disabled": false,
"enumType": "TABLE",
"fileName": "definitions/action.sql",
"hermeticity": "NON_HERMETIC",
"query": "SELECT 1",
"type": "table"
}
]));
});

test(`test with multiple_inputs input`, () => {
const projectDir = tmpDirFixture.createNewTmpDir();
const workflowSettingsPath = path.join(projectDir, "workflow_settings.yaml");
const definitionsDir = path.join(projectDir, "definitions");
const actionsYamlPath = path.join(definitionsDir, "actions.yaml");
const action1SqlxPath = path.join(definitionsDir, "action1.sqlx");
const action1TestSqlxPath = path.join(definitionsDir, "action1_test.sqlx");
const action2SqlxPath = path.join(definitionsDir, "action2.sqlx");
const action2TestSqlxPath = path.join(definitionsDir, "action2_test.sqlx");

fs.writeFileSync(workflowSettingsPath, VALID_WORKFLOW_SETTINGS_YAML);
fs.mkdirSync(definitionsDir);

// Add a declaration
fs.writeFileSync(actionsYamlPath, `
actions:
- declaration:
name: a_declaration`
);

// Add an action with a test, reads from declaration
fs.writeFileSync(action1SqlxPath, `
config {
type: "table",
}
SELECT a,b,c FROM \${ref("a_declaration")}
`);
fs.writeFileSync(action1TestSqlxPath, `
config {
type: "test",
dataset: "action1"
}
input "a_declaration" {
SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d
}
SELECT 1 AS a, 2 AS b, 3 AS c`);


// Add an action with a test, reads from previous action
fs.writeFileSync(action2SqlxPath, `
config {
type: "table",
}
SELECT a,b FROM \${ref("action1")}
`);
fs.writeFileSync(action2TestSqlxPath, `
config {
type: "test",
dataset: "action2"
}
input "action1" {
SELECT 1 AS a, 2 AS b, 3 AS c
}
SELECT 1 AS a, 2 AS b`);

const result = runMainInVm(coreExecutionRequestFromPath(projectDir));

expect(result.compile.compiledGraph.graphErrors.compilationErrors).deep.equals([]);
expect(asPlainObject(result.compile.compiledGraph.tests)).deep.equals(
asPlainObject([
{
// Original test properties
name: "action1_test",
testQuery: "\n\nSELECT a,b,c FROM (\n SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d\n)\n ",
expectedOutputQuery: "\n\n\nSELECT 1 AS a, 2 AS b, 3 AS c",
fileName: "definitions/action1_test.sqlx",
},
{
// Original test properties
name: "action2_test",
testQuery: "\n\nSELECT a,b FROM (\n SELECT 1 AS a, 2 AS b, 3 AS c\n)\n ",
expectedOutputQuery: "\n\n\nSELECT 1 AS a, 2 AS b",
fileName: "definitions/action2_test.sqlx",
}
])
);
expect(asPlainObject(result.compile.compiledGraph.tables)).deep.equals(
asPlainObject([
{
"target": {
"database": "defaultProject",
"name": "action1",
"schema": "defaultDataset"
},
"canonicalTarget": {
"database": "defaultProject",
"name": "action1",
"schema": "defaultDataset"
},
"dependencyTargets": [
{
"database": "defaultProject",
"name": "a_declaration",
"schema": "defaultDataset"
}
],
"disabled": false,
"enumType": "TABLE",
"fileName": "definitions/action1.sqlx",
"hermeticity": "NON_HERMETIC",
"query": "\n\nSELECT a,b,c FROM `defaultProject.defaultDataset.a_declaration`\n ",
"type": "table"
},
{
"target": {
"database": "defaultProject",
"name": "action2",
"schema": "defaultDataset"
},
"canonicalTarget": {
"database": "defaultProject",
"name": "action2",
"schema": "defaultDataset"
},
"dependencyTargets": [
{
"database": "defaultProject",
"name": "action1",
"schema": "defaultDataset"
}
],
"disabled": false,
"enumType": "TABLE",
"fileName": "definitions/action2.sqlx",
"hermeticity": "NON_HERMETIC",
"query": "\n\nSELECT a,b FROM `defaultProject.defaultDataset.action1`\n ",
"type": "table"
}
])
);
});

test(`test with empty test sql`, () => {
const projectDir = tmpDirFixture.createNewTmpDir();
const workflowSettingsPath = path.join(projectDir, "workflow_settings.yaml");
const definitionsDir = path.join(projectDir, "definitions");
const actionsYamlPath = path.join(definitionsDir, "actions.yaml");
const action1SqlxPath = path.join(definitionsDir, "action1.sqlx");
const action1TestSqlxPath = path.join(definitionsDir, "action1_test.sqlx");
const action2SqlxPath = path.join(definitionsDir, "action2.sqlx");
const action2TestSqlxPath = path.join(definitionsDir, "action2_test.sqlx");

fs.writeFileSync(workflowSettingsPath, VALID_WORKFLOW_SETTINGS_YAML);
fs.mkdirSync(definitionsDir);

// Add a declaration
fs.writeFileSync(actionsYamlPath, `
actions:
- declaration:
name: a_declaration`
);

// Add an action with a test, reads from declaration
fs.writeFileSync(action1SqlxPath, `
config {
type: "table",
}
SELECT a,b,c FROM \${ref("a_declaration")}
`);
fs.writeFileSync(action1TestSqlxPath, `
config {
type: "test",
dataset: "action1"
}
input "a_declaration" {
SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d
}
`);


// Add an action with a test, reads from previous action
fs.writeFileSync(action2SqlxPath, `
config {
type: "table",
}
SELECT a,b FROM \${ref("action1")}
`);
fs.writeFileSync(action2TestSqlxPath, `
config {
type: "test",
dataset: "action2"
}
input "action1" {
SELECT 1 AS a, 2 AS b, 3 AS c
}
SELECT 1 AS a, 2 AS b`);

const result = runMainInVm(coreExecutionRequestFromPath(projectDir));

expect(result.compile.compiledGraph.graphErrors.compilationErrors.length).equals(1);
expect(result.compile.compiledGraph.graphErrors.compilationErrors[0].message).contains(
`Expected query is empty.`
);
});
});
Loading