| Index: test/snippets.js | 
| =================================================================== | 
| --- a/test/snippets.js | 
| +++ b/test/snippets.js | 
| @@ -207,16 +207,147 @@ | 
| [["foo"], ["bar", "1"]]); | 
| checkParsedScript("Script with blank argument in the middle", "foo '' Hello", | 
| [["foo", "", "Hello"]]); | 
| checkParsedScript("Script with blank argument at the end", "foo Hello ''", | 
| [["foo", "Hello", ""]]); | 
| checkParsedScript("Script with consecutive blank arguments", "foo '' ''", | 
| [["foo", "", ""]]); | 
| + // Most tests now repeated with named arguments. | 
| + checkParsedScript("Script with one named argument", "foo one=1", | 
| + [{0: "foo", one: "1"}]); | 
| + checkParsedScript("Script with two named arguments", "foo one=1 hello=Hello", | 
| + [{0: "foo", one: "1", hello: "Hello"}]); | 
| + checkParsedScript("Script with named argument containing an escaped space", | 
| + "foo hello-world=Hello\\ world", | 
| + [{"0": "foo", "hello-world": "Hello world"}]); | 
| + checkParsedScript("Script with name containing an escaped space", | 
| + "foo hello\\ world=Hello\\ world", | 
| + [{"0": "foo", "hello world": "Hello world"}]); | 
| + checkParsedScript("Script with named argument containing a quoted space", | 
| + "foo hello-world='Hello world'", | 
| + [{"0": "foo", "hello-world": "Hello world"}]); | 
| + checkParsedScript("Script with name containing a quoted space", | 
| + "foo 'hello world'='Hello world'", | 
| + [{"0": "foo", "hello world": "Hello world"}]); | 
| + checkParsedScript("Script with named argument containing a quoted escaped quote", | 
| + "foo hello-world='Hello \\'world\\''", | 
| + [{"0": "foo", "hello-world": "Hello 'world'"}]); | 
| + checkParsedScript("Script with name containing a quoted escaped quote", | 
| + "foo 'hello \\'world\\''='Hello \\'world\\''", | 
| + [{"0": "foo", "hello 'world'": "Hello 'world'"}]); | 
| + checkParsedScript("Script with named argument containing an escaped semicolon", | 
| + "foo tldr=TL\\;DR", | 
| + [{0: "foo", tldr: "TL;DR"}]); | 
| + checkParsedScript("Script with name containing an escaped semicolon", | 
| + "foo tl\\;dr=TL\\;DR", | 
| + [{"0": "foo", "tl;dr": "TL;DR"}]); | 
| + checkParsedScript("Script with named argument containing a quoted semicolon", | 
| + "foo tldr='TL;DR'", | 
| + [{0: "foo", tldr: "TL;DR"}]); | 
| + checkParsedScript("Script with name containing a quoted semicolon", | 
| + "foo 'tl;dr'='TL;DR'", | 
| + [{"0": "foo", "tl;dr": "TL;DR"}]); | 
| + checkParsedScript("Script with named argument containing single character " + | 
| + "escape sequences", | 
| + "foo yin-yang=yin\\tyang\\n", | 
| + [{"0": "foo", "yin-yang": "yin\tyang\n"}]); | 
| + checkParsedScript("Script with name containing single character " + | 
| + "escape sequences", | 
| + "foo yin\\tyang\\n=yin\\tyang\\n", | 
| + [{"0": "foo", "yin\tyang\n": "yin\tyang\n"}]); | 
| + checkParsedScript("Script with named argument containing Unicode " + | 
| + "escape sequences", | 
| + "foo bar=\\u0062\\ud83d\\ude42r " + | 
| + "lambda='l\\ud83d\\ude02mbd\\ud83d\\ude02'", [{ | 
| + 0: "foo", bar: "b\ud83d\ude42r", | 
| + lambda: "l\ud83d\ude02mbd\ud83d\ude02" | 
| + }]); | 
| + checkParsedScript("Script with name containing Unicode " + | 
| + "escape sequences", | 
| + "foo \\u0062\\ud83d\\ude42r=\\u0062\\ud83d\\ude42r " + | 
| + "'l\\ud83d\\ude02mbd\\ud83d\\ude02'=" + | 
| + "'l\\ud83d\\ude02mbd\\ud83d\\ude02'", [{ | 
| + "0": "foo", "b\ud83d\ude42r": "b\ud83d\ude42r", | 
| + "l\ud83d\ude02mbd\ud83d\ude02": | 
| + "l\ud83d\ude02mbd\ud83d\ude02" | 
| + }]); | 
| + | 
| + checkParsedScript("Script with multiple commands and multiple " + | 
| + "named arguments each", | 
| + "foo 1=1 hello=Hello; bar world=world! hash=#", [ | 
| + {0: "foo", 1: "1", hello: "Hello"}, | 
| + {0: "bar", world: "world!", hash: "#"} | 
| + ]); | 
| + checkParsedScript("Script with multiple commands and multiple " + | 
| + "escaped and quoted named arguments each", | 
| + "foo 1=1 'Hello, \\'Tommy\\'!'='Hello, \\'Tommy\\'!' ;" + | 
| + "bar Hi!\\ How\\ are\\ you?=Hi!\\ How\\ are\\ you? " + | 
| + "http://example.com=http://example.com", [{ | 
| + "0": "foo", "1": "1", | 
| + "Hello, 'Tommy'!": "Hello, 'Tommy'!" | 
| + }, { | 
| + "0": "bar", "Hi! How are you?": "Hi! How are you?", | 
| + "http://example.com": "http://example.com" | 
| + }]); | 
| + | 
| + // Some more tests specific to named arguments. | 
| + checkParsedScript("Script with blank named argument", "foo blank=", | 
| + [{0: "foo", blank: ""}]); | 
| + checkParsedScript("Script with blank and non-blank named arguments", | 
| + "foo blank= non-blank=non-blank", | 
| + [{"0": "foo", "blank": "", "non-blank": "non-blank"}]); | 
| + checkParsedScript("Script with quoted blank named argument", | 
| + "foo blank=''", | 
| + [{0: "foo", blank: ""}]); | 
| + checkParsedScript("Script with quoted blank and non-blank named arguments", | 
| + "foo blank='' non-blank='non-blank'", | 
| + [{"0": "foo", "blank": "", "non-blank": "non-blank"}]); | 
| + checkParsedScript("Script with multiple commands and blank named arguments", | 
| + "foo blank=; bar blank=", | 
| + [{0: "foo", blank: ""}, {0: "bar", blank: ""}]); | 
| + checkParsedScript("Script with multiple commands and " + | 
| + "quoted blank named arguments", | 
| + "foo blank=''; bar blank=''", | 
| + [{0: "foo", blank: ""}, {0: "bar", blank: ""}]); | 
| + checkParsedScript("Script with multiple commands and " + | 
| + "quoted blank named arguments ending with a semicolon", | 
| + "foo blank=''; bar blank='';", | 
| + [{0: "foo", blank: ""}, {0: "bar", blank: ""}]); | 
| + checkParsedScript("Script with blank name", "foo =blank", | 
| + [{"0": "foo", "": "blank"}]); | 
| + checkParsedScript("Script with quoted blank name", "foo ''=blank", | 
| + [{"0": "foo", "": "blank"}]); | 
| + checkParsedScript("Script with quoted blank name and blank named argument", | 
| + "foo ''=''", [{"0": "foo", "": ""}]); | 
| + checkParsedScript("Script with command name containing an " + | 
| + "assignment operator", | 
| + "foo=bar", [["foo=bar"]]); | 
| + checkParsedScript("Script with argument containing a quoted " + | 
| + "assignment operator", | 
| + "foo 'name=bar'", [["foo", "name=bar"]]); | 
| + checkParsedScript("Script with argument containing an escaped " + | 
| + "assignment operator", | 
| + "foo name\\=bar", [["foo", "name=bar"]]); | 
| + checkParsedScript("Script with named argument containing assignment operator", | 
| + "foo name=bar=one", [{0: "foo", name: "bar=one"}]); | 
| + checkParsedScript("Script with named argument starting with " + | 
| + "assignment operator", | 
| + "foo name==bar", [{0: "foo", name: "=bar"}]); | 
| + checkParsedScript("Script with named argument ending with " + | 
| + "assignment operator", | 
| + "foo name=bar=", [{0: "foo", name: "bar="}]); | 
| + checkParsedScript("Script with name containing a quoted " + | 
| + "assignment operator", | 
| + "foo 'name=one'=bar", [{"0": "foo", "name=one": "bar"}]); | 
| + checkParsedScript("Script with name containing an escaped " + | 
| + "assignment operator", | 
| + "foo name\\=one=bar", [{"0": "foo", "name=one": "bar"}]); | 
| + | 
| // Undocumented quirks (#6853). | 
| checkParsedScript("Script with quotes within an argument", "foo Hello''world", | 
| [["foo", "Helloworld"]]); | 
| checkParsedScript("Script with quotes within an argument containing whitespace", | 
| "foo Hello' 'world", | 
| [["foo", "Hello world"]]); | 
| checkParsedScript("Script with quotes within an argument containing non-whitespace", | 
| "foo Hello','world", |