Nothing
# Tests for expected element functionality in error messages
test_that("'literal' parser includes expected in error marker", {
reset_LNR()
r <- literal("A")("B")
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'A'")
})
test_that("'eof' parser includes expected in error marker", {
reset_LNR()
r <- eof()("A")
expect_true(failed(r))
expect_identical(marker_expected(r), "end of file")
})
test_that("'satisfy' parser includes expected in error marker", {
reset_LNR()
starts_with_a <- function(x) grepl("^a", x)
r <- satisfy(starts_with_a)("B")
expect_true(failed(r))
expect_identical(marker_expected(r), "matching input")
})
test_that("'satisfy' parser can have custom expected message", {
reset_LNR()
is_number <- function(x) grepl("^\\d+$", x)
r <- satisfy(is_number, expected = "numeric value")("abc")
expect_true(failed(r))
expect_identical(marker_expected(r), "numeric value")
})
test_that("'%or%' combinator merges expected values when both fail at same position", {
reset_LNR()
r <- (literal("A") %or% literal("B"))("C")
expect_true(failed(r))
expected <- marker_expected(r)
expect_true("literal 'A'" %in% expected)
expect_true("literal 'B'" %in% expected)
expect_equal(length(expected), 2)
})
test_that("'%or%' combinator returns expected from furthest failure", {
reset_LNR()
p1 <- literal("A") %then% literal("B")
p2 <- literal("A") %then% literal("C")
r <- (p1 %or% p2)(c("A", "D"))
expect_true(failed(r))
expected <- marker_expected(r)
# Both parsers fail on line 2, so both expectations should be included
expect_true("literal 'B'" %in% expected)
expect_true("literal 'C'" %in% expected)
})
test_that("'%or%' combinator with three alternatives merges all expected at same position", {
reset_LNR()
r <- (literal("A") %or% literal("B") %or% literal("C"))("D")
expect_true(failed(r))
expected <- marker_expected(r)
expect_true("literal 'A'" %in% expected)
expect_true("literal 'B'" %in% expected)
expect_true("literal 'C'" %in% expected)
})
test_that("'%then%' combinator propagates expected from first parser", {
reset_LNR()
r <- (literal("A") %then% literal("B"))("C")
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'A'")
})
test_that("'%then%' combinator propagates expected from second parser", {
reset_LNR()
r <- (literal("A") %then% literal("B"))(c("A", "C"))
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'B'")
})
test_that("'%xthen%' combinator propagates expected information", {
reset_LNR()
r <- (literal("A") %xthen% literal("B"))(c("A", "C"))
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'B'")
})
test_that("'%thenx%' combinator propagates expected information", {
reset_LNR()
r <- (literal("A") %thenx% literal("B"))(c("A", "C"))
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'B'")
})
test_that("'named' parser adds semantic name to error marker", {
reset_LNR()
nucleotide <- named(
satisfy(function(x) grepl("^[GATC]+$", x)),
"nucleotide sequence"
)
r <- nucleotide("XYZ")
expect_true(failed(r))
expect_identical(marker_expected(r), "nucleotide sequence")
})
test_that("'named' parser replaces underlying expected value", {
reset_LNR()
# literal would normally say "literal 'A'", but named overrides it
named_parser <- named(literal("A"), "start token")
r <- named_parser("B")
expect_true(failed(r))
expect_identical(marker_expected(r), "start token")
})
test_that("'named' parsers combine nicely with %or%", {
reset_LNR()
p1 <- named(literal("A"), "token A")
p2 <- named(literal("B"), "token B")
r <- (p1 %or% p2)("C")
expect_true(failed(r))
expected <- marker_expected(r)
expect_true("token A" %in% expected)
expect_true("token B" %in% expected)
})
test_that("'reporter' includes expected in error message for single expectation", {
reset_LNR()
expect_error(
reporter(literal("A"))("B"),
regexp = "Expected: literal 'A'"
)
})
test_that("'reporter' includes expected in error message for multiple expectations", {
reset_LNR()
expect_error(
reporter(literal("A") %or% literal("B"))("C"),
regexp = "Expected one of:.*literal 'A'.*literal 'B'"
)
})
test_that("'reporter' error message shows correct line number and expected", {
reset_LNR()
p <- literal("A") %then% literal("B") %then% literal("C")
err <- tryCatch(
reporter(p)(c("A", "B", "D")),
error = function(e) e
)
expect_match(err$message, "line 3")
expect_match(err$message, "Expected: literal 'C'")
})
test_that("'reporter' with %or% shows combined expectations at failure point", {
reset_LNR()
nucleotide <- named(
satisfy(function(x) grepl("^[GATC]+$", x)),
"nucleotide sequence"
)
protein <- named(
satisfy(function(x) grepl("^[ARNDCQEGHILKMFPSTWYV]+$", x)),
"protein sequence"
)
p <- nucleotide %or% protein
err <- tryCatch(
reporter(p %then% eof())(c("12345")),
error = function(e) e
)
expect_match(err$message, "Expected one of:")
expect_match(err$message, "nucleotide sequence")
expect_match(err$message, "protein sequence")
})
test_that("'reporter' error object contains expected attribute", {
reset_LNR()
err <- tryCatch(
reporter(literal("A") %or% literal("B"))("C"),
error = function(e) e
)
expect_true(!is.null(err$expected))
expect_true("literal 'A'" %in% err$expected)
expect_true("literal 'B'" %in% err$expected)
})
test_that("complex parser with nested %or% produces meaningful expectations", {
reset_LNR()
# Simulating a fasta header or sequence line
header <- named(
satisfy(function(x) grepl("^>", x)),
"header line (starting with '>')"
)
nucl_seq <- named(
satisfy(function(x) grepl("^[GATC]+$", x)),
"nucleotide sequence"
)
prot_seq <- named(
satisfy(function(x) grepl("^[ARNDCQEGHILKMFPSTWYV]+$", x)),
"protein sequence"
)
fasta_line <- header %or% nucl_seq %or% prot_seq
err <- tryCatch(
reporter(fasta_line %then% eof())("12345"),
error = function(e) e
)
expect_match(err$message, "Expected one of:")
expect_match(err$message, "header line")
expect_match(err$message, "nucleotide sequence")
expect_match(err$message, "protein sequence")
})
test_that("'one_or_more' propagates expected information", {
reset_LNR()
# one_or_more requires at least one match
r <- one_or_more(literal("A"))("B")
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'A'")
})
test_that("'match_n' propagates expected information", {
reset_LNR()
r <- match_n(2, literal("A"))(c("A", "B"))
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'A'")
})
test_that("'match_s' with custom stringparser maintains error reporting", {
reset_LNR()
get_numbers <- function(x) {
m <- gregexpr("[[:digit:]]+", x)
matches <- regmatches(x, m)[[1]]
if (length(matches) == 0) {
return(list())
} else {
return(as.numeric(matches))
}
}
r <- match_s(get_numbers)("no numbers here")
expect_true(failed(r))
# match_s doesn't add expected by default, but the error still occurs
})
test_that("empty input produces expected information", {
reset_LNR()
r <- literal("A")(character(0))
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'A'")
})
test_that("'%using%' does not alter expected information", {
reset_LNR()
r <- (literal("A") %using% toupper)("B")
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'A'")
})
test_that("'%ret%' does not alter expected information", {
reset_LNR()
r <- (literal("A") %ret% "custom value")("B")
expect_true(failed(r))
expect_identical(marker_expected(r), "literal 'A'")
})
test_that("'exactly' propagates expected information", {
reset_LNR()
r <- exactly(2, literal("A"))(c("A", "A", "A"))
expect_true(failed(r))
# exactly fails when there are too many matches
})
test_that("'zero_or_one' propagates expected information on failure", {
reset_LNR()
r <- zero_or_one(literal("A"))(c("A", "A"))
expect_true(failed(r))
# Fails because there are two A's, not zero or one
})
test_that("EmptyLine and Spacer return expected messages on failure", {
reset_LNR()
r <- EmptyLine()("text content")
expect_true(failed(r))
expect_identical(marker_expected(r), "Emptyline")
reset_LNR()
r <- Spacer()("text content")
expect_true(failed(r))
expect_identical(marker_expected(r), "Spacer")
})
test_that("complex realistic parser produces helpful error messages", {
reset_LNR()
# Build a simple CSV-like parser
number <- named(
satisfy(function(x) grepl("^\\d+$", x)),
"number"
)
text <- named(
satisfy(function(x) grepl("^[a-zA-Z]+$", x)),
"text"
)
csv_value <- number %or% text
# Test with invalid input
err <- tryCatch(
reporter(csv_value %then% eof())("###"),
error = function(e) e
)
expect_match(err$message, "line 1")
expect_match(err$message, "Expected one of:")
expect_match(err$message, "number")
expect_match(err$message, "text")
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.