Skip to content

Commit 0a8f2f4

Browse files
authored
Testing (#63)
* Adding more unit tests
1 parent bb9f3b7 commit 0a8f2f4

File tree

14 files changed

+655
-1
lines changed

14 files changed

+655
-1
lines changed

community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ private static void enumerationsItem(LexerlessGrammarBuilder b) {
563563
SPC, b.optional(ENUM_ITEMS), SPC, "}");
564564
b.rule(ENUM_ITEMS).is(seq(b, ENUM_ITEM, RustPunctuator.COMMA));
565565
b.rule(ENUM_ITEM).is(b.zeroOrMore(OUTER_ATTRIBUTE, SPC), b.optional(VISIBILITY, SPC),
566-
IDENTIFIER, SPC, b.optional(b.firstOf(ENUM_ITEM_TUPLE, ENUM_ITEM_STRUCT, ENUM_ITEM_DISCRIMINANT)));
566+
IDENTIFIER, SPC, b.optional(b.firstOf(ENUM_ITEM_TUPLE, ENUM_ITEM_STRUCT), SPC, b.optional(ENUM_ITEM_DISCRIMINANT)));
567567
b.rule(ENUM_ITEM_TUPLE).is("(", SPC, b.optional(TUPLE_FIELDS), SPC, ")");
568568
b.rule(ENUM_ITEM_STRUCT).is("{", SPC, b.optional(STRUCT_FIELDS), SPC, "}");
569569
b.rule(ENUM_ITEM_DISCRIMINANT).is(RustPunctuator.EQ, SPC, EXPRESSION);
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package org.elegoff.plugins.communityrust;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.nio.charset.StandardCharsets;
6+
import java.nio.file.Files;
7+
import org.elegoff.plugins.communityrust.language.RustLanguage;
8+
import org.fest.assertions.Assertions;
9+
import org.junit.Test;
10+
import org.sonar.api.batch.fs.InputFile;
11+
import org.sonar.api.batch.fs.internal.DefaultInputFile;
12+
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
13+
import org.sonar.api.batch.rule.CheckFactory;
14+
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
15+
import org.sonar.api.batch.sensor.internal.SensorContextTester;
16+
import org.sonar.api.config.internal.MapSettings;
17+
import org.sonar.api.measures.FileLinesContext;
18+
import org.sonar.api.measures.FileLinesContextFactory;
19+
20+
import static org.mockito.ArgumentMatchers.any;
21+
import static org.mockito.Mockito.mock;
22+
import static org.mockito.Mockito.verify;
23+
import static org.mockito.Mockito.when;
24+
25+
26+
public class RustcParsingTest {
27+
private final File dir = new File("src/test/resources/rustc");
28+
private FileLinesContext fileLinesContext;
29+
private SensorContextTester tester;
30+
private RustSensor sensor;
31+
32+
33+
public void reinit() {
34+
tester = SensorContextTester.create(dir);
35+
36+
MapSettings settings = CommunityRustPluginConfigurationTest.getDefaultSettings();
37+
tester.setSettings(settings);
38+
39+
FileLinesContextFactory fileLinesContextFactory = mock(FileLinesContextFactory.class);
40+
fileLinesContext = mock(FileLinesContext.class);
41+
when(fileLinesContextFactory.createFor(any(InputFile.class))).thenReturn(fileLinesContext);
42+
ActiveRulesBuilder activeRuleBuilder = new ActiveRulesBuilder();
43+
CheckFactory checkFactory = new CheckFactory(activeRuleBuilder.build());
44+
sensor = new RustSensor(checkFactory, fileLinesContextFactory);
45+
}
46+
47+
private DefaultInputFile addInputFile(String fileName) throws IOException {
48+
String content = new String(Files.readAllBytes(new File(dir, fileName).toPath()));
49+
Assertions.assertThat(content).isNotEmpty();
50+
DefaultInputFile inputFile = new TestInputFileBuilder(tester.module().key(), fileName)
51+
.setModuleBaseDir(tester.fileSystem().baseDirPath())
52+
.setType(InputFile.Type.MAIN)
53+
.setLanguage(RustLanguage.KEY)
54+
.setCharset(StandardCharsets.UTF_8)
55+
.initMetadata(content)
56+
.build();
57+
tester.fileSystem().add(inputFile);
58+
return inputFile;
59+
}
60+
61+
private DefaultInputFile executeSensorOnSingleFile(String fileName) throws IOException {
62+
DefaultInputFile inputFile = addInputFile(fileName);
63+
sensor.execute(tester);
64+
return inputFile;
65+
}
66+
67+
68+
private void checkme(String testfile) throws IOException {
69+
reinit();
70+
DefaultInputFile inputFile = executeSensorOnSingleFile(testfile);
71+
verify(fileLinesContext).save();
72+
Assertions.assertThat(tester.allAnalysisErrors()).isEmpty();
73+
}
74+
75+
@Test
76+
public void DebugInfoTest() throws IOException {
77+
checkme("debuginfo/associated-types.rs");
78+
checkme("debuginfo/borrowed-enums.rs");
79+
}
80+
81+
@Test
82+
public void RunMakeFulldepsTest() throws IOException {
83+
checkme("run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs");
84+
}
85+
86+
@Test
87+
public void UITest() throws IOException {
88+
checkme("ui/cfg/cfg-panic.rs");
89+
90+
checkme("ui/borrowck/issue-88434-minimal-example.rs");
91+
checkme("ui/borrowck/issue-88434-removal-index-should-be-less.rs");
92+
checkme("ui/const-generics/generic_const_exprs/issue-85848.rs");
93+
checkme("ui/const-generics/issues/issue-79674.rs");
94+
95+
checkme("ui/cfg/cfg-panic-abort.rs");
96+
checkme("ui/feature-gates/feature-gate-cfg-target-has-atomic-equal-alignment.rs");
97+
checkme("ui/fmt/format-args-capture.rs");
98+
checkme("ui/issues/issue-68696-catch-during-unwind.rs");
99+
}
100+
101+
102+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Some versions of the non-rust-enabled LLDB print the wrong generic
2+
// parameter type names in this test.
3+
// rust-lldb
4+
5+
// compile-flags:-g
6+
7+
// === GDB TESTS ===================================================================================
8+
// gdb-command:run
9+
10+
// gdb-command:print arg
11+
// gdbg-check:$1 = {b = -1, b1 = 0}
12+
// gdbr-check:$1 = associated_types::Struct<i32> {b: -1, b1: 0}
13+
// gdb-command:continue
14+
15+
// gdb-command:print inferred
16+
// gdb-check:$2 = 1
17+
// gdb-command:print explicitly
18+
// gdb-check:$3 = 1
19+
// gdb-command:continue
20+
21+
// gdb-command:print arg
22+
// gdb-check:$4 = 2
23+
// gdb-command:continue
24+
25+
// gdb-command:print arg
26+
// gdbg-check:$5 = {__0 = 4, __1 = 5}
27+
// gdbr-check:$5 = (4, 5)
28+
// gdb-command:continue
29+
30+
// gdb-command:print a
31+
// gdb-check:$6 = 6
32+
// gdb-command:print b
33+
// gdb-check:$7 = 7
34+
// gdb-command:continue
35+
36+
// gdb-command:print a
37+
// gdb-check:$8 = 8
38+
// gdb-command:print b
39+
// gdb-check:$9 = 9
40+
// gdb-command:continue
41+
42+
// === LLDB TESTS ==================================================================================
43+
// lldb-command:run
44+
45+
// lldb-command:print arg
46+
// lldbg-check:[...]$0 = { b = -1, b1 = 0 }
47+
// lldbr-check:(associated_types::Struct<i32>) arg = { b = -1, b1 = 0 }
48+
// lldb-command:continue
49+
50+
// lldb-command:print inferred
51+
// lldbg-check:[...]$1 = 1
52+
// lldbr-check:(i64) inferred = 1
53+
// lldb-command:print explicitly
54+
// lldbg-check:[...]$2 = 1
55+
// lldbr-check:(i64) explicitly = 1
56+
// lldb-command:continue
57+
58+
// lldb-command:print arg
59+
// lldbg-check:[...]$3 = 2
60+
// lldbr-check:(i64) arg = 2
61+
// lldb-command:continue
62+
63+
// lldb-command:print arg
64+
// lldbg-check:[...]$4 = (4, 5)
65+
// lldbr-check:((i32, i64)) arg = { = 4 = 5 }
66+
// lldb-command:continue
67+
68+
// lldb-command:print a
69+
// lldbg-check:[...]$5 = 6
70+
// lldbr-check:(i32) a = 6
71+
// lldb-command:print b
72+
// lldbg-check:[...]$6 = 7
73+
// lldbr-check:(i64) b = 7
74+
// lldb-command:continue
75+
76+
// lldb-command:print a
77+
// lldbg-check:[...]$7 = 8
78+
// lldbr-check:(i64) a = 8
79+
// lldb-command:print b
80+
// lldbg-check:[...]$8 = 9
81+
// lldbr-check:(i32) b = 9
82+
// lldb-command:continue
83+
84+
#![allow(unused_variables)]
85+
#![allow(dead_code)]
86+
#![feature(omit_gdb_pretty_printer_section)]
87+
#![omit_gdb_pretty_printer_section]
88+
89+
trait TraitWithAssocType {
90+
type Type;
91+
92+
fn get_value(&self) -> Self::Type;
93+
}
94+
95+
impl TraitWithAssocType for i32 {
96+
type Type = i64;
97+
98+
fn get_value(&self) -> i64 { *self as i64 }
99+
}
100+
101+
struct Struct<T: TraitWithAssocType> {
102+
b: T,
103+
b1: T::Type,
104+
}
105+
106+
enum Enum<T: TraitWithAssocType> {
107+
Variant1(T, T::Type),
108+
Variant2(T::Type, T),
109+
}
110+
111+
fn assoc_struct<T: TraitWithAssocType>(arg: Struct<T>) {
112+
zzz(); // #break
113+
}
114+
115+
fn assoc_local<T: TraitWithAssocType>(x: T) {
116+
let inferred = x.get_value();
117+
let explicitly: T::Type = x.get_value();
118+
119+
zzz(); // #break
120+
}
121+
122+
fn assoc_arg<T: TraitWithAssocType>(arg: T::Type) {
123+
zzz(); // #break
124+
}
125+
126+
fn assoc_return_value<T: TraitWithAssocType>(arg: T) -> T::Type {
127+
return arg.get_value();
128+
}
129+
130+
fn assoc_tuple<T: TraitWithAssocType>(arg: (T, T::Type)) {
131+
zzz(); // #break
132+
}
133+
134+
fn assoc_enum<T: TraitWithAssocType>(arg: Enum<T>) {
135+
match arg {
136+
Enum::Variant1(a, b) => {
137+
zzz(); // #break
138+
}
139+
Enum::Variant2(a, b) => {
140+
zzz(); // #break
141+
}
142+
}
143+
}
144+
145+
fn main() {
146+
assoc_struct(Struct { b: -1, b1: 0 });
147+
assoc_local(1);
148+
assoc_arg::<i32>(2);
149+
assoc_return_value(3);
150+
assoc_tuple((4, 5));
151+
assoc_enum(Enum::Variant1(6, 7));
152+
assoc_enum(Enum::Variant2(8, 9));
153+
}
154+
155+
fn zzz() { () }
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Require a gdb or lldb that can read DW_TAG_variant_part.
2+
// min-gdb-version: 8.2
3+
// rust-lldb
4+
5+
// compile-flags:-g
6+
7+
// === GDB TESTS ===================================================================================
8+
9+
// gdb-command:run
10+
11+
// gdb-command:print *the_a_ref
12+
// gdbr-check:$1 = borrowed_enum::ABC::TheA{x: 0, y: 8970181431921507452}
13+
14+
// gdb-command:print *the_b_ref
15+
// gdbr-check:$2 = borrowed_enum::ABC::TheB(0, 286331153, 286331153)
16+
17+
// gdb-command:print *univariant_ref
18+
// gdbr-check:$3 = borrowed_enum::Univariant::TheOnlyCase(4820353753753434)
19+
20+
21+
// === LLDB TESTS ==================================================================================
22+
23+
// lldb-command:run
24+
25+
// lldb-command:print *the_a_ref
26+
// lldbr-check:(borrowed_enum::ABC::TheA) *the_a_ref = TheA { TheA: 0, TheB: 8970181431921507452 }
27+
// lldb-command:print *the_b_ref
28+
// lldbr-check:(borrowed_enum::ABC::TheB) *the_b_ref = { = 0 = 286331153 = 286331153 }
29+
// lldb-command:print *univariant_ref
30+
// lldbr-check:(borrowed_enum::Univariant) *univariant_ref = { TheOnlyCase = { = 4820353753753434 } }
31+
32+
#![allow(unused_variables)]
33+
#![feature(omit_gdb_pretty_printer_section)]
34+
#![omit_gdb_pretty_printer_section]
35+
36+
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
37+
// the size of the discriminant value is machine dependent, this has be taken into account when
38+
// datatype layout should be predictable as in this case.
39+
enum ABC {
40+
TheA { x: i64, y: i64 },
41+
TheB(i64, i32, i32),
42+
}
43+
44+
// This is a special case since it does not have the implicit discriminant field.
45+
enum Univariant {
46+
TheOnlyCase(i64)
47+
}
48+
49+
fn main() {
50+
51+
// 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
52+
// 0b01111100011111000111110001111100 = 2088533116
53+
// 0b0111110001111100 = 31868
54+
// 0b01111100 = 124
55+
let the_a = ABC::TheA { x: 0, y: 8970181431921507452 };
56+
let the_a_ref: &ABC = &the_a;
57+
58+
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
59+
// 0b00010001000100010001000100010001 = 286331153
60+
// 0b0001000100010001 = 4369
61+
// 0b00010001 = 17
62+
let the_b = ABC::TheB(0, 286331153, 286331153);
63+
let the_b_ref: &ABC = &the_b;
64+
65+
let univariant = Univariant::TheOnlyCase(4820353753753434);
66+
let univariant_ref: &Univariant = &univariant;
67+
68+
zzz(); // #break
69+
}
70+
71+
fn zzz() { () }

0 commit comments

Comments
 (0)