def test_optional_namespaces_included(self): # If no us-gaap concepts are used, there should be no us-gaap namespace # definition in header: doc = OBInstance("MonthlyOperatingReport", self.taxonomy) doc.set("solar:MonthlyOperatingReportEffectiveDate", date(year=2018, month=6, day=1), entity="JUPITER", duration="forever") xml = doc.to_XML_string() root = etree.fromstring(xml) self.assertIn("solar", root.nsmap) self.assertIn("xlink", root.nsmap) self.assertIn("units", root.nsmap) self.assertNotIn("us-gaap", root.nsmap) # If a us-gaap concept has been set, however, there should be a us-gaap # namespace definition in header: doc.set("us-gaap:PartnersCapitalAccountReturnOfCapital", 4, unit_name="USD", entity="JUPITER", duration="forever", InvestmentClassAxis="placeholder", ProjectIdentifierAxis="1", CashDistributionAxis="placeholder") xml = doc.to_XML_string() root = etree.fromstring(xml) self.assertIn("solar", root.nsmap) self.assertIn("xlink", root.nsmap) self.assertIn("units", root.nsmap) self.assertIn("us-gaap", root.nsmap)
def test_ids_in_xml_and_json(self): # facts should have IDs in both exported JSON and exported XML, and they # should be the same ID either way. doc = OBInstance("CutSheet", self.taxonomy) now = datetime.now() doc.set_default_context({ "entity": "JUPITER", "solar:TestConditionAxis": "solar:StandardTestConditionMember", PeriodType.instant: now, PeriodType.duration: "forever" }) doc.set("solar:ModuleNameplateCapacity", "6.25", unit_name="W", ProductIdentifierAxis=1) fact = doc.get( "solar:ModuleNameplateCapacity", Context(ProductIdentifierAxis=1, TestConditionAxis="solar:StandardTestConditionMember", entity="JUPITER", duration="forever")) # Read the fact ID that was automatically assigned when we set the fact: fact_id = fact.id # Look for fact ID in JSON: jsonstring = doc.to_JSON_string() facts = json.loads(jsonstring)["facts"] self.assertEqual(len(list(facts.keys())), 1) self.assertEqual(list(facts.keys())[0], fact_id) # Look for fact ID in XML: xml = doc.to_XML_string() root = etree.fromstring(xml) fact = root.find( "{http://xbrl.us/Solar/v1.2/2018-03-31/solar}ModuleNameplateCapacity" ) self.assertEqual(fact.attrib["id"], fact_id)
def test_conversion_to_xml(self): doc = OBInstance("CutSheet", self.taxonomy) doc.set("solar:TypeOfDevice", "ModuleMember", entity="JUPITER", duration="forever", ProductIdentifierAxis="placeholder", TestConditionAxis="solar:StandardTestConditionMember") now = datetime.now() doc.set("solar:DeviceCost", 100, entity="JUPITER", instant=now, ProductIdentifierAxis="placeholder", TestConditionAxis="solar:StandardTestConditionMember", unit_name="USD") xml = doc.to_XML_string() root = etree.fromstring(xml) self.assertEqual(len(root.getchildren()), 6) # top-level xml should have child <link:schemaRef>, one <unit>, two <context>s and two <fact>s. schemaRef = root.getchildren()[0] self.assertEqual(schemaRef.tag, "{http://www.xbrl.org/2003/linkbase}schemaRef") # expect to see 2 contexts with id "solar:CutSheetDetailsTable_0" and "solar:CutSheetDetailsTable_1" contexts = root.findall('{http://www.xbrl.org/2003/instance}context') self.assertEqual(len(contexts), 2) for context in contexts: # both should have entity tag containing identifier containing text JUPITER self.assertTrue( context.attrib["id"] == 'solar:CutSheetDetailsTable_0' or \ context.attrib["id"] == 'solar:CutSheetDetailsTable_1' ) entity = context.find("{http://www.xbrl.org/2003/instance}entity") identifier = entity.find( "{http://www.xbrl.org/2003/instance}identifier") self.assertEqual(identifier.text, "JUPITER") # both should have segment containing xbrldi:explicitMember dimension="<axis name>" # containing text "placeholder" # (wait i have segment inside of entity? is that correct?) segment = entity.find("{http://www.xbrl.org/2003/instance}segment") axes = segment.findall("{http://xbrl.org/2006/xbrldi}typedMember") axis_names = [x.attrib["dimension"] for x in axes] self._check_arrays_equivalent( axis_names, ['solar:ProductIdentifierAxis', 'solar:TestConditionAxis']) for axis in axes: if axis.attrib["dimension"] == 'solar:ProductIdentifierAxis': self.assertEqual( axis.getchildren()[0].tag, "{http://xbrl.us/Solar/v1.2/2018-03-31/solar}ProductIdentifierDomain" ) self.assertEqual(axis.getchildren()[0].text, "placeholder") elif axis.attrib["dimension"] == 'solar:TestConditionsAxis': self.assertEqual( axis.getchildren()[0].tag, "{http://xbrl.us/Solar/v1.2/2018-03-31/solar}TestConditionDomain" ) self.assertEqual(axis.getchildren()[0].text, "solar:StandardTestConditionMember") # one should have period containing <forever/> other should have period containing <instant> containing today's date. period = context.find("{http://www.xbrl.org/2003/instance}period") tag = period.getchildren()[0].tag self.assertTrue(tag == "{http://www.xbrl.org/2003/instance}instant" or\ tag == "{http://www.xbrl.org/2003/instance}forever") # Expect one unit tag with id=USD containing <measure>units:USD</measure> unit_tag = root.findall("{http://www.xbrl.org/2003/instance}unit") self.assertEqual(len(unit_tag), 1) self.assertEqual(unit_tag[0].attrib["id"], "USD") self.assertEqual(unit_tag[0].getchildren()[0].text, "units:USD") # Expect to see two facts solar:DeviceCost and solar:TypeOfDevice, # each containing text of the fact value costFact = root.find( '{http://xbrl.us/Solar/v1.2/2018-03-31/solar}DeviceCost') typeFact = root.find( '{http://xbrl.us/Solar/v1.2/2018-03-31/solar}TypeOfDevice') self.assertEqual(costFact.text, "100") self.assertEqual(typeFact.text, "ModuleMember") # They should have contextRef and (in the case of cost) unitRef attributes: self.assertEqual(typeFact.attrib['contextRef'], "solar:CutSheetDetailsTable_0") self.assertEqual(costFact.attrib['unitRef'], "USD") self.assertEqual(costFact.attrib['contextRef'], "solar:CutSheetDetailsTable_1")