diff --git a/crates/xtce-codegen-e2e/tests/against_interpreter.rs b/crates/xtce-codegen-e2e/tests/against_interpreter.rs index 7726a4b..2ce5270 100644 --- a/crates/xtce-codegen-e2e/tests/against_interpreter.rs +++ b/crates/xtce-codegen-e2e/tests/against_interpreter.rs @@ -167,8 +167,6 @@ fn ctim_generated_matches_interpreted_on_every_packet() { /// IDEX: a binary field whose width comes from `PKT_LEN`, with two fields after it. /// /// This is the case that forced the cursor. Everything up to the blob is read at literal -/// offsets; the blob and the two fields behind it are walked, because where they sit is a -/// property of the packet. #[test] fn idex_generated_matches_interpreted_on_every_packet() { compare_with_interpreter!( @@ -220,7 +218,6 @@ fn synthetic_packet(apid: u16, payload: usize) -> Vec { /// `APID_6`, `APID_10` and `APID_28` — never occur in it. Without this, compiled string /// decoding would have no comparison against the interpreter at all, which is precisely the /// kind of gap the differential suite exists to close. Synthetic packets are enough, because -/// both decoders read the same bytes and any difference between them is real. #[test] fn ctim_string_containers_match_on_synthetic_packets() { let db = XtceDb::from_path(testdata("ctim/ctim_xtce_v1.xml")).expect("definition loads"); @@ -286,8 +283,6 @@ fn ctim_strings_are_borrowed_from_the_packet() { /// /// The packets are generated rather than fixed: bit patterns matter here — NaN payloads, /// subnormals, the sign bit of a 63-bit two's-complement field — and a handful of -/// hand-written packets would test whichever ones happened to be written. A fixed seed keeps -/// a failure reproducible. #[test] fn every_numeric_shape_matches_the_interpreter() { const BYTES: usize = 80; @@ -332,8 +327,6 @@ fn every_numeric_shape_matches_the_interpreter() { /// has no answer outside its points. Agreement therefore has to include agreeing to fail, and /// on the same packets — which the macro, written when nothing could fail, does not express. /// -/// `calibrators.xml` is deliberately built so both outcomes are common: two of its splines -/// sit on a four-bit field whose range is wider than their points. #[test] fn calibration_matches_the_interpreter_bit_for_bit() { const BYTES: usize = 23; @@ -426,7 +419,6 @@ fn calibration_matches_the_interpreter_bit_for_bit() { /// /// Without this, an emitter that sent both through one path would pass everything above — /// the two fields are compared against the interpreter separately, and a test that never -/// feeds them the same number never notices they agree when they should not. #[test] fn the_integer_power_path_is_not_the_float_one() { // 2^27 + 1. Its cube needs 82 bits, so rounding it once is not the same as rounding the @@ -461,8 +453,6 @@ fn the_integer_power_path_is_not_the_float_one() { /// A calibrator on an enumeration or a boolean is ignored, because the reference ignores it. /// /// XTCE looks both up from the *raw* value, and the interpreter returns before it consults a -/// calibrator. `ENUM_CAL` and `BOOL_CAL` carry one anyway; a generator that helpfully applied -/// it would turn `ARMED` into 1000. #[test] fn a_calibrator_on_an_enumeration_or_boolean_is_ignored() { let mut packet = vec![0u8; 23]; @@ -500,8 +490,6 @@ fn a_calibrator_on_an_enumeration_or_boolean_is_ignored() { /// /// The loop below has to tolerate failure on both sides, and for two different reasons: a /// packet may match nothing, or it may match two inheritors at once. `boolean_criteria.xml` -/// gives Alpha and Beta overlapping branches so that the second case is common, because an -/// OR is exactly what makes it easy to write by accident. #[test] fn a_boolean_expression_tree_matches_the_interpreter() { let db = XtceDb::from_path(testdata("boolean_criteria.xml")).expect("definition loads"); @@ -616,8 +604,6 @@ fn a_boolean_expression_tree_matches_the_interpreter() { /// reversed load; where they do not, the reversal has to happen after the read, and for a /// twelve-bit field it produces a value wider than the field it came from. /// -/// One packet in four carries an APID the definition does not describe, so both -/// implementations have to refuse the same packets as well as decode the same ones. #[test] fn byte_order_matches_the_interpreter() { let db = XtceDb::from_path(testdata("byte_order.xml")).expect("definition loads"); @@ -687,8 +673,6 @@ fn byte_order_matches_the_interpreter() { /// the file loads, and both of them read whatever it produced — so this test is not proving /// the semantics, which `crates/xtce-model/tests/arrays.rs` pins against the XTCE text. It is /// proving that reading 27 fields whose offsets came from an expansion is no different from -/// reading 27 fields written out by hand, including the six nibbles that are not byte-aligned -/// and the three floats behind them. #[test] fn arrays_match_the_interpreter() { const BYTES: usize = 39; @@ -777,8 +761,6 @@ fn the_expanded_field_names_are_the_ones_xtce_describes() { /// Like arrays, this has no Python rung — the reference refuses aggregates too. And like /// arrays, the comparison cannot see a misreading the two implementations share, because both /// read the same expansion. It is here for what it *can* prove: that seventeen fields whose -/// offsets came out of a nesting are read the same way as seventeen written out by hand, -/// including the four-bit member that leaves everything after it off a byte boundary. #[test] fn aggregates_match_the_interpreter() { const BYTES: usize = 37; @@ -817,7 +799,6 @@ fn aggregates_match_the_interpreter() { /// /// Checked against the XTCE text rather than against the interpreter, for the same reason as /// the array version: the interpreter derives its names from the same expansion, so a shared -/// misreading would pass a comparison between them. #[test] fn the_nested_field_names_are_the_ones_xtce_describes() { let packet = vec![0u8; 37]; @@ -1127,8 +1108,6 @@ fn telecommands_match_the_interpreter() { /// Driven deliberately: the loop above proves they agree with the interpreter, and this proves /// what they agree *on*. `POWER = "ON"` and `POWER = "OFF"` are the same comparison against /// different labels, and a resolution that lost the distinction — took the first label, or the -/// raw value of the literal, or matched everything — would still pass a test that only asked -/// whether the two implementations said the same thing, if both were wrong the same way. #[test] fn an_assignment_on_an_enumeration_picks_the_command_by_its_label() { let mut packet = vec![0u8; 24]; diff --git a/crates/xtce-codegen/src/emit.rs b/crates/xtce-codegen/src/emit.rs index 28a956c..5aa947f 100644 --- a/crates/xtce-codegen/src/emit.rs +++ b/crates/xtce-codegen/src/emit.rs @@ -449,12 +449,6 @@ fn byte_slice(field: &Field, packet: &Ident) -> TokenStream { } /// The body of a container's `decode`. -/// -/// Two shapes. When every width is fixed, the packet is narrowed to an array once and each -/// field is a literal offset into it — no cursor exists at run time. When one field takes its -/// width from the packet, everything before it still reads that way, and only the tail is -/// walked with a cursor. The split is the honest one: the offsets after a data-dependent -/// width are a property of the data, not of this generator. fn decode_body(plan: &ContainerPlan) -> TokenStream { let packet = ident("packet"); let prefix_bits = if plan.is_dynamic() { @@ -736,8 +730,6 @@ fn accessor(field: &Field) -> Option { /// addition is neither associative nor commutative, so "the same arithmetic in a different /// order" is a different answer, and a calibrator is where that is easiest to get wrong. /// -/// Two things carry that: -/// /// * **Terms are summed in document order**, not by Horner's method and not sorted. /// * **The integer and float paths are separate.** For an integral raw the power is computed /// in `i128` and converted once, exactly as the reference does with its arbitrary-precision @@ -1093,9 +1085,6 @@ const fn mask_for(width: u32) -> u64 { /// The expression that extracts `width` bits at `offset` as a `u64`. /// -/// The byte span, shift and mask are all decided here, so the emitted code is a load, a -/// shift and an `and` — no loop, no cursor, no branch. -/// /// The load uses the narrowest integer that spans the field rather than always padding to /// eight bytes. That is not cosmetic: a 1.6 MB mission database has nine thousand fields, and /// padding every one of them to an eight-element array literal turned the generated file into @@ -1105,11 +1094,6 @@ const fn mask_for(width: u32) -> u64 { /// beyond the packet for a field that ends at its final byte, which on a fixed-size array is /// a compile error rather than something to discover later. /// A generated expression, and whether embedding it needs parentheses. -/// -/// Rust binds `as` and `<<` tighter than `&`, so splicing `a & b` into `#expr as u32` would -/// silently produce `a & (b as u32)`. Tracking atomicity means the parentheses go in exactly -/// where they are needed — adding them everywhere would trip `unused_parens`, which a file -/// meant for `include!` cannot switch off. #[derive(Clone)] struct Expr { tokens: TokenStream, @@ -1832,9 +1816,6 @@ fn swap_helper() -> TokenStream { /// exponent in the bottom, neither biased, no implicit leading one, no infinities and no /// NaN. Line for line what `xtce_decode::decoder::mil_std_1750a` computes, which in turn is /// what the reference computes: `mantissa * 2 ** (exponent - 23)`. -/// -/// Both fields are masked before the sign extension, so the shifts below have nothing above -/// their width to discard and the masking and unmasked forms coincide. fn mil_helper() -> TokenStream { quote! { fn mil_std_1750a(bits: u64) -> f64 { @@ -1877,13 +1858,6 @@ fn powi_helper() -> TokenStream { } /// Spline interpolation, line for line as `xtce_decode::calibrate::interpolate` does it. -/// -/// The order and the extrapolation flag are passed in rather than specialised away, so that -/// the two implementations can be read side by side; both are constants at every call site, -/// so nothing survives optimisation. -/// -/// Orders above one and an empty point list are refused when the code is generated, which is -/// why the only failure left here is a query outside the points. fn spline_helpers() -> TokenStream { quote! { fn spline_line(x: f64, x0: f64, x1: f64, y0: f64, y1: f64) -> f64 { diff --git a/crates/xtce-codegen/src/plan.rs b/crates/xtce-codegen/src/plan.rs index 68b8fa2..feedd5e 100644 --- a/crates/xtce-codegen/src/plan.rs +++ b/crates/xtce-codegen/src/plan.rs @@ -350,11 +350,6 @@ impl GuardTest { /// operator is therefore meaningful and every one is resolvable here: the enumeration is a /// finite list, so the answer for each entry is known when the code is generated, and what is /// left for run time is a membership test over the raw values. -/// -/// Adjacent ranges are merged where the `` is in ascending order, which it -/// almost always is, so an enumeration whose labels all satisfy the comparison becomes one -/// range rather than two hundred. Out of order it simply does not merge: the set is the same -/// either way, only longer to write. fn labels_satisfying( entries: &[(i128, i128, String)], operator: CompareOp, @@ -488,10 +483,6 @@ const MAX_DEPTH: usize = 64; /// How far into the packet the layout has reached, while it is still knowable. /// -/// Becomes `None` the moment a field's width comes from the data: from there on the offsets -/// are whatever the packet says, and the generated decoder has to carry a cursor. -/// `bytes` as exactly `bit_width.div_ceil(8)` bytes, right-aligned, leading bits cleared. -/// /// XTCE gives a fixed value as `hexBinary` and its width separately, and does not require the /// two to agree. Reading the bytes as one big-endian unsigned number and keeping the low /// `bit_width` bits of it is the only interpretation that handles both directions: a value diff --git a/crates/xtce-codegen/tests/commands.rs b/crates/xtce-codegen/tests/commands.rs index 8a771d3..e27a531 100644 --- a/crates/xtce-codegen/tests/commands.rs +++ b/crates/xtce-codegen/tests/commands.rs @@ -38,7 +38,6 @@ fn container<'p>(plan: &'p plan::Plan, name: &str) -> &'p plan::ContainerPlan { .unwrap_or_else(|| panic!("no container named {name}")) } -/// Every fixed value reaches the plan, at the bit it occupies, inherited ones included. #[test] fn fixed_values_keep_their_place() { let plan = commands_plan(); @@ -78,8 +77,6 @@ fn fixed_values_keep_their_place() { /// /// XTCE requires both `binaryValue` and `sizeInBits` and does not require them to agree. /// `TRAILER` gives four bytes for a sixteen-bit field: read as one big-endian number, -/// `DEADBEEF` in sixteen bits is `BEEF`, and an encoder that wrote `DEAD` — or all four bytes -/// — would produce a packet nothing recognises. #[test] fn a_fixed_value_wider_than_its_field_is_truncated_from_the_left() { let plan = commands_plan(); @@ -104,8 +101,6 @@ fn a_fixed_value_wider_than_its_field_is_truncated_from_the_left() { /// A value narrower than its field is zero-extended, and spare leading bits are cleared. /// /// The other direction of the same rule. `SPARE` is four bits and its `binaryValue` is a -/// whole byte, `0A`: the byte that reaches the plan has the high nibble cleared, so a caller -/// writing it into a four-bit field cannot spill into whatever sits above it. #[test] fn a_fixed_value_narrower_than_its_bytes_has_its_leading_bits_cleared() { let plan = commands_plan(); @@ -119,7 +114,6 @@ fn a_fixed_value_narrower_than_its_bytes_has_its_leading_bits_cleared() { assert_eq!(spare.value, vec![0x0A]); } -/// A container with no fixed values has none, rather than an empty one invented for it. #[test] fn a_telemetry_container_has_no_fixed_values() { let db = XtceDb::from_path(testdata("commands.xml")).expect("definition loads"); @@ -138,8 +132,6 @@ fn a_telemetry_container_has_no_fixed_values() { /// A criterion on an enumeration resolves to the raw values its labels cover. /// /// Not a string comparison at run time, and not a comparison against the literal read as a -/// number either: the labels are a finite list, so which of them satisfy the operator is known -/// when the code is generated, and what is left is a set of raw values. #[test] fn a_criterion_on_a_label_becomes_a_set_of_raw_values() { let plan = commands_plan(); @@ -188,8 +180,6 @@ fn collect(node: &plan::Node, out: &mut Vec) { /// A criterion comparing a *raw* enumeration value is an ordinary number comparison. /// -/// `useCalibratedValue="false"` says to compare the bits, and the bits are a number. Only the -/// engineering value is a label. #[test] fn a_raw_criterion_on_an_enumeration_stays_a_number() { let db = XtceDb::from_xml( diff --git a/crates/xtce-codegen/tests/generated_decoder.rs b/crates/xtce-codegen/tests/generated_decoder.rs index 3b36213..f2be12d 100644 --- a/crates/xtce-codegen/tests/generated_decoder.rs +++ b/crates/xtce-codegen/tests/generated_decoder.rs @@ -62,7 +62,6 @@ fn the_committed_decoder_is_what_the_generator_produces() { ); } -/// Both decoders, over every packet of the real stream, compared field by field. #[test] fn generated_matches_interpreted_on_every_packet() { let db = load(); @@ -200,8 +199,6 @@ fn a_packet_of_another_type_is_refused() { /// and its `` compiles. /// /// So the assertion is inverted. If one of these ever stops compiling, that is either a -/// regression or a definition that grew a construct outside the subset, and either way it -/// should be noticed here rather than in whatever downstream build goes quiet. #[test] fn every_bundled_definition_compiles() { let directory = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../testdata/spp"); @@ -292,8 +289,6 @@ fn planned_offsets_match_the_interpreters_offsets() { /// Constructs that must stay refused, each with the reason it cannot be compiled. /// -/// Written inline because no bundled definition contains them, and a refusal path with no -/// test is a refusal that can silently turn into a wrong answer. #[test] fn constructs_outside_the_compilable_subset_are_refused() { fn definition(types: &str, parameters: &str, entries: &str) -> String { @@ -416,8 +411,6 @@ fn constructs_outside_the_compilable_subset_are_refused() { /// engineering value is a float, or a boolean, whose engineering value is 0 or 1 rather than /// its raw bits — comparing the raw bits would select a different container. Silently. /// -/// The first of those became reachable the day calibrators started compiling: before then a -/// calibrated field was refused outright, so a criterion could not name one. #[test] fn criteria_the_generator_would_evaluate_differently_are_refused() { fn definition(types: &str, parameters: &str, criteria: &str) -> String { diff --git a/crates/xtce-decode/src/bits.rs b/crates/xtce-decode/src/bits.rs index 250ca80..0964d4f 100644 --- a/crates/xtce-decode/src/bits.rs +++ b/crates/xtce-decode/src/bits.rs @@ -513,8 +513,6 @@ mod tests { /// Every width at every offset, against the one-bit-at-a-time oracle. /// /// The generator is written so that width 64 at a non-byte-aligned offset — the - /// nine-byte case — is actually reachable, rather than being buried under a uniform - /// distribution that would hit it once in a thousand runs. #[test] fn matches_naive_reference( data in proptest::collection::vec(proptest::num::u8::ANY, 1..24), @@ -535,7 +533,6 @@ mod tests { } } - /// Wide fields specifically: nine-byte spans and everything around them. #[test] fn wide_reads_at_every_bit_offset( data in proptest::collection::vec(proptest::num::u8::ANY, 9..17), @@ -548,7 +545,6 @@ mod tests { proptest::prop_assert_eq!(cursor.read_uint(width), Ok(want)); } - /// Reading N bits as bytes and as an integer must agree for N <= 64. #[test] fn bytes_and_integers_agree( data in proptest::collection::vec(proptest::num::u8::ANY, 1..20), @@ -578,8 +574,6 @@ mod tests { /// Sign extension at every width, against the arbitrary-precision oracle. /// - /// Width 63 is the interesting one and a uniform generator finds it once in sixty - /// runs, so widths are drawn across the whole range deliberately. #[test] fn twos_complement_matches_naive_reference( bits in proptest::num::u64::ANY, @@ -610,7 +604,6 @@ mod tests { ); } - /// Above the field's width the two part company, and the unmasked one is right. #[test] fn unmasked_sign_extension_keeps_the_high_bits( bits in proptest::num::u64::ANY, @@ -629,7 +622,6 @@ mod tests { ); } - /// A read never panics and never moves the cursor on failure. #[test] fn failures_leave_the_cursor_untouched( data in proptest::collection::vec(proptest::num::u8::ANY, 0..8), diff --git a/crates/xtce-decode/src/decoder.rs b/crates/xtce-decode/src/decoder.rs index 516747c..1b4029c 100644 --- a/crates/xtce-decode/src/decoder.rs +++ b/crates/xtce-decode/src/decoder.rs @@ -913,15 +913,6 @@ impl<'db> Decoder<'db> { } /// The largest number of entries any single decode path from `root` can visit. -/// -/// A decode walks from the root down one chain of inheritors, decoding each container's own -/// entry list and expanding any `` inline. This is the deepest such walk, -/// used to size a packet's storage once instead of regrowing it. -/// -/// Container expansion is memoised, which is what actually bounds the work: the depth limit -/// alone would not: a chain of forty containers each referencing the next twice is 2^40 -/// calls before the cap ever fires. Decoding has the same shape but is braked by running out -/// of packet; this runs at construction time with no such brake. fn longest_path_entries(db: &XtceDb, root: ContainerId) -> usize { let mut expanded: Vec> = vec![None; db.containers().len()]; let mut deepest: Vec> = vec![None; db.containers().len()]; diff --git a/crates/xtce-decode/tests/decode_inline.rs b/crates/xtce-decode/tests/decode_inline.rs index b582c2c..1ee3471 100644 --- a/crates/xtce-decode/tests/decode_inline.rs +++ b/crates/xtce-decode/tests/decode_inline.rs @@ -698,8 +698,6 @@ fn namespace_spelling_does_not_change_the_result() { /// Every reference shape XTCE allows, across nested space systems. /// /// All ten bundled test files have exactly one `SpaceSystem`, so nothing in `testdata` -/// reaches path resolution, ancestor search, or `.`/`..` segments. This is the only coverage -/// those paths have. #[test] fn references_resolve_across_nested_space_systems() { let xml = r#" @@ -840,8 +838,6 @@ fn an_unresolvable_reference_names_itself() { /// /// The reference raises when a definition says otherwise, and raises at *load*, so a file /// like this one does not open in Python at all. Here it opens — loading always succeeds, and -/// only decoding reports what it cannot do — but the parameter reports rather than decoding -/// the low 32 bits of a 48-bit field, which is a number nothing else would ever produce. #[test] fn a_mil_std_1750a_float_that_is_not_32_bits_is_refused() { let xml = r#" @@ -944,8 +940,6 @@ const COMMANDS: &str = r#" /// A telecommand decodes with the machinery telemetry uses, because it is a container. /// /// Nothing in the decoder knows what a command is. The root is named rather than defaulted — -/// see below — and from there the argument assignment selects the specialisation exactly as -/// a `` would. #[test] fn a_telecommand_decodes_like_any_other_container() { let db = load(COMMANDS); @@ -978,7 +972,6 @@ fn a_telecommand_decodes_like_any_other_container() { ); } -/// An opcode the assignment does not match stops at the abstract base, and is refused. #[test] fn a_telecommand_whose_assignment_does_not_hold_is_not_that_command() { let db = load(COMMANDS); @@ -997,8 +990,6 @@ fn a_telecommand_whose_assignment_does_not_hold_is_not_that_command() { /// Adding a command half does not take the default root away from the telemetry. /// /// A command container with no `` is a root of the command tree, so counting -/// it among the candidates would leave a definition that used to have exactly one root with -/// two, and `Decoder::new` would stop working on a file whose telemetry had not changed. #[test] fn the_default_root_ignores_command_containers() { let db = load(COMMANDS); diff --git a/crates/xtce-model/src/lower.rs b/crates/xtce-model/src/lower.rs index 9cc1b19..06ee4b0 100644 --- a/crates/xtce-model/src/lower.rs +++ b/crates/xtce-model/src/lower.rs @@ -266,13 +266,6 @@ impl<'d> Lowering<'d> { } /// Registers what a `` section defines. - /// - /// It may hold its own `` and `` as well as an - /// `` — the schema puts them there "so that `MetaCommand` data can be - /// built independently of `TelemetryMetaData`" — and all three register exactly as their - /// telemetry counterparts do. An argument type is a parameter type: the encodings are the - /// same elements, and `IntegerArgumentType` extends the same base `IntegerParameterType` - /// does. fn register_command_meta_data( &mut self, element: Element<'d>, @@ -367,14 +360,6 @@ impl<'d> Lowering<'d> { /// unqualified index: that index is what `` and every /// telemetry reference searches, and an argument appearing there could shadow a real /// parameter of the same name. - /// - /// The container is qualified under the command for the same reason and one more: the - /// schema's uniqueness key for container names covers `ContainerSet` and - /// `CommandContainerSet` but *not* a `MetaCommand`'s own ``, which is - /// "private except as referred to in `BaseMetaCommand`". Two commands may therefore give - /// their containers the same name, and registering both at the system level would reject - /// a file the schema allows. It is still indexed by its bare name, first one winning, so - /// that the usual `` resolves. fn register_meta_command( &mut self, element: Element<'d>, @@ -1462,16 +1447,6 @@ impl<'d> Lowering<'d> { /// Turns an entry that names an array or an aggregate into one entry per leaf field, or /// `None` if it names neither. - /// - /// Both are containers of other things, and both are laid out packed and in order, so - /// both flatten the same way: an array repeats one type under `[i]`, an aggregate lists - /// named members under `.name`, and either may hold the other. What comes out is one - /// synthetic parameter per leaf, carrying the leaf's own type and a name that spells the - /// path to it — `GRID[1][2]`, `STATE.voltage`, `SENSORS[0].reading`. - /// - /// The synthetic parameters go into the arena but **not** into the name-resolution index. - /// That index is what ``, `DynamicValue` and context - /// calibrators all search, and a synthetic entry there could shadow a real parameter. fn expand_composite( &mut self, element: Element<'d>, @@ -1952,10 +1927,6 @@ impl<'d> Lowering<'d> { /// /// XTCE reference syntax (CCSDS 660.1-G-2 §4.3.1) is path-like: /// - /// * `/A/B/name` — absolute from the document root; - /// * `sub/name`, `./name`, `../name` — relative to the current space system; - /// * `name` — searched in the current space system, then each ancestor in turn. - /// /// A final fallback searches the whole document by unqualified name. That is not in the /// standard, but the reference implementation keys its lookup tables that way, and /// several shipped databases rely on it. @@ -2203,12 +2174,6 @@ struct Walk<'a> { } /// How many leaf fields one entry may expand into. -/// -/// Every leaf becomes a parameter in the arena and a field in any generated decoder, so a -/// definition asking for a million of them would produce something no compiler will finish. -/// An aggregate of arrays of aggregates reaches large numbers quickly, which is why the limit -/// counts leaves rather than one array's elements. It is arbitrary but named: nothing in a -/// real database comes close, and the refusal says what it was asked for. const MAX_EXPANDED_FIELDS: usize = 4096; /// A `` or `` that is a plain ``. diff --git a/crates/xtce-model/tests/commands.rs b/crates/xtce-model/tests/commands.rs index 203341a..b3b5307 100644 --- a/crates/xtce-model/tests/commands.rs +++ b/crates/xtce-model/tests/commands.rs @@ -138,8 +138,6 @@ fn a_command_becomes_a_container_and_its_arguments_become_parameters() { /// /// Both halves of this definition declare a `MODE`. They are different things — one is /// reported by the spacecraft, the other is supplied by whoever sends the command — and the -/// index that `` searches has to keep pointing at the -/// telemetry one. #[test] fn an_argument_does_not_shadow_a_parameter_of_the_same_name() { let db = load(INHERITED); @@ -162,8 +160,6 @@ fn an_argument_does_not_shadow_a_parameter_of_the_same_name() { /// An argument assignment becomes a restriction criterion on the command's container. /// /// It is the same statement read two ways: assigning `OPCODE = 7` is what makes this command -/// a specialisation of `Base`, and comparing `OPCODE == 7` is what recognises an arriving -/// packet as this command rather than as a sibling. #[test] fn an_argument_assignment_becomes_a_restriction_criterion() { let db = load(INHERITED); @@ -198,7 +194,6 @@ fn an_argument_assignment_becomes_a_restriction_criterion() { ); } -/// A `` keeps its bytes and its width, and carries no parameter. #[test] fn a_fixed_value_entry_keeps_its_bytes() { let db = load(INHERITED); @@ -223,8 +218,6 @@ fn a_fixed_value_entry_keeps_its_bytes() { /// Two commands may give their containers the same name, and both must load. /// /// The schema's uniqueness key for container names covers `ContainerSet` and -/// `CommandContainerSet` but not a MetaCommand's own ``, which it calls -/// private. Rejecting this file would reject one the schema allows. #[test] fn two_commands_may_name_their_containers_the_same() { let db = load( @@ -272,7 +265,6 @@ fn two_commands_may_name_their_containers_the_same() { } } -/// An `argumentRef` naming nothing the command can see is a load failure, not a guess. #[test] fn an_unknown_argument_reference_is_refused() { let error = refusal( @@ -297,8 +289,6 @@ fn an_unknown_argument_reference_is_refused() { /// An `argumentRef` cannot reach a *telemetry* parameter of the same name. /// /// "There is no path, this is a local reference." A command whose entry list names `MODE` -/// without declaring a `MODE` argument is missing an argument, not silently packing the -/// spacecraft's telemetry parameter. #[test] fn an_argument_reference_does_not_fall_back_to_a_parameter() { let error = refusal( @@ -324,8 +314,6 @@ fn an_argument_reference_does_not_fall_back_to_a_parameter() { /// /// "Arguments are user provided to the specific command definition. Parameters are /// provided/calculated/determined by the software creating the command instance." A sequence -/// count the ground fills in is a parameter, and `` is how a command names -/// one. #[test] fn a_command_container_may_reference_a_parameter() { let db = load( @@ -356,7 +344,6 @@ fn a_command_container_may_reference_a_parameter() { ); } -/// Command inheritance that loops is refused at load, not followed. #[test] fn a_cycle_in_command_inheritance_is_refused() { let error = refusal( @@ -375,7 +362,6 @@ fn a_cycle_in_command_inheritance_is_refused() { ); } -/// `CommandMetaData` is no longer reported as a section this crate skipped. #[test] fn the_command_section_is_no_longer_skipped() { let db = load(INHERITED); @@ -389,7 +375,6 @@ fn the_command_section_is_no_longer_skipped() { assert_eq!(db.stats().meta_commands, 2); } -/// A definition with no command half has no commands, and nothing else changes. #[test] fn a_definition_with_no_commands_is_unaffected() { let db = XtceDb::from_xml( @@ -418,8 +403,6 @@ fn a_definition_with_no_commands_is_unaffected() { /// `abstract` on a `MetaCommand` means it is "not instantiated, rather only used as bases to /// inherit from to create specialized command definitions". No packet is one, so its /// container can never be a packet's final match either. That is what `abstract` means on a -/// container, said one level up — and without carrying it down, a packet that matched no -/// specialisation would decode as the base rather than being refused. #[test] fn a_container_packing_an_abstract_command_is_abstract() { let db = load(INHERITED); @@ -438,7 +421,6 @@ fn a_container_packing_an_abstract_command_is_abstract() { ); } -/// The container a command packs knows which command that is; a telemetry container does not. #[test] fn a_command_container_points_back_at_its_command() { let db = load(INHERITED); @@ -461,8 +443,6 @@ fn a_command_container_points_back_at_its_command() { /// The schema keys these in two overlapping ways. One key covers `TelemetryMetaData`'s and /// `CommandMetaData`'s ``s; another covers `CommandMetaData`'s /// `` and its ``. An argument type and a *telemetry* -/// parameter type are in no key together — so `U8` may be both, meaning two different things, -/// and a loader that shared one index would reject a file the schema allows. #[test] fn an_argument_type_may_share_a_name_with_a_parameter_type() { let db = load( @@ -497,7 +477,6 @@ fn an_argument_type_may_share_a_name_with_a_parameter_type() { ); } -/// Two argument types of the same name are still a duplicate, as the schema requires. #[test] fn two_argument_types_of_the_same_name_are_refused() { let error = refusal( @@ -559,8 +538,6 @@ fn a_command_parameter_type_is_reachable_from_both_kinds_of_reference() { /// /// The effective argument scope is built root-first over the whole chain, so a command sees /// every argument its ancestors declare. Two levels is where a one-level shortcut would still -/// pass, so this goes three deep: `Leaf` pins an argument that `Root` declares and `Middle` -/// never mentions. #[test] fn an_assignment_reaches_an_argument_two_levels_up() { let db = load( @@ -623,8 +600,6 @@ fn an_assignment_reaches_an_argument_two_levels_up() { /// A container in a `` is shared, and belongs to no single command. /// /// The schema puts them there so that MetaCommand definitions can "reference/share" them, and -/// keys their names at the system level like a telemetry container's. So they register like -/// one — and, unlike a command's own private container, they carry no back-link to a command. #[test] fn a_shared_command_container_belongs_to_no_command() { let db = load( @@ -684,8 +659,6 @@ fn a_shared_command_container_belongs_to_no_command() { /// The awkward one. A `` container that is neither abstract nor derived /// looks exactly like a telemetry root: no ``, a name keyed at the system /// level, entries like any other. Counting it would leave a definition that had one root with -/// two, and `Decoder::new` would stop working on a file whose telemetry had not changed — -/// the same failure a command's own container would have caused, one level further out. #[test] fn a_shared_command_container_does_not_steal_the_default_root() { let db = load( diff --git a/crates/xtce-model/tests/composites.rs b/crates/xtce-model/tests/composites.rs index ed6088f..fa50dd5 100644 --- a/crates/xtce-model/tests/composites.rs +++ b/crates/xtce-model/tests/composites.rs @@ -87,8 +87,6 @@ fn one_dimension_expands_in_order() { /// Two dimensions, with **different** extents. /// /// The extents differ on purpose. With a square array a transposed expansion produces the -/// same number of fields covering the same bits, and every test passes; 2 by 3 is the -/// smallest shape where row-major and column-major disagree about which name sits where. #[test] fn two_dimensions_expand_with_the_last_varying_fastest() { let xml = definition( @@ -117,8 +115,6 @@ fn two_dimensions_expand_with_the_last_varying_fastest() { /// A `` on the *entry* subsets the array, and keeps the array's own indices. /// /// XTCE: "Only used for subsetting an array. The array's maximum dimension sizes are set in -/// the type." Renumbering the subset from zero would make its fields impossible to line up -/// with the same array read whole. #[test] fn a_subset_keeps_the_indices_it_covers() { let xml = definition( @@ -135,7 +131,6 @@ fn a_subset_keeps_the_indices_it_covers() { assert_eq!(expanded(&xml), ["ARR[2]", "ARR[3]", "ARR[4]"]); } -/// A subset that runs past the type's declared size is a definition error. #[test] fn a_subset_outside_the_declared_dimensions_is_refused() { let xml = definition( @@ -158,7 +153,6 @@ fn a_subset_outside_the_declared_dimensions_is_refused() { ); } -/// An index the packet supplies cannot be expanded when the file is loaded. #[test] fn a_dimension_read_from_the_packet_is_not_expanded() { let xml = definition( @@ -185,8 +179,6 @@ fn a_dimension_read_from_the_packet_is_not_expanded() { /// The synthetic parameters are not visible to a `parameterRef`. /// /// They live in the arena so that entries can point at them, but not in the index that -/// ``, `DynamicValue` and context calibrators search. A synthetic -/// `ARR[0]` there could shadow a real parameter of that name, and nothing would say so. #[test] fn synthetic_elements_cannot_be_referenced_by_name() { let xml = definition( @@ -225,8 +217,6 @@ fn synthetic_elements_cannot_be_referenced_by_name() { /// The expansion has a ceiling, and the refusal names it and the entry. /// /// It does not name the total. Counting the leaves of an arbitrary nesting first would mean a -/// second traversal that has to agree with the one that builds them, and the pair drifting -/// apart is a worse failure than a message that says "more than this". #[test] fn an_array_larger_than_the_ceiling_is_refused() { let xml = definition( @@ -251,7 +241,6 @@ fn an_array_larger_than_the_ceiling_is_refused() { ); } -/// An aggregate becomes its members, in order, under the dot syntax. #[test] fn an_aggregate_expands_into_its_members() { let xml = definition( @@ -273,8 +262,6 @@ fn an_aggregate_expands_into_its_members() { /// An array of aggregates, and an aggregate holding an array, both compose. /// /// The two nest in either direction, and the name spells the path either way. Three members -/// and two elements rather than two and two: the counts differ so that a mix-up between the -/// axis and the member list cannot produce the same list. #[test] fn arrays_and_aggregates_nest_in_both_directions() { let outer_array = definition( @@ -328,7 +315,6 @@ fn arrays_and_aggregates_nest_in_both_directions() { /// A type that contains itself cannot be expanded, and says so rather than not returning. /// /// XTCE forbids it — `MemberType`: "Circular references are not allowed" — but a file can -/// still say it, and following it would recurse until the stack ran out. #[test] fn a_type_that_contains_itself_is_refused() { let xml = definition( @@ -348,7 +334,6 @@ fn a_type_that_contains_itself_is_refused() { ); } -/// An aggregate with no members has nothing to place, which is a definition error. #[test] fn an_aggregate_with_no_members_is_reported() { let xml = definition( @@ -367,8 +352,6 @@ fn an_aggregate_with_no_members_is_reported() { /// The ceiling counts leaves, not one array's elements. /// -/// An aggregate of arrays of aggregates reaches large numbers without any single dimension -/// looking unreasonable, which is why the limit is where it is. #[test] fn the_ceiling_counts_leaves_across_the_whole_nesting() { let xml = definition( diff --git a/crates/xtce-py/src/lib.rs b/crates/xtce-py/src/lib.rs index 5df7191..5e10e27 100644 --- a/crates/xtce-py/src/lib.rs +++ b/crates/xtce-py/src/lib.rs @@ -184,13 +184,6 @@ impl Definition { } /// Decodes every CCSDS packet in `data`. - /// - /// Returns one dictionary per packet, mapping parameter name to value. The Rust decoding - /// runs with the GIL released. - /// - /// `raw=True` returns the values as encoded in the packet rather than after calibration - /// and enumeration lookup. `skip_unrecognized=True` drops packets whose type the - /// definition does not describe instead of raising. #[pyo3(signature = (data, *, skip_header_bytes = 0, root = None, raw = false, skip_unrecognized = false))] fn decode_stream( &self, diff --git a/xtask/src/diff.rs b/xtask/src/diff.rs index 758f620..6f8d823 100644 --- a/xtask/src/diff.rs +++ b/xtask/src/diff.rs @@ -604,7 +604,6 @@ mod tests { assert_eq!(windows.first_difference(&expected(1000, 256, None)), None); } - /// The window is reported as the packets it covers, not as its index. #[test] fn a_differing_window_is_reported_as_a_packet_range() { let windows = observed(1000, 256); @@ -617,8 +616,6 @@ mod tests { /// The last window is short unless the stream divides evenly, and still has to be checked. /// /// Without finishing it, a divergence in the final packets would be the one case the - /// windows could not localise — and a stream whose length is a multiple of the window is - /// the exception rather than the rule. #[test] fn the_short_final_window_is_compared_too() { let windows = observed(700, 256); @@ -628,7 +625,6 @@ mod tests { assert_eq!(windows.first_difference(&theirs), Some((512, 767))); } - /// A stream of a different length differs at the first window one side does not have. #[test] fn a_shorter_stream_differs_at_the_window_it_runs_out_on() { let windows = observed(512, 256); @@ -638,7 +634,6 @@ mod tests { ); } - /// A golden written before window digests existed localises nothing, and says nothing. #[test] fn a_golden_without_windows_reports_none() { let windows = observed(1000, 0);