Add bootNGF. Organise tests better.

This commit is contained in:
John J. Camilleri
2021-10-04 15:07:23 +02:00
parent 7551926383
commit 1f72ef77c4
4 changed files with 103 additions and 38 deletions

View File

@@ -61,6 +61,7 @@ jobs:
working-directory: ./src/runtime/javascript
env:
LD_LIBRARY_PATH: /usr/local/lib
PYTHON: /usr/bin/python2
run: |
npm ci
npm run test

View File

@@ -64,6 +64,8 @@ interface Pointer extends Buffer {
class PGFError extends Error {
constructor(message: string) {
super(message)
// https://stackoverflow.com/a/65243177/98600
Object.setPrototypeOf(this, PGFError.prototype)
}
}
@@ -147,17 +149,17 @@ function PgfText_AsString (txtPtr: Pointer) {
// ----------------------------------------------------------------------------
// PGF grammar object
class PGF {
db: Pointer
revision: number
export class PGFGrammar {
readonly db: Pointer
readonly revision: number
constructor () {
this.db = ref.NULL_POINTER as Pointer
this.revision = 0
constructor (db: Pointer, revision: number) {
this.db = db
this.revision = revision
}
// NB the library user is responsible for calling this
destructor () {
release () {
runtime.pgf_free_revision(this.db, this.revision)
}
@@ -199,23 +201,29 @@ class PGF {
// ----------------------------------------------------------------------------
// PGF module functions
function readPGF (path: string): PGF {
function readPGF (path: string): PGFGrammar {
const rev = ref.alloc(PgfRevision) as Pointer
const err = ref.alloc(PgfExn) as Pointer
const db = runtime.pgf_read_pgf(path, rev, err)
handleError(err)
return new PGFGrammar(db, rev.deref())
}
const state = new PGF()
state.db = db
state.revision = rev.deref()
return state
function bootNGF (pgf_path: string, ngf_path: string): PGFGrammar {
const rev = ref.alloc(PgfRevision) as Pointer
const err = ref.alloc(PgfExn) as Pointer
const db = runtime.pgf_boot_ngf(pgf_path, ngf_path, rev, err)
handleError(err)
return new PGFGrammar(db, rev.deref())
}
// ----------------------------------------------------------------------------
// Exposed library API
export default {
readPGF
PGFError,
readPGF,
bootNGF
}
// ----------------------------------------------------------------------------

View File

@@ -1,30 +1,86 @@
import PGF from '../index'
import PGF, { PGFGrammar } from '../index'
import fs from 'fs'
// readPGF
describe('readPGF', () => {
test('valid', () => {
PGF.readPGF('../haskell/tests/basic.pgf')
})
test('readPGF successful', () => {
let gr = PGF.readPGF('../haskell/tests/basic.pgf')
test('non-existent', () => {
expect(() => {
PGF.readPGF('../haskell/tests/abc.pgf')
}).toThrow(Error)
})
test('GF', () => {
expect(() => {
PGF.readPGF('../haskell/tests/basic.gf')
}).toThrow(PGF.PGFError)
})
// test('NGF', () => {
// expect(() => {
// PGF.readPGF('basic.ngf')
// }).toThrow(PGF.PGFError)
// })
})
test('readPGF missing file', () => {
expect(() => {
PGF.readPGF('abc.pgf')
}).toThrow()
describe('bootNGF', () => {
beforeAll(() => {
try {
fs.unlinkSync('./basic.ngf')
} catch { }
})
test('valid', () => {
PGF.bootNGF('../haskell/tests/basic.pgf', './basic.ngf')
})
test('non-existent', () => {
expect(() => {
PGF.bootNGF('../haskell/tests/abc.pgf', './abc.ngf')
}).toThrow(Error)
})
test('GF', () => {
expect(() => {
PGF.bootNGF('../haskell/tests/basic.gf', './abc.ngf')
}).toThrow(PGF.PGFError)
})
test('NGF', () => {
expect(() => {
PGF.bootNGF('./basic.ngf', './abc.ngf')
}).toThrow(PGF.PGFError)
})
test('existing', () => {
expect(() => {
PGF.bootNGF('../haskell/tests/basic.pgf', './basic.ngf')
}).toThrow(Error)
})
})
// abstract syntax
describe('abstract syntax', () => {
let gr: PGFGrammar
test('abstract name', () => {
let gr = PGF.readPGF('../haskell/tests/basic.pgf')
expect(gr.getAbstractName()).toBe('basic')
})
beforeAll(() => {
gr = PGF.readPGF('../haskell/tests/basic.pgf')
})
test('categories', () => {
let gr = PGF.readPGF('../haskell/tests/basic.pgf')
expect(gr.getCategories()).toEqual(['Float','Int','N','P','S','String'])
})
afterAll(() => {
gr.release()
})
test('functions', () => {
let gr = PGF.readPGF('../haskell/tests/basic.pgf')
expect(gr.getFunctions()).toEqual(['c','ind','s','z'])
test('abstract name', () => {
expect(gr.getAbstractName()).toBe('basic')
})
test('categories', () => {
expect(gr.getCategories()).toEqual(['Float','Int','N','P','S','String'])
})
test('functions', () => {
expect(gr.getFunctions()).toEqual(['c','ind','s','z'])
})
})

View File

@@ -8,7 +8,7 @@ from pgf import *
def PGF():
return readPGF("../haskell/tests/basic.pgf")
def test_readPGF_non_existant():
def test_readPGF_non_existent():
with pytest.raises(FileNotFoundError):
readPGF("../haskell/tests/abc.pgf")
@@ -28,7 +28,7 @@ def NGF():
yield ngf
os.remove("./basic.ngf")
def test_bootNGF_non_existant():
def test_bootNGF_non_existent():
with pytest.raises(FileNotFoundError):
bootNGF("../haskell/tests/abc.pgf", "./abc.ngf")
@@ -46,7 +46,7 @@ def test_bootNGF_existing(NGF):
# readNGF
def test_readNGF_non_existant():
def test_readNGF_non_existent():
with pytest.raises(FileNotFoundError):
readNGF("./abc.ngf")
@@ -100,7 +100,7 @@ def test_functionsByCat_1(PGF):
def test_functionsByCat_2(PGF):
assert PGF.functionsByCat("S") == ["c"]
def test_functionsByCat_non_existant(PGF):
def test_functionsByCat_non_existent(PGF):
assert PGF.functionsByCat("X") == []
def test_categoryContext_1(PGF):
@@ -169,7 +169,7 @@ def test_functionType_2(PGF):
def test_functionType_3(PGF):
assert PGF.functionType("c") == readType("N -> S")
def test_functionType_non_existant(PGF):
def test_functionType_non_existent(PGF):
with pytest.raises(KeyError):
assert PGF.functionType("cbx")