Ejemplo n.º 1
0
    def test_decimals_and_precision(self):
        # if we set a fact and pass in a Decimals argument,
        # then when we write out to JSON or XML we should see decimals there.
        # Same with Precision.
        # Trying to set both Decimals and Precision should give an error.
        # If we don't set either, it should default to decimals=2.

        doc = OBInstance("CutSheet", self.taxonomy)
        now = datetime.now()
        doc.set_default_context({
            "entity": "JUPITER",
            "solar:TestConditionAxis": "solar:StandardTestConditionMember",
            PeriodType.instant: now,
            PeriodType.duration: "forever"
        })

        # Set fact with precision:
        doc.set("solar:ModuleNameplateCapacity",
                "6.25",
                unit_name="W",
                ProductIdentifierAxis=1,
                precision=3)

        jsonstring = doc.to_JSON_string()
        facts = json.loads(jsonstring)["facts"]

        # TODO is supposed to be in aspects or not?
        self.assertEqual(len(facts), 1)
        self.assertEqual(list(facts.values())[0]["aspects"]["precision"], "3")

        # Set fact with decimals:
        doc.set("solar:ModuleNameplateCapacity",
                "6.25",
                unit_name="W",
                ProductIdentifierAxis=1,
                decimals=3)
        jsonstring = doc.to_JSON_string()
        facts = json.loads(jsonstring)["facts"]
        self.assertEqual(len(facts), 1)
        self.assertEqual(list(facts.values())[0]["aspects"]["decimals"], "3")

        # Trying to set both decimals and precision should raise an error
        with self.assertRaises(OBException):
            doc.set("solar:ModuleNameplateCapacity",
                    "6.25",
                    unit_name="W",
                    ProductIdentifierAxis=1,
                    decimals=3,
                    precision=3)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    def test_json_fields_are_strings(self):
        # Issue #77 - all json fields should be strings other than None which should convert
        # a JSON null literal.
        # e.g. numbers should be "100" not 100
        # booleans should be "true" not true

        doc = OBInstance("System", self.taxonomy, dev_validation_off=True)
        now = datetime.now()
        doc.set_default_context({
            "entity": "JUPITER",
            "solar:InverterPowerLevelPercentAxis":
            "solar:InverterPowerLevel100PercentMember",
            PeriodType.instant: now,
            PeriodType.duration: "forever"
        })

        # Set fact using a numeric type as value:
        doc.set("solar:InverterOutputRatedPowerAC",
                1.25,
                unit_name="kW",
                ProductIdentifierAxis=1)

        # Set fact using a boolean type as value:
        doc.set("solar:ModuleHasCertificationIEC61646",
                True,
                ProductIdentifierAxis=1)

        jsonstring = doc.to_JSON_string()
        facts = json.loads(jsonstring)["facts"]

        self.assertEqual(len(facts), 2)

        for fact in list(facts.values()):
            self.assertTrue(isinstance(fact['value'], string_types))
            self.assertTrue(
                isinstance(fact['aspects']['solar:ProductIdentifierAxis'],
                           string_types))
Ejemplo n.º 4
0
    def test_conversion_to_json(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")
        jsonstring = doc.to_JSON_string()

        root = json.loads(jsonstring)

        # should have 2 facts:
        all_facts = list(root["facts"].values())
        self.assertEqual(len(all_facts), 2)

        # each should have expected 'value' and 'aspects':
        typeFacts = [
            x for x in all_facts
            if x['aspects']['concept'] == 'solar:TypeOfDevice'
        ]
        self.assertEqual(len(typeFacts), 1)
        typeFact = typeFacts[0]
        self.assertEqual(typeFact['value'], "ModuleMember")
        self.assertEqual(typeFact['aspects']['solar:ProductIdentifierAxis'],
                         'placeholder')
        self.assertEqual(typeFact['aspects']['solar:TestConditionAxis'],
                         "solar:StandardTestConditionMember")
        self.assertEqual(typeFact['aspects']['entity'], 'JUPITER')
        # period = Forever means we don't write a period aspect:
        self.assertNotIn("period", typeFact['aspects'])
        # TODO if there's no unit is it correct to write 'xbrl:unit':'None' or to leave out
        # xbrl:unit?  Currently assuming we leave it out:
        self.assertNotIn("unit", typeFact["aspects"])

        costFacts = [
            x for x in all_facts
            if x['aspects']['concept'] == 'solar:DeviceCost'
        ]
        self.assertEqual(len(costFacts), 1)

        costFact = costFacts[0]
        self.assertEqual(costFact['value'], '100')
        self.assertEqual(costFact['aspects']['solar:ProductIdentifierAxis'],
                         'placeholder')
        self.assertEqual(costFact['aspects']['solar:TestConditionAxis'],
                         "solar:StandardTestConditionMember")
        self.assertEqual(costFact['aspects']['entity'], 'JUPITER')
        self.assertEqual(costFact['aspects']['period'],
                         now.strftime("%Y-%m-%dT%H:%M:%S"))
        self.assertEqual(costFact['aspects']['unit'], 'USD')