-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcommands.js
119 lines (94 loc) · 2.84 KB
/
commands.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
const childProcess = require('child_process')
const copy = require('recursive-copy')
const fs = require('fs')
const glob = require('glob')
const mkdirp = require('mkdirp')
const parser = require('solidity-parser-antlr')
const mutators = require('./mutators')
const config = require('./config')
const Reporter = require('./reporter')
const baselineDir = config.baselineDir
const contractsDir = config.contractsDir
const contractsGlob = config.contractsGlob
function prepare(callback) {
mkdirp(baselineDir, () =>
copy(contractsDir, baselineDir, { dot: true }, callback)
)
}
function generateAllMutations(files) {
let mutations = []
const mutator = new mutators.CompositeMutator([
new mutators.ConditionalBoundaryMutator(),
new mutators.LiteralMutator(),
new mutators.EventEliminatorMutator()
])
for (const file of files) {
const source = fs.readFileSync(file, 'utf8')
const ast = parser.parse(source, { range: true })
const visit = parser.visit.bind(parser, ast)
mutations = mutations.concat(mutator.getMutations(file, source, visit))
}
return mutations
}
function mutationsByHash(mutations) {
return mutations.reduce((obj, mutation) => {
obj[mutation.hash()] = mutation
return obj
}, {})
}
function runTests(mutation) {
const proc = childProcess.spawnSync('npm', ['test'])
return proc.status === 0
}
function test(argv) {
const reporter = new Reporter()
prepare(() =>
glob(contractsDir + contractsGlob, (err, files) => {
if (err) {
console.error(err)
process.exit(1)
}
const mutations = generateAllMutations(files)
for (const mutation of mutations) {
mutation.apply()
reporter.beginMutant(mutation)
const result = runTests(mutation)
if (result) {
reporter.mutantSurvived(mutation)
if (argv.failfast) process.exit(1)
} else {
reporter.mutantKilled(mutation)
}
mutation.restore()
}
reporter.summary()
})
)
}
function preflight(argv) {
prepare(() =>
glob(contractsDir + contractsGlob, (err, files) => {
const mutations = generateAllMutations(files)
console.log(mutations.length + ' possible mutations found.')
console.log('---')
for (const mutation of mutations) {
console.log(mutation.file + ':' + mutation.hash() + ':')
process.stdout.write(mutation.diff())
}
})
)
}
function diff(argv) {
prepare(() =>
glob(contractsDir + contractsGlob, (err, files) => {
const mutations = generateAllMutations(files)
const index = mutationsByHash(mutations)
if (!index[argv.hash]) {
console.error('Mutation ' + argv.hash + ' not found.')
process.exit(1)
}
console.log(index[argv.hash].diff())
})
)
}
module.exports = { test: test, preflight, preflight, diff: diff }