Skip to content

Commit

Permalink
feat: add snapshot tests for compiler errors
Browse files Browse the repository at this point in the history
Verify good compiler error output by creating several snapshot tests.
Also, slightly improve some of the messages.
  • Loading branch information
dnaka91 committed Oct 25, 2023
1 parent 92f039b commit 0efc118
Show file tree
Hide file tree
Showing 30 changed files with 349 additions and 12 deletions.
17 changes: 9 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ check:
fmt:
cargo +nightly fmt --all

# Run snapshot tests and review any updates
snapshots:
cargo insta test --workspace --all-features \
--test-runner nextest \
--unreferenced delete \
--review

# Start up the local server for the book
@book:
cd book && just dev
Expand Down
2 changes: 1 addition & 1 deletion crates/stef-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ name = "stef"
path = "src/main.rs"

[dependencies]
clap = { version = "4.4.6", features = ["derive", "wrap_help"] }
clap = { version = "4.4.7", features = ["derive", "wrap_help"] }
color-eyre.workspace = true
glob.workspace = true
miette = { workspace = true, features = ["fancy-no-backtrace"] }
Expand Down
4 changes: 4 additions & 0 deletions crates/stef-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ license.workspace = true
miette.workspace = true
stef-parser = { path = "../stef-parser" }
thiserror.workspace = true

