Skip to content

Commit 031232e

Browse files
author
legend
authored
Merge pull request jest-community#1 from orta/ast-parse
AST Parse for it/test blocks
2 parents 4e73bc1 + d8ca05a commit 031232e

8 files changed

Lines changed: 243 additions & 15 deletions

File tree

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"type": "extensionHost",
1919
"request": "launch",
2020
"runtimeExecutable": "${execPath}",
21-
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ],
21+
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test"],
2222
"stopOnEntry": false,
2323
"sourceMaps": true,
2424
"outDir": "${workspaceRoot}/out/test",

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@
4040
"postinstall": "node ./node_modules/vscode/bin/install"
4141
},
4242
"devDependencies": {
43-
"typescript": "^2.0.3",
44-
"vscode": "^1.0.0",
45-
"mocha": "^2.3.3",
43+
"@types/babylon": "^6.7.14",
44+
"@types/mocha": "^2.2.32",
4645
"@types/node": "^6.0.40",
47-
"@types/mocha": "^2.2.32"
46+
"mocha": "^2.3.3",
47+
"typescript": "^2.0.3",
48+
"vscode": "^1.0.0"
4849
},
4950
"dependencies": {
51+
"babylon": "^6.13.0",
5052
"tmp": "0.0.29"
5153
}
5254
}

src/jest_runner.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class JestRunner extends EventEmitter {
1212
constructor() {
1313
super();
1414

15-
var runtimeArgs = ['.', '--json', '--useStderr', '--watch', '--coverage', 'true ', '--colors', 'false', "--verbose"];
15+
var runtimeArgs = ['.', '--json', '--useStderr', '--watch', '--colors', 'false', "--verbose"];
1616
var runtimeExecutable: string;
1717

1818
runtimeExecutable = "node_modules/.bin/jest"
@@ -49,20 +49,12 @@ export class JestRunner extends EventEmitter {
4949
this.emit('terminalError', "Process failed: " + error.message);
5050
});
5151

52-
this.debugprocess.on('disconnect', () => {
53-
console.log("DDD")
54-
});
55-
56-
this.debugprocess.on('message', () => {
57-
console.log("MMM")
58-
});
59-
6052
this.debugprocess.on('close', () => {
6153
console.log("Jest Closed")
6254
});
6355
}
6456

65-
// This doens't work...
57+
// This doesn't work yet...
6658
public triggerFullTestSuite() {
6759
this.debugprocess.stdin.write("o")
6860
}

