Skip to content

Commit d55483e

Browse files
authored
Updates ion-tests, conformance test runner bugfixes (#880)
* Update ion-tests to main * Rename `bytes` fragment to `binary` * Allow `(denotes (Null))` w/o type, defaulting to null.null
1 parent df7ba6c commit d55483e

File tree

13 files changed

+510
-295
lines changed

13 files changed

+510
-295
lines changed

ion-tests

Submodule ion-tests updated 41 files

src/element/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,21 @@ impl Element {
522522
}
523523
}
524524

525+
pub fn as_usize(&self) -> Option<usize> {
526+
match &self.value {
527+
Value::Int(i) => i.as_usize(),
528+
_ => None,
529+
}
530+
}
531+
532+
pub fn expect_usize(&self) -> IonResult<usize> {
533+
self.expected(self.as_usize())
534+
}
535+
536+
pub fn try_into_usize(self) -> ConversionOperationResult<Element, usize> {
537+
self.as_usize().ok_or_else(|| self.into())
538+
}
539+
525540
pub fn as_float(&self) -> Option<f64> {
526541
match &self.value {
527542
Value::Float(f) => Some(*f),

src/element/sequence.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ impl AsRef<[Element]> for Sequence {
138138
}
139139
}
140140

141+
impl From<Sequence> for Vec<Element> {
142+
fn from(value: Sequence) -> Self {
143+
value.elements
144+
}
145+
}
146+
141147
// This is more efficient than Sequence::new(), which will iterate over and convert each value to
142148
// an Element for better ergonomics.
143149
impl From<Vec<Element>> for Sequence {

src/lazy/encoder/annotation_seq.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use smallvec::SmallVec;
22

33
use crate::raw_symbol_ref::SystemSymbol_1_1;
4-
use crate::{RawSymbolRef, SymbolId};
4+
use crate::{Annotations, RawSymbolRef, SymbolId};
55

66
/// A sequence of annotations.
77
///
@@ -129,3 +129,13 @@ where
129129
annotations
130130
}
131131
}
132+
133+
impl<'a> AnnotationSeq<'a> for &'a Annotations {
134+
fn into_annotations_vec(self) -> AnnotationsVec<'a> {
135+
let mut annotations = AnnotationsVec::new();
136+
for token in self {
137+
annotations.push(token.into());
138+
}
139+
annotations
140+
}
141+
}

src/lazy/encoder/binary/v1_0/container_writers.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,13 @@ impl<'value, 'top> BinaryContainerWriter_1_0<'value, 'top> {
6666
};
6767
symbol_ids.push(symbol_address);
6868
}
69-
self.annotations = Some(symbol_ids);
69+
// If this was called with an empty iterator, act as though it was never called at all.
70+
// This prevents writing out an empty annotations sequence in binary, which is illegal.
71+
self.annotations = if !symbol_ids.is_empty() {
72+
Some(symbol_ids)
73+
} else {
74+
None
75+
};
7076
Ok(self)
7177
}
7278

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ macro_rules! v1_x_tooling_apis {
294294
LazyExpandedField,
295295
LazyExpandedFieldName
296296
},
297-
lazy::expanded::e_expression::{EExpression, EExpressionArgsIterator},
297+
lazy::expanded::e_expression::{EExpression, EExpressionArgsIterator, EExpArgGroup, EExpArgGroupIterator},
298298
lazy::expanded::sequence::{Environment, ExpandedListSource, ExpandedSExpSource, LazyExpandedList, LazyExpandedSExp},
299299
lazy::expanded::{ExpandedStreamItem, LazyExpandedValue, ExpandingReader, ExpandedValueSource, ExpandedAnnotationsSource, ExpandedValueRef},
300300
lazy::system_stream_item::SystemStreamItem,

