elliptical
Version:
Interactive natural-language interfaces
172 lines (147 loc) • 4.77 kB
JSX
/* eslint-env mocha */
/** @jsx createElement */
import createElement from '../src/element'
import {compileAndTraverse, text} from './_util'
import { expect } from 'chai'
describe('choice', () => {
it('suggests one valid choice', () => {
const grammar = (
<choice>
<literal text='right' />
<literal text='wrong' />
</choice>
)
const options = compileAndTraverse(grammar, 'r')
expect(options).to.have.length(1)
expect(options[0].words).to.eql([{text: 'r', input: true}, {text: 'ight', input: false}])
})
it('suggests multiple valid choices', () => {
const grammar = (
<choice>
<literal text='right' />
<literal text='right also' />
</choice>
)
const options = compileAndTraverse(grammar, 'r')
expect(options).to.have.length(2)
expect(options[0].words).to.eql([{text: 'r', input: true}, {text: 'ight', input: false}])
expect(options[1].words).to.eql([{text: 'r', input: true}, {text: 'ight also', input: false}])
})
it('suggests no valid choices', () => {
const grammar = (
<choice>
<literal text='wrong' />
<literal text='wrong also' />
</choice>
)
const options = compileAndTraverse(grammar, 'r')
expect(options).to.eql([])
})
it('adopts the value of the child', () => {
const grammar = (
<choice>
<literal text='right' value='testValue' />
<literal text='wrong' />
</choice>
)
const options = compileAndTraverse(grammar, 'r')
expect(options).to.have.length(1)
expect(options[0].result).to.eql('testValue')
})
it('can set a value', () => {
const grammar = (
<choice value='override'>
<literal text='right' value='testValue' />
<literal text='wrong' />
</choice>
)
const options = compileAndTraverse(grammar, 'r')
expect(options).to.have.length(1)
expect(options[0].result).to.eql('override')
})
it('can set a value in an object with an id', () => {
const grammar = (
<choice>
<literal text='right' value='testValue' id='key' />
<literal text='wrong' />
</choice>
)
const options = compileAndTraverse(grammar, 'r')
expect(options).to.have.length(1)
expect(options[0].result).to.eql({key: 'testValue'})
})
it('can be restricted by a limit of 1', () => {
const grammar = (
<choice limit={1}>
<literal text='right' value='testValue' />
<literal text='right also' value='also' />
</choice>
)
const options = compileAndTraverse(grammar, '')
expect(options).to.have.length(1)
expect(text(options[0])).to.equal('right')
expect(options[0].result).to.equal('testValue')
})
it('can be restricted by a limit of more than 1', () => {
const grammar = (
<choice limit={2}>
<literal text='right' />
<literal text='right also' />
<literal text='right but excluded' />
</choice>
)
const options = compileAndTraverse(grammar, '')
expect(options).to.have.length(2)
expect(text(options[0])).to.equal('right')
expect(text(options[1])).to.equal('right also')
})
it('still works when a limited child has multiple options', () => {
const grammar = (
<choice limit={2}>
<choice>
<literal text='right' />
<literal text='right also' />
</choice>
<literal text='wrong' />
<literal text='right third' />
</choice>
)
const options = compileAndTraverse(grammar, 'ri')
expect(options).to.have.length(3)
expect(text(options[0])).to.equal('right')
expect(text(options[1])).to.equal('right also')
expect(text(options[2])).to.equal('right third')
})
it('allows choices in sequences to be limited', () => {
const grammar = (
<sequence>
<choice limit={2}>
<literal text='testa' />
<literal text='x' />
<literal text='testb' />
<literal text='testc' />
</choice>
<literal text='also' />
</sequence>
)
const options = compileAndTraverse(grammar, 'test')
expect(options).to.have.length(2)
expect(text(options[0])).to.equal('testaalso')
expect(text(options[1])).to.equal('testbalso')
})
it('limits even if valid parses do not parse to completion', () => {
const grammar = (
<sequence>
<choice limit={1}>
<literal text='righ' />
<literal text='right' />
<literal text='righta' />
</choice>
<literal text='also' />
</sequence>
)
const options = compileAndTraverse(grammar, 'righta')
expect(options).to.have.length(1)
expect(text(options[0])).to.equal('rightalso')
})
})