/*******************************************************************************
* Copyright (c) 2014 Bruno Medeiros and other Contributors.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package com.github.rustdt.tooling;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertFail;
import static melnorme.utilbox.core.CoreUtil.listFrom;
import static melnorme.utilbox.status.Severity.ERROR;
import static melnorme.utilbox.status.Severity.WARNING;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import melnorme.lang.tooling.common.ToolSourceMessage;
import melnorme.utilbox.core.CommonException;
public class RustBuildOutputParserClassicTest extends CommonRustMessageParserTest {
public class TestsRustBuildOutputParser extends RustBuildOutputParser {
@Override
protected void handleParseError(CommonException ce) {
assertFail();
}
}
protected static final String NL = "\n";
protected static String MULTILINE_MESSAGE =
"mismatched types:\n" +
" expected `u32`,\n" +
" found `core::option::Option<_>`";
@Test
public void test() throws Exception { test$(); }
public void test$() throws Exception {
RustBuildOutputParser buildParser = new TestsRustBuildOutputParser();
RustBuildOutputParser buildParser_allowParseErrors = new RustBuildOutputParser() {
@Override
protected void handleParseError(CommonException ce) {
}
};
testParseMessages(buildParser, "", listFrom()); // Empty
{
testParseMessages(buildParser_allowParseErrors, "libbar/blah.rs:", listFrom());
testParseMessages(buildParser_allowParseErrors, "libbar/blah.rs:1:2: info: BLAH BLAH", listFrom());
testParseMessages(buildParser_allowParseErrors, "libbar/blah.rs:1:2: 3:16 info: BLAH BLAH", listFrom());
}
testParseMessages(buildParser,
"src/main.rs:1:2: 3:17 warning: BLAH BLAH BLAH\n",
listFrom(msg(path("src/main.rs"), 1, 2, 3, 17, WARNING, "BLAH BLAH BLAH")));
testParseMessages(buildParser,
"src/main.rs:1:2: warning: BLAH BLAH BLAH\n",
listFrom(msg(path("src/main.rs"), 1, 2, -1, -1, WARNING, "BLAH BLAH BLAH")));
testParseMessages(buildParser,
"src/main.rs:1: warning: BLAH BLAH BLAH\n",
listFrom(msg(path("src/main.rs"), 1, -1, -1, -1, WARNING, "BLAH BLAH BLAH")));
testParseMessages(buildParser_allowParseErrors,
"src/main.rs:1:2: 3:17 warning: BLAH BLAH BLAH\n" +
"src/main.rs:1:2: 3: warning: INVALID\n" +
"src/main.rs:1:2: :17 warning: INVALID\n" +
"src/main.rs:1:2: 3:17 blah: INVALID\n" +
"src/main.rs:1: warning: BLAH BLAH BLAH\n" +
"src/foo/main.rs:2:1: 4:18 error: XXX\n",
listFrom(
msg(path("src/main.rs"), 1, 2, 3, 17, WARNING, "BLAH BLAH BLAH"),
msg(path("src/main.rs"), 1, -1, -1, -1, WARNING, "BLAH BLAH BLAH"),
msg(path("src/foo/main.rs"), 2, 1, 4, 18, ERROR, "XXX")
)
);
// test Rust message source text component
testParseMessages(buildParser,
"src/main.rs:1:2: 3:17 warning: BLAH BLAH BLAH\n"+
"src/main.rs:1 const STRING2 : str = xxx;" +NL+
" ^~~" +NL+
"src/main.rs:2:2: 3:10 error: XXX\n"+
"src/main.rs:1 const STRING2 : str = ;" +NL+
" ^"
,
listFrom(
msg(path("src/main.rs"), 1, 2, 3, 17, WARNING, "BLAH BLAH BLAH"),
msg(path("src/main.rs"), 2, 2, 3, 10, ERROR, "XXX")
)
);
// Test actual multiline message
testParseMessages(buildParser,
"src/main.rs:1:2: 3:17 error: " + MULTILINE_MESSAGE + NL +
"src/main.rs:1: warning: xxx" + MULTILINE_MESSAGE,
listFrom(
msg(path("src/main.rs"), 1, 2, 3, 17, ERROR, MULTILINE_MESSAGE),
msg(path("src/main.rs"), 1, -1, -1, -1, WARNING, "xxx" + MULTILINE_MESSAGE)
)
);
// Test "aborting due to "
testParseMessages(buildParser,
"src/main.rs:1:2: warning: BLAH BLAH BLAH"+NL+
"error: aborting due to 3 previous errors",
listFrom(msg(path("src/main.rs"), 1, 2, -1, -1, WARNING, "BLAH BLAH BLAH")));
testParseMessages(buildParser,
"error: aborting due to previous error",
listFrom());
testMacroExpansionMessages(buildParser);
}
protected void testParseMessages(RustBuildOutputParser buildProcessor, String stderr, List<?> expected)
throws CommonException {
ArrayList<ToolSourceMessage> buildMessages = buildProcessor.parseOutput(stderr);
assertEquals(buildMessages, expected);
}
public static final String MACRO_MSG_1 = "src/main.rs:52:18: 52:28 error: unresolved name `abc`";
public static final String MACRO_MSG_2 = "src/main.rs:46:1: 58:2 note: in expansion of create_function!";
public static final String MACRO_MSG_3 = "src/main.rs:60:1: 60:23 note: expansion site";
protected void testMacroExpansionMessages(RustBuildOutputParser buildParser) throws CommonException {
// Test macro expansion error message
testParseMessages(buildParser,
MACRO_MSG_1 +NL+
"src/main.rs:52 let a = $func_name;" +NL+
" ^~~~~~~~~~" +NL+
MACRO_MSG_2 +NL+
MACRO_MSG_3 +NL+
"error: aborting due to previous error",
listFrom(
msg(path("src/main.rs"), 52, 18, 52, 28, ERROR, "unresolved name `abc`"
+NL+ MACRO_MSG_2 +NL+ MACRO_MSG_3)
, msg(path("src/main.rs"), 60, 1, 60, 23, ERROR, "[macro expansion error]"
+NL+ MACRO_MSG_2 +NL+ MACRO_MSG_1)
)
);
}
@Test
public void testCargoErrorMesages() throws Exception { testCargoErrorMesages$(); }
public void testCargoErrorMesages$() throws Exception {
RustBuildOutputParser buildParser = new TestsRustBuildOutputParser();
testParseMessages(buildParser,
"Cargo.toml:17:15-18:0 expected `=`, but found `",
listFrom(msg(path("Cargo.toml"), 17, 15, 18, 0, ERROR, "expected `=`, but found `")));
}
}