Add coverage for ternary conditionals (#587)
parent
02cea3db2c
commit
64f205ab22
@ -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