src/test_file_parser.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
'use strict'
2+
3+
import fs = require('fs');
4+
5+
import {basename, dirname} from 'path';
6+
import * as path from 'path';
7+
8+
// var esprima = require('esprima');
9+
import * as babylon from 'babylon'
10+
11+
interface Location {
12+
line: number
13+
column: number
14+
}
15+
16+
export class ItBlock {
17+
name: string
18+
file: string
19+
start: Location
20+
end: Location
21+
22+
updateWithNode(node: any){
23+
this.start = node.loc.start
24+
this.end = node.loc.end
25+
this.name = node.expression.arguments[0].value
26+
}
27+
}
28+
29+
export default class TestFileParser {
30+
31+
itBlocks: ItBlock[]
32+
33+
async run(file: string): Promise<any> {
34+
let data = await this.generateAST(file)
35+
this.itBlocks = []
36+
this.findItBlocksInBody(data["program"])
37+
return data
38+
}
39+
40+
foundItNode(node){
41+
let it = new ItBlock()
42+
it.updateWithNode(node)
43+
this.itBlocks.push(it)
44+
}
45+
46+
isAnIt(node) {
47+
return (
48+
node.type === "ExpressionStatement" &&
49+
node.expression.type === "CallExpression"
50+
)
51+
&&
52+
(
53+
node.expression.callee.name === "it" ||
54+
node.expression.callee.name === "test"
55+
)
56+
}
57+
58+
isADescribe(node) {
59+
return node.type === "ExpressionStatement" &&
60+
node.expression.type === "CallExpression" &&
61+
node.expression.callee.name === "describe"
62+
}
63+
64+
findItBlocksInBody(root) {
65+
for (var node in root.body) {
66+
if (root.body.hasOwnProperty(node)) {
67+
var element = root.body[node];
68+
if (this.isADescribe(element)){
69+
if (element.expression.arguments.length == 2) {
70+
let newBody = element.expression.arguments[1].body
71+
this.findItBlocksInBody(newBody);
72+
}
73+
}
74+
if (this.isAnIt(element)) {
75+
this.foundItNode(element)
76+
}
77+
}
78+
}
79+
}
80+
81+
generateAST(file: string): Promise<babylon.Node> {
82+
return new Promise((resolve, reject) =>{
83+
var parentDir = path.resolve(process.cwd(), '..');
84+
85+
fs.readFile(file, "utf8", (err, data) => {
86+
if (err) { return reject(err.message) }
87+
resolve(babylon.parse(data, { sourceType:"module", plugins: ["jsx", "flow"] }))
88+
})
89+
})
90+
}
91+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import Travis from "../travis.js"
2+
3+
let correctEnv = {
4+
"HAS_JOSH_K_SEAL_OF_APPROVAL": "true",
5+
"TRAVIS_PULL_REQUEST": "800",
6+
"TRAVIS_REPO_SLUG": "artsy/eigen"
7+
}
8+
9+
describe(".isCI", () => {
10+
test("validates when all Travis environment vars are set and Josh K says so", () => {
11+
let travis = new Travis(correctEnv)
12+
expect(travis.isCI).toBeTruthy()
13+
})
14+
15+
test("does not validate without josh", () => {
16+
let travis = new Travis({})
17+
expect(travis.isCI).toBeFalsy()
18+
})
19+
})
20+
21+
describe(".isPR", () => {
22+
test("validates when all Travis environment vars are set and Josh K says so", () => {
23+
let travis = new Travis(correctEnv)
24+
expect(travis.isPR).toBeTruthy()
25+
})
26+
27+
test("does not validate without josh", () => {
28+
let travis = new Travis({})
29+
expect(travis.isPR).toBeFalsy()
30+
})
31+
32+
let envs = ["TRAVIS_PULL_REQUEST", "TRAVIS_REPO_SLUG"]
33+
envs.forEach((key: string) => {
34+
var env = {
35+
"HAS_JOSH_K_SEAL_OF_APPROVAL": "true",
36+
"TRAVIS_PULL_REQUEST": "800",
37+
"TRAVIS_REPO_SLUG": "artsy/eigen"
38+
}
39+
env[key] = null
40+
41+
test(`does not validate when ${key} is missing`, () => {
42+
let travis = new Travis({})
43+
expect(travis.isPR).toBeFalsy()
44+
})
45+
})
46+
47+
it("needs to have a PR number", () => {
48+
var env = {
49+
"HAS_JOSH_K_SEAL_OF_APPROVAL": "true",
50+
"TRAVIS_PULL_REQUEST": "asdasd",
51+
"TRAVIS_REPO_SLUG": "artsy/eigen"
52+
}
53+
let travis = new Travis(env)
54+
expect(travis.isPR).toBeFalsy()
55+
})
56+
})
57+
58+
describe(".pullReuestID", () => {
59+
it("pulls it out of the env", () => {
60+
let travis = new Travis(correctEnv)
61+
expect(travis.pullRequestID).toEqual("800")
62+
})
63+
})
64+
65+
describe(".repoSlug", () => {
66+
it("pulls it out of the env", () => {
67+
let travis = new Travis(correctEnv)
68+
expect(travis.repoSlug).toEqual("artsy/eigen")
69+
})
70+
})

test/fixtures/global_its.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
it("works with old functions", function() {
2+
3+
})
4+
5+
it("works with new functions", () => {
6+
7+
})

test/fixtures/nested_its.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
describe("some context", () => {
2+
it("1", function() {
3+
})
4+
it("2", function() {
5+
})
6+
})
7+
8+
describe("some other context", function() {
9+
it("3", () => {
10+
})
11+
})

test/test_file_parser.test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// The module 'assert' provides assertion methods from node
2+
import * as assert from 'assert';
3+
4+
// You can import and use all API from the 'vscode' module
5+
// as well as import your extension to test it
6+
import * as vscode from 'vscode';
7+
import * as myExtension from '../src/extension';
8+
9+
import Parser from '../src/test_file_parser'
10+
11+
suite("File Parsing", () => {
12+
13+
test("For the simplest global case", async () => {
14+
let parser = new Parser()
15+
await parser.run(__dirname + "/../../test/fixtures/global_its.js")
16+
assert.equal(parser.itBlocks.length, 2)
17+
18+
let firstIt = parser.itBlocks[0]
19+
assert.equal(firstIt.name, "works with old functions")
20+
assert.notStrictEqual(firstIt.start, { line: 1, column: 0 })
21+
assert.notStrictEqual(firstIt.end, { line: 3, column: 0 })
22+
23+
let secondIt = parser.itBlocks[1]
24+
assert.equal(secondIt.name, "works with new functions")
25+
assert.notStrictEqual(secondIt.start, { line: 5, column: 0 })
26+
assert.notStrictEqual(secondIt.end, { line: 7, column: 0 })
27+
});
28+
29+
test("For its inside describes", async () => {
30+
let parser = new Parser()
31+
await parser.run(__dirname + "/../../test/fixtures/nested_its.js")
32+
assert.equal(parser.itBlocks.length, 3)
33+
34+
let firstIt = parser.itBlocks[0]
35+
assert.equal(firstIt.name, "1")
36+
assert.deepEqual(firstIt.start, { line: 2, column: 4 })
37+
assert.deepEqual(firstIt.end, { line: 3, column: 6 })
38+
39+
let secondIt = parser.itBlocks[1]
40+
assert.equal(secondIt.name, "2")
41+
assert.deepEqual(secondIt.start, { line: 4, column: 4 })
42+
assert.deepEqual(secondIt.end, { line: 5, column: 6 })
43+
44+
let thirdIt = parser.itBlocks[2]
45+
assert.equal(thirdIt.name, "3")
46+
assert.deepEqual(thirdIt.start, { line: 9, column: 4 })
47+
assert.deepEqual(thirdIt.end, { line: 10, column: 6 })
48+
});
49+
50+
test("For a danger test file (which has flow annotations)", async () => {
51+
let parser = new Parser()
52+
await parser.run(__dirname + "/../../test/fixtures/dangerjs/travis-ci.jstest.js")
53+
assert.equal(parser.itBlocks.length, 7)
54+
})
55+
});

0 commit comments

Comments
 (0)