import * as chai from 'chai';
import * as fs from 'fs';
import * as _ from 'lodash';
import 'mocha';
import * as path from 'path';
import { getLocationByOffset, parseSourceMap } from '../src/source_maps';
const expect = chai.expect;
const simplestContractBaseName = 'Simplest.sol';
const simplestContractFileName = path.resolve(__dirname, 'fixtures/contracts', simplestContractBaseName);
const simplestContract = fs.readFileSync(simplestContractFileName).toString();
describe('source maps', () => {
describe('#getLocationByOffset', () => {
it('correctly computes location by offset', () => {
const locationByOffset = getLocationByOffset(simplestContract);
const expectedLocationByOffset = {
'0': { line: 1, column: 0 },
'1': { line: 1, column: 1 },
'2': { line: 1, column: 2 },
'3': { line: 1, column: 3 },
'4': { line: 1, column: 4 },
'5': { line: 1, column: 5 },
'6': { line: 1, column: 6 },
'7': { line: 1, column: 7 },
'8': { line: 1, column: 8 },
'9': { line: 1, column: 9 },
'10': { line: 1, column: 10 },
'11': { line: 1, column: 11 },
'12': { line: 1, column: 12 },
'13': { line: 1, column: 13 },
'14': { line: 1, column: 14 },
'15': { line: 1, column: 15 },
'16': { line: 1, column: 16 },
'17': { line: 1, column: 17 },
'18': { line: 1, column: 18 },
'19': { line: 1, column: 19 },
'20': { line: 2, column: 0 },
'21': { line: 2, column: 1 },
'22': { line: 3, column: 0 },
};
expect(locationByOffset).to.be.deep.equal(expectedLocationByOffset);
});
});
describe('#parseSourceMap', () => {
it('correctly parses the source map', () => {
// This is the source map and bytecode for an empty contract like Example.sol
const srcMap = '0:21:0:-;;;;;;;;;;;;;;;;;';
const bytecodeHex =
'60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00a165627a7a72305820377cdef690e46589f40efeef14d8ef73504af059fb3fd46f1da3cd2fc52ef7890029';
const sources = [simplestContractBaseName];
const pcToSourceRange = parseSourceMap([simplestContract], srcMap, bytecodeHex, sources);
const expectedSourceRange = {
location: {
start: { line: 1, column: 0 },
end: { line: 2, column: 1 },
},
fileName: simplestContractBaseName,
};
_.forEach(pcToSourceRange, sourceRange => {
// Solidity source maps are too short and we map some instructions to undefined
// Source: https://github.com/ethereum/solidity/issues/3741
if (!_.isUndefined(sourceRange)) {
expect(sourceRange).to.be.deep.equal(expectedSourceRange);
}
});
});
});
});