[dev-dependencies]
insta.workspace = true
miette = { workspace = true, features = ["fancy-no-backtrace"] }
6 changes: 3 additions & 3 deletions crates/stef-compiler/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub enum DuplicateFieldId {
#[label("used here again")]
second: Range<usize>,
},
#[error("duplicate ID {} in field {position}, already used in {other_position}", id.get())]
#[error("duplicate ID {} in position {position}, already used at {other_position}", id.get())]
#[diagnostic(help("the IDs for each field must be unique"))]
Unnamed {
id: Id,
Expand Down Expand Up @@ -116,8 +116,8 @@ fn validate_field_ids(value: &Fields<'_>) -> Result<(), DuplicateFieldId> {
visited.insert(field.id.get(), (pos, field.id.span())).map(
|(other_position, other_span)| DuplicateFieldId::Unnamed {
id: field.id.clone(),
position: pos,
other_position,
position: pos + 1,
other_position: other_position + 1,
first: other_span.into(),
second: field.id.span().into(),
},
Expand Down
43 changes: 43 additions & 0 deletions crates/stef-compiler/tests/compiler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use std::{
fmt::{self, Display},
fs,
};

use insta::{assert_snapshot, glob};
use miette::{Diagnostic, MietteHandler, MietteHandlerOpts, NamedSource, Report, ReportHandler};
use stef_parser::Schema;

#[test]
fn compile_invalid_schema() {
struct Wrapper<'a>(&'a MietteHandler, &'a dyn Diagnostic);

impl<'a> Display for Wrapper<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.debug(self.1, f)
}
}

let handler = MietteHandlerOpts::new()
.color(false)
.context_lines(3)
.force_graphical(true)
.terminal_links(false)
.width(120)
.build();

glob!("inputs/invalid/*.stef", |path| {
let input = fs::read_to_string(path).unwrap();
let schema = Schema::parse(input.as_str()).unwrap();
let result = stef_compiler::validate_schema(&schema).unwrap_err();
let report = Report::new(result).with_source_code(NamedSource::new(
path.file_name().unwrap().to_string_lossy(),
input,
));

assert_snapshot!(
"error",
Wrapper(&handler, &*report).to_string(),
stringify!(stef_compiler::validate_schema(&schema).unwrap_err())
);
});
}
4 changes: 4 additions & 0 deletions crates/stef-compiler/tests/inputs/invalid/enum_gen_dup.stef
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
enum Sample<T, T> {
One @1,
Two { value: T @1 } @2,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
enum Sample<T> {
One @1,
Two { value: string @1 } @2,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enum Sample {
One @1,
Two {
field1: string @1,
field2: string @1,
} @2,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enum Sample {
One @1,
Two {
field: string @1,
field: string @2,
} @2,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
enum Sample {
One @1,
Two(string @1, string @1) @2,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
enum Sample {
One @1,
Two @1,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
enum Sample {
One @1,
One @2,
}
3 changes: 3 additions & 0 deletions crates/stef-compiler/tests/inputs/invalid/struct_gen_dup.stef
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
struct Sample<T, T> {
value: T @1,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
struct Sample<T> {
value: string @1,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
struct Sample {
field1: string @1,
field2: string @1,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
struct Sample {
field: string @1,
field: string @2,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
struct Sample(string @1, string @1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/enum_gen_dup.stef
---
× invalid generic type found
├─▶ duplicate generic type name found
╰─▶ duplicate generic type name `T`
╭─[enum_gen_dup.stef:1:1]
1enum Sample<T, T> {
· ┬ ┬
· │ ╰── used here again
· ╰── first declared here
2 │ One @1,
3 │ Two { value: T @1 } @2,
4 │ }
╰────
help: the names of each generic type must be unique

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/enum_gen_unused.stef
---
× invalid generic type found
├─▶ unused generic type argument found
╰─▶ unused generic type argument `T`
╭─[enum_gen_unused.stef:1:1]
1enum Sample<T> {
· ┬
· ╰── declared here
2 │ One @1,
3 │ Two { value: string @1 } @2,
4 │ }
╰────
help: each declared generic must be used in some way

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/enum_named_dup_id.stef
---
× duplicate ID found
├─▶ duplicate ID in a field
╰─▶ duplicate ID 1 in field `field2`, already used in `field1`
╭─[enum_named_dup_id.stef:1:1]
1enum Sample {
2 │ One @1,
3 │ Two {
4 │ field1: string @1,
· ─┬
· ╰── first declared here
5 │ field2: string @1,
· ─┬
· ╰── used here again
6 │ } @2,
7 │ }
╰────
help: the IDs for each field must be unique

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/enum_named_dup_name.stef
---
× duplicate name found
├─▶ duplicate name in a field
╰─▶ duplicate field name `field`
╭─[enum_named_dup_name.stef:1:1]
1enum Sample {
2 │ One @1,
3 │ Two {
4 │ field: string @1,
· ──┬──
· ╰── first declared here
5 │ field: string @2,
· ──┬──
· ╰── used here again
6 │ } @2,
7 │ }
╰────
help: the names of each field must be unique

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/enum_unnamed_dup_id.stef
---
× duplicate ID found
├─▶ duplicate ID in a field
╰─▶ duplicate ID 1 in position 2, already used at 1
╭─[enum_unnamed_dup_id.stef:1:1]
1enum Sample {
2 │ One @1,
3 │ Two(string @1, string @1) @2,
· ─┬ ─┬
· │ ╰── used here again
· ╰── first declared here
4 │ }
╰────
help: the IDs for each field must be unique

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/enum_variant_dup_id.stef
---
× duplicate ID found
├─▶ duplicate ID in an enum variant
╰─▶ duplicate ID 1 in enum variant `Two`, already used in `One`
╭─[enum_variant_dup_id.stef:1:1]
1 │ enum Sample {
2 │ One @1,
· ─┬
· ╰── first declared here
3 │ Two @1,
· ─┬
· ╰── used here again
4 │ }
╰────
help: the IDs for each variant of an enum must be unique

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/enum_variant_dup_name.stef
---
× duplicate name found
├─▶ duplicate name in an enum variant
╰─▶ duplicate variant name `One` in enum
╭─[enum_variant_dup_name.stef:1:1]
1 │ enum Sample {
2 │ One @1,
· ─┬─
· ╰── first declared here
3 │ One @2,
· ─┬─
· ╰── used here again
4 │ }
╰────
help: the names of each variant must be unique

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/struct_gen_dup.stef
---
× invalid generic type found
├─▶ duplicate generic type name found
╰─▶ duplicate generic type name `T`
╭─[struct_gen_dup.stef:1:1]
1struct Sample<T, T> {
· ┬ ┬
· │ ╰── used here again
· ╰── first declared here
2 │ value: T @1,
3 │ }
╰────
help: the names of each generic type must be unique

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
source: crates/stef-compiler/tests/compiler.rs
expression: "stef_compiler :: validate_schema(& schema).unwrap_err()"
input_file: crates/stef-compiler/tests/inputs/invalid/struct_gen_unused.stef
---
× invalid generic type found
├─▶ unused generic type argument found
╰─▶ unused generic type argument `T`
╭─[struct_gen_unused.stef:1:1]
1struct Sample<T> {
· ┬
· ╰── declared here
2 │ value: string @1,
3 │ }
╰────
help: each declared generic must be used in some way

Loading

0 comments on commit 0efc118

Please sign in to comment.