Skip to content

Commit

Permalink
fix: better handling of quoted strings (#153)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: quotes and beginning and endings of strings are not removed during parsing.
  • Loading branch information
bcoe committed Jan 28, 2019
1 parent ee122f8 commit 2fb71b2
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 15 deletions.
2 changes: 1 addition & 1 deletion example.js
@@ -1,3 +1,3 @@
var parser = require('./')
var parse = parser(['-cats', 'meow'])
var parse = parser('--foo "-bar"')
console.log(parse)
9 changes: 9 additions & 0 deletions index.js
Expand Up @@ -9,6 +9,7 @@ function parse (args, opts) {
// allow a string argument to be passed in rather
// than an argv array.
args = tokenizeArgString(args)

// aliases might have transitive relationships, normalize this.
var aliases = combineAliases(opts.alias || {})
var configuration = assign({
Expand Down Expand Up @@ -450,6 +451,14 @@ function parse (args, opts) {
}

function processValue (key, val) {
// strings may be quoted, clean this up as we assign values.
if (typeof val === 'string' &&
(val[0] === "'" || val[0] === '"') &&
val[val.length - 1] === val[0]
) {
val = val.substring(1, val.length - 1)
}

// handle parsing boolean arguments --foo=true --bar false.
if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) {
if (typeof val === 'string') val = val === 'true'
Expand Down
2 changes: 0 additions & 2 deletions lib/tokenize-arg-string.js
Expand Up @@ -27,10 +27,8 @@ module.exports = function (argString) {
if (c === opening) {
if (!args[i]) args[i] = ''
opening = null
continue
} else if ((c === "'" || c === '"') && !opening) {
opening = c
continue
}

if (!args[i]) args[i] = ''
Expand Down
24 changes: 12 additions & 12 deletions test/tokenize-arg-string.js
Expand Up @@ -15,42 +15,42 @@ describe('TokenizeArgString', function () {
it('handles quoted string with no spaces', function () {
var args = tokenizeArgString("--foo 'hello'")
args[0].should.equal('--foo')
args[1].should.equal('hello')
args[1].should.equal("'hello'")
})

it('handles single quoted string with spaces', function () {
var args = tokenizeArgString("--foo 'hello world' --bar='foo bar'")
args[0].should.equal('--foo')
args[1].should.equal('hello world')
args[2].should.equal('--bar=foo bar')
args[1].should.equal("'hello world'")
args[2].should.equal("--bar='foo bar'")
})

it('handles double quoted string with spaces', function () {
var args = tokenizeArgString('--foo "hello world" --bar="foo bar"')
args[0].should.equal('--foo')
args[1].should.equal('hello world')
args[2].should.equal('--bar=foo bar')
args[1].should.equal('"hello world"')
args[2].should.equal('--bar="foo bar"')
})

it('handles single quoted empty string', function () {
var args = tokenizeArgString('--foo \'\' --bar=\'\'')
args[0].should.equal('--foo')
args[1].should.equal('')
args[2].should.equal('--bar=')
args[1].should.equal("''")
args[2].should.equal("--bar=''")
})

it('handles double quoted empty string', function () {
var args = tokenizeArgString('--foo "" --bar=""')
args[0].should.equal('--foo')
args[1].should.equal('')
args[2].should.equal('--bar=')
args[1].should.equal('""')
args[2].should.equal('--bar=""')
})

it('handles quoted string with embeded quotes', function () {
var args = tokenizeArgString('--foo "hello \'world\'" --bar=\'foo "bar"\'')
args[0].should.equal('--foo')
args[1].should.equal('hello \'world\'')
args[2].should.equal('--bar=foo "bar"')
args[1].should.equal('"hello \'world\'"')
args[2].should.equal('--bar=\'foo "bar"\'')
})

// https://github.com/yargs/yargs-parser/pull/100
Expand All @@ -59,6 +59,6 @@ describe('TokenizeArgString', function () {
var args = tokenizeArgString(' foo bar "foo bar" ')
args[0].should.equal('foo')
expect(args[1]).equal('bar')
expect(args[2]).equal('foo bar')
expect(args[2]).equal('"foo bar"')
})
})
27 changes: 27 additions & 0 deletions test/yargs-parser.js
Expand Up @@ -2796,4 +2796,31 @@ describe('yargs-parser', function () {
argv.foo[3].bla.should.equal('banana')
})
})

// see: https://github.com/yargs/yargs-parser/issues/145
describe('strings with quotes and dashes', () => {
it('handles double quoted strings', function () {
const args = parser('--foo "hello world" --bar="goodnight\'moon"')
args.foo.should.equal('hello world')
args.bar.should.equal('goodnight\'moon')
const args2 = parser(['--foo', '"hello world"', '--bar="goodnight\'moon"'])
args2.foo.should.equal('hello world')
args2.bar.should.equal('goodnight\'moon')
})

it('handles single quoted strings', function () {
const args = parser("--foo 'hello world' --bar='goodnight\"moon'")
args.foo.should.equal('hello world')
args.bar.should.equal('goodnight"moon')
const args2 = parser(['--foo', "'hello world'", "--bar='goodnight\"moon'"])
args2.foo.should.equal('hello world')
args2.bar.should.equal('goodnight"moon')
})

it('handles strings with dashes', function () {
const args = parser('--foo "-hello world" --bar="--goodnight moon"')
args.foo.should.equal('-hello world')
args.bar.should.equal('--goodnight moon')
})
})
})

0 comments on commit 2fb71b2

Please sign in to comment.