Skip to content

Add Moar Tests#39

Merged
redvers merged 4 commits into
mainfrom
test/extensive-api
May 22, 2026
Merged

Add Moar Tests#39
redvers merged 4 commits into
mainfrom
test/extensive-api

Conversation

@redvers
Copy link
Copy Markdown
Collaborator

@redvers redvers commented May 22, 2026

┌────────────────────────────────────────┬───────┬─────────────────────────────────────────────┐
│ Stage │ Tests │ Delta │
├────────────────────────────────────────┼───────┼─────────────────────────────────────────────┤
│ Baseline (start of test/extensive-api) │ 63 │ — │
├────────────────────────────────────────┼───────┼─────────────────────────────────────────────┤
│ Batch 1 │ 77 │ +14 │
├────────────────────────────────────────┼───────┼─────────────────────────────────────────────┤
│ Batch 2 │ 92 │ +15 │
├────────────────────────────────────────┼───────┼─────────────────────────────────────────────┤
│ Batch 3 │ 102 │ +10 (incl. 5 property bumps to 500 samples) │
├────────────────────────────────────────┼───────┼─────────────────────────────────────────────┤
│ Batch 4 (this commit) │ 117 │ +15 + 1 tighten │
└────────────────────────────────────────┴───────┴─────────────────────────────────────────────┘

redvers added 4 commits May 22, 2026 03:01
A new test file libxml2/_tests/extensive_tests.pony covering the
public API beyond the happy-path basic tests. 14 new tests in five
groups:

API branch coverage
  - TestSetRootElementReplacesOldRoot: the "had a previous root"
    return-value branch of Xml2Doc.setRootElement
  - TestCreateDocWithCustomVersion: Xml2Doc.create("1.1") and
    verifying the version appears in serialised output
  - TestSetPropOverwritesExisting: repeated setProp on same name
    updates rather than duplicating
  - TestEmptyAttributeValue: <e a=""/> distinguishes from absent

Unicode / encoding
  - TestUnicodeContentRoundTrip: Cyrillic / Greek / CJK / Arabic /
    emoji content survives parse-serialize-parse
  - TestUnicodeAttributeValues: non-ASCII attribute values
    round-trip through setProp / getProp / serialize / parse
  - TestSerializeUTF16Encoding: UTF-16 output has the right BOM
    prefix; transcoding actually re-encodes the body bytes rather
    than relabeling the encoding declaration

Parser options interaction
  - TestParserOptionsCombined: error_recovery + no_blanks applied
    together; recovery completes despite trailing garbage and
    element-only content has its indentation stripped

XPath function coverage (XPath 1.0)
  - TestXPathStringFunctionsExtensive: concat, substring,
    substring-before, substring-after, normalize-space,
    string-length, contains, starts-with
  - TestXPathPositionAndLast: position(), last(), last()-1 in
    predicates; count() returns cardinality
  - TestXPathNameFunctions: XPath name() / local-name() /
    namespace-uri() match the Xml2Node namespace accessors

Edge cases
  - TestManyAttributesRoundTrip: 50 attributes on one element
    survive setProp / serialize / parse / getProp, order-independent

Property-based (PonyCheck)
  - PropSetGetPropRoundTrip: for ASCII-letter names and
    printable-ASCII values, setProp/getProp is identity
  - PropAppendChildPreservesCount: getChildren().size() equals
    appendChild call count, and XPath count(./elem) agrees

All 77 tests pass; stability confirmed across 3 consecutive runs.

No release note: test-only changes don't get user-facing entries
in this project, consistent with prior PRs that added test
coverage.
15 more tests in libxml2/_tests/extensive_tests.pony, covering
XPath features, parser/serialiser semantics, mutation behaviour,
inheritance, and boundary cases.

XPath features
  - TestXPathAxes: descendant, ancestor, parent, following-sibling,
    preceding-sibling axes exercised on a fixed tree
  - TestXPathNumberFunctions: sum, floor, ceiling, round, number
  - TestXPathBooleanFunctions: true, false, not, boolean
  - TestXPathAttributePredicates: existence, equality, inequality,
    negation, wildcard predicates on attributes

