diff --git a/tests/unit/test_database_events.py b/tests/unit/test_database_events.py index f94de8e..9ae991b 100644 --- a/tests/unit/test_database_events.py +++ b/tests/unit/test_database_events.py @@ -1,8 +1,3 @@ -# Test database copy (create and then write) -# Test database rename (metadata, write, delete) -# Test no signal on `write` with unsourced database - - import json from bw2data import databases, get_node @@ -567,11 +562,10 @@ def test_database_write_revision_expected_format(): { "type": "lci_edge", "id": ExchangeDataset.get( - ExchangeDataset.input_code - == "2", ExchangeDataset.output_code - == "1", ExchangeDataset.input_database - == "food", ExchangeDataset.output_database - == "food" + ExchangeDataset.input_code == "2", + ExchangeDataset.output_code == "1", + ExchangeDataset.input_database == "food", + ExchangeDataset.output_database == "food", ).id, "change_type": "create", "delta": { @@ -600,11 +594,10 @@ def test_database_write_revision_expected_format(): { "type": "lci_edge", "id": ExchangeDataset.get( - ExchangeDataset.input_code - == "1", ExchangeDataset.output_code - == "1", ExchangeDataset.input_database - == "biosphere", ExchangeDataset.output_database - == "food" + ExchangeDataset.input_code == "1", + ExchangeDataset.output_code == "1", + ExchangeDataset.input_database == "biosphere", + ExchangeDataset.output_database == "food", ).id, "change_type": "create", "delta": { @@ -633,11 +626,10 @@ def test_database_write_revision_expected_format(): { "type": "lci_edge", "id": ExchangeDataset.get( - ExchangeDataset.input_code - == "1", ExchangeDataset.output_code - == "2", ExchangeDataset.input_database - == "food", ExchangeDataset.output_database - == "food" + ExchangeDataset.input_code == "1", + ExchangeDataset.output_code == "2", + ExchangeDataset.input_database == "food", + ExchangeDataset.output_database == "food", ).id, "change_type": "create", "delta": { @@ -666,11 +658,10 @@ def test_database_write_revision_expected_format(): { "type": "lci_edge", "id": ExchangeDataset.get( - ExchangeDataset.input_code - == "2", ExchangeDataset.output_code - == "2", ExchangeDataset.input_database - == "biosphere", ExchangeDataset.output_database - == "food" + ExchangeDataset.input_code == "2", + ExchangeDataset.output_code == "2", + ExchangeDataset.input_database == "biosphere", + ExchangeDataset.output_database == "food", ).id, "change_type": "create", "delta": { @@ -965,22 +956,628 @@ def test_database_write_revision_apply(num_revisions): assert "food" in databases node = get_node(code="1", database="food") - assert node['categories'] == ["stuff", "meals"] - assert node['location'] == "CA" + assert node["categories"] == ["stuff", "meals"] + assert node["location"] == "CA" assert len(node.exchanges()) == 2 for exc in node.technosphere(): - assert exc['amount'] == 0.5 - assert exc.input['code'] == "2" + assert exc["amount"] == 0.5 + assert exc.input["code"] == "2" assert not exc["uncertainty type"] node = get_node(code="2", database="food") - assert node['categories'] == ["stuff", "meals"] - assert node['location'] == "CH" + assert node["categories"] == ["stuff", "meals"] + assert node["location"] == "CH" assert len(node.exchanges()) == 2 for exc in node.biosphere(): - assert exc['amount'] == 0.15 - assert exc.input['code'] == "2" + assert exc["amount"] == 0.15 + assert exc.input["code"] == "2" assert not exc["uncertainty type"] assert len(DatabaseChooser("food")) == 2 assert ExchangeDataset.select().where(ExchangeDataset.output_database == "food").count() == 4 + + +@bw2test +def test_database_write_unsourced_project(num_revisions): + projects.set_current("activity-event") + DatabaseChooser("biosphere").write(basic.biosphere) + DatabaseChooser("food").write(basic.food) + + assert projects.dataset.revision is None + assert not num_revisions(projects) + + +@bw2test +def test_database_copy_revision_expected_format(): + projects.set_current("activity-event") + DatabaseChooser("biosphere").write(basic.biosphere) + DatabaseChooser("food").write(basic.food) + + projects.dataset.set_sourced() + assert projects.dataset.revision is None + + DatabaseChooser("food").copy("yum") + + assert projects.dataset.revision is not None + revisions = sorted( + [ + (int(fp.stem), json.load(open(fp))) + for fp in sorted((projects.dataset.dir / "revisions").iterdir()) + if fp.is_file() + if fp.stem.lower() != "head" + ] + ) + + expected = [ + { + "metadata": { + "parent_revision": None, + "revision": revisions[0][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_database", + "id": None, + "change_type": "database_metadata_change", + "delta": { + "dictionary_item_added": { + "root['yum']": { + "depends": ["biosphere"], + "backend": "sqlite", + "geocollections": ["world"], + "searchable": True, + "format": "Copied from 'food'", + } + } + }, + } + ], + }, + { + "metadata": { + "parent_revision": revisions[0][0], + "revision": revisions[1][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_database", + "id": None, + "change_type": "database_metadata_change", + "delta": { + "iterable_item_removed": { + "root['yum']['depends'][0]": "biosphere", + "root['yum']['geocollections'][0]": "world", + } + }, + } + ], + }, + { + "metadata": { + "parent_revision": revisions[1][0], + "revision": revisions[2][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_database", + "id": "yum", + "change_type": "database_reset", + "delta": {}, + } + ], + }, + { + "metadata": { + "parent_revision": revisions[2][0], + "revision": revisions[3][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_database", + "id": None, + "change_type": "database_metadata_change", + "delta": {"iterable_item_added": {"root['yum']['geocollections'][0]": "world"}}, + } + ], + }, + { + "metadata": { + "parent_revision": revisions[3][0], + "revision": revisions[4][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_database", + "id": None, + "change_type": "database_metadata_change", + "delta": {"iterable_item_added": {"root['yum']['depends'][0]": "biosphere"}}, + } + ], + }, + { + "metadata": { + "parent_revision": revisions[4][0], + "revision": revisions[5][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_node", + "id": get_node(code="2", database="yum").id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "categories": ["stuff", "meals"], + "code": "2", + "location": "CH", + "name": "dinner", + "type": "processwithreferenceproduct", + "unit": "kg", + "database": "yum", + }, + } + } + }, + }, + { + "type": "lci_node", + "id": get_node(code="1", database="yum").id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "categories": ["stuff", "meals"], + "code": "1", + "location": "CA", + "name": "lunch", + "type": "processwithreferenceproduct", + "unit": "kg", + "database": "yum", + }, + } + } + }, + }, + { + "type": "lci_edge", + "id": ExchangeDataset.get( + ExchangeDataset.input_code == "1", + ExchangeDataset.output_code == "2", + ExchangeDataset.input_database == "yum", + ExchangeDataset.output_database == "yum", + ).id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "data": { + "amount": 0.25, + "input": ["yum", "1"], + "type": "technosphere", + "uncertainty type": 0, + "output": ["yum", "2"], + }, + "input_database": "yum", + "input_code": "1", + "output_database": "yum", + "output_code": "2", + "type": "technosphere", + }, + } + } + }, + }, + { + "type": "lci_edge", + "id": ExchangeDataset.get( + ExchangeDataset.input_code == "2", + ExchangeDataset.output_code == "2", + ExchangeDataset.input_database == "biosphere", + ExchangeDataset.output_database == "yum", + ).id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "data": { + "amount": 0.15, + "input": ["biosphere", "2"], + "type": "biosphere", + "uncertainty type": 0, + "output": ["yum", "2"], + }, + "input_database": "biosphere", + "input_code": "2", + "output_database": "yum", + "output_code": "2", + "type": "biosphere", + }, + } + } + }, + }, + { + "type": "lci_edge", + "id": ExchangeDataset.get( + ExchangeDataset.input_code == "2", + ExchangeDataset.output_code == "1", + ExchangeDataset.input_database == "yum", + ExchangeDataset.output_database == "yum", + ).id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "data": { + "amount": 0.5, + "input": ["yum", "2"], + "type": "technosphere", + "uncertainty type": 0, + "output": ["yum", "1"], + }, + "input_database": "yum", + "input_code": "2", + "output_database": "yum", + "output_code": "1", + "type": "technosphere", + }, + } + } + }, + }, + { + "type": "lci_edge", + "id": ExchangeDataset.get( + ExchangeDataset.input_code == "1", + ExchangeDataset.output_code == "1", + ExchangeDataset.input_database == "biosphere", + ExchangeDataset.output_database == "yum", + ).id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "data": { + "amount": 0.05, + "input": ["biosphere", "1"], + "type": "biosphere", + "uncertainty type": 0, + "output": ["yum", "1"], + }, + "input_database": "biosphere", + "input_code": "1", + "output_database": "yum", + "output_code": "1", + "type": "biosphere", + }, + } + } + }, + }, + ], + }, + ] + + assert [x[1] for x in revisions] == expected + assert projects.dataset.revision == revisions[5][0] + + assert [x[1] for x in revisions][:-1] == expected[:-1] + assert revisions[-1][1]['metadata'] == expected[-1]['metadata'] + for x in range(2): + assert revisions[-1][1]['data'][x] in expected[-1]['data'][:2] + for x in range(2, 5): + assert revisions[-1][1]['data'][x] in expected[-1]['data'][2:] + assert projects.dataset.revision == revisions[5][0] + + +@bw2test +def test_database_rename_revision_expected_format(): + projects.set_current("activity-event") + DatabaseChooser("biosphere").write(basic.biosphere) + DatabaseChooser("food").write(basic.food) + + projects.dataset.set_sourced() + assert projects.dataset.revision is None + + DatabaseChooser("food").rename("yum") + + assert projects.dataset.revision is not None + revisions = sorted( + [ + (int(fp.stem), json.load(open(fp))) + for fp in sorted((projects.dataset.dir / "revisions").iterdir()) + if fp.is_file() + if fp.stem.lower() != "head" + ] + ) + + expected = [ + { + "metadata": { + "parent_revision": None, + "revision": revisions[0][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_database", + "id": None, + "change_type": "database_metadata_change", + "delta": { + "dictionary_item_added": { + "root['yum']": { + "depends": ["biosphere"], + "backend": "sqlite", + "geocollections": ["world"], + "searchable": True, + } + } + }, + } + ], + }, + { + "metadata": { + "parent_revision": revisions[0][0], + "revision": revisions[1][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_database", + "id": "yum", + "change_type": "database_reset", + "delta": {}, + } + ], + }, + { + "metadata": { + "parent_revision": revisions[1][0], + "revision": revisions[2][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_node", + "id": get_node(code="2", database="yum").id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "categories": ["stuff", "meals"], + "code": "2", + "location": "CH", + "name": "dinner", + "type": "processwithreferenceproduct", + "unit": "kg", + "database": "yum", + }, + } + } + }, + }, + { + "type": "lci_node", + "id": get_node(code="1", database="yum").id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "categories": ["stuff", "meals"], + "code": "1", + "location": "CA", + "name": "lunch", + "type": "processwithreferenceproduct", + "unit": "kg", + "database": "yum", + }, + } + } + }, + }, + { + "type": "lci_edge", + "id": ExchangeDataset.get( + ExchangeDataset.input_code == "1", + ExchangeDataset.output_code == "2", + ExchangeDataset.input_database == "yum", + ExchangeDataset.output_database == "yum", + ).id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "data": { + "amount": 0.25, + "input": ["yum", "1"], + "type": "technosphere", + "uncertainty type": 0, + "output": ["yum", "2"], + }, + "input_database": "yum", + "input_code": "1", + "output_database": "yum", + "output_code": "2", + "type": "technosphere", + }, + } + } + }, + }, + { + "type": "lci_edge", + "id": ExchangeDataset.get( + ExchangeDataset.input_code == "2", + ExchangeDataset.output_code == "2", + ExchangeDataset.input_database == "biosphere", + ExchangeDataset.output_database == "yum", + ).id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "data": { + "amount": 0.15, + "input": ["biosphere", "2"], + "type": "biosphere", + "uncertainty type": 0, + "output": ["yum", "2"], + }, + "input_database": "biosphere", + "input_code": "2", + "output_database": "yum", + "output_code": "2", + "type": "biosphere", + }, + } + } + }, + }, + { + "type": "lci_edge", + "id": ExchangeDataset.get( + ExchangeDataset.input_code == "2", + ExchangeDataset.output_code == "1", + ExchangeDataset.input_database == "yum", + ExchangeDataset.output_database == "yum", + ).id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "data": { + "amount": 0.5, + "input": ["yum", "2"], + "type": "technosphere", + "uncertainty type": 0, + "output": ["yum", "1"], + }, + "input_database": "yum", + "input_code": "2", + "output_database": "yum", + "output_code": "1", + "type": "technosphere", + }, + } + } + }, + }, + { + "type": "lci_edge", + "id": ExchangeDataset.get( + ExchangeDataset.input_code == "1", + ExchangeDataset.output_code == "1", + ExchangeDataset.input_database == "biosphere", + ExchangeDataset.output_database == "yum", + ).id, + "change_type": "create", + "delta": { + "type_changes": { + "root": { + "old_type": "NoneType", + "new_type": "dict", + "new_value": { + "data": { + "amount": 0.05, + "input": ["biosphere", "1"], + "type": "biosphere", + "uncertainty type": 0, + "output": ["yum", "1"], + }, + "input_database": "biosphere", + "input_code": "1", + "output_database": "yum", + "output_code": "1", + "type": "biosphere", + }, + } + } + }, + }, + ], + }, + { + "metadata": { + "parent_revision": revisions[2][0], + "revision": revisions[3][0], + "authors": "Anonymous", + "title": "Untitled revision", + "description": "No description", + }, + "data": [ + { + "type": "lci_database", + "id": "food", + "change_type": "database_delete", + "delta": {}, + } + ], + }, + ] + + assert [x[1] for x in revisions][:-2] == expected[:-2] + assert revisions[-1][1] == expected[-1] + assert revisions[-2][1]['metadata'] == expected[-2]['metadata'] + for x in range(2): + assert revisions[-2][1]['data'][x] in expected[-2]['data'][:2] + for x in range(2, 5): + assert revisions[-2][1]['data'][x] in expected[-2]['data'][2:] + assert projects.dataset.revision == revisions[3][0]