-
Notifications
You must be signed in to change notification settings - Fork 17
/
StepDefinitionFile.js
120 lines (97 loc) · 4 KB
/
StepDefinitionFile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Constants:
const PENDING_IDENTIFIER = 'pending';
const PENDING_QUERY = 'CallExpression[callee.name="callback"] .arguments[value]';
const REQUIRE_QUERY = 'CallExpression[callee.name="require"] Literal';
// Utilities:
import path from 'path';
// Dependencies:
import esquery from 'esquery';
import { JavaScriptFile } from './JavaScriptFile';
import { registerFileType } from 'tractor-file-structure';
export class StepDefinitionFile extends JavaScriptFile {
move (update, options) {
let referencePaths = Object.keys(this.fileStructure.references)
.filter(reference => this.fileStructure.references[reference].includes(this.path));
// Hack to fix coverage bug: https://github.com/gotwarlost/istanbul/issues/690
/* istanbul ignore next */
let move = super.move(update, options);
return move.then(newFile => {
referencePaths.forEach(referencePath => {
newFile.transformRequirePaths({
oldFromPath: this.path,
newFromPath: newFile.path,
toPath: referencePath
});
});
return newFile.save(newFile.ast);
});
}
read () {
// Hack to fix coverage bug: https://github.com/gotwarlost/istanbul/issues/690
/* istanbul ignore next */
let read = super.read();
return read.then(() => getFileReferences.call(this))
.then(() => checkIfPending.call(this))
.then(() => this.content);
}
save (data) {
// Hack to fix coverage bug: https://github.com/gotwarlost/istanbul/issues/690
/* istanbul ignore next */
let save = super.save(data);
return save.then(() => getFileReferences.call(this))
.then(() => checkIfPending.call(this))
.then(() => this.content);
}
transformRequirePaths (options) {
let { oldFromPath, newFromPath } = options;
if (!(oldFromPath && newFromPath)) {
oldFromPath = newFromPath = options.fromPath;
}
let { oldToPath, newToPath } = options;
if (!(oldToPath && newToPath)) {
oldToPath = newToPath = options.toPath;
}
let oldRequirePath = getRelativeRequirePath(path.dirname(oldFromPath), oldToPath);
let newRequirePath = getRelativeRequirePath(path.dirname(newFromPath), newToPath);
updatePaths.call(this, oldRequirePath, newRequirePath);
}
}
StepDefinitionFile.prototype.extension = '.step.js';
StepDefinitionFile.prototype.type = 'step-definitions';
function checkIfPending () {
this.isPending = false;
let pendingIdentifiers = esquery(this.ast, PENDING_QUERY);
pendingIdentifiers.forEach(pendingIdentifier => {
if (pendingIdentifier.value === PENDING_IDENTIFIER) {
this.isPending = true;
}
});
}
function getFileReferences () {
let { references } = this.fileStructure;
Object.keys(references).forEach(filePath => {
let referencePaths = references[filePath];
if (referencePaths.includes(this.path)) {
let index = referencePaths.indexOf(this.path);
referencePaths.splice(index, 1);
}
});
esquery(this.ast, REQUIRE_QUERY).forEach(requirePath => {
let directoryPath = path.dirname(this.path);
let referencePath = path.resolve(directoryPath, requirePath.value);
references[referencePath] = references[referencePath] || [];
references[referencePath].push(this.path);
});
}
function getRelativeRequirePath (from, to) {
let relativePath = path.relative(from, to).replace(/\\/g, '/');
return /^\./.test(relativePath) ? relativePath : `./${relativePath}`;
}
function updatePaths (oldRequirePath, newRequirePath) {
let query = `CallExpression[callee.name="require"] Literal[value="${oldRequirePath}"]`;
esquery(this.ast, query).forEach(requirePathLiteral => {
requirePathLiteral.value = newRequirePath;
requirePathLiteral.raw = `'${newRequirePath}'`;
});
}
registerFileType(StepDefinitionFile);