@Test
	public void moduleArguments_xd1613() {
		if (JobParser.SUPPORTS_INLINE_JOB_DEFINITIONS) {
			// notice no space between the ' and final >
			js = parse(
					"transform X --expression='payload.toUpperCase()' || filter Y --expression='payload.length() > 4'");
			assertEquals("payload.toUpperCase()", js.getJobDefinition("X").getArguments()[0].getValue());
			assertEquals("payload.length() > 4", js.getJobDefinition("Y").getArguments()[0].getValue());

			js = parse(
					"time || transform X --expression='T(org.joda.time.format.DateTimeFormat).forPattern(\"yyyy-MM-dd HH:mm:ss\").parseDateTime(payload)'");
			assertEquals(
					"T(org.joda.time.format.DateTimeFormat).forPattern(\"yyyy-MM-dd HH:mm:ss\").parseDateTime(payload)",
					js.getJobDefinition("X").getArguments()[0].getValue());

			// allow for pipe/semicolon if quoted
			js = parse("http || transform X --outputType='text/plain|charset=UTF-8' || log");
			assertEquals("text/plain|charset=UTF-8", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http || transform X --outputType='text/plain;charset=UTF-8' || log");
			assertEquals("text/plain;charset=UTF-8", js.getJobDefinition("X").getArguments()[0].getValue());

			// Want to treat all of 'hi'+payload as the argument value
			js = parse("http || transform X --expression='hi'+payload || log");
			assertEquals("'hi'+payload", js.getJobDefinition("X").getArguments()[0].getValue());

			// Want to treat all of payload+'hi' as the argument value
			js = parse("http || transform X --expression=payload+'hi' || log");
			assertEquals("payload+'hi'", js.getJobDefinition("X").getArguments()[0].getValue());

			// Alternatively, can quote all around it to achieve the same thing
			js = parse("http || transform X --expression='payload+''hi''' || log");
			assertEquals("payload+'hi'", js.getJobDefinition("X").getArguments()[0].getValue());
			js = parse("http || transform X --expression='''hi''+payload' || log");
			assertEquals("'hi'+payload", js.getJobDefinition("X").getArguments()[0].getValue());


			js = parse("http || transform X --expression=\"payload+'hi'\" || log");
			assertEquals("payload+'hi'", js.getJobDefinition("X").getArguments()[0].getValue());
			js = parse("http || transform X --expression=\"'hi'+payload\" || log");
			assertEquals("'hi'+payload", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http || transform X --expression=payload+'hi'--param2='foobar' || log");
			assertEquals("payload+'hi'--param2='foobar'", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http || transform X --expression='hi'+payload--param2='foobar' || log");
			assertEquals("'hi'+payload--param2='foobar'", js.getJobDefinition("X").getArguments()[0].getValue());

			// This also works, which is cool
			js = parse("http || transform X --expression='hi'+'world' || log");
			assertEquals("'hi'+'world'", js.getJobDefinition("X").getArguments()[0].getValue());
			js = parse("http || transform X --expression=\"'hi'+'world'\" || log");
			assertEquals("'hi'+'world'", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http || filter X --expression=payload.matches('hello world') || log");
			assertEquals("payload.matches('hello world')", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http || transform X --expression='''hi''' || log");
			assertEquals("'hi'", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http || transform X --expression=\"''''hi''''\" || log");
			assertEquals("''''hi''''", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http asdf --port=9014 || filter X --expression=\"payload == 'foo'\" || log");
			assertEquals("payload == 'foo'", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http asdf --port=9014 || filter X --expression='new Foo()' || log");
			assertEquals("new Foo()", js.getJobDefinition("X").getArguments()[0].getValue());

			js = parse("http || transform XX --expression='payload.replace(\"abc\", \"\")' || log");
			assertEquals("payload.replace(\"abc\", \"\")", js.getJobDefinition("XX").getArguments()[0].getValue());

			js = parse("http || transform XX --expression='payload.replace(\"abc\", '''')' || log");
			assertEquals("payload.replace(\"abc\", '')", js.getJobDefinition("XX").getArguments()[0].getValue());
		}
		else {
			checkForParseError(
					"transform X --expression='payload.toUpperCase()' || filter Y --expression='payload.length() > 4'",
					JobDSLMessage.EXPECTED_FLOW_OR_SPLIT_CHARS, 10, "X");
		}
	}
Parse job specifications and verify either the correct abstract syntax tree is produced or the current exception comes out.
The parser does no semantic validation, it is purely syntax checking.

@author Andy Clement
spring-xd-dirt/src/test/java/org/springframework/xd/dirt/job/dsl/JobParserTests.java