Skip to content

Commit

Permalink
feat(parsers/whitespace): add whitespace & whitespaceOptional par…
Browse files Browse the repository at this point in the history
…sers
  • Loading branch information
norskeld committed Nov 28, 2021
1 parent 2421d6d commit 821680a
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
16 changes: 16 additions & 0 deletions src/internal/parsers/whitespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Parser } from '../state'

import { regexp } from './regexp'

const WHITESPACE_REQUIRED_RE = /\s+/g
const WHITESPACE_OPTIONAL_RE = /\s*/g

export function whitespace(): Parser<string> {
return regexp(WHITESPACE_REQUIRED_RE, 'whitespace')
}

export function whitespaceOptional(): Parser<string> {
return regexp(WHITESPACE_OPTIONAL_RE, 'optional whitespace')
}

export { whitespace as ws, whitespaceOptional as wsOpt }
1 change: 1 addition & 0 deletions src/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './internal/parsers/lazy'
export * from './internal/parsers/nothing'
export * from './internal/parsers/regexp'
export * from './internal/parsers/string'
export * from './internal/parsers/whitespace'
82 changes: 82 additions & 0 deletions tests/internal/parsers/whitespace.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { whitespace, whitespaceOptional } from '@lib/internal/parsers/whitespace'
import { sequence } from '@lib/internal/combinators/sequence'
import { string } from '@lib/internal/parsers/string'
import { regexp } from '@lib/internal/parsers/regexp'

import { run, result, should } from '@tests/@helpers'

describe(whitespace, () => {
it('should succeed if given a string of spaces', () => {
const space = ' '

const actual = run(whitespace(), space.repeat(4))
const expected = result('success', space.repeat(4))

should.matchState(actual, expected)
})

it('should succeed if given a string starting with spaces', () => {
const space = ' '

const actual = run(whitespace(), space.repeat(4) + 'const')
const expected = result('success', space.repeat(4))

should.matchState(actual, expected)
})

it('should succeed if given a mixed string with spaces', () => {
const identifier = regexp(/\w+/g, 'identifier')
const keyword = string('let')
const ws = whitespace()

const actual = run(sequence(keyword, ws, identifier), 'let identity')
const expected = result('success', ['let', ' ', 'identity'])

should.matchState(actual, expected)
})

it('should fail if given a non-matching input', () => {
const actual = run(sequence(string('let'), whitespace(), string('rec')), 'letrec')
const expected = result('failure', 'whitespace')

should.matchState(actual, expected)
})
})

describe(whitespaceOptional, () => {
it('should succeed if given a mixed string with spaces', () => {
const letKeyword = string('let')
const identifier = regexp(/\w+/g, 'identifier')
const wsOptional = whitespaceOptional()

const parser = sequence(letKeyword, wsOptional, identifier)

const actual = run(parser, 'let identity')
const expected = result('success', ['let', ' ', 'identity'])

should.matchState(actual, expected)
})

it('should succeed if given a mixed string with optional spaces', () => {
const letKeyword = string('let')
const equalKeyword = string('=')
const identifier = regexp(/\w+/g, 'identifier')
const wsOptional = whitespaceOptional()
const wsRequired = whitespace()

const parser = sequence(
letKeyword,
wsRequired,
identifier,
wsOptional,
equalKeyword,
wsOptional,
identifier
)

const actual = run(parser, 'let identity=something')
const expected = result('success', ['let', ' ', 'identity', '', '=', '', 'something'])

should.matchState(actual, expected)
})
})
6 changes: 5 additions & 1 deletion tests/parsers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ it('should expose parsers', () => {
'string',
'str',
'uniString',
'ustr'
'ustr',
'whitespace',
'ws',
'whitespaceOptional',
'wsOpt'
)
})

0 comments on commit 821680a

Please sign in to comment.