Parser / serialiser semantics
  - TestCDATAContentPreserved: content inside <![CDATA[...]]>
    reaches getContent verbatim
  - TestSelfClosingEquivalence: <a/> and <a></a> produce equivalent
    trees (same children count, same name, same content)
  - TestCommentRoundTrip: <!-- comment --> survives both a single
    serialise pass and a parse-then-serialise round-trip

Mutation semantics
  - TestSetContentReplacesChildren: setContent on an element with
    existing element children replaces them with the new text
  - TestSetUnsetGetPropEmpty: setProp + unsetProp leaves the
    attribute absent (getProp returns "", getProps reports zero
    entries)

Boundary / volume
  - TestLongNamesAndValues: 256-char element names and 4096-char
    attribute values round-trip cleanly

Inheritance
  - TestGetLangNestedScopes: xml:lang declarations are inherited
    through ancestors and overridden by nested redeclarations

I/O options
  - TestSaveToFileWithFormatAndEncoding: saveToFile(auth, path,
    format=true, encoding="ISO-8859-1") produces a formatted file
    with the requested encoding declaration

Property-based
  - PropStructuralRoundTripStable: parsing a doc built from a
    generated array of element names, then running 3 parse-serialise
    cycles, the child count and per-position names stay identical
  - PropGetPropsCardinality: setting N distinct-named attributes
    produces exactly N getProps entries
  - PropSetUnsetIsEmpty: setProp(n,v) + unsetProp(n) is observably
    equivalent to never having set the attribute

All 92 tests pass; stability confirmed across 3 consecutive runs.

No release note: test-only change.
Adds 10 new unit tests and bumps all property-based tests'
num_samples from 100 (PonyCheck default) to 500. Two property
generators also gained wider input ranges (usize 0-50 -> 0-200,
seq_of length 0-8 -> 0-32) for deeper coverage of larger inputs.

Tree mutation
  - TestAppendChildPreservesOrder: appendChild on multiple new
    children preserves insertion order; XPath positional indexing
    agrees. (Re-parenting an existing child via appendChild is
    not supported in the current API - xmlAddChild does not
    detach from the previous parent, which would require an
    xmlUnlinkNode call the binding doesn't expose. The test
    docstring notes this limitation.)

Parser surface
  - TestDoctypeParsing: documents with DOCTYPE declarations parse,
    navigate, and round-trip through serialise
  - TestEmptyDocumentVariants: <r/> and <r></r> parse; XML
    declaration alone, whitespace-only, and empty string do not
  - TestXPathOnDocWithoutRoot: Xml2Doc.create() with no root
    element accepts XPath evaluation without crashing
  - TestLoadDtdFlagsAcceptValidInput: load_dtd + load_dtd_attrs
    options on a doc with internal DTD subset parse cleanly and
    preserve the DOCTYPE through serialise (DTD-default-attribute
    application behaviour is libxml2-version-specific and is
    intentionally not asserted)
  - TestPedanticAcceptsValidInput: pedantic = true does not
    reject standards-compliant XML (regression guard)

Path / namespace
  - TestDeepXPathExpression: 20-level-deep tree built one
    appendChild at a time; absolute path and descendant-axis
    queries both find the deepest node
  - TestXmlSpaceAttributePreserved: xml:space attribute is in the
    implicit XML namespace and is readable via
    getPropNs(XML_NS, "space"); also survives serialise
  - TestNamespacePrefixShadowing: a nested xmlns:x declaration
    shadows the outer binding for that subtree;
    namespaceUri() reports the in-scope URI at each level while
    namespacePrefix() consistently returns the source-level prefix

Error paths
  - TestFromPTRRejectsNull: Xml2Node.fromPTR with a None pointer
    raises rather than silently producing a wrapper around null

