def test_full_round_trip():
    """
    This test makes sure that it can read a full record,
    save it as JSON, and then read it back again
    """
    record = ExxonDataReader.read_excel_file(
        example_dir / "Crude_Oil_HOOPS_Blend_assay_xls.xlsx")

    assert record[0][0] == "ExxonMobil"

    oil = ExxonMapper(('HOOPS Blend Example', record))

    assert oil.metadata.name == 'HOOPS Blend Example'

    print(oil.oil_id)

    filename = example_dir / "ExampleOutput.json"
    oil.to_file(filename)

    oil2 = Oil.from_file(filename)

    for bc2, bc in zip(oil2.sub_samples[0].bulk_composition,
                       oil.sub_samples[0].bulk_composition):
        assert bc2 == bc
    assert oil2.sub_samples[0].bulk_composition == oil.sub_samples[
        0].bulk_composition
    assert oil2.sub_samples[0].industry_properties == oil.sub_samples[
        0].industry_properties
    assert oil2 == oil
    def test_industry_properties_units(self, prop, unit, unit_type):
        """
        Data points that are classified in industry properties:
        - Total Acid Number (Neutralization Number)
        - Reid Vapor Pressure

        - Aniline Point
        - Cetane Index
        - Vanadium
        - Cloud Point
        - Smoke Point
        - Conradson Carbon Residue
        - Conradson Residuum (Vacuum Residue)
        - Gel Point (Freeze Point)
        """
        # just check the zeroth one:

        print("testing:", prop)

        for sample in ExxonMapper(self.record).sub_samples:
            print(sample.industry_properties)
            for p in sample.industry_properties:
                print(f"\n{p.name=}")
                print(f"{prop=}")
                if p.name == prop:
                    measurement = p.measurement
                    print("checking units of:", prop)
                    assert measurement.unit == unit
                    assert measurement.unit_type == unit_type
                    return
                continue
        assert False
    def test_save_to_json(self):
        """
        Save an example .json file.  This is not so much a test, but a job
        to provide sample data that people can look at.
        """
        mapper = ExxonMapper(self.record)
        py_json = mapper.py_json()

        py_json['status'] = []

        filename = 'EX-Example-Record.json'
        file_path = os.path.sep.join(
            adios_db.__file__.split(os.path.sep)[:-3] + ['examples', filename])

        print(f'saving to: {file_path}')
        with open(file_path, 'w', encoding="utf-8") as fd:
            json.dump(py_json, fd, indent=4, sort_keys=True)
    def test_dist_cuts(self, samp_ind, cut_index, fraction, temp_f):
        samples = ExxonMapper(self.record).sub_samples

        cut = samples[samp_ind].distillation_data.cuts[cut_index]

        assert cut.fraction.value == fraction
        assert isclose(cut.vapor_temp.value,
                       sigfigs(uc.convert("F", "C", temp_f), 5),
                       rel_tol=1e-4)
    def test_dist_end_point(self, sample_idx, expected):
        samples = ExxonMapper(self.record).sub_samples

        if expected is None:
            assert samples[sample_idx].distillation_data.end_point is None
        else:
            expected_c = sigfigs(uc.convert("F", "C", expected), 5)
            end_point = samples[sample_idx].distillation_data.end_point

            assert isclose(end_point.value, expected_c, rel_tol=1e-4)
            assert end_point.unit == 'C'
    def test_kinematic_viscosities(self, sample_idx, viscosity_idx, expected):
        samples = ExxonMapper(self.record).sub_samples
        sample = samples[sample_idx]
        phys = sample.physical_properties
        viscosity = phys.kinematic_viscosities[viscosity_idx]

        # viscosity tests
        # whole oil
        assert viscosity.viscosity.value == expected
        assert viscosity.viscosity.unit == "cSt"

        for sample in samples:
            assert len(sample.physical_properties.dynamic_viscosities) == 0
    def test_bulk_composition(self, attr, indexes, values):
        """
        Data points that are classified in bulk composition:
        - Sulphur
        - Naphthenes
        - Paraffins
        - Nickel
        - Vanadium
        - Carbon
        - Hydrogen
        - Mercaptan Sulfur
        - Nitrogen
        - Calcium
        - Hydrogen Sulfide
        - Salt content

        Notes:
        - These values are now kept in a list of compounds held by the
          bulk_composition attribute
        - Ideally, the name & groups of each compound would have the
          original field text from the datasheet.  This is not the case
          at present.
        """
        samples = ExxonMapper(self.record).sub_samples

        for i, val in zip(indexes, values):
            filter_list = [
                c for c in samples[i].bulk_composition if c.name == attr
            ]

            if val is None:
                assert len(filter_list) == 0
            else:
                assert len(filter_list) == 1

                compound = filter_list[0]

                assert isclose(compound.measurement.value,
                               values[i],
                               rel_tol=1e-4)
    def test_sara(self, attr, indexes, values):
        """
        Test the sara attributes:
        - Aromatics
        - Asphaltenes

        Note: saturates and resins are not found in the Exxon Assays
        Note: We have decided that instead of C7 asphaltenes & aromatics
              going into SARA, we will put them into the bulk_composition
              list.
        """
        samples = ExxonMapper(self.record).sub_samples

        for i, val in zip(indexes, values):
            sara = samples[i].SARA

            if val is None:
                assert getattr(sara, attr) is None
            else:
                sara_attr = getattr(sara, attr)

                assert isclose(sara_attr.value, values[i], rel_tol=1e-4)
    def test_industry_properties(self, attr, indexes, values):
        """
        Data points that are classified in industry properties:
        - Total Acid Number (Neutralization Number)
        - Reid Vapor Pressure

        - Aniline Point
        - Cetane Index
        - Vanadium
        - Cloud Point
        - Smoke Point
        - Conradson Carbon Residue
        - Conradson Residuum (Vacuum Residue)
        - Gel Point (Freeze Point)

        Notes:
        - These values are kept in a list of attributes held by the
          industry_properties attribute
        - Ideally, the name & groups of each compound would have the
          original field text from the datasheet.  This is not the case
          at present.
        """
        samples = ExxonMapper(self.record).sub_samples

        for i, val in zip(indexes, values):
            filter_list = [
                c for c in samples[i].industry_properties if c.name == attr
            ]
            if val is None:
                assert len(filter_list) == 0
            else:
                assert len(filter_list) == 1

                compound = filter_list[0]

                assert isclose(compound.measurement.value,
                               values[i],
                               rel_tol=1e-4)
    def test_header(self):
        oil = ExxonMapper(self.record)

        assert oil.metadata.name == 'HOOPS Blend'
        assert oil.metadata.reference.reference.startswith("ExxonMobil")
        assert oil.metadata.API == 35.2
 def test_init(self):
     with pytest.raises(TypeError):
         _mapper = ExxonMapper()
    def test_sample_ids(self, index, expected):
        samples = ExxonMapper(self.record).sub_samples

        assert len(samples) == 8
        assert samples[index].metadata.name == expected['name']
        assert samples[index].metadata.short_name == expected['short_name']
 def test_no_cuts_in_butane(self):
     assert (ExxonMapper(
         self.record).sub_samples[1].distillation_data.cuts == [])
 def test_dist_type(self):
     for sample in ExxonMapper(self.record).sub_samples:
         assert sample.distillation_data.type == 'volume fraction'
    def test_boiling_point_range(self, index, expected):
        samples = ExxonMapper(self.record).sub_samples

        assert len(samples) == 8
        assert samples[index].metadata.boiling_point_range == expected
 def test_dist_cuts_units(self):
     for sample in ExxonMapper(self.record).sub_samples:
         for cut in sample.distillation_data.cuts:
             assert cut.vapor_temp.unit == "C"
             assert cut.fraction.unit == "%"
    def test_cut_volume(self, index, expected):
        samples = ExxonMapper(self.record).sub_samples

        assert samples[index].cut_volume == expected
    def test_densities(self, sample_idx, density_idx, expected):
        samples = ExxonMapper(self.record).sub_samples
        sample = samples[sample_idx]
        density = sample.physical_properties.densities[density_idx]

        assert isclose(density.density.value, expected, rel_tol=1e-3)
 def test_init_invalid(self):
     with pytest.raises(TypeError):
         _mapper = ExxonMapper(None)
    def test_dynamic_viscosities(self):
        samples = ExxonMapper(self.record).sub_samples

        for sample in samples:
            # no dynamic viscosities in the Exxon Assays
            assert len(sample.physical_properties.dynamic_viscosities) == 0