src/result/conversion.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ macro_rules! impl_type_and_ref_expectation {
100100

101101
impl_type_and_ref_expectation!(Int, IonType::Int);
102102
impl_type_expectation!(i64, "i64 value");
103+
impl_type_expectation!(usize, "usize value");
103104
impl_type_expectation!(f64, IonType::Float);
104105
impl_type_and_ref_expectation!(Decimal, IonType::Decimal);
105106
impl_type_and_ref_expectation!(Timestamp, IonType::Timestamp);

tests/conformance_dsl/clause.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub(crate) enum ClauseType {
2626
Text,
2727
/// Provide a sequence of bytes that is interpreted as binary ion, that will be inserted into
2828
/// the document.
29-
Bytes,
29+
Binary,
3030
/// Provide a major and minor version that will be emitted into the document as an IVM.
3131
Ivm,
3232
/// Specify a ion data to be inserted into the document, using inline ion syntax.
@@ -72,7 +72,7 @@ impl FromStr for ClauseType {
7272
"produces" => Ok(Produces),
7373
"denotes" => Ok(Denotes),
7474
"text" => Ok(Text),
75-
"bytes" => Ok(Bytes),
75+
"binary" => Ok(Binary),
7676
"and" => Ok(And),
7777
"not" => Ok(Not),
7878
"then" => Ok(Then),
@@ -91,7 +91,7 @@ impl ClauseType {
9191
/// Utility function to test if the Clause is a fragment node.
9292
pub fn is_fragment(&self) -> bool {
9393
use ClauseType::*;
94-
matches!(self, Text | Bytes | Ivm | TopLevel | Encoding | MacTab)
94+
matches!(self, Text | Binary | Ivm | TopLevel | Encoding | MacTab)
9595
}
9696

9797
/// Utility function to test if the Clause is an expectation node.

tests/conformance_dsl/continuation.rs

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
//! of the test document when read) and Extensions (clauses that allow the chaining, or
33
//! permutations for document creation).
44
5-
use super::*;
65
use super::context::Context;
76
use super::model::{compare_values, ModelValue};
7+
use super::*;
88

9-
use ion_rs::{Element, Sequence};
9+
use ion_rs::{Element, ElementReader, Sequence};
1010

1111
#[derive(Clone, Debug)]
1212
pub(crate) enum Continuation {
@@ -60,39 +60,36 @@ impl Continuation {
6060
}
6161
Continuation::Each(branches, continuation) => {
6262
for branch in branches {
63-
let frags = vec!(branch.fragment.clone());
63+
let frags = vec![branch.fragment.clone()];
6464
let mut new_context = Context::extend(ctx, &frags);
6565
new_context.set_encoding(branch.fragment.required_encoding());
6666
continuation.evaluate(&new_context)?;
6767
}
6868
Ok(())
6969
}
70-
Continuation::Signals(msg) => {
71-
match ctx.read_all(ctx.encoding()) {
72-
Err(_e) => Ok(()),
73-
Ok(_) => Err(ConformanceErrorKind::ExpectedSignal(msg.to_owned()))?,
74-
}
75-
}
70+
Continuation::Signals(msg) => match ctx.read_all(ctx.encoding()) {
71+
Err(_e) => Ok(()),
72+
Ok(_) => Err(ConformanceErrorKind::ExpectedSignal(msg.to_owned()))?,
73+
},
7674
}
7775
}
78-
7976
}
8077

8178
impl Default for Continuation {
8279
fn default() -> Self {
83-
Continuation::Produces(Produces { elems: vec!() })
80+
Continuation::Produces(Produces { elems: vec![] })
8481
}
8582
}
8683

8784
/// Parses a clause known to be a continuation into a proper Continuation instance.
8885
pub fn parse_continuation(clause: Clause) -> InnerResult<Continuation> {
8986
let continuation = match clause.tpe {
90-
ClauseType::Produces => {
91-
Continuation::Produces(Produces { elems: clause.body.clone() })
92-
}
87+
ClauseType::Produces => Continuation::Produces(Produces {
88+
elems: clause.body.clone(),
89+
}),
9390
ClauseType::And => {
9491
if !clause.body.is_empty() {
95-
let mut args = vec!();
92+
let mut args = vec![];
9693
for elem in clause.body {
9794
if let Some(seq) = elem.as_sequence() {
9895
let clause = Clause::try_from(seq)?;
@@ -108,7 +105,7 @@ pub fn parse_continuation(clause: Clause) -> InnerResult<Continuation> {
108105
}
109106
Continuation::And(args)
110107
} else {
111-
return Err(ConformanceErrorKind::ExpectedExpectation)
108+
return Err(ConformanceErrorKind::ExpectedExpectation);
112109
}
113110
}
114111
ClauseType::Not => {
@@ -129,21 +126,17 @@ pub fn parse_continuation(clause: Clause) -> InnerResult<Continuation> {
129126
Continuation::Then(Box::new(then))
130127
}
131128
ClauseType::Denotes => {
132-
let mut values: Vec<ModelValue> = vec!();
129+
let mut values: Vec<ModelValue> = vec![];
133130
for elem in clause.body {
134-
if let Some(seq) = elem.as_sequence() {
135-
let model_value = ModelValue::try_from(seq)?;
136-
values.push(model_value);
137-
} else {
138-
return Err(ConformanceErrorKind::ExpectedModelValue);
139-
}
131+
let model_value = ModelValue::try_from(&elem)?;
132+
values.push(model_value);
140133
}
141134
Continuation::Denotes(Denotes { model: values })
142135
}
143136
ClauseType::Each => {
144137
let mut parsing_branches = true;
145138
let mut sequence_idx = 0;
146-
let mut branches: Vec<EachBranch> = vec!();
139+
let mut branches: Vec<EachBranch> = vec![];
147140
loop {
148141
if sequence_idx >= clause.body.len() {
149142
return Err(ConformanceErrorKind::ExpectedClause);
@@ -152,12 +145,18 @@ pub fn parse_continuation(clause: Clause) -> InnerResult<Continuation> {
152145
let mut name: Option<String> = None;
153146
// Branch: name-string? fragment
154147
// Check for name-string..
155-
if let Some(elem) = clause.body.get(sequence_idx).filter(|e| e.ion_type() == IonType::String) {
148+
if let Some(elem) = clause
149+
.body
150+
.get(sequence_idx)
151+
.filter(|e| e.ion_type() == IonType::String)
152+
{
156153
name = elem.as_string().map(|s| s.to_string());
157154
sequence_idx += 1;
158155
}
159156

160-
let seq = clause.body.get(sequence_idx)
157+
let seq = clause
158+
.body
159+
.get(sequence_idx)
161160
.and_then(|e| e.as_sequence())
162161
.ok_or(ConformanceErrorKind::ExpectedModelValue)?;
163162
let seq_iter = seq.iter().peekable();
@@ -170,12 +169,11 @@ pub fn parse_continuation(clause: Clause) -> InnerResult<Continuation> {
170169
}
171170
Err(x) => return Err(x),
172171
};
173-
branches.push(EachBranch {
174-
name,
175-
fragment,
176-
});
172+
branches.push(EachBranch { name, fragment });
177173
} else {
178-
let seq = clause.body.get(sequence_idx)
174+
let seq = clause
175+
.body
176+
.get(sequence_idx)
179177
.and_then(|e| e.as_sequence())
180178
.ok_or(ConformanceErrorKind::ExpectedModelValue)?;
181179
let clause = Clause::try_from(seq.clone())?;
@@ -188,7 +186,9 @@ pub fn parse_continuation(clause: Clause) -> InnerResult<Continuation> {
188186
}
189187
}
190188
ClauseType::Signals => {
191-
let msg = clause.body.first()
189+
let msg = clause
190+
.body
191+
.first()
192192
.and_then(|e| e.as_string())
193193
.ok_or(ConformanceErrorKind::ExpectedString)?
194194
.to_string();
@@ -197,7 +197,6 @@ pub fn parse_continuation(clause: Clause) -> InnerResult<Continuation> {
197197
_ => unreachable!(),
198198
};
199199

200-
201200
Ok(continuation)
202201
}
203202

@@ -219,19 +218,19 @@ impl Produces {
219218
/// Creates a reader using the provided context, and compares the read values from the input
220219
/// document with the elements specified in the associated Produces clause for equality.
221220
pub fn evaluate(&self, ctx: &Context) -> InnerResult<()> {
222-
use ion_rs::{Decoder, AnyEncoding};
221+
use ion_rs::{AnyEncoding, Decoder};
223222
let (input, _encoding) = ctx.input(ctx.encoding())?;
224223
let mut reader = ion_rs::Reader::new(AnyEncoding.with_catalog(ctx.build_catalog()), input)?;
225224

226225
let mut is_equal = true;
227226
let mut elem_iter = self.elems.iter();
228227

229228
while is_equal {
230-
let (actual_value, expected_elem) = (reader.next()?, elem_iter.next());
229+
let (actual_value, expected_elem) = (reader.read_next_element()?, elem_iter.next());
231230
match (actual_value, expected_elem) {
232231
(None, None) => break,
233232
(Some(actual_value), Some(expected_elem)) => {
234-
is_equal &= super::fragment::ProxyElement(expected_elem, ctx) == actual_value
233+
is_equal &= expected_elem.eq(&actual_value);
235234
}
236235
_ => is_equal = false,
237236
}
@@ -253,7 +252,7 @@ pub(crate) struct Denotes {
253252

254253
impl Denotes {
255254
pub fn evaluate(&self, ctx: &Context) -> InnerResult<()> {
256-
use ion_rs::{Decoder, AnyEncoding};
255+
use ion_rs::{AnyEncoding, Decoder};
257256
let (input, _encoding) = ctx.input(ctx.encoding())?;
258257
let mut reader = ion_rs::Reader::new(AnyEncoding.with_catalog(ctx.build_catalog()), input)?;
259258
let mut elem_iter = self.model.iter();
@@ -262,8 +261,9 @@ impl Denotes {
262261
while is_equal {
263262
let (read_value, expected_element) = (reader.next()?, elem_iter.next());
264263
is_equal = match (read_value, expected_element) {
265-
(Some(actual), Some(expected)) =>
266-
is_equal && compare_values(ctx, expected, &actual)?,
264+
(Some(actual), Some(expected)) => {
265+
is_equal && compare_values(ctx, expected, &actual)?
266+
}
267267
(None, None) => break,
268268
_ => false,
269269
}
@@ -299,7 +299,10 @@ impl Then {
299299

300300
/// Determine the encoding (text/binary) of the fragments contained within this Then clause.
301301
fn fragment_encoding(&self) -> IonEncoding {
302-
let enc = self.fragments.iter().find(|f| matches!(f, Fragment::Text(_) | Fragment::Binary(_)));
302+
let enc = self
303+
.fragments
304+
.iter()
305+
.find(|f| matches!(f, Fragment::Text(_) | Fragment::Binary(_)));
303306
match enc {
304307
Some(Fragment::Text(_)) => IonEncoding::Text,
305308
Some(Fragment::Binary(_)) => IonEncoding::Binary,

0 commit comments

Comments
 (0)