UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

132 lines 8.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const mocha_1 = require("mocha"); const flattener_1 = require("../../src/flattening/flattener"); const IRprinting_1 = require("../../src/ir/IRprinting"); const idGenerator_1 = require("../../src/idGenerator"); const quintParserFrontend_1 = require("../../src/parsing/quintParserFrontend"); (0, mocha_1.describe)('flattenModule', () => { function getFlatennedDecls(baseDecls, decls, thirdModuleDecls, moduleToCheck = 'B') { const idGenerator = (0, idGenerator_1.newIdGenerator)(); const fake_path = { normalizedPath: 'fake_path', toSourceName: () => 'fake_path' }; const quintModules = `module A { ${baseDecls.join('\n')} } module B { ${decls.join('\n')} } module C { ${thirdModuleDecls.join('\n')} }`; const { modules, table, errors } = (0, quintParserFrontend_1.parse)(idGenerator, 'fake_location', fake_path, quintModules); chai_1.assert.isEmpty(errors, 'Failed to parse mocked up module'); const modulesByName = new Map(modules.map(m => [m.name, m])); modules.forEach(m => { const flattenedModule = (0, flattener_1.flattenModule)(m, modulesByName, table); modulesByName.set(m.name, flattenedModule); }); const flattenedModule = modulesByName.get(moduleToCheck); return flattenedModule.declarations.map(decl => (0, IRprinting_1.declarationToString)(decl)); } (0, mocha_1.it)('flattens simple import', () => { const baseDecls = ['def f(x) = x + 1']; const decls = ['import A.*', 'def g(x) = f(x)']; const expectedDecls = ['def f = ((x) => iadd(x, 1))', 'def g = ((x) => f(x))']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, []); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('flattens import with qualifier', () => { const baseDecls = ['def f(x) = x + 1']; const decls = ['import A as MyA', 'val a = MyA::f(1)']; const expectedDecls = ['def MyA::f = ((MyA::x) => iadd(MyA::x, 1))', 'val a = MyA::f(1)']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, []); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('flattens import with self-qualifier', () => { const baseDecls = ['def f(x) = x + 1']; const decls = ['import A', 'val a = A::f(1)']; const expectedDecls = ['def A::f = ((A::x) => iadd(A::x, 1))', 'val a = A::f(1)']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, []); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('flattens export with previous import without definitions being used', () => { const baseDecls = ['def f(x) = x + 1']; // No definition from A is used here const decls = ['import A.*', 'export A.*']; const thirdModuleDecls = ['import B.*', 'val a = f(1)']; const expectedDecls = ['def f = ((x) => iadd(x, 1))']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, thirdModuleDecls); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('flattens export with previous import with used definition', () => { const baseDecls = ['def f(x) = x + 1']; const decls = ['import A.*', 'val a = f(2)', 'export A.*']; const thirdModuleDecls = ['import B.*', 'val b = f(1)']; const expectedDecls = ['def f = ((x) => iadd(x, 1))', 'val a = f(2)']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, thirdModuleDecls); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('flattens export without previous import', () => { const baseDecls = ['def f(x) = x + 1']; const decls = ['export A.*']; const thirdModuleDecls = ['import B.*', 'val a = f(1)']; const expectedDecls = ['def f = ((x) => iadd(x, 1))']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, thirdModuleDecls); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('does not flatten definitions that come from instance', () => { const baseDecls = ['const N: int', 'def f(x) = x + 1']; const decls = ['import A(N = 1) as A1', 'val a = A1::f(1)']; const expectedDecls = decls; const flattenedDecls = getFlatennedDecls(baseDecls, decls, []); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('flattens export qualified module with no qualifier', () => { const baseDecls = ['def f(x) = x + 1']; const decls = ['import A as MyA', 'export MyA.*']; const thirdModuleDecls = ['import B.*', 'val a = f(1)']; const expectedDecls = ['def f = ((x) => iadd(x, 1))']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, thirdModuleDecls); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('flattens export instance with no qualifier', () => { // I was not able to make this scenario work in the PoC, not with interactions with the instance flattener. // In #1102, we should make sure a proper error is raised in the export + import combinatinos we do not support. // Alternatively (and at some point), we could support this scenario. const baseDecls = ['const N: int', 'def f(x) = x + 1']; const decls = ['import A(N = 1) as A1', 'export A1.*']; const thirdModuleDecls = ['import B.*', 'val a = f(1)']; const expectedDecls = ['import A(N = 1) as A1', 'def f = ((x) => iadd(x, 1))', 'const N: int']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, thirdModuleDecls); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('imports definitions recursively when there are dependencies', () => { const baseDecls = ['val z = 3', 'def f(x) = x + z']; const decls = ['import A as MyA', 'val a = MyA::f(1)']; const expectedDecls = ['val MyA::z = 3', 'def MyA::f = ((MyA::x) => iadd(MyA::x, MyA::z))', 'val a = MyA::f(1)']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, []); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('imports definitions recursively when there are dependencies in single def import', () => { const baseDecls = ['val z = 3', 'def f(x) = x + z']; const decls = ['import A.f', 'val a = f(1)']; const expectedDecls = ['val z = 3', 'def f = ((x) => iadd(x, z))', 'val a = f(1)']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, []); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('does not create conflicts', () => { const baseDecls = ['val z = val x = 3 { x }', 'def f(x) = x + z', 'val y = 1']; const decls = ['import A.f', 'val a = def g = f { g(1) }', 'export A.*']; const thirdModuleDecls = ['import B.*', 'val b = z + y']; const expectedDecls = [ 'val z = val x = 3 { x }', 'def f = ((x) => iadd(x, z))', 'val y = 1', 'val a = def g = f { g(1) }', ]; const flattenedDecls = getFlatennedDecls(baseDecls, decls, thirdModuleDecls); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); (0, mocha_1.it)('can have definitions with same id but different name (#1141)', () => { const baseDecls = ['val a = 1']; const decls = ['import A.*', 'val b = a']; const thirdModuleDecls = ['import A.*', 'import B', 'val c = a + B::b']; const expectedDecls = ['val a = 1', 'val B::a = 1', 'val B::b = B::a', 'val c = iadd(a, B::b)']; const flattenedDecls = getFlatennedDecls(baseDecls, decls, thirdModuleDecls, 'C'); chai_1.assert.deepEqual(flattenedDecls, expectedDecls); }); }); //# sourceMappingURL=flattener.test.js.map