Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parser: Incomplete() returns false for unclosed double quotes and true for unclosed single quotes, while it is expected to return true for both #1020

Open
Rossil2012 opened this issue Jul 23, 2023 · 0 comments

Comments

@Rossil2012
Copy link

Hello,

I have encountered a problem with the javascript mvdan/sh library, specifically with the parser's InteractiveStep and Incomplete methods.

In my understanding, when InteractiveStep encounters a string like echo " or echo ', InteractiveStep returns an empty array. And when the Incomplete method is subsequently invoked, it returns true, indicating that InteractiveStep is awaiting the end of the current statement, i.e., the closing double or single quote.

However, my tests indicate that while this behavior is as expected for single quotes echo ', it does not hold for double quotes echo ". In the latter case, the Incomplete method returns false instead of true.

I have written a test that emulates the style of __js/testmain.js:

const assert = require('assert').strict

const sh = require('mvdan-sh')

const syntax = sh.syntax
const parser = syntax.NewParser()

{
  // using the parser interactively with steps
  const lines = [
    "foo\n",
    "bar; baz\n",
    "\n",
    "foo; 'incom\n",
    " \n",
    "plete'\n",

    // testing quote and new line
    // single quote
    "echo \'\n",  // expect: {"count": 0, "incomplete": true}
    "123\n",      // expect: {"count": 0, "incomplete": true}
    "\'\n",       // expect: {"count": 1, "incomplete": false}

    //double quote
    "echo \"\n",  // expect: {"count": 0, "incomplete": true}
    "123\n",      // expect: {"count": 0, "incomplete": true}
    "\"\n",       // expect: {"count": 1, "incomplete": false}
  ]
  const wantResults = [
    { "count": 1, "incomplete": false },
    { "count": 2, "incomplete": false },
    { "count": 0, "incomplete": false },
    { "count": 1, "incomplete": true },
    { "count": 1, "incomplete": true },
    { "count": 2, "incomplete": false },
    // single quote expectation
    { "count": 0, "incomplete": true },
    { "count": 0, "incomplete": true },
    { "count": 1, "incomplete": false },
    // double quote expectation
    { "count": 0, "incomplete": true },
    { "count": 0, "incomplete": true },
    { "count": 1, "incomplete": false },
  ]
  var gotResults = []
  for (var i = 0; i < lines.length; i++) {
    var line = lines[i]
    var want = wantResults[i]

    var stmts = parser.InteractiveStep(line)
    gotResults.push({
      "count": stmts.length,
      "incomplete": parser.Incomplete(),
    })
  }
  assert.deepEqual(gotResults, wantResults)
}

The test fails with the following error:

AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected ... Lines skipped

[
...
{
  count: 0,
+ incomplete: false
- incomplete: true
},
{
  count: 0,
+ incomplete: false
- incomplete: true
},
...
  incomplete: false
}
]

{
  generatedMessage: true,
  code: 'ERR_ASSERTION',
  actual: [
    { count: 1, incomplete: false },
    { count: 2, incomplete: false },
    { count: 0, incomplete: false },
    { count: 1, incomplete: true },
    { count: 1, incomplete: true },
    { count: 2, incomplete: false },
    { count: 0, incomplete: true },
    { count: 0, incomplete: true },
    { count: 1, incomplete: false },
    { count: 0, incomplete: false },
    { count: 0, incomplete: false },
    { count: 1, incomplete: false }
  ],
  expected: [
    { count: 1, incomplete: false },
    { count: 2, incomplete: false },
    { count: 0, incomplete: false },
    { count: 1, incomplete: true },
    { count: 1, incomplete: true },
    { count: 2, incomplete: false },
    { count: 0, incomplete: true },
    { count: 0, incomplete: true },
    { count: 1, incomplete: false },
    { count: 0, incomplete: true },
    { count: 0, incomplete: true },
    { count: 1, incomplete: false }
  ],
  operator: 'deepStrictEqual'
}

I am currently using version "0.10.1" of the mvdan-sh library.

Could you please help with this issue?

Thank you in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant