Add coverage for ternary conditionals (#587)
parent
292819dc64
commit
7403f3f0e1
@ -1,185 +0,0 @@ |
|||||||
/* eslint-env node, mocha */ |
|
||||||
|
|
||||||
/*const path = require('path'); |
|
||||||
const getInstrumentedVersion = require('./../lib/instrumentSolidity.js'); |
|
||||||
const util = require('./util/util.js'); |
|
||||||
const CoverageMap = require('./../lib/coverageMap'); |
|
||||||
const vm = require('./util/vm'); |
|
||||||
const assert = require('assert'); |
|
||||||
|
|
||||||
describe.skip('conditional statements', () => { |
|
||||||
const filePath = path.resolve('./test.sol'); |
|
||||||
const pathPrefix = './'; |
|
||||||
|
|
||||||
it('should cover a conditional that reaches the consequent (same-line)', done => { |
|
||||||
const contract = util.getCode('conditional/sameline-consequent.sol'); |
|
||||||
const info = getInstrumentedVersion(contract, filePath); |
|
||||||
const coverage = new CoverageMap(); |
|
||||||
coverage.addContract(info, filePath); |
|
||||||
|
|
||||||
vm.execute(info.contract, 'a', []).then(events => { |
|
||||||
const mapping = coverage.generate(events, pathPrefix); |
|
||||||
assert.deepEqual(mapping[filePath].l, { |
|
||||||
5: 1, 6: 1, 7: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].b, { |
|
||||||
1: [1, 0], |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].s, { |
|
||||||
1: 1, 2: 1, 3: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].f, { |
|
||||||
1: 1, |
|
||||||
}); |
|
||||||
done(); |
|
||||||
}).catch(done); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should cover a conditional that reaches the alternate (same-line)', done => { |
|
||||||
const contract = util.getCode('conditional/sameline-alternate.sol'); |
|
||||||
const info = getInstrumentedVersion(contract, filePath); |
|
||||||
const coverage = new CoverageMap(); |
|
||||||
coverage.addContract(info, filePath); |
|
||||||
|
|
||||||
vm.execute(info.contract, 'a', []).then(events => { |
|
||||||
const mapping = coverage.generate(events, pathPrefix); |
|
||||||
assert.deepEqual(mapping[filePath].l, { |
|
||||||
5: 1, 6: 1, 7: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].b, { |
|
||||||
1: [0, 1], |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].s, { |
|
||||||
1: 1, 2: 1, 3: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].f, { |
|
||||||
1: 1, |
|
||||||
}); |
|
||||||
done(); |
|
||||||
}).catch(done); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should cover a conditional that reaches the consequent (multi-line)', done => { |
|
||||||
const contract = util.getCode('conditional/multiline-consequent.sol'); |
|
||||||
const info = getInstrumentedVersion(contract, filePath); |
|
||||||
const coverage = new CoverageMap(); |
|
||||||
coverage.addContract(info, filePath); |
|
||||||
|
|
||||||
vm.execute(info.contract, 'a', []).then(events => { |
|
||||||
const mapping = coverage.generate(events, pathPrefix); |
|
||||||
assert.deepEqual(mapping[filePath].l, { |
|
||||||
5: 1, 6: 1, 7: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].b, { |
|
||||||
1: [1, 0], |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].s, { |
|
||||||
1: 1, 2: 1, 3: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].f, { |
|
||||||
1: 1, |
|
||||||
}); |
|
||||||
done(); |
|
||||||
}).catch(done); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should cover a conditional that reaches the alternate (multi-line)', done => { |
|
||||||
const contract = util.getCode('conditional/multiline-alternate.sol'); |
|
||||||
const info = getInstrumentedVersion(contract, filePath); |
|
||||||
const coverage = new CoverageMap(); |
|
||||||
coverage.addContract(info, filePath); |
|
||||||
|
|
||||||
vm.execute(info.contract, 'a', []).then(events => { |
|
||||||
const mapping = coverage.generate(events, pathPrefix); |
|
||||||
assert.deepEqual(mapping[filePath].l, { |
|
||||||
5: 1, 6: 1, 7: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].b, { |
|
||||||
1: [0, 1], |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].s, { |
|
||||||
1: 1, 2: 1, 3: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].f, { |
|
||||||
1: 1, |
|
||||||
}); |
|
||||||
done(); |
|
||||||
}).catch(done); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should cover a DeclarativeExpression assignment by conditional that reaches the alternate', done => { |
|
||||||
const contract = util.getCode('conditional/declarative-exp-assignment-alternate.sol'); |
|
||||||
const info = getInstrumentedVersion(contract, filePath); |
|
||||||
const coverage = new CoverageMap(); |
|
||||||
coverage.addContract(info, filePath); |
|
||||||
|
|
||||||
// Runs bool z = (x) ? false : true;
|
|
||||||
vm.execute(info.contract, 'a', []).then(events => { |
|
||||||
const mapping = coverage.generate(events, pathPrefix); |
|
||||||
assert.deepEqual(mapping[filePath].l, { |
|
||||||
5: 1, 6: 1, 7: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].b, { |
|
||||||
1: [0, 1], |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].s, { |
|
||||||
1: 1, 2: 1, 3: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].f, { |
|
||||||
1: 1, |
|
||||||
}); |
|
||||||
done(); |
|
||||||
}).catch(done); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should cover an Identifier assignment by conditional that reaches the alternate', done => { |
|
||||||
const contract = util.getCode('conditional/identifier-assignment-alternate.sol'); |
|
||||||
const info = getInstrumentedVersion(contract, filePath); |
|
||||||
const coverage = new CoverageMap(); |
|
||||||
coverage.addContract(info, filePath); |
|
||||||
|
|
||||||
// Runs z = (x) ? false : true;
|
|
||||||
vm.execute(info.contract, 'a', []).then(events => { |
|
||||||
const mapping = coverage.generate(events, pathPrefix); |
|
||||||
assert.deepEqual(mapping[filePath].l, { |
|
||||||
5: 1, 6: 1, 7: 1, 8: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].b, { |
|
||||||
1: [0, 1], |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].s, { |
|
||||||
1: 1, 2: 1, 3: 1, 4: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].f, { |
|
||||||
1: 1, |
|
||||||
}); |
|
||||||
done(); |
|
||||||
}).catch(done); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should cover an assignment to a member expression (reaches the alternate)', done => { |
|
||||||
const contract = util.getCode('conditional/mapping-assignment.sol'); |
|
||||||
const info = getInstrumentedVersion(contract, filePath); |
|
||||||
const coverage = new CoverageMap(); |
|
||||||
coverage.addContract(info, filePath); |
|
||||||
|
|
||||||
vm.execute(info.contract, 'a', []).then(events => { |
|
||||||
const mapping = coverage.generate(events, pathPrefix); |
|
||||||
assert.deepEqual(mapping[filePath].l, { |
|
||||||
11: 1, 12: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].b, { |
|
||||||
1: [0, 1], |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].s, { |
|
||||||
1: 1, 2: 1, |
|
||||||
}); |
|
||||||
assert.deepEqual(mapping[filePath].f, { |
|
||||||
1: 1, |
|
||||||
}); |
|
||||||
done(); |
|
||||||
}).catch(done); |
|
||||||
}); |
|
||||||
|
|
||||||
}); |
|
||||||
*/ |
|
@ -1,121 +0,0 @@ |
|||||||
/** |
|
||||||
* This is logic to instrument ternary conditional assignment statements. Preserving |
|
||||||
* here for the time being, because instrumentation of these became impossible in |
|
||||||
* solc >= 0.5.0 |
|
||||||
*/ |
|
||||||
|
|
||||||
function instrumentAssignmentExpression(contract, expression) { |
|
||||||
|
|
||||||
// This is suspended for 0.5.0 which tries to accomodate the new `emit` keyword.
|
|
||||||
// Solc is not allowing us to use the construction `emit SomeEvent()` within the parens :/
|
|
||||||
return; |
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// The only time we instrument an assignment expression is if there's a conditional expression on
|
|
||||||
// the right
|
|
||||||
/*if (expression.right.type === 'ConditionalExpression') { |
|
||||||
if (expression.left.type === 'DeclarativeExpression' || expression.left.type === 'Identifier') { |
|
||||||
// Then we need to go from bytes32 varname = (conditional expression)
|
|
||||||
// to bytes32 varname; (,varname) = (conditional expression)
|
|
||||||
createOrAppendInjectionPoint(contract, expression.left.range[1], { |
|
||||||
type: 'literal', string: '; (,' + expression.left.name + ')', |
|
||||||
}); |
|
||||||
instrumenter.instrumentConditionalExpression(contract, expression.right); |
|
||||||
} else if (expression.left.type === 'MemberExpression') { |
|
||||||
createOrAppendInjectionPoint(contract, expression.left.range[0], { |
|
||||||
type: 'literal', string: '(,', |
|
||||||
}); |
|
||||||
createOrAppendInjectionPoint(contract, expression.left.range[1], { |
|
||||||
type: 'literal', string: ')', |
|
||||||
}); |
|
||||||
instrumenter.instrumentConditionalExpression(contract, expression.right); |
|
||||||
} else { |
|
||||||
const err = 'Error instrumenting assignment expression @ solidity-coverage/lib/instrumenter.js'; |
|
||||||
console.log(err, contract, expression.left); |
|
||||||
process.exit(); |
|
||||||
} |
|
||||||
}*/ |
|
||||||
}; |
|
||||||
|
|
||||||
function instrumentConditionalExpression(contract, expression) { |
|
||||||
// ----------------------------------------------------------------------------------------------
|
|
||||||
// This is suspended for 0.5.0 which tries to accomodate the new `emit` keyword.
|
|
||||||
// Solc is not allowing us to use the construction `emit SomeEvent()` within the parens :/
|
|
||||||
// Very sad, this is the coolest thing in here.
|
|
||||||
return; |
|
||||||
// ----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*contract.branchId += 1; |
|
||||||
|
|
||||||
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; |
|
||||||
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; |
|
||||||
const consequentStartCol = startcol + (contract, expression.trueBody.range[0] - expression.range[0]); |
|
||||||
const consequentEndCol = consequentStartCol + (contract, expression.trueBody.range[1] - expression.trueBody.range[0]); |
|
||||||
const alternateStartCol = startcol + (contract, expression.falseBody.range[0] - expression.range[0]); |
|
||||||
const alternateEndCol = alternateStartCol + (contract, expression.falseBody.range[1] - expression.falseBody.range[0]); |
|
||||||
// NB locations for conditional branches in istanbul are length 1 and associated with the : and ?.
|
|
||||||
contract.branchMap[contract.branchId] = { |
|
||||||
line: startline, |
|
||||||
type: 'cond-expr', |
|
||||||
locations: [{ |
|
||||||
start: { |
|
||||||
line: startline, column: consequentStartCol, |
|
||||||
}, |
|
||||||
end: { |
|
||||||
line: startline, column: consequentEndCol, |
|
||||||
}, |
|
||||||
}, { |
|
||||||
start: { |
|
||||||
line: startline, column: alternateStartCol, |
|
||||||
}, |
|
||||||
end: { |
|
||||||
line: startline, column: alternateEndCol, |
|
||||||
}, |
|
||||||
}], |
|
||||||
}; |
|
||||||
// Right, this could be being used just by itself or as an assignment. In the case of the latter, because
|
|
||||||
// the comma operator doesn't exist, we're going to have to get funky.
|
|
||||||
// if we're on a line by ourselves, this is easier
|
|
||||||
//
|
|
||||||
// Now if we've got to wrap the expression it's being set equal to, do that...
|
|
||||||
|
|
||||||
|
|
||||||
// Wrap the consequent
|
|
||||||
createOrAppendInjectionPoint(contract, expression.trueBody.range[0], { |
|
||||||
type: 'openParen', |
|
||||||
}); |
|
||||||
createOrAppendInjectionPoint(contract, expression.trueBody.range[0], { |
|
||||||
type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 0, |
|
||||||
}); |
|
||||||
createOrAppendInjectionPoint(contract, expression.trueBody.range[1], { |
|
||||||
type: 'closeParen', |
|
||||||
}); |
|
||||||
|
|
||||||
// Wrap the alternate
|
|
||||||
createOrAppendInjectionPoint(contract, expression.falseBody.range[0], { |
|
||||||
type: 'openParen', |
|
||||||
}); |
|
||||||
createOrAppendInjectionPoint(contract, expression.falseBody.range[0], { |
|
||||||
type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 1, |
|
||||||
}); |
|
||||||
createOrAppendInjectionPoint(contract, expression.falseBody.range[1], { |
|
||||||
type: 'closeParen', |
|
||||||
});*/ |
|
||||||
}; |
|
||||||
|
|
||||||
// Paren / Literal injectors
|
|
||||||
/* |
|
||||||
|
|
||||||
injector.openParen = function injectOpenParen(contract, fileName, injectionPoint, injection) { |
|
||||||
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + '(' + contract.instrumented.slice(injectionPoint); |
|
||||||
}; |
|
||||||
|
|
||||||
injector.closeParen = function injectCloseParen(contract, fileName, injectionPoint, injection) { |
|
||||||
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + ')' + contract.instrumented.slice(injectionPoint); |
|
||||||
}; |
|
||||||
|
|
||||||
injector.literal = function injectLiteral(contract, fileName, injectionPoint, injection) { |
|
||||||
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + injection.string + contract.instrumented.slice(injectionPoint); |
|
||||||
}; |
|
||||||
|
|
||||||
*/ |
|
@ -0,0 +1,54 @@ |
|||||||
|
pragma solidity ^0.7.0; |
||||||
|
|
||||||
|
|
||||||
|
contract Contract_ternary { |
||||||
|
|
||||||
|
// Sameline consequent |
||||||
|
function a() public { |
||||||
|
bool x = true; |
||||||
|
bool y = true; |
||||||
|
x && y ? y = false : y = false; |
||||||
|
} |
||||||
|
|
||||||
|
// Multiline consequent |
||||||
|
function b() public { |
||||||
|
bool x = false; |
||||||
|
bool y = false; |
||||||
|
(x) |
||||||
|
? y = false |
||||||
|
: y = false; |
||||||
|
} |
||||||
|
|
||||||
|
// Sameline w/ logicalOR |
||||||
|
function c() public { |
||||||
|
bool x = false; |
||||||
|
bool y = true; |
||||||
|
(x || y) ? y = false : y = false; |
||||||
|
} |
||||||
|
|
||||||
|
// Multiline w/ logicalOR |
||||||
|
function d() public { |
||||||
|
bool x = false; |
||||||
|
bool y = true; |
||||||
|
(x || y) |
||||||
|
? y = false |
||||||
|
: y = false; |
||||||
|
} |
||||||
|
|
||||||
|
// Sameline alternate |
||||||
|
function e() public { |
||||||
|
bool x = false; |
||||||
|
bool y = false; |
||||||
|
(x) ? y = false : y = false; |
||||||
|
} |
||||||
|
|
||||||
|
// Multiline w/ logicalOR (both false) |
||||||
|
function f() public { |
||||||
|
bool x = false; |
||||||
|
bool y = false; |
||||||
|
(x || y) |
||||||
|
? y = false |
||||||
|
: y = false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
const Contract_ternary = artifacts.require("Contract_ternary"); |
||||||
|
|
||||||
|
contract("contract_ternary", function(accounts) { |
||||||
|
let instance; |
||||||
|
|
||||||
|
before(async () => instance = await Contract_ternary.new()) |
||||||
|
|
||||||
|
it('misc ternary conditionals', async function(){ |
||||||
|
await instance.a(); |
||||||
|
await instance.b(); |
||||||
|
await instance.c(); |
||||||
|
await instance.d(); |
||||||
|
await instance.e(); |
||||||
|
await instance.f(); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,9 @@ |
|||||||
|
pragma solidity ^0.7.0; |
||||||
|
|
||||||
|
contract Test { |
||||||
|
function a() public { |
||||||
|
bool x = true; |
||||||
|
bool y = true; |
||||||
|
x && y ? y = false : y = false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
pragma solidity ^0.7.0; |
||||||
|
|
||||||
|
contract Test { |
||||||
|
function a() public { |
||||||
|
bool x = false; |
||||||
|
bool y = false; |
||||||
|
(x || y) ? y = false : y = false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
pragma solidity ^0.7.0; |
||||||
|
|
||||||
|
contract Test { |
||||||
|
function a() public { |
||||||
|
bool x = false; |
||||||
|
bool y = true; |
||||||
|
(x || y) ? y = false : y = false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
pragma solidity ^0.7.0; |
||||||
|
|
||||||
|
contract Test { |
||||||
|
function a() public { |
||||||
|
bool x = true; |
||||||
|
bool y = false; |
||||||
|
x ? y = false : y = false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
pragma solidity ^0.7.0; |
||||||
|
|
||||||
|
contract Test { |
||||||
|
function a() public { |
||||||
|
bool x = false; |
||||||
|
bool y = true; |
||||||
|
x || y ? y = false : y = false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,232 @@ |
|||||||
|
const assert = require('assert'); |
||||||
|
const util = require('./../util/util.js'); |
||||||
|
|
||||||
|
const client = require('ganache-cli'); |
||||||
|
const Coverage = require('./../../lib/coverage'); |
||||||
|
const Api = require('./../../lib/api') |
||||||
|
|
||||||
|
describe('ternary conditionals', () => { |
||||||
|
let coverage; |
||||||
|
let api; |
||||||
|
|
||||||
|
before(async () => { |
||||||
|
api = new Api({silent: true}); |
||||||
|
await api.ganache(client); |
||||||
|
}) |
||||||
|
beforeEach(() => coverage = new Coverage()); |
||||||
|
after(async() => await api.finish()); |
||||||
|
|
||||||
|
async function setupAndRun(solidityFile){ |
||||||
|
const contract = await util.bootstrapCoverage(solidityFile, api); |
||||||
|
coverage.addContract(contract.instrumented, util.filePath); |
||||||
|
await contract.instance.a(); |
||||||
|
return coverage.generate(contract.data, util.pathPrefix); |
||||||
|
} |
||||||
|
|
||||||
|
it('should cover a conditional that reaches the consequent (same-line)', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/sameline-consequent'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [1, 0], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover an unbracketed conditional that reaches the consequent (same-line)', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/unbracketed-condition'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [1, 0], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover a multi-part conditional (&&) that reaches the consequent', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/and-condition'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [1, 0], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover a multi-part conditional (||) that reaches the consequent', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/or-condition'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [0, 1], 2: [1, 0], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover a multi-part unbracketed conditional (||) that reaches the consequent', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/unbracketed-or-condition'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [0, 1], 2: [1, 0], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover an always-false multi-part unbracketed conditional (||)', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/or-always-false-condition'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [0, 0], 2: [0, 1], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover a conditional that reaches the alternate (same-line)', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/sameline-alternate'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [0, 1], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover a conditional that reaches the consequent (multi-line)', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/multiline-consequent'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [1, 0], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover a conditional that reaches the alternate (multi-line)', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/multiline-alternate'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [0, 1], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
// Runs bool z = (x) ? false : true;
|
||||||
|
it('should cover a definition assignment by conditional that reaches the alternate', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/declarative-exp-assignment-alternate'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [0, 1], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
// Runs z = (x) ? false : true;
|
||||||
|
it('should cover an identifier assignment by conditional that reaches the alternate', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/identifier-assignment-alternate'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
5: 1, 6: 1, 7: 1, 8: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [0, 1], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, 3: 1, 4: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should cover an assignment to a member expression (reaches the alternate)', async function() { |
||||||
|
const mapping = await setupAndRun('conditional/mapping-assignment'); |
||||||
|
|
||||||
|
assert.deepEqual(mapping[util.filePath].l, { |
||||||
|
11: 1, 12: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].b, { |
||||||
|
1: [0, 1], |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].s, { |
||||||
|
1: 1, 2: 1, |
||||||
|
}); |
||||||
|
assert.deepEqual(mapping[util.filePath].f, { |
||||||
|
1: 1, |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
Loading…
Reference in new issue