simple-dfa
Version:
Allow construction, validation, and manual step-through of a simple DFA.
142 lines (127 loc) • 7.09 kB
JavaScript
const assert = require("assert");
const SimpleDFA = require('../../simple-dfa.js');
const states = ["1","2","3"];
const alphabet = ["a", "b"];
const transitions = {
1: {'a': '1', 'b': '2'},
2: {'a': '1', 'b': '3'},
3: {'a': '2'},
};
const start = "1";
const accept = ["1","2"];
let dfa;
describe("Step Simulation .step.simulation", () => {
beforeEach(() => {
dfa = new SimpleDFA(states, alphabet, transitions, start, accept);
});
describe ("Accept", () => {
it("aaa", () => {
assert.deepEqual(dfa.start('aaa'), { state: '1', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: undefined, accept: true });
});
it("aba", () => {
assert.deepEqual(dfa.start('aba'), { state: '1', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: undefined, accept: true });
});
it("bab", () => {
assert.deepEqual(dfa.start('bab'), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: undefined, accept: true });
});
it("bbaa", () => {
assert.deepEqual(dfa.start('bbaa'), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '3', symbol: 'a', accept: false });
assert.deepEqual(dfa.step(), { source: '3', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: undefined, accept: true });
});
it("baaab", () => {
assert.deepEqual(dfa.start('baaab'),{ state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: undefined, accept: true });
});
});
describe ("Reject", () => {
it("bb", () => {
assert.deepEqual(dfa.start('bb'), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '3', symbol: undefined, accept: false });
});
it("bbb", () => {
assert.deepEqual(dfa.start('bbb'), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '3', symbol: 'b', accept: false });
assert.deepEqual(dfa.step(), { state: '3', symbol: 'b', reject: true });
});
it("bbba", () => {
assert.deepEqual(dfa.start('bbba'), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '3', symbol: 'b', accept: false });
assert.deepEqual(dfa.step(), { state: '3', symbol: 'b', reject: true });
});
it("babb", () => {
assert.deepEqual(dfa.start('babb'), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'a', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'a' });
assert.deepEqual(dfa.step(), { state: '1', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '1', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '2', symbol: 'b', accept: true });
assert.deepEqual(dfa.step(), { source: '2', symbol: 'b' });
assert.deepEqual(dfa.step(), { state: '3', symbol: undefined, accept: false });
});
});
describe ("Illegal", () => {
it("Attempt edit while running", () => {
dfa.start('babababababababababa');
dfa.step();
assert.throws(() => dfa.addSymbol('x'));
dfa.step();
assert.throws(() => dfa.removeSymbol('a'));
dfa.step();
assert.throws(() => dfa.addState('5'));
dfa.step();
assert.throws(() => dfa.markStart('2'));
dfa.step();
assert.throws(() => dfa.toggleAccept('3'));
dfa.step();
assert.throws(() => dfa.removeState('3'));
dfa.step();
assert.throws(() => dfa.addTransition('1','4','a'));
dfa.step();
assert.throws(() => dfa.removeTransition('3','1','c'));
});
});
});