Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ Both are optional: EDGAR works unattributed under the default, saying so once.
And filings.xbrl.org, local packages and TAVI/holon JSON need no identity at all.

Then load filings from the chat — a ticker, an EDGAR `cik:accession`, a
`lei:`, a local package, or a holon or TAVI by path or URL — and ask for
`lei:`, a local package, or a holon or TAVI by path or URL; a ticker or `cik:accession` loads the filing's
published holon first when the RoboSystems CDN has one, falling back to
EDGAR — and ask for
statements, facts by concept and period, calculations, exhibits and text.
No graph and no database sits behind any of it: every answer about a filing is
read from that filing. The one outward call is `search_filings`, which asks
Expand Down
14 changes: 14 additions & 0 deletions tests/test_deserialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ def _model() -> XbrlModel:
from_qname="us-gaap:SegmentDomain",
to_qname="us-gaap:NorthAmerica",
arcrole=f"{DIM}/domain-member",
# The members continue in another role: a cube rebuilt without
# following this loses them.
target_role="http://example.com/role/SegmentMembers",
),
],
),
Expand Down Expand Up @@ -723,6 +726,17 @@ def test_tavi_gaps_are_declared(model: XbrlModel) -> None:
assert gaps.unmapped_label_types == {}


def test_holon_keeps_the_target_role(model: XbrlModel) -> None:
"""``xbrldt:targetRole`` rides on the association: the role the next hop of
a hypercube's wiring continues in, without which a cube declared across
roles reads as one role's arcs."""
got = from_holon_json(to_holon(model))
definition = next(n for n in got.networks if n.kind == "definition")
by_target = {a.to_qname: a.target_role for a in definition.arcs}
assert by_target["us-gaap:NorthAmerica"] == "http://example.com/role/SegmentMembers"
assert by_target["us-gaap:SegmentTable"] is None


def test_holon_gaps_are_declared(model: XbrlModel) -> None:
got, gaps = from_holon_report(to_holon(model))
reported = " ".join(gaps.missing)
Expand Down
23 changes: 23 additions & 0 deletions tests/test_lpg.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,29 @@ def test_structures_and_associations(self, model):
{"from": structure["identifier"], "to": tables.nodes["Taxonomy"][0]["identifier"]}
]

def test_calculations_1_1_arcs_are_calculation_associations(self, model):
"""The 2023 summation-item arcrole is the calculation linkbase too, and
keeps its weight."""
model.networks[1].arcs[0].arcrole = "https://xbrl.org/2023/arcrole/summation-item"
tables = to_graph_tables(model)
calculation = next(
a for a in tables.nodes["Association"] if a["association_type"] == "Calculation"
)
assert calculation["arcrole"] == "https://xbrl.org/2023/arcrole/summation-item"
assert calculation["weight"] == 1.0

def test_a_type_without_a_qname_keeps_its_namespace(self, model):
"""A concept read back from a serialization may carry a type's namespace
and local name but no QName for a prefix the filing never bound; the
projection writes the type from what it has rather than dropping it."""
concept = model.concepts["us-gaap:Assets"]
concept.item_type = "monetaryItemType"
concept.item_type_qname = None
concept.item_type_namespace = "http://www.xbrl.org/2003/instance"
tables = to_graph_tables(model)
assets = next(e for e in tables.nodes["Element"] if e["qname"] == "us-gaap:Assets")
assert assets["item_type"] == "http://www.xbrl.org/2003/instance#monetaryItemType"

def test_projection_is_deterministic(self, model):
first = to_graph_tables(model)
second = to_graph_tables(model)
Expand Down
18 changes: 18 additions & 0 deletions tests/test_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from xbrlkit.parse import ids
from xbrlkit.parse.to_model import (
_classify_arcrole,
_make_period,
_make_unit,
_measure_token,
Expand Down Expand Up @@ -250,3 +251,20 @@ def test_sec_ixt_transforms_register():
register_sec_transforms()
assert FunctionIxt.ixtNamespaceFunctions[SEC_IXT_NAMESPACE] is not None
assert len(FunctionIxt.ixtNamespaceFunctions[SEC_IXT_NAMESPACE]) == len(registry)


def test_calculations_1_1_is_the_calculation_linkbase():
"""Calculations 1.1 declares the same roll-ups under the 2023 arcrole; a
filer that adopted it must not come back with no calculation network."""
assert (
_classify_arcrole("http://www.xbrl.org/2003/arcrole/summation-item")
== "calculation"
)
assert (
_classify_arcrole("https://xbrl.org/2023/arcrole/summation-item") == "calculation"
)
assert (
_classify_arcrole("http://www.xbrl.org/2003/arcrole/parent-child") == "presentation"
)
assert _classify_arcrole("http://xbrl.org/int/dim/arcrole/all") == "definition"
assert _classify_arcrole("http://www.xbrl.org/2003/arcrole/concept-label") is None
Loading