tamer: span::dummy: New module to hold DUMMY_SPAN and derivatives

Various DUMMY_SPAN-derived spans are used by many test cases, so this
finally extracts them---something I've been meaning to do for some time.

This also places DUMMY_SPAN behind a `cfg(test)` directive to ensure that it
is _only_ used in tests; UNKNOWN_SPAN should be used when a span is actually
unknown, which may also be the case during development.

DEV-7145
main
Mike Gerwitz 2022-07-29 10:27:46 -04:00
parent 0edb21429d
commit 8f3301431c
16 changed files with 111 additions and 119 deletions

View File

@ -21,7 +21,7 @@ use super::*;
use crate::{
convert::ExpectInto,
diagnose::resolve::Column,
span::{DUMMY_CONTEXT, DUMMY_SPAN},
span::dummy::{DUMMY_CONTEXT, DUMMY_SPAN},
};
use std::{io, num::NonZeroU32};

View File

@ -399,17 +399,12 @@ mod test {
num::{Dim, Dtype},
obj::xmlo::{SymAttrs, SymType},
parse::Parsed,
span::{DUMMY_SPAN, UNKNOWN_SPAN},
span::{dummy::*, UNKNOWN_SPAN},
sym::GlobalSymbolIntern,
};
type Sut = XmloToAir;
const S1: Span = DUMMY_SPAN;
const S2: Span = S1.offset_add(1).unwrap();
const S3: Span = S2.offset_add(1).unwrap();
const S4: Span = S3.offset_add(1).unwrap();
#[test]
fn data_from_package_event() {
let name = "name".into();

View File

@ -25,7 +25,7 @@ use crate::{
num::Dtype,
obj::xmlo::SymType,
parse::{ParseError, ParseState, Parsed},
span::{Span, DUMMY_SPAN},
span::{dummy::*, Span},
sym::GlobalSymbolIntern,
xir::{
attr::Attr,
@ -37,12 +37,6 @@ use crate::{
},
};
const S1: Span = DUMMY_SPAN;
const S2: Span = S1.offset_add(1).unwrap();
const S3: Span = S2.offset_add(1).unwrap();
const S4: Span = S3.offset_add(1).unwrap();
const S5: Span = S4.offset_add(1).unwrap();
type Sut = XmloReader;
#[test]

View File

@ -36,7 +36,7 @@ pub use state::{
Transitionable,
};
use crate::span::{Span, DUMMY_SPAN};
use crate::span::{Span, UNKNOWN_SPAN};
use std::{
error::Error,
fmt::{Debug, Display},
@ -73,7 +73,7 @@ pub struct UnknownToken;
impl Token for UnknownToken {
fn span(&self) -> Span {
DUMMY_SPAN
UNKNOWN_SPAN
}
fn ir_name() -> &'static str {
@ -121,7 +121,7 @@ pub mod test {
use super::*;
use crate::{
diagnose::{AnnotatedSpan, Diagnostic},
span::{DUMMY_SPAN as DS, UNKNOWN_SPAN},
span::{dummy::DUMMY_SPAN as DS, UNKNOWN_SPAN},
sym::GlobalSymbolIntern,
};
use std::{assert_matches::assert_matches, iter::once};

View File

@ -456,7 +456,7 @@ pub mod test {
use crate::{
diagnose::Diagnostic,
parse::{Object, Token},
span::DUMMY_SPAN,
span::dummy::DUMMY_SPAN,
};
use std::{assert_matches::assert_matches, error::Error, fmt::Display};

View File

@ -490,16 +490,6 @@ impl Display for Span {
/// known.
pub const UNKNOWN_SPAN: Span = Span::st_ctx(st16::CTX_UNKNOWN);
/// A dummy span that can be used in contexts where a span is expected but
/// is not important.
///
/// This is intended primarily for tests;
/// you should always use an appropriate span to permit sensible error
/// messages and source analysis.
///
/// Additional dummy spans can be derived from this one.
pub const DUMMY_SPAN: Span = Span::st_ctx(st16::CTX_DUMMY);
/// Context for byte offsets (e.g. a source file).
///
/// A context is lifetime-free and [`Copy`]-able,
@ -558,16 +548,6 @@ impl Context {
/// yet known.
pub const UNKNOWN_CONTEXT: Context = Context(st16::raw::CTX_UNKNOWN);
/// A dummy context that can be used where a span is expected but is not
/// important.
///
/// This is intended primarily for tests;
/// you should always use an appropriate span to permit sensible error
/// messages and source analysis.
///
/// See also [`UNKNOWN_CONTEXT`].
pub const DUMMY_CONTEXT: Context = Context(st16::raw::CTX_DUMMY);
impl<P: Into<PathSymbolId>> From<P> for Context {
fn from(sym: P) -> Self {
Self(sym.into())
@ -610,6 +590,52 @@ impl<T: Copy + PartialOrd> From<(T, T)> for ClosedByteInterval<T> {
assert_eq_size!(ClosedByteInterval, u64);
/// Dummy spans for testing.
#[cfg(test)]
pub mod dummy {
use super::{st16, Context, Span};
/// A dummy span that can be used in contexts where a span is expected
/// but is not important.
///
/// This is intended primarily for tests;
/// you should always use an appropriate span to permit sensible error
/// messages and source analysis.
/// For spans that are actually unknown,
/// use [`super::UNKNOWN_SPAN`].
///
/// Additional dummy spans can be derived from this one.
pub const DUMMY_SPAN: Span = Span::st_ctx(st16::CTX_DUMMY);
/// A dummy context that can be used where a span is expected but is not
/// important.
///
/// This is intended primarily for tests;
/// you should always use an appropriate span to permit sensible error
/// messages and source analysis.
/// For contexts that are actually unknown,
/// use [`super::UNKNOWN_CONTEXT`].
///
/// See also [`UNKNOWN_CONTEXT`].
pub const DUMMY_CONTEXT: Context = Context(st16::raw::CTX_DUMMY);
// This name is for brevity;
// we don't want to expose it because we don't want anyone to assume
// that a different name means that it's somehow different from
// `DUMMY_SPAN`.
const S0: Span = DUMMY_SPAN;
pub const S1: Span = S0.offset_add(1).unwrap();
pub const S2: Span = S0.offset_add(2).unwrap();
pub const S3: Span = S0.offset_add(3).unwrap();
pub const S4: Span = S0.offset_add(4).unwrap();
pub const S5: Span = S0.offset_add(5).unwrap();
pub const S6: Span = S0.offset_add(6).unwrap();
pub const S7: Span = S0.offset_add(7).unwrap();
pub const S8: Span = S0.offset_add(8).unwrap();
pub const S9: Span = S0.offset_add(9).unwrap();
}
#[cfg(test)]
mod test {
use super::*;

View File

@ -786,7 +786,7 @@ pub mod test {
mod ele_span {
use super::*;
use crate::span::DUMMY_CONTEXT as DC;
use crate::span::dummy::DUMMY_CONTEXT as DC;
#[test]
fn open_without_attrs() {

View File

@ -262,7 +262,7 @@ impl<const N: usize> From<[Attr; N]> for AttrList {
#[cfg(test)]
mod test {
use crate::span::DUMMY_CONTEXT as DC;
use crate::span::dummy::DUMMY_CONTEXT as DC;
use super::*;

View File

@ -150,16 +150,14 @@ mod test {
use crate::{
convert::ExpectInto,
parse::{ParseError, Parsed},
span::dummy::*,
sym::GlobalSymbolIntern,
xir::test::{close_empty, open},
};
const S: Span = crate::span::DUMMY_SPAN;
const S2: Span = S.offset_add(1).unwrap();
#[test]
fn dead_if_first_token_is_non_attr() {
let tok = open("foo", S);
let tok = open("foo", S1);
let mut sut = AttrParseState::parse(vec![tok.clone()].into_iter());
@ -176,7 +174,7 @@ mod test {
let attr = "attr".unwrap_into();
let val = "val".intern();
let toks = [XirToken::AttrName(attr, S), XirToken::AttrValue(val, S2)]
let toks = [XirToken::AttrName(attr, S1), XirToken::AttrValue(val, S2)]
.into_iter();
let sut = AttrParseState::parse(toks);
@ -184,7 +182,7 @@ mod test {
assert_eq!(
Ok(vec![
Parsed::Incomplete,
Parsed::Object(Attr::new(attr, val, (S, S2))),
Parsed::Object(Attr::new(attr, val, (S1, S2))),
]),
sut.collect()
);
@ -196,7 +194,7 @@ mod test {
let recover = "value".intern();
let toks = vec![
XirToken::AttrName(attr, S),
XirToken::AttrName(attr, S1),
close_empty(S2),
XirToken::AttrValue(recover, S2),
];
@ -211,7 +209,7 @@ mod test {
assert_eq!(
sut.next(),
Some(Err(ParseError::StateError(
AttrParseError::AttrValueExpected(attr, S, close_empty(S2))
AttrParseError::AttrValueExpected(attr, S1, close_empty(S2))
)))
);
@ -227,7 +225,7 @@ mod test {
// let's actually attempt a recovery.
assert_eq!(
sut.next(),
Some(Ok(Parsed::Object(Attr::new(attr, recover, (S, S2))))),
Some(Ok(Parsed::Object(Attr::new(attr, recover, (S1, S2))))),
);
// Finally, we should now be in an accepting state.

View File

@ -27,7 +27,7 @@ use std::assert_matches::assert_matches;
use super::*;
use crate::convert::ExpectInto;
use crate::parse::{ParseError, Parsed};
use crate::span::DUMMY_SPAN;
use crate::span::dummy::*;
use crate::sym::GlobalSymbolIntern;
use crate::xir::test::{
close as xir_close, close_empty as xir_close_empty, open as xir_open,
@ -80,22 +80,17 @@ where
XirfToken::Close(qname.map(ExpectInto::unwrap_into), span.into(), depth)
}
const S: Span = DUMMY_SPAN;
const S2: Span = S.offset_add(1).unwrap();
const S3: Span = S2.offset_add(1).unwrap();
const S4: Span = S3.offset_add(1).unwrap();
#[test]
fn empty_element_self_close() {
let name = ("ns", "elem");
let toks = [xir_open(name, S), xir_close_empty(S2)].into_iter();
let toks = [xir_open(name, S1), xir_close_empty(S2)].into_iter();
let sut = parse::<1, Text>(toks);
assert_eq!(
Ok(vec![
Parsed::Object(open(name, S, Depth(0))),
Parsed::Object(open(name, S1, Depth(0))),
Parsed::Object(close_empty(S2, Depth(0))),
]),
sut.collect(),
@ -108,13 +103,13 @@ fn empty_element_self_close() {
fn empty_element_balanced_close() {
let name = ("ns", "openclose");
let toks = [xir_open(name, S), xir_close(Some(name), S2)].into_iter();
let toks = [xir_open(name, S1), xir_close(Some(name), S2)].into_iter();
let sut = parse::<1, Text>(toks);
assert_eq!(
Ok(vec![
Parsed::Object(open(name, S, Depth(0))),
Parsed::Object(open(name, S1, Depth(0))),
Parsed::Object(close(Some(name), S2, Depth(0))),
]),
sut.collect(),
@ -130,7 +125,7 @@ fn extra_closing_tag() {
let name = ("ns", "openclose");
let toks = [
// We need an opening tag to actually begin document parsing.
xir_open(name, S),
xir_open(name, S1),
xir_close(Some(name), S2),
xir_close(Some(name), S3),
]
@ -155,7 +150,7 @@ fn extra_self_closing_tag() {
let name = ("ns", "openclose");
let toks = [
// We need an opening tag to actually begin document parsing.
xir_open(name, S),
xir_open(name, S1),
xir_close_empty(S2),
xir_close_empty(S3),
]
@ -178,18 +173,18 @@ fn empty_element_unbalanced_close() {
let close_name = "unbalanced_name".unwrap_into();
let toks =
[xir_open(open_name, S), xir_close(Some(close_name), S2)].into_iter();
[xir_open(open_name, S1), xir_close(Some(close_name), S2)].into_iter();
let mut sut = parse::<1, Text>(toks);
assert_eq!(
sut.next(),
Some(Ok(Parsed::Object(open(open_name, S, Depth(0)))))
Some(Ok(Parsed::Object(open(open_name, S1, Depth(0)))))
);
assert_eq!(
sut.next(),
Some(Err(ParseError::StateError(XirToXirfError::UnbalancedTag {
open: (open_name, S),
open: (open_name, S1),
close: (close_name, S2),
})))
);
@ -202,7 +197,7 @@ fn single_empty_child() {
let child = "child";
let toks = [
xir_open(name, S),
xir_open(name, S1),
xir_open(child, S2),
xir_close_empty(S3),
xir_close(Some(name), S4),
@ -213,7 +208,7 @@ fn single_empty_child() {
assert_eq!(
Ok(vec![
Parsed::Object(open(name, S, Depth(0))),
Parsed::Object(open(name, S1, Depth(0))),
Parsed::Object(open(child, S2, Depth(1))),
Parsed::Object(close_empty(S3, Depth(1))),
Parsed::Object(close(Some(name), S4, Depth(0))),
@ -228,7 +223,7 @@ fn depth_exceeded() {
let exceed = "exceed".unwrap_into();
let toks = [
xir_open(name, S),
xir_open(name, S1),
// This one exceeds the max depth, ...
xir_open(exceed, S2),
]
@ -238,7 +233,7 @@ fn depth_exceeded() {
let mut sut = parse::<1, Text>(toks);
assert_eq!(
Some(Ok(Parsed::Object(open(name, S, Depth(0))))),
Some(Ok(Parsed::Object(open(name, S1, Depth(0))))),
sut.next()
);
assert_eq!(
@ -261,7 +256,7 @@ fn empty_element_with_attrs() {
let val2 = "val2".intern();
let toks = [
xir_open(name, S),
xir_open(name, S1),
XirToken::AttrName(attr1, S2),
XirToken::AttrValue(val1, S3),
XirToken::AttrName(attr2, S3),
@ -274,7 +269,7 @@ fn empty_element_with_attrs() {
assert_eq!(
Ok(vec![
Parsed::Object(open(name, S, Depth(0))),
Parsed::Object(open(name, S1, Depth(0))),
Parsed::Incomplete,
Parsed::Object(XirfToken::Attr(Attr::new(attr1, val1, (S2, S3)))),
Parsed::Incomplete,
@ -293,10 +288,10 @@ fn child_element_after_attrs() {
let val = "val".intern();
let toks = [
xir_open(name, S),
XirToken::AttrName(attr, S),
xir_open(name, S1),
XirToken::AttrName(attr, S1),
XirToken::AttrValue(val, S2),
xir_open(child, S),
xir_open(child, S1),
xir_close_empty(S2),
xir_close(Some(name), S3),
]
@ -306,10 +301,10 @@ fn child_element_after_attrs() {
assert_eq!(
Ok(vec![
Parsed::Object(open(name, S, Depth(0))),
Parsed::Object(open(name, S1, Depth(0))),
Parsed::Incomplete,
Parsed::Object(XirfToken::Attr(Attr::new(attr, val, (S, S2)))),
Parsed::Object(open(child, S, Depth(1))),
Parsed::Object(XirfToken::Attr(Attr::new(attr, val, (S1, S2)))),
Parsed::Object(open(child, S1, Depth(1))),
Parsed::Object(close_empty(S2, Depth(1))),
Parsed::Object(close(Some(name), S3, Depth(0))),
]),
@ -324,7 +319,7 @@ fn element_with_empty_sibling_children() {
let childb = "childb";
let toks = [
xir_open(parent, S),
xir_open(parent, S1),
xir_open(childa, S2),
xir_close_empty(S3),
xir_open(childb, S2),
@ -337,7 +332,7 @@ fn element_with_empty_sibling_children() {
assert_eq!(
Ok(vec![
Parsed::Object(open(parent, S, Depth(0))),
Parsed::Object(open(parent, S1, Depth(0))),
Parsed::Object(open(childa, S2, Depth(1))),
Parsed::Object(close_empty(S3, Depth(1))),
Parsed::Object(open(childb, S2, Depth(1))),
@ -357,9 +352,9 @@ fn element_with_child_with_attributes() {
let value = "attr value".intern();
let toks = [
xir_open(parent, S),
xir_open(child, S),
XirToken::AttrName(attr, S),
xir_open(parent, S1),
xir_open(child, S1),
XirToken::AttrName(attr, S1),
XirToken::AttrValue(value, S2),
xir_close_empty(S3),
xir_close(Some(parent), S3),
@ -370,10 +365,10 @@ fn element_with_child_with_attributes() {
assert_eq!(
Ok(vec![
Parsed::Object(open(parent, S, Depth(0))),
Parsed::Object(open(child, S, Depth(1))),
Parsed::Object(open(parent, S1, Depth(0))),
Parsed::Object(open(child, S1, Depth(1))),
Parsed::Incomplete,
Parsed::Object(XirfToken::Attr(Attr::new(attr, value, (S, S2)))),
Parsed::Object(XirfToken::Attr(Attr::new(attr, value, (S1, S2)))),
Parsed::Object(close_empty(S3, Depth(1))),
Parsed::Object(close(Some(parent), S3, Depth(0))),
]),
@ -387,7 +382,7 @@ fn element_with_text() {
let text = "inner text".into();
let toks = [
xir_open(parent, S),
xir_open(parent, S1),
XirToken::Text(text, S2),
xir_close(Some(parent), S3),
]
@ -397,7 +392,7 @@ fn element_with_text() {
assert_eq!(
Ok(vec![
Parsed::Object(open(parent, S, Depth(0))),
Parsed::Object(open(parent, S1, Depth(0))),
Parsed::Object(XirfToken::Text(Text(text, S2))),
Parsed::Object(close(Some(parent), S3, Depth(0))),
]),
@ -408,12 +403,12 @@ fn element_with_text() {
#[test]
fn not_accepting_state_if_element_open() {
let name = "unclosed";
let toks = [xir_open(name, S)].into_iter();
let toks = [xir_open(name, S1)].into_iter();
let mut sut = parse::<1, Text>(toks);
assert_eq!(
Some(Ok(Parsed::Object(open(name, S, Depth(0))))),
Some(Ok(Parsed::Object(open(name, S1, Depth(0))))),
sut.next()
);
@ -429,7 +424,7 @@ fn comment_before_or_after_root_ok() {
let cend = "end comment".intern();
let toks = [
XirToken::Comment(cstart, S),
XirToken::Comment(cstart, S1),
xir_open(name, S2),
xir_close_empty(S3),
XirToken::Comment(cend, S4),
@ -440,7 +435,7 @@ fn comment_before_or_after_root_ok() {
assert_eq!(
Ok(vec![
Parsed::Object(XirfToken::Comment(cstart, S)),
Parsed::Object(XirfToken::Comment(cstart, S1)),
Parsed::Object(open(name, S2, Depth(0))),
Parsed::Object(close_empty(S3, Depth(0))),
Parsed::Object(XirfToken::Comment(cend, S4)),
@ -457,7 +452,7 @@ fn whitespace_before_or_after_root_ok() {
let ws = " ".unwrap_into();
let toks = [
XirToken::Text(ws, S),
XirToken::Text(ws, S1),
xir_open(name, S2),
xir_close_empty(S3),
XirToken::Text(ws, S4),
@ -490,7 +485,7 @@ fn content_after_root_close_error() {
let name = "root".unwrap_into();
let toks = [
xir_open(name, S),
xir_open(name, S1),
xir_close_empty(S2),
// Document ends here
xir_open(name, S3),
@ -512,13 +507,13 @@ fn content_after_root_close_error() {
fn content_before_root_open_error() {
let text = "foo".intern();
let toks = [XirToken::Text(text, S)].into_iter();
let toks = [XirToken::Text(text, S1)].into_iter();
let sut = parse::<1, Text>(toks);
assert_eq!(
Result::<Vec<Parsed<_>>, _>::Err(ParseError::StateError(
XirToXirfError::RootOpenExpected(XirToken::Text(text, S))
XirToXirfError::RootOpenExpected(XirToken::Text(text, S1))
)),
sut.collect()
);
@ -540,7 +535,7 @@ fn whitespace_refinement() {
.into_iter()
.for_each(|(given, expected)| {
let mut sut = parse::<1, RefinedText>(
vec![xir_open("root", S), XirToken::Text(given, S)].into_iter(),
vec![xir_open("root", S1), XirToken::Text(given, S1)].into_iter(),
);
let _ = sut.next(); // discard root
@ -550,7 +545,7 @@ fn whitespace_refinement() {
Whitespace(Text(ws, span)),
))) => {
assert_eq!(ws, given);
assert_eq!(span, S);
assert_eq!(span, S1);
assert!(expected == true)
}
@ -559,7 +554,7 @@ fn whitespace_refinement() {
span,
)))) => {
assert_eq!(text, given);
assert_eq!(span, S);
assert_eq!(span, S1);
assert!(expected == false)
}

View File

@ -86,7 +86,7 @@ impl<I: TokenStream> Iterator for ElemWrapIter<I> {
#[cfg(test)]
mod test {
use super::*;
use crate::{convert::ExpectInto, span::DUMMY_SPAN, xir::Token};
use crate::{convert::ExpectInto, span::dummy::DUMMY_SPAN, xir::Token};
#[test]
fn elem_wrap_iter() {

View File

@ -20,7 +20,7 @@
use super::*;
use crate::{
parse::{ParseError, ParseState, Parsed, Parser, TokenStream},
span::{Span, DUMMY_SPAN},
span::dummy::*,
sym::SymbolId,
xir::{
attr::{Attr, AttrSpan},
@ -30,9 +30,6 @@ use crate::{
};
use std::assert_matches::assert_matches;
const S1: Span = DUMMY_SPAN.offset_add(1).unwrap();
const S2: Span = S1.offset_add(1).unwrap();
const S3: Span = S2.offset_add(1).unwrap();
const SE: OpenSpan = OpenSpan(S1.offset_add(100).unwrap(), 0);
// Random choice of QName for tests.

View File

@ -38,7 +38,7 @@ use crate::{
convert::ExpectInto,
diagnose::Diagnostic,
parse::{Object, ParseError, ParseState, Parsed},
span::{Span, DUMMY_SPAN},
span::{dummy::*, Span},
sym::SymbolId,
xir::{
attr::{Attr, AttrSpan},
@ -48,15 +48,6 @@ use crate::{
},
};
const S1: Span = DUMMY_SPAN;
const S2: Span = S1.offset_add(1).unwrap();
const S3: Span = S2.offset_add(1).unwrap();
const S4: Span = S3.offset_add(1).unwrap();
const S5: Span = S4.offset_add(1).unwrap();
const S6: Span = S5.offset_add(1).unwrap();
const S7: Span = S6.offset_add(1).unwrap();
const S8: Span = S7.offset_add(1).unwrap();
// Some number (value does not matter).
const N: EleNameLen = 10;

View File

@ -27,7 +27,7 @@ use crate::{
ParseError::StateError as PE,
Parsed::{self, Object as O},
},
span::DUMMY_CONTEXT as DC,
span::dummy::DUMMY_CONTEXT as DC,
xir::{Error, Token},
};
use std::borrow::Cow;

View File

@ -22,14 +22,10 @@ use std::assert_matches::assert_matches;
use super::*;
use crate::convert::ExpectInto;
use crate::parse::ParseError;
use crate::span::DUMMY_SPAN;
use crate::span::dummy::*;
use crate::sym::GlobalSymbolIntern;
use crate::xir::test::{close, close_empty, open};
const S1: Span = DUMMY_SPAN;
const S2: Span = S1.offset_add(1).unwrap();
const S3: Span = S2.offset_add(1).unwrap();
mod tree {
use super::*;

View File

@ -316,7 +316,7 @@ mod test {
use super::*;
use crate::{
convert::ExpectInto,
span::{Span, DUMMY_SPAN},
span::{dummy::DUMMY_SPAN, Span},
sym::GlobalSymbolIntern,
xir::{
error::SpanlessError,