Property-based budget changes
  - PropSetGetPropRoundTrip:        100 -> 500 samples
  - PropAppendChildPreservesCount:  100 -> 500 samples, max 200
  - PropStructuralRoundTripStable:  100 -> 500 samples, max len 32
  - PropGetPropsCardinality:        100 -> 500 samples, max 200
  - PropSetUnsetIsEmpty:            100 -> 500 samples

All 102 tests pass; stability confirmed across 3 consecutive runs
(each running 5 property tests x 500 samples = 2500 property
iterations per run on top of the unit tests).

No release note: test-only change.
15 new tests + tightens the existing TestNodeUtilityMethods
getLineNo tautology assertion that the earlier review flagged as
counterfactually meaningless.

Primitive identity sweeps (3)
  - TestAllXml2ErrorDomainPrimitives: every documented
    xmlErrorDomain integer (0-30) plus out-of-range maps to the
    expected Xml2ErrorDomain* primitive; every primitive's
    string() returns the documented short name. Catches any drift
    between libxml2's enum ordering and the Pony mapping table.
  - TestAllXml2ErrorLevelPrimitives: same shape for the 4
    documented levels plus Unknown.
  - TestAllXPathTypePrimitives: each XPathType* primitive's
    apply() returns the corresponding xmlXPathObjectType integer.

Edge cases on creation and content (7)
  - TestCreateTextNodeEntityChars: text nodes containing <, >, &,
    quotes are escaped in the serialised output and decode back
    to the original on re-parse.
  - TestCreateCommentEdgeCases: empty, single-space, and unicode
    comments serialise + re-parse cleanly.
  - TestSetPropEmptyValue: attribute with explicit empty value is
    distinct from absent attribute (getProps lists it).
  - TestGetContentMixedChildren: getContent on a mixed-content
    element returns concatenated descendant text; getChildren
    filters to element nodes.
  - TestAddChildWithContent: Xml2Node.addChild(name, content) and
    addChild(name) (default empty content) both work and produce
    the right children.
  - TestCommentsFilteredFromGetChildren: getChildren skips
    comment nodes; XPath count(/*) and count(comment()) agree
    with the Pony-side filter.
  - TestSerializeUnsupportedEncoding: serialize with an unknown
    encoding either succeeds or raises - it does not crash
    (regression guard for the "safe from crashes" promise).

Error-path field assertions (3)
  - TestXPathErrorFields: malformed XPath produces an Xml2Error
    with domain=XPath, non-zero code, non-empty message.
  - TestParseFileMissingFile: parseFile on a non-existent path
    returns an Xml2Error with domain=Io.
  - TestParseErrorFieldsAreAccessible: after a parse error,
    every Xml2Error field (str1/2/3 and int1/2 included) is
    readable without raising or crashing. Structural-access
    guarantee rather than value assertion, since libxml2 only
    populates some of these per error class.

Property-based (2)
  - PropElementNameRoundTrip: for any ASCII-letter name,
    createElement(name) then getRootElement().name() returns the
    input. 500 samples.
  - PropMultiplePropsAllRetrievable: for N (name, value) pairs
    with unique names, every pair is retrievable via getProp
    and getProps cardinality is N. 500 samples.

Existing test tightened
  - TestNodeUtilityMethods's getLineNo block previously asserted
    `true == true` (called out as counterfactually weak in an
    earlier review). Replaced with a documented-range assertion:
    libxml2 returns -1 when line tracking is unavailable,
    otherwise a non-negative line number; both are acceptable
    but anything else (NaN-equivalent, very negative) would fail.

All 117 tests pass; stability confirmed across 3 consecutive runs.

No release note: test-only change.
@redvers redvers force-pushed the test/extensive-api branch from 8b5359b to 722f80e Compare May 22, 2026 11:16
@redvers redvers merged commit 6e6b8a4 into main May 22, 2026
6 checks passed
@redvers redvers deleted the test/extensive-api branch May 22, 2026 11:38
@redvers redvers restored the test/extensive-api branch May 22, 2026 12:03
@redvers redvers deleted the test/extensive-api branch May 22, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant