def test_protocol_iadd(): # The core functionality is tested by `test_protocol_merge()`; this just # needs to make sure the `+=` syntax works. p = Protocol() assert p.steps == [] p += "A" assert p.steps == ["A"] assert p[-1] == "A" # Do it again just to make sure the first addition didn't put the protocol # into some kind of broken state. p += "B" assert p.steps == ["A", "B"] assert p[-1] == "B" p += ["C", "D"] assert p.steps == ["A", "B", "C", "D"] assert p[-1] == "D" p += pl("E") assert p.steps == ["A", "B", "C", "D", pl("E")] assert p[-1] == pl("E") p += [pl("F"), pl("G")] assert p.steps == ["A", "B", "C", "D", pl("E"), pl("F"), pl("G")] assert p[-1] == pl("G") p += Protocol(steps=["H"], footnotes={1: "h"}) assert p.steps == ["A", "B", "C", "D", pl("E"), pl("F"), pl("G"), "H"] assert p.footnotes == {1: "h"} assert p[-1] == "H"
def test_protocol_add(): p1 = Protocol(steps=["Step 1"]) p2 = Protocol(steps=["Step 2"]) p3 = p1 + p2 assert p1.steps == ["Step 1"] assert p2.steps == ["Step 2"] assert p3.steps == ["Step 1", "Step 2"]
def test_api_add_categories(empty_db): db = empty_db assert stash_rows(db) == ul([]) assert stash_category_rows(db) == ul([]) assert category_rows(db) == ul([]) # - Add the protocol. # - Add an association table entry. # - Add a category. add_protocol(db, Protocol(), categories=['A']) assert stash_rows(db) == ul([ dict(pk=1, id=1, is_complete=False), ]) assert stash_category_rows(db) == ul([ dict(stash_pk=1, category_pk=1), ]) assert category_rows(db) == ul([ dict(pk=1, name='A'), ]) # - Add the protocol. # - Add an association table entry. # - Reuse the existing category. add_protocol(db, Protocol(), categories=['A']) assert stash_rows(db) == ul([ dict(pk=1, id=1, is_complete=False), dict(pk=2, id=2, is_complete=False), ]) assert stash_category_rows(db) == ul([ dict(stash_pk=1, category_pk=1), dict(stash_pk=2, category_pk=1), ]) assert category_rows(db) == ul([ dict(pk=1, name='A'), ]) # - Add the protocol. # - Add two association table entrys. # - Add one category, reuse the other. add_protocol(db, Protocol(), categories=['A', 'B']) assert stash_rows(db) == ul([ dict(pk=1, id=1, is_complete=False), dict(pk=2, id=2, is_complete=False), dict(pk=3, id=3, is_complete=False), ]) assert stash_category_rows(db) == ul([ dict(stash_pk=1, category_pk=1), dict(stash_pk=2, category_pk=1), dict(stash_pk=3, category_pk=1), dict(stash_pk=3, category_pk=2), ]) assert category_rows(db) == ul([ dict(pk=1, name='A'), dict(pk=2, name='B'), ])
def test_api_edit_protocol(empty_db): db = empty_db add_protocol(db, Protocol(steps=["A"])) assert get_protocol(db).protocol.steps == ["A"] # Keep the existing protocol (since no new protocol is specified): edit_protocol(db) assert get_protocol(db).protocol.steps == ["A"] # Replace the existing protocol: edit_protocol(db, protocol=Protocol(steps=["B"])) assert get_protocol(db).protocol.steps == ["B"]
def get_protocol(self): rxn = self.reaction p = Protocol() p += """\ Prepare a HyBond N+ membrane [1]: - Draw a 50x50 mm grid using a dull pencil. - Float in distilled water and allow to sink. - Leave soaking for 10 min. """ p += f"""\ Prepare {plural(rxn.num_reactions):# DNA sample/s} [1]: {rxn} - Incubate at 95°C for 10 min. """ p += """\ Spot DNA [1]: - Suspend the wetted membrane (e.g. over the top of an open plastic box). - Spot 2 µL of prepared DNA into each grid cell. - Allow to dry. """ if self.transfer_type == 'alkaline': p.steps[-1] += """\ - Rinse briefly in 2x SSC. - Allow to dry. """ if self.transfer_type == 'saline': p += f"""\ Denature and fix the DNA [1]: - Place the membrane on sheets of Whatman 3MM paper soaked in the following solutions: - 1.5 M NaCl, 0.5 M NaOH for 10 min. - 1.0 M NaCl, 0.5 M Tris HCl, pH=7.0 for 5 min. - Not soaked, until dry. - Irradiate with 254 nm UV light for {self.uv_time}. """ p.footnotes[1] = """\ Brown (1993). doi:10.1002/0471142727.mb0209bs21 The NaOH is to chemically hybridize the DNA to the membrane. """ return p
def test_api_reset_dependencies_2(empty_db): # Dependency graph: 1 → 2 # ↓ ↓ # 3 → 4 db = empty_db p1 = add_protocol(db, Protocol()) p2 = add_protocol(db, Protocol(), dependencies=[p1.id]) p3 = add_protocol(db, Protocol(), dependencies=[p1.id]) p4 = add_protocol(db, Protocol(), dependencies=[p2.id, p3.id]) db.commit() # Check that the tables were setup correctly: assert stash_rows(db) == ul([ dict(pk=1, id=1, is_complete=False), dict(pk=2, id=2, is_complete=False), dict(pk=3, id=3, is_complete=False), dict(pk=4, id=4, is_complete=False), ]) assert stash_dependency_rows(db) == ul([ dict(upstream_pk=1, downstream_pk=2), dict(upstream_pk=1, downstream_pk=3), dict(upstream_pk=2, downstream_pk=4), dict(upstream_pk=3, downstream_pk=4), ]) # Delete an upstream protocol, update id numbers. # Delete two association table entries. drop_protocols(db, [1]) reset_protocols(db) assert stash_rows(db) == ul([ dict(pk=2, id=1, is_complete=False), dict(pk=3, id=2, is_complete=False), dict(pk=4, id=3, is_complete=False), ]) assert stash_dependency_rows(db) == ul([ dict(upstream_pk=2, downstream_pk=4), dict(upstream_pk=3, downstream_pk=4), ]) # Delete a downstream protocol. # Delete two association table entries. drop_protocols(db, [3]) reset_protocols(db) assert stash_rows(db) == ul([ dict(pk=2, id=1, is_complete=False), dict(pk=3, id=2, is_complete=False), ]) assert stash_dependency_rows(db) == ul([])
def full_db(empty_db): """ Initialize a database with a reasonably diverse set of protocols. """ db = empty_db p1 = add_protocol(db, Protocol(steps=["X"]), message='M') p2 = add_protocol(db, Protocol(steps=["Y"]), categories=['A']) p3 = add_protocol(db, Protocol(steps=["Z"]), dependencies=[1]) # Manually change the id numbers to catch bugs any bugs resulting from # using ids where primary keys are expected or vice versa. p1.id, p2.id, p3.id = 11, 12, 13 db.commit() return db
def test_api_get_next_id(empty_db): db = empty_db assert get_next_id(db) == 1 p = add_protocol(db, Protocol()) assert get_next_id(db) == 2 p.id = 10 assert get_next_id(db) == 11
def test_protocol_prepend(): a = Protocol( date=arrow.get(1988, 11, 8), commands=['command-1'], steps=['Step 1'], footnotes={1: 'Footnote A'}, ) b = Protocol( date=arrow.get(1989, 9, 19), commands=['command-2'], steps=['Step 2'], footnotes={1: 'Footnote B'}, ) b.prepend(a) assert b.date == arrow.get(1989, 9, 19) assert b.commands == ['command-1', 'command-2'] assert b.steps == ['Step 1', 'Step 2'] assert b.footnotes == {1: 'Footnote A', 2: 'Footnote B'}
def test_api_reset_categories_1(empty_db): db = empty_db add_protocol(db, Protocol(), categories=['A']) add_protocol(db, Protocol(), categories=['A']) db.commit() # Check that the tables were setup correctly. assert stash_rows(db) == ul([ dict(pk=1, id=1, is_complete=False), dict(pk=2, id=2, is_complete=False), ]) assert stash_category_rows(db) == ul([ dict(stash_pk=1, category_pk=1), dict(stash_pk=2, category_pk=1), ]) assert category_rows(db) == ul([ dict(pk=1, name='A'), ]) # - Delete the protocol, update id numbers. # - Delete the association table entry. # - Keep the category. drop_protocols(db, [1]) reset_protocols(db) assert stash_rows(db) == ul([ dict(pk=2, id=1, is_complete=False), ]) assert stash_category_rows(db) == ul([ dict(stash_pk=2, category_pk=1), ]) assert category_rows(db) == ul([ dict(pk=1, name='A'), ]) # - Delete the protocol. # - Delete the association table entry. # - Delete the category. drop_protocols(db, [1]) reset_protocols(db) assert stash_rows(db) == ul([]) assert stash_category_rows(db) == ul([]) assert category_rows(db) == ul([])
def test_api_find_protocols_dependencies(empty_db): # Extra tests for the specific case where a protocol has two dependencies, # one of which is completed. This is a bit tricky to get right. db = empty_db p1 = add_protocol(db, Protocol()) p2 = add_protocol(db, Protocol()) p3 = add_protocol(db, Protocol(), dependencies=[p1.id, p2.id]) p1.id, p2.id, p3.id = 11, 12, 13 db.commit() hits = find_protocols(db) assert {x.id for x in hits} == {p1.id, p2.id} drop_protocols(db, [p1.id]) hits = find_protocols(db) assert {x.id for x in hits} == {p2.id} drop_protocols(db, [p2.id]) hits = find_protocols(db) assert {x.id for x in hits} == {p3.id}
def test_protocol_format_everything(): """ Just make sure the spacing between all the elements looks right. """ p = Protocol() p.date = arrow.get(1988, 11, 8) p.commands = ['sw cmd-1', 'sw cmd-2'] p.steps = ['Step 1', 'Step 2'] p.footnotes = {1: 'Footnote 1', 2: 'Footnote 2'} assert p.format_text(inf) == """\
def test_api_add(empty_db): db = empty_db rows = query_helper( Stash.id, Stash.is_complete, Stash.message, ) assert rows(db) == ul([]) p1 = add_protocol(db, Protocol(steps=["X"])) assert get_protocol(db, 1).protocol.steps == ["X"] assert rows(db) == ul([ dict(id=1, is_complete=False, message=None), ]) p2 = add_protocol(db, Protocol(steps=["Y"]), message="A") assert get_protocol(db, 2).protocol.steps == ["Y"] assert rows(db) == ul([ dict(id=1, is_complete=False, message=None), dict(id=2, is_complete=False, message="A"), ])
def test_api_add_dependencies(empty_db): db = empty_db assert stash_rows(db) == ul([]) assert stash_dependency_rows(db) == ul([]) # No dependencies: add_protocol(db, Protocol()) assert stash_rows(db) == ul([ dict(pk=1, id=1, is_complete=False), ]) assert stash_dependency_rows(db) == ul([]) # One dependency: add_protocol(db, Protocol(), dependencies=[1]) assert stash_rows(db) == ul([ dict(pk=1, id=1, is_complete=False), dict(pk=2, id=2, is_complete=False), ]) assert stash_dependency_rows(db) == ul([ dict(upstream_pk=1, downstream_pk=2), ]) # Two dependencies: add_protocol(db, Protocol(), dependencies=[1, 2]) assert stash_rows(db) == ul([ dict(pk=1, id=1, is_complete=False), dict(pk=2, id=2, is_complete=False), dict(pk=3, id=3, is_complete=False), ]) assert stash_dependency_rows(db) == ul([ dict(upstream_pk=1, downstream_pk=2), dict(upstream_pk=1, downstream_pk=3), dict(upstream_pk=2, downstream_pk=3), ]) # Fail to create self-dependency: with pytest.raises(UsageError, match="No stashed protocol with id '11'"): add_protocol(db, Protocol(), dependencies=[11])
def test_protocol_clear_footnotes(steps_before, steps_after, footnotes_before): p = Protocol() p.steps = steps_before p.footnotes = footnotes_before p.clear_footnotes() assert p.steps == steps_after assert p.footnotes == {}
def test_protocol_prune_footnotes(steps_before, footnotes_before, steps_after, footnotes_after): p = Protocol() p.steps = steps_before p.footnotes = footnotes_before p.prune_footnotes() assert p.steps == steps_after assert p.footnotes == footnotes_after
def test_protocol_renumber_footnotes(new_ids, steps_before, footnotes_before, steps_after, footnotes_after): p = Protocol() p.steps = steps_before p.footnotes = footnotes_before p.renumber_footnotes(new_ids) assert p.steps == steps_after assert p.footnotes == footnotes_after
def test_protocol_insert_footnotes(steps_before, footnotes_before, footnotes_new, pattern, steps_after, footnotes_after, error): p = Protocol() p.steps = steps_before p.footnotes = footnotes_before with error: p.insert_footnotes(*footnotes_new, pattern=pattern) assert p.steps == steps_after assert p.footnotes == footnotes_after
def test_protocol_format_footnotes(footnotes, expected): p = Protocol() p.footnotes = footnotes assert p.format_text(inf) == expected.rstrip()
def test_protocol_format_steps(steps, expected): p = Protocol() p.steps = steps assert p.format_text(inf) == expected.rstrip()
def test_protocol_format_commands(commands, expected): p = Protocol() p.commands = commands assert p.format_text(inf) == expected.rstrip()
def test_protocol_format_date(date, expected): p = Protocol() p.date = arrow.get(date) assert p.format_text(inf) == expected.rstrip()
def test_protocol_format_text_empty(): p = Protocol() assert p.format_text(inf) == ''
def test_protocol_pick_slug(date, commands, expected): p = Protocol(date=date, commands=commands) assert p.pick_slug() == expected
def test_protocol_merge_footnotes(steps_before, steps_after): p = Protocol() p.steps = steps_before p.merge_footnotes() assert p.steps == steps_after
def test_protocol_repr(): p = Protocol() assert repr(p) == 'Protocol(date=None, commands=[], steps=[], footnotes={})'
#!/usr/bin/env python3 import stepwise from inform import plural from stepwise import Protocol, Step, Footnote, MasterMix p = Protocol() n = 6 loading_buf = MasterMix("""\ Reagent Stock Volume MM? ====================== ===== ========= === water to 5.0 µL y Bolt LDS sample buffer 4x 2.5 µL y Bolt reducing agent 10x 1.0 µL y """) loading_buf.num_reactions = 2 * n loading_buf.extra_percent = 50 protein_samples = MasterMix("""\ Reagent Stock Volume MM? ========================= ========= ========== === water to 10.0 µL y loading buffer master mix 2x 5.0 µL y BSA 500 ng/µL 1.0 µL y """) protein_samples.num_reactions = n protein_samples.extra_percent = 10 dna_samples = MasterMix("""\ Reagent Stock Volume MM?
def test_protocol_merge_err(): with raises(ParseError, match="cannot interpret 42 as a protocol"): Protocol.merge(42)
def get_protocol(self): p = Protocol() p += "Miniprep." return p
def test_protocol_add_footnotes(footnotes_new, footnotes_before, footnotes_after, formatted_ids): p = Protocol() p.footnotes = footnotes_before assert p.add_footnotes(*footnotes_new) == formatted_ids assert p.footnotes == footnotes_after