mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
proptest reveals that dsl breaks at invalid char boundaries
This commit is contained in:
parent
2e18ca96fd
commit
e8e0f5646d
11 changed files with 145 additions and 51 deletions
|
|
@ -13,3 +13,4 @@ default = []
|
|||
|
||||
[dev-dependencies]
|
||||
tek_tui = { path = "../tui" }
|
||||
proptest = "^1.6.0"
|
||||
|
|
|
|||
7
edn/proptest-regressions/iter.txt
Normal file
7
edn/proptest-regressions/iter.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Seeds for failure cases proptest has generated in the past. It is
|
||||
# automatically read and these particular cases re-run before any
|
||||
# novel cases are generated.
|
||||
#
|
||||
# It is recommended to check this file in to source control so that
|
||||
# everyone who runs the test benefits from these saved cases.
|
||||
cc bbb90b16e6106f17dbb5a4f57594f451360a2ea7e3e20c28adeb8babc98d39df # shrinks to source = "(𰀀"
|
||||
7
edn/proptest-regressions/token.txt
Normal file
7
edn/proptest-regressions/token.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Seeds for failure cases proptest has generated in the past. It is
|
||||
# automatically read and these particular cases re-run before any
|
||||
# novel cases are generated.
|
||||
#
|
||||
# It is recommended to check this file in to source control so that
|
||||
# everyone who runs the test benefits from these saved cases.
|
||||
cc 5fb814b74ae035bdecb536817090cfb473f0a874e9acf9aaa136a4794cdb367f # shrinks to source = "", start = 10336420442936153584, length = 8110323630773398032
|
||||
|
|
@ -108,3 +108,20 @@ pub const fn to_digit (c: char) -> Result<usize, ParseError> {
|
|||
_ => return Result::Err(Unexpected(c))
|
||||
})
|
||||
}
|
||||
#[cfg(test)] mod test_token_iter {
|
||||
use proptest::prelude::*;
|
||||
proptest! {
|
||||
#[test] fn proptest_source_iter (
|
||||
source in "\\PC*"
|
||||
) {
|
||||
let mut iter = crate::SourceIter::new(&source);
|
||||
let _ = iter.next();
|
||||
}
|
||||
#[test] fn proptest_token_iter (
|
||||
source in "\\PC*"
|
||||
) {
|
||||
let mut iter = crate::TokenIter::new(&source);
|
||||
let _ = iter.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,45 +35,6 @@ pub(crate) use std::fmt::{Debug, Display, Formatter, Result as FormatResult};
|
|||
}
|
||||
}
|
||||
}
|
||||
#[cfg(test)] #[test] fn test_token () -> Result<(), Box<dyn std::error::Error>> {
|
||||
let source = ":f00";
|
||||
let mut token = Token { source, start: 0, length: 1, value: Sym(":") };
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 2, value: Sym(":f") });
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 3, value: Sym(":f0") });
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 4, value: Sym(":f00") });
|
||||
|
||||
let src = "";
|
||||
assert_eq!(None, SourceIter(src).next());
|
||||
|
||||
let src = " \n \r \t ";
|
||||
assert_eq!(None, SourceIter(src).next());
|
||||
|
||||
let src = "7";
|
||||
assert_eq!(Num(7), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " 100 ";
|
||||
assert_eq!(Num(100), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " 9a ";
|
||||
assert_eq!(Err(Unexpected('a')), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " :123foo ";
|
||||
assert_eq!(Sym(":123foo"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " \r\r\r\n\n\n@bar456\t\t\t\t\t\t";
|
||||
assert_eq!(Sym("@bar456"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = "foo123";
|
||||
assert_eq!(Key("foo123"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = "foo/bar";
|
||||
assert_eq!(Key("foo/bar"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
//#[cfg(test)] #[test] fn test_examples () -> Result<(), ParseError> {
|
||||
//// Let's pretend to render some view.
|
||||
//let source = include_str!("../../tek/src/view_arranger.edn");
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl<'a> Token<'a> {
|
|||
Self { source, start, length, value }
|
||||
}
|
||||
pub const fn end (&self) -> usize {
|
||||
self.start + self.length
|
||||
self.start.saturating_add(self.length)
|
||||
}
|
||||
pub const fn slice (&'a self) -> &'a str {
|
||||
self.slice_source(self.source)
|
||||
|
|
@ -51,7 +51,7 @@ impl<'a> Token<'a> {
|
|||
str_range(source, self.start, self.end())
|
||||
}
|
||||
pub const fn slice_source_exp <'b> (&'a self, source: &'b str) -> &'b str {
|
||||
str_range(source, self.start + 1, self.end())
|
||||
str_range(source, self.start.saturating_add(1), self.end())
|
||||
}
|
||||
pub const fn value (&self) -> Value {
|
||||
self.value
|
||||
|
|
@ -60,7 +60,7 @@ impl<'a> Token<'a> {
|
|||
Self { value: Value::Err(error), ..self }
|
||||
}
|
||||
pub const fn grow (self) -> Self {
|
||||
Self { length: self.length + 1, ..self }
|
||||
Self { length: self.length.saturating_add(1), ..self }
|
||||
}
|
||||
pub const fn grow_num (self, m: usize, c: char) -> Self {
|
||||
match to_digit(c) {
|
||||
|
|
@ -90,7 +90,7 @@ impl<'a> Token<'a> {
|
|||
pub const fn grow_in (self) -> Self {
|
||||
let mut token = self.grow_exp();
|
||||
if let Value::Exp(depth, source) = token.value {
|
||||
token.value = Value::Exp(depth + 1, source)
|
||||
token.value = Value::Exp(depth.saturating_add(1), source)
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
|
|
@ -110,3 +110,60 @@ impl<'a> Token<'a> {
|
|||
token
|
||||
}
|
||||
}
|
||||
#[cfg(test)] mod test_token_prop {
|
||||
use proptest::prelude::*;
|
||||
proptest! {
|
||||
#[test] fn test_token_prop (
|
||||
source in "\\PC*",
|
||||
start in usize::MIN..usize::MAX,
|
||||
length in usize::MIN..usize::MAX,
|
||||
) {
|
||||
let token = crate::Token {
|
||||
source: &source,
|
||||
start,
|
||||
length,
|
||||
value: crate::Value::Nil
|
||||
};
|
||||
let _ = token.slice();
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(test)] #[test] fn test_token () -> Result<(), Box<dyn std::error::Error>> {
|
||||
let source = ":f00";
|
||||
let mut token = Token { source, start: 0, length: 1, value: Sym(":") };
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 2, value: Sym(":f") });
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 3, value: Sym(":f0") });
|
||||
token = token.grow_sym();
|
||||
assert_eq!(token, Token { source, start: 0, length: 4, value: Sym(":f00") });
|
||||
|
||||
let src = "";
|
||||
assert_eq!(None, SourceIter(src).next());
|
||||
|
||||
let src = " \n \r \t ";
|
||||
assert_eq!(None, SourceIter(src).next());
|
||||
|
||||
let src = "7";
|
||||
assert_eq!(Num(7), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " 100 ";
|
||||
assert_eq!(Num(100), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " 9a ";
|
||||
assert_eq!(Err(Unexpected('a')), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " :123foo ";
|
||||
assert_eq!(Sym(":123foo"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = " \r\r\r\n\n\n@bar456\t\t\t\t\t\t";
|
||||
assert_eq!(Sym("@bar456"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = "foo123";
|
||||
assert_eq!(Key("foo123"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
let src = "foo/bar";
|
||||
assert_eq!(Key("foo/bar"), SourceIter(src).next().unwrap().0.value);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue