Skip to content

Commit

Permalink
Line continuations for rust step definitions (#179)
Browse files Browse the repository at this point in the history
* fix: rust line continuation

* Unit test patterns ending with continuation
  • Loading branch information
kieran-ryan authored Jan 16, 2024
1 parent 4d7327e commit c8d94c9
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 6 deletions.
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
### Fixed
- (Rust) Support for r# raw strings with step definition patterns ([#176](https://github.com/cucumber/language-service/pull/176))

### Fixed
- (Rust) Line continuation characters in rust step definition patterns ([#179](https://github.com/cucumber/language-service/pull/179))
- (Python) Unexpected spaces and commas in generated step definitions [#160](https://github.com/cucumber/language-service/issues/160)

## [1.4.1] - 2023-07-16
Expand Down
14 changes: 11 additions & 3 deletions src/language/rustLanguage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,17 @@ fn {{ #lowercase }}{{ #underscore }}{{ expression }}{{ /underscore }}{{ /lowerca

export function stringLiteral(node: TreeSitterSyntaxNode | null): string {
if (node === null) throw new Error('node cannot be null')
if (node.text.startsWith('r#')) return unescapeString(node.text.slice(3, -2))
if (node.text.startsWith('r')) return unescapeString(node.text.slice(2, -1))
return unescapeString(node.text.slice(1, -1))

let result
if (node.text.startsWith('r#')) result = unescapeString(node.text.slice(3, -2))
else if (node.text.startsWith('r')) result = unescapeString(node.text.slice(2, -1))
else result = unescapeString(node.text.slice(1, -1))

return stripLineContinuation(result)
}

export function stripLineContinuation(s: string): string {
return s.replace(/\\\n\s*/g, '')
}

function unescapeString(s: string): string {
Expand Down
69 changes: 68 additions & 1 deletion test/language/rustLanguage.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import assert from 'assert'

import { stringLiteral } from '../../src/language/rustLanguage.js'
import { stringLiteral, stripLineContinuation } from '../../src/language/rustLanguage.js'
import { TreeSitterSyntaxNode } from '../../src/language/types.js'

describe('rustLanguage', () => {
Expand Down Expand Up @@ -41,4 +41,71 @@ describe('rustLanguage', () => {
assert.strictEqual(stringLiteral(node), expected)
})
})

it('should strip line continuations from expressions', () => {
const cases = [
{
// Single line continuation
input: '"Line \\\n continuation"',
expected: '"Line continuation"',
},
{
input: '"Multiple \\\n line \\\n continuations"',
expected: '"Multiple line continuations"',
},
{
// Continuation with consecutive new lines
input: '"Continuation with \\\n\n consecutive new lines"',
expected: '"Continuation with consecutive new lines"',
},
{
// No space before continuation
input: '"No space\\\n before continuation"',
expected: '"No spacebefore continuation"',
},
{
// Multiple spaces before continuation
input: '"Two spaces \\\n before continuation"',
expected: '"Two spaces before continuation"',
},
{
// Line continuation with extra space
input: '"this \\ line \\\nshould too"',
expected: '"this \\ line should too"',
},
{
// Ends with line continuation
input: '"Ends with continuation\\\n"',
expected: '"Ends with continuation"',
},
{
// Ends with line continuation and whitespace
input: '"Ends with continuation and whitespace\\\n "',
expected: '"Ends with continuation and whitespace"',
},
]

cases.forEach(({ input, expected }) => {
assert.strictEqual(stripLineContinuation(input), expected)
})
})

it('should not strip invalid line continuations from expressions', () => {
const cases = [
{
// Space after continuation but before new line
input: '"Space after continuation \\ \n but before new line"',
expected: '"Space after continuation \\ \n but before new line"',
},
{
// Ends with escape character
input: '"Escaped backslash \\"',
expected: '"Escaped backslash \\"',
},
]

cases.forEach(({ input, expected }) => {
assert.strictEqual(stripLineContinuation(input), expected)
})
})
})

0 comments on commit c8d94c9

Please sign in to comment.