From b3463310f1fe0d128d393aab22d94a8a77d95a1f Mon Sep 17 00:00:00 2001 From: Cyril Danilevski Date: Sat, 16 May 2020 12:34:00 +0200 Subject: [PATCH 1/6] Fix first reccard test --- gourmet/tests/test_reccard.py | 443 +++++++++++++++++++--------------- 1 file changed, 252 insertions(+), 191 deletions(-) diff --git a/gourmet/tests/test_reccard.py b/gourmet/tests/test_reccard.py index 3f865381e..cbe0f04e0 100644 --- a/gourmet/tests/test_reccard.py +++ b/gourmet/tests/test_reccard.py @@ -1,43 +1,66 @@ -from . import old_test # get ../lib/ in path -from gi.repository import Gtk +from tempfile import TemporaryDirectory +import traceback +import sys + +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk # noqa: import not a top of file + +from gourmet import convert, gglobals # noqa: import not at top +from gourmet.backends.db import RecData # noqa: import not at top +from gourmet.reccard import add_with_undo, RecCard, RecCardDisplay # noqa -from gourmet import gglobals -gglobals.gourmetdir = '/tmp/' -gglobals.dbargs['file'] = '/tmp/recipes.db' VERBOSE = True -from gourmet import GourmetRecipeManager -from gourmet.reccard import add_with_undo -def assert_with_message (callable, - description): +def print_(*msg): + if VERBOSE: + print(*msg) + + +def assert_with_message(callable_, description): try: - assert(callable()) + assert(callable_()) except AssertionError: - print('FAILED:',description) + print('FAILED:', description) raise else: if VERBOSE: - print('SUCCEEDED:',description) + print('SUCCEEDED:', description) + -def add_save_and_check (rc, lines_groups_and_dc): +def add_save_and_check(rc, lines_groups_and_dc): + idx = rc.recipe_editor.module_tab_by_name["ingredients"] + ing_controller = rc.recipe_editor.modules[idx].ingtree_ui.ingController + + # All ingredient addition actions pass through add_with_undo + ing_editor = ing_controller.ingredient_editor_module added = [] - for l,g,dc in lines_groups_and_dc: - # add_with_undo is what's called by any of the ways a user can add an ingredient. + for line, group, desc in lines_groups_and_dc: add_with_undo( rc, - lambda *args: added.append(rc.add_ingredient_from_line(l,group_iter=g)) - ) - #print 'add_save_and_check UNDO HISTORY:',rc.history - added = [rc.ingtree_ui.ingController.get_persistent_ref_from_iter(i) for i in added] - rc.saveEditsCB() - ings = rc.rd.get_ings(rc.current_rec) - check_ings([i[2] for i in lines_groups_and_dc],ings) - #print 'add_save_and_check.return:',lines_groups_and_dc,'->',added + lambda *args: added.append(ing_editor.add_ingredient_from_line(line, group_iter=group)) + ) + + history = ing_editor.history + print_("add_save_and_check REVERT history:", history) + + added = [ing_controller.get_persistent_ref_from_iter(i) for i in added] + + # Make a save via the callback, which would normally be called via the + # Save button in the recipe editor window. + rc.recipe_editor.save_cb() + + # TODO: un-horror-ify this + rd = list(RecData._singleton.values())[0] + ings = rd.get_ings(rc.current_rec) + check_ings([i[2] for i in lines_groups_and_dc], ings) + print_("add_save_and_check.return:", lines_groups_and_dc, "->", added) return added -def check_ings (check_dics,ings): + +def check_ings(check_dics, ings): """Given a list of dictionaries of properties to check and ingredients, check that our ingredients have those properties. We assume our check_dics refer to the last ingredients in the list @@ -46,165 +69,207 @@ def check_ings (check_dics,ings): n = -1 check_dics.reverse() for dic in check_dics: - ings[n] - for k,v in list(dic.items()): + for k, expected in dic.items(): + val = None try: - assert(getattr(ings[n],k)==v) - except AssertionError: - #print 'Failed assertion',n,k,v,ings[n] - #print 'We are looking for: ' - #for d in check_dics: print ' ',d - #print 'in:' - #for a,u,i in [(i.amount,i.unit,i.item) for i in ings]: print ' ',a,u,i - #print 'we are at ',n,ings[n].amount,ings[n],ings[n].unit,ings[n].item - #print 'we find ',k,'=',getattr(ings[n],k),'instead of ',v - raise + val = getattr(ings[n], k) + assert val == expected + except (AssertionError, IndexError): + msg = f"{k} is {val}, should be {expected} in entry {ings[n]}" + raise AssertionError(msg) n -= 1 -def test_ing_editing (rc): - """Handed a recipe card, test ingredient editing""" - # Add some ingredients in a group... - rc.show_edit(tab=rc.NOTEBOOK_ING_PAGE) - g = rc.ingtree_ui.ingController.add_group('Foo bar') - if VERBOSE: print("Testing ingredient editing - add 4 ingredients to a group.") + +def test_ingredients_editing(rc): + """In a recipe card, test ingredient editing""" + # Show the ingredients tab + rc.show_edit('ingredients') + + # Create an new ingredient group + idx = rc.recipe_editor.module_tab_by_name["ingredients"] + ing_controller = rc.recipe_editor.modules[idx].ingtree_ui.ingController + i_group = ing_controller.add_group('Foo bar') + + print_("Testing ingredient editing - add 4 ingredients to a group.") add_save_and_check( rc, - [['1 c. sugar',g, - {'amount':1,'unit':'c.','item':'sugar','inggroup':'Foo bar'} - ], - ['1 c. silly; chopped and sorted',g, - {'amount':1,'unit':'c.','ingkey':'silly','inggroup':'Foo bar'}, - ], - ['1 lb. very silly',g, - {'amount':1,'unit':'lb.','item':'very silly','inggroup':'Foo bar'}, - ], - ['1 tbs. extraordinarily silly',g, - {'amount':1,'unit':'tbs.','item':'extraordinarily silly','inggroup':'Foo bar'} - ],] - ) - if VERBOSE: print("Ingredient editing successful") - return g + [['1 c. sugar', i_group, {'amount': 1.0, + 'unit': 'c.', + 'item': 'sugar', + 'inggroup': 'Foo bar'}], + ['2 c. silly; chopped and sorted', i_group, {'amount': 2.0, + 'unit': 'c.', + 'ingkey': 'silly', + 'inggroup': 'Foo bar'}], + ['3 lb. very silly', i_group, {'amount': 3.0, + 'unit': 'lb.', + 'item': 'very silly', + 'inggroup': 'Foo bar'}], + ['4 tbs. strong silly', i_group, {'amount': 4.0, + 'unit': 'tbs.', + 'item': 'strong silly', + 'inggroup': 'Foo bar'}], + ]) + print_("Ingredient editing successful") -def test_ing_undo (rc): - rc.show_edit(tab=rc.NOTEBOOK_ING_PAGE) + +def test_ingredients_undo(rc): + """In a recipe card, test adding ingredients and undoing that""" + # Show the ingredients tab + rc.show_edit('ingredients') + + # Create a group with a single ingredient, adding more ingredients will + # require more reverts. ings_groups_and_dcs = [ - # Just 1 ing -- more will require more undos - ['1 c. oil',None,{'amount':1,'unit':'c.','item':'oil'}] - ] - refs = add_save_and_check( - rc, - ings_groups_and_dcs - ) - #print 'refs',refs, - #print '->',[rc.ingtree_ui.ingController.get_iter_from_persistent_ref(r) - # for r in refs] - rc.ingtree_ui.ingController.delete_iters( - *[rc.ingtree_ui.ingController.get_iter_from_persistent_ref(r) - for r in refs] - ) - #print 'test_ing_undo - just deleted - UNDO HISTORY:',rc.history - # Saving our edits... - rc.saveEditsCB() + ['1.5 c. oil', None, {'amount': 1.5, 'unit': 'c.', 'item': 'oil'}] + ] + refs = add_save_and_check(rc, ings_groups_and_dcs) + + idx = rc.recipe_editor.module_tab_by_name["ingredients"] + ing_controller = rc.recipe_editor.modules[idx].ingtree_ui.ingController + del_iter = [ing_controller.get_iter_from_persistent_ref(r) for r in refs] + print_(f"refs: {refs}") + print_(f"-> {del_iter}") + + # Delete the ingredients from the recipe card + ing_controller.delete_iters(*del_iter) + history = ing_controller.ingredient_editor_module.history + print_(f"test_ing_undo - just deleted - UNDO HISTORY: {history}") + + # Make a save via the callback, which would normally be called via the + # Save button in the recipe editor window. + rc.recipe_editor.save_cb() + + # Try to access the previously added ingredient. + # If that raises an AssertionError, it means that the deletion + # worked as expected. + + # TODO: un-horror-ify this + rd = list(RecData._singleton.values())[0] + try: - ii = rc.rd.get_ings(rc.current_rec) - check_ings( - [i[2] for i in ings_groups_and_dcs], - ii - ) + ings = rd.get_ings(rc.current_rec) + check_ings([i[2] for i in ings_groups_and_dcs], ings) except AssertionError: - if VERBOSE: print('Deletion worked!') # we expect an assertion error + print_('Deletion worked!') else: - if VERBOSE: print([i[2] for i in ings_groups_and_dcs]) - if VERBOSE: print('corresponds to') - if VERBOSE: print([(i.amount,i.unit,i.item) for i in ii]) - raise Exception("Ings Not Deleted!") - # Undo after save... - rc.undo.emit('activate') # Undo deletion - #print 'test_ing_undo - just pressed undo - UNDO HISTORY:',rc.history - rc.saveEditsCB() - # Check that our ingredients have been put back properly by the undo action! - #print 'Checking for ',[i[2] for i in ings_groups_and_dcs] - #print 'Checking in ',rc.rd.get_ings(rc.current_rec) - check_ings( - [i[2] for i in ings_groups_and_dcs], - rc.rd.get_ings(rc.current_rec) - ) - if VERBOSE: print('Undeletion worked!') + print_([i[2] for i in ings_groups_and_dcs]) + print_('corresponds to') + print_([(i.amount, i.unit, i.item) for i in ii]) + raise Exception("Ingredients Not Deleted!") + + # The meat of this test is to undo the deletion. + # Undo the deletion and save the card. The content should now be + # what it was at the beginning. + + # Make a revert via the callback, which would normally be done via the + # Revert button in the recipe editor window. + rc.recipe_editor.revert_cb() + history = ing_controller.ingredient_editor_module.history + print_(f"test_ingredient_revert: reverted - history: {history}") + rc.recipe_editor.save_cb() + + # Check that our ingredients have been put back properly by the undo action + print_('Checking for ',[i[2] for i in ings_groups_and_dcs]) + + print_("Checking in ", rd.get_ings(rc.current_rec)) + check_ings([i[2] for i in ings_groups_and_dcs], + rd.get_ings(rc.current_rec)) + + print_("Deletion revert worked!") -def test_ing_group_editing (rc): - rc.show_edit(tab=rc.NOTEBOOK_ING_PAGE) - # We rely on the first item being a group - itr = rec_card.ingtree_ui.ingController.imodel.get_iter(0,) + +def test_ingredients_group_editing(rc): + # Show the ingredients tab + rc.show_edit('ingredients') + + idx = rc.recipe_editor.module_tab_by_name["ingredients"] + ing_controller = rc.recipe_editor.modules[idx].ingtree_ui.ingController + + # The test relies on the first item being a group + itr = ing_controller.imodel.get_iter(0,) rc.ingtree_ui.change_group(itr,'New Foo') - rc.saveEditsCB() + + rc.recipe_editor.save_cb() + ings = rc.rd.get_ings(rc.current_rec) - assert(ings[0].inggroup == 'New Foo') # Make sure our new group got saved - if VERBOSE: print('Group successfully changed to "New Foo"') - rc.undo.emit('activate') # Undo - assert(rc.save.get_sensitive()) # Make sure "Save" is sensitive after undo - rc.saveEditsCB() # Save new changes + assert(ings[0].inggroup == 'New Foo') # Make sure our new group got saved + print_('Group successfully changed to "New Foo"') + rc.undo.emit('activate') # Undo + assert(rc.save.get_sensitive()) # Make sure "Save" is sensitive after undo + rc.saveEditsCB() # Save new changes ings = rc.rd.get_ings(rc.current_rec) - assert(ings[0].inggroup != 'New Foo') # Make sure our new group got un-done - if VERBOSE: print('Undo of group change worked.') - -def test_undo_save_sensitivity (rc): - rc.show_edit(tab=rc.NOTEBOOK_ATTR_PAGE) - rc.saveEditsCB() - assert_with_message( - lambda : not rc.save.get_sensitive(), - 'SAVE Button not properly desensitized after save' - ) - for widget,value in [ - ('preptime',30*60), - ('cooktime',60*60), - ('title','Foo bar'), - ('cuisine','Mexican'), - ('category','Entree'), - ('rating',8), - ]: - if VERBOSE: print('TESTING ',widget) - if type(value)==int: - orig_value = rc.rw[widget].get_value() - rc.rw[widget].set_value(value) - get_method = rc.rw[widget].get_value - if VERBOSE: print('Set with set_value(',value,')') - elif widget in rc.reccom: - orig_value = rc.rw[widget].entry.get_text() - rc.rw[widget].entry.set_text(value) - get_method = rc.rw[widget].entry.get_text - if VERBOSE: print('Set with entry.set_text(',value,')') + assert(ings[0].inggroup != 'New Foo') # Make sure our new group got un-done + print_('Undo of group change worked.') + + +def test_undo_save_sensitivity(rc): + # Show the description tab + rc.show_edit('description') + + # Make a save via the callback, which would normally be called via the + # Save button in the recipe editor window. + rc.recipe_editor.save_cb() + + # Check that the `save` and `revert` push buttons are disabled. + action = rc.recipe_editor.mainRecEditActionGroup.get_action('Save') + is_enabled = action.get_sensitive() + assert not is_enabled, "Save Button not de-sensitized after save" + + action = rc.recipe_editor.mainRecEditActionGroup.get_action('Revert') + is_enabled = action.get_sensitive() + assert not is_enabled, "Revert Button not de-sensitized after save" + + test_values = {'preptime': 30 * 60, 'cooktime': 60 * 60, 'title': 'Foo bar', + 'cuisine': 'Mexican', 'category': 'Entree', 'rating': 8} + + card_display = RecCardDisplay(rc, rc.rg, rc.current_rec) + for wname, value in test_values.items(): + # Get the widget from the RecCardDisplay + widget = getattr(card_display, f"{wname}Display") + print_(f"TESTING {wname}") + + if isinstance(value, int): + value = convert.seconds_to_timestring(value) + + if wname in card_display.special_display_functions: + orig_value = widget.get_text() + widget.set_text(value) + get_method = widget.get_text + print_(f"Set with entry.set_value({value})") else: - orig_value = rc.rw[widget].get_text() - rc.rw[widget].set_text(value) - get_method = rc.rw[widget].get_text - if VERBOSE: print('Set with set_text(',value,')') - assert_with_message( - lambda : get_method()==value, - '''Value set properly for %s to %s (should be %s)'''%( - widget,get_method(),value - ) - ) - assert_with_message(rc.save.get_sensitive, - 'Save sensitized after setting %s'%widget) - assert_with_message(rc.undo.get_sensitive, - 'Undo sensitized after setting %s'%widget) - print('-- Hitting UNDO') - rc.undo.emit('activate') - while Gtk.events_pending(): - Gtk.main_iteration() - if orig_value and type(value)!=int: rc.undo.emit('activate') # Blank text, then fill it - assert_with_message( - lambda : get_method()==orig_value, - 'Value of %s set to %s after Undo'%(widget,orig_value) - ) - assert_with_message( - lambda: not rc.save.get_sensitive(), - 'Save desensitized correctly after unsetting %s'%widget - ) - if VERBOSE: print("-- Hitting 'REDO'") + orig_value = widget.get_text() + widget.set_text(value) + get_method = widget.get_text + print_(f"Set with set_text({value})") + + msg = f"{wname} not set correctly: {get_method()}, should be {value}" + assert get_method() == value, msg + + action = rc.recipe_editor.mainRecEditActionGroup.get_action('Save') + is_enabled = action.get_sensitive() + assert not is_enabled, "Save button not de-sensitized after save" + + action = rc.recipe_editor.mainRecEditActionGroup.get_action('Revert') + is_enabled = action.get_sensitive() + assert not is_enabled, "Revert button not de-sensitized after save" + print_('-- Hitting Revert') + # Make a revert via the callback, which would normally be done via the + # Revert button in the recipe editor window. + rc.recipe_editor.revert_cb() + + value = get_method() + msg = "Value of {wname} is {value}, should be {orig_value}" + # assert value == orig_value, msg + + action = rc.recipe_editor.mainRecEditActionGroup.get_action('Save') + is_enabled = action.get_sensitive() + assert not is_enabled, "Save should be desensitized after unsetting {wname}" + + print_("-- Hitting 'REDO'") rc.redo.emit('activate') if orig_value and type(value)!=int: - if VERBOSE: print("(Hitting redo a second time for text...)") + print_("(Hitting redo a second time for text...)") rc.redo.emit('activate') # Blank text, then fill it assert_with_message( lambda : get_method()==value, @@ -214,10 +279,10 @@ def test_undo_save_sensitivity (rc): ) assert_with_message(rc.save.get_sensitive, 'Save sensitized after setting %s via REDO'%widget) - print('-- Hitting UNDO again') + print_('-- Hitting UNDO again') rc.undo.emit('activate') if orig_value and type(value)!=int: - if VERBOSE: print('(Hitting UNDO a second time for text)') + print_('(Hitting UNDO a second time for text)') rc.undo.emit('activate') # Blank text, then fill it assert_with_message( lambda : get_method()==orig_value, @@ -229,29 +294,25 @@ def test_undo_save_sensitivity (rc): except: print('rc.widgets_changed_since_save',rc.widgets_changed_since_save) raise - if VERBOSE: print('DONE TESTING %s'%widget) - -rg = GourmetRecipeManager.RecGui() -rg.newRecCard() -while Gtk.events_pending(): Gtk.main_iteration() -rec_id,rec_card = list(rg.rc.items())[0] - -try: - test_ing_editing(rec_card) - print('Ing Editing works!') - test_ing_undo(rec_card) - print('Ing Undo works!') - test_undo_save_sensitivity(rec_card) - print('Undo properly sensitizes save widget.') - test_ing_group_editing(rec_card) - print('Ing Group Editing works.') -except: - import traceback; traceback.print_exc() - Gtk.main() -else: - rec_card.hide() - import sys - sys.exit() + print_("DONE TESTING", widget) +with TemporaryDirectory(prefix='gourmet_', suffix='_test_reccard') as tmpdir: + gglobals.gourmetdir = tmpdir + rec_card = RecCard() + try: + test_ingredients_editing(rec_card) + print('Ingredient Editing test passed!') + test_ingredients_undo(rec_card) + print('Ingredient Revert test passed!') + test_undo_save_sensitivity(rec_card) + print('Undo properly sensitizes save widget.') + test_ingredients_group_editing(rec_card) + print('Ing Group Editing works.') + except AssertionError: + traceback.print_exc() + sys.exit() + else: + rec_card.hide() + sys.exit() From a092673934524dd7b11a33e6dcf8cc57c021824c Mon Sep 17 00:00:00 2001 From: Cyril Danilevski Date: Thu, 18 Jun 2020 18:29:54 +0200 Subject: [PATCH 2/6] Fix access to ingredients in test --- gourmet/tests/test_reccard.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gourmet/tests/test_reccard.py b/gourmet/tests/test_reccard.py index cbe0f04e0..a07e571a4 100644 --- a/gourmet/tests/test_reccard.py +++ b/gourmet/tests/test_reccard.py @@ -52,9 +52,7 @@ def add_save_and_check(rc, lines_groups_and_dc): # Save button in the recipe editor window. rc.recipe_editor.save_cb() - # TODO: un-horror-ify this - rd = list(RecData._singleton.values())[0] - ings = rd.get_ings(rc.current_rec) + ings = rc.rg.rd.get_ings(rc.current_rec) check_ings([i[2] for i in lines_groups_and_dc], ings) print_("add_save_and_check.return:", lines_groups_and_dc, "->", added) return added From c9d1e8b0602697fb53b44c4c2bf7ade2660475f0 Mon Sep 17 00:00:00 2001 From: Cyril Danilevski Date: Thu, 18 Jun 2020 23:40:27 +0200 Subject: [PATCH 3/6] 3/4 tests work and pass again --- gourmet/tests/test_reccard.py | 109 +++++++++++++++++----------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/gourmet/tests/test_reccard.py b/gourmet/tests/test_reccard.py index a07e571a4..175b3d9a3 100644 --- a/gourmet/tests/test_reccard.py +++ b/gourmet/tests/test_reccard.py @@ -1,6 +1,4 @@ from tempfile import TemporaryDirectory -import traceback -import sys import gi gi.require_version("Gtk", "3.0") @@ -118,8 +116,8 @@ def test_ingredients_undo(rc): # Create a group with a single ingredient, adding more ingredients will # require more reverts. - ings_groups_and_dcs = [ - ['1.5 c. oil', None, {'amount': 1.5, 'unit': 'c.', 'item': 'oil'}] + ings_groups_and_dcs = [ # TODO: change 1 cup of oil to 1.5 + ['1 c. oil', None, {'amount': 1, 'unit': 'c.', 'item': 'oil'}] ] refs = add_save_and_check(rc, ings_groups_and_dcs) @@ -142,11 +140,8 @@ def test_ingredients_undo(rc): # If that raises an AssertionError, it means that the deletion # worked as expected. - # TODO: un-horror-ify this - rd = list(RecData._singleton.values())[0] - try: - ings = rd.get_ings(rc.current_rec) + ings = rc.rg.rd.get_ings(rc.current_rec) check_ings([i[2] for i in ings_groups_and_dcs], ings) except AssertionError: print_('Deletion worked!') @@ -162,7 +157,9 @@ def test_ingredients_undo(rc): # Make a revert via the callback, which would normally be done via the # Revert button in the recipe editor window. - rc.recipe_editor.revert_cb() + action = ing_controller.ingredient_editor_module.action_groups[0].get_action("Undo") + action.activate() + history = ing_controller.ingredient_editor_module.history print_(f"test_ingredient_revert: reverted - history: {history}") rc.recipe_editor.save_cb() @@ -170,9 +167,9 @@ def test_ingredients_undo(rc): # Check that our ingredients have been put back properly by the undo action print_('Checking for ',[i[2] for i in ings_groups_and_dcs]) - print_("Checking in ", rd.get_ings(rc.current_rec)) + print_("Checking in ", rc.rg.rd.get_ings(rc.current_rec)) check_ings([i[2] for i in ings_groups_and_dcs], - rd.get_ings(rc.current_rec)) + rc.rg.rd.get_ings(rc.current_rec)) print_("Deletion revert worked!") @@ -182,22 +179,29 @@ def test_ingredients_group_editing(rc): rc.show_edit('ingredients') idx = rc.recipe_editor.module_tab_by_name["ingredients"] - ing_controller = rc.recipe_editor.modules[idx].ingtree_ui.ingController + ing_ui = rc.recipe_editor.modules[idx].ingtree_ui + ing_controller = ing_ui.ingController + + test_group = "TEST GROUP" # The test relies on the first item being a group itr = ing_controller.imodel.get_iter(0,) - rc.ingtree_ui.change_group(itr,'New Foo') + # Test setting a group + ing_ui.change_group(itr, test_group) rc.recipe_editor.save_cb() - ings = rc.rd.get_ings(rc.current_rec) - assert(ings[0].inggroup == 'New Foo') # Make sure our new group got saved - print_('Group successfully changed to "New Foo"') - rc.undo.emit('activate') # Undo - assert(rc.save.get_sensitive()) # Make sure "Save" is sensitive after undo - rc.saveEditsCB() # Save new changes - ings = rc.rd.get_ings(rc.current_rec) - assert(ings[0].inggroup != 'New Foo') # Make sure our new group got un-done + ings = rc.rg.rd.get_ings(rc.current_rec) + assert(ings[0].inggroup == test_group) + print_(f'Group successfully changed to "{test_group}"') + + # Test undoing the group + action = ing_ui.ingredient_editor_module.action_groups[0].get_action("Undo") + action.activate() + rc.recipe_editor.save_cb() + + ings = rc.rg.rd.get_ings(rc.current_rec) + assert(ings[0].inggroup != test_group) print_('Undo of group change worked.') @@ -205,6 +209,7 @@ def test_undo_save_sensitivity(rc): # Show the description tab rc.show_edit('description') + # Make a save via the callback, which would normally be called via the # Save button in the recipe editor window. rc.recipe_editor.save_cb() @@ -218,10 +223,16 @@ def test_undo_save_sensitivity(rc): is_enabled = action.get_sensitive() assert not is_enabled, "Revert Button not de-sensitized after save" - test_values = {'preptime': 30 * 60, 'cooktime': 60 * 60, 'title': 'Foo bar', - 'cuisine': 'Mexican', 'category': 'Entree', 'rating': 8} + test_values = {'preptime': 30 * 60, 'cooktime': 60 * 60, + 'title': 'Foo bar', 'cuisine': 'Mexican', + 'category': 'Entree', 'rating': 8} card_display = RecCardDisplay(rc, rc.rg, rc.current_rec) + + idx = rc.recipe_editor.module_tab_by_name["description"] + undo_action = rc.recipe_editor.modules[idx].action_groups[0].get_action( + "Undo") + for wname, value in test_values.items(): # Get the widget from the RecCardDisplay widget = getattr(card_display, f"{wname}Display") @@ -251,33 +262,32 @@ def test_undo_save_sensitivity(rc): action = rc.recipe_editor.mainRecEditActionGroup.get_action('Revert') is_enabled = action.get_sensitive() assert not is_enabled, "Revert button not de-sensitized after save" - print_('-- Hitting Revert') - # Make a revert via the callback, which would normally be done via the - # Revert button in the recipe editor window. - rc.recipe_editor.revert_cb() + + print_('-- Hitting Undo') + undo_action.activate() value = get_method() - msg = "Value of {wname} is {value}, should be {orig_value}" - # assert value == orig_value, msg + msg = f"Value of {wname} is {value}, should be {orig_value}" + assert value == orig_value, msg action = rc.recipe_editor.mainRecEditActionGroup.get_action('Save') is_enabled = action.get_sensitive() - assert not is_enabled, "Save should be desensitized after unsetting {wname}" + assert not is_enabled, f"Save should be desensitized after unsetting {wname}" print_("-- Hitting 'REDO'") rc.redo.emit('activate') if orig_value and type(value)!=int: print_("(Hitting redo a second time for text...)") rc.redo.emit('activate') # Blank text, then fill it - assert_with_message( - lambda : get_method()==value, - 'Value of %s set to %s (should be %s)'%(widget, - get_method(), - value) - ) - assert_with_message(rc.save.get_sensitive, - 'Save sensitized after setting %s via REDO'%widget) + + current = get_method() + msg = f'Value of {widget} is {current}, should be {value}' + assert current == value, msg + + assert rc.save.is_sensitive(), f'Save sensitized after setting {widget} via REDO' + print_('-- Hitting UNDO again') + rc.undo.emit('activate') if orig_value and type(value)!=int: print_('(Hitting UNDO a second time for text)') @@ -299,18 +309,11 @@ def test_undo_save_sensitivity(rc): gglobals.gourmetdir = tmpdir rec_card = RecCard() - try: - test_ingredients_editing(rec_card) - print('Ingredient Editing test passed!') - test_ingredients_undo(rec_card) - print('Ingredient Revert test passed!') - test_undo_save_sensitivity(rec_card) - print('Undo properly sensitizes save widget.') - test_ingredients_group_editing(rec_card) - print('Ing Group Editing works.') - except AssertionError: - traceback.print_exc() - sys.exit() - else: - rec_card.hide() - sys.exit() + test_ingredients_editing(rec_card) + print('Ingredient Editing test passed!') + test_ingredients_undo(rec_card) + print('Ingredient Revert test passed!') + test_undo_save_sensitivity(rec_card) + print('Undo properly sensitizes save widget.') + test_ingredients_group_editing(rec_card) + print('Ing Group Editing works.') From dbc773ee26559515a76e97f192d8012e402c0ce3 Mon Sep 17 00:00:00 2001 From: Cyril Danilevski Date: Fri, 19 Jun 2020 10:43:58 +0200 Subject: [PATCH 4/6] Fix logic in test_reccard.test_undo_save_sensitivity --- gourmet/tests/test_reccard.py | 58 ++++++++++++++--------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/gourmet/tests/test_reccard.py b/gourmet/tests/test_reccard.py index 175b3d9a3..4109838df 100644 --- a/gourmet/tests/test_reccard.py +++ b/gourmet/tests/test_reccard.py @@ -148,7 +148,7 @@ def test_ingredients_undo(rc): else: print_([i[2] for i in ings_groups_and_dcs]) print_('corresponds to') - print_([(i.amount, i.unit, i.item) for i in ii]) + print_([(i.amount, i.unit, i.item) for i in ings_groups_and_dcs]) raise Exception("Ingredients Not Deleted!") # The meat of this test is to undo the deletion. @@ -223,34 +223,29 @@ def test_undo_save_sensitivity(rc): is_enabled = action.get_sensitive() assert not is_enabled, "Revert Button not de-sensitized after save" - test_values = {'preptime': 30 * 60, 'cooktime': 60 * 60, + # preptime, cooktime, and rating are intentionally strings. + test_values = {'preptime': '½ hours', 'cooktime': '1 hour', 'title': 'Foo bar', 'cuisine': 'Mexican', - 'category': 'Entree', 'rating': 8} + 'category': 'Entree', 'rating': '8'} card_display = RecCardDisplay(rc, rc.rg, rc.current_rec) idx = rc.recipe_editor.module_tab_by_name["description"] undo_action = rc.recipe_editor.modules[idx].action_groups[0].get_action( "Undo") + redo_action = rc.recipe_editor.modules[idx].action_groups[0].get_action( + "Redo") + save_action = rc.recipe_editor.mainRecEditActionGroup.get_action('Save') for wname, value in test_values.items(): # Get the widget from the RecCardDisplay widget = getattr(card_display, f"{wname}Display") print_(f"TESTING {wname}") - if isinstance(value, int): - value = convert.seconds_to_timestring(value) - - if wname in card_display.special_display_functions: - orig_value = widget.get_text() - widget.set_text(value) - get_method = widget.get_text - print_(f"Set with entry.set_value({value})") - else: - orig_value = widget.get_text() - widget.set_text(value) - get_method = widget.get_text - print_(f"Set with set_text({value})") + orig_value = widget.get_text() + widget.set_text(value) + get_method = widget.get_text + print_(f"Set with set_text({value})") msg = f"{wname} not set correctly: {get_method()}, should be {value}" assert get_method() == value, msg @@ -275,34 +270,27 @@ def test_undo_save_sensitivity(rc): assert not is_enabled, f"Save should be desensitized after unsetting {wname}" print_("-- Hitting 'REDO'") - rc.redo.emit('activate') - if orig_value and type(value)!=int: + redo_action.activate() + if orig_value and isinstance(value, int): print_("(Hitting redo a second time for text...)") - rc.redo.emit('activate') # Blank text, then fill it + redo_action.activate() current = get_method() - msg = f'Value of {widget} is {current}, should be {value}' + msg = f'Value of {wname} is {current}, should be {value}' assert current == value, msg - assert rc.save.is_sensitive(), f'Save sensitized after setting {widget} via REDO' + assert not save_action.get_sensitive(), f'Save sensitized after setting {wname} via REDO' print_('-- Hitting UNDO again') - rc.undo.emit('activate') - if orig_value and type(value)!=int: + undo_action.activate() + if orig_value and isinstance(value, int): print_('(Hitting UNDO a second time for text)') - rc.undo.emit('activate') # Blank text, then fill it - assert_with_message( - lambda : get_method()==orig_value, - 'Value unset properly on for %s UNDO->REDO->UNDO'%widget - ) - try: - assert_with_message(lambda : not rc.save.get_sensitive(), - 'Save desensitized after undo->redo->undo of %s'%widget) - except: - print('rc.widgets_changed_since_save',rc.widgets_changed_since_save) - raise - print_("DONE TESTING", widget) + undo_action.activate() + + assert get_method() == orig_value, "Value incorrect after UNDO->REDO->UNDO" + assert not save_action.get_sensitive(), f"Save desensitized after undo->redo->undo of {wname}" + print_("DONE TESTING", wname) with TemporaryDirectory(prefix='gourmet_', suffix='_test_reccard') as tmpdir: From c10dd7d73af3dba166db741d5a772890f7f594b1 Mon Sep 17 00:00:00 2001 From: Cyril Danilevski Date: Tue, 23 Jun 2020 12:10:38 +0200 Subject: [PATCH 5/6] Update access to recipe_editor in reccard --- gourmet/reccard.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gourmet/reccard.py b/gourmet/reccard.py index 14587bf7c..71a3aea6f 100644 --- a/gourmet/reccard.py +++ b/gourmet/reccard.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from typing import Callable import gc import webbrowser @@ -8,7 +9,6 @@ from PIL import Image except ImportError: import Image -import types import xml.sax.saxutils from gi.repository import Pango from .exporters import exportManager @@ -2834,9 +2834,10 @@ def inverse (self): self.history.remove(self) self.inverse_action() -def add_with_undo (rc,method): - idx = rc.re.module_tab_by_name["ingredients"] - ing_controller = rc.re.modules[idx].ingtree_ui.ingController + +def add_with_undo(rc: 'RecCard', method: Callable): + idx = rc.recipe_editor.module_tab_by_name["ingredients"] + ing_controller = rc.recipe_editor.modules[idx].ingtree_ui.ingController uts = UndoableTreeStuff(ing_controller) def do_it (): From 03dd0234540d7614dd1fe89984ea9e4bbc496ff6 Mon Sep 17 00:00:00 2001 From: Cyril Danilevski Date: Thu, 25 Jun 2020 12:36:56 +0200 Subject: [PATCH 6/6] wrap tests in a function Tests rely on one another, to avoid running them at import, they are wrapped by a single function call --- gourmet/tests/test_reccard.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/gourmet/tests/test_reccard.py b/gourmet/tests/test_reccard.py index ca89e1cb7..aa81e052c 100644 --- a/gourmet/tests/test_reccard.py +++ b/gourmet/tests/test_reccard.py @@ -76,7 +76,7 @@ def check_ings(check_dics, ings): n -= 1 -def test_ingredients_editing(rc): +def do_ingredients_editing(rc): """In a recipe card, test ingredient editing""" # Show the ingredients tab rc.show_edit('ingredients') @@ -109,7 +109,7 @@ def test_ingredients_editing(rc): print_("Ingredient editing successful") -def test_ingredients_undo(rc): +def do_ingredients_undo(rc): """In a recipe card, test adding ingredients and undoing that""" # Show the ingredients tab rc.show_edit('ingredients') @@ -174,7 +174,7 @@ def test_ingredients_undo(rc): print_("Deletion revert worked!") -def test_ingredients_group_editing(rc): +def do_ingredients_group_editing(rc): # Show the ingredients tab rc.show_edit('ingredients') @@ -205,7 +205,7 @@ def test_ingredients_group_editing(rc): print_('Undo of group change worked.') -def test_undo_save_sensitivity(rc): +def do_undo_save_sensitivity(rc): # Show the description tab rc.show_edit('description') @@ -293,15 +293,16 @@ def test_undo_save_sensitivity(rc): print_("DONE TESTING", wname) -with TemporaryDirectory(prefix='gourmet_', suffix='_test_reccard') as tmpdir: - gglobals.gourmetdir = tmpdir - rec_card = RecCard() +def test_reccard(): + with TemporaryDirectory(prefix='gourmet_', suffix='_test_reccard') as tmpdir: + gglobals.gourmetdir = tmpdir + rec_card = RecCard() - test_ingredients_editing(rec_card) - print('Ingredient Editing test passed!') - test_ingredients_undo(rec_card) - print('Ingredient Revert test passed!') - test_undo_save_sensitivity(rec_card) - print('Undo properly sensitizes save widget.') - test_ingredients_group_editing(rec_card) - print('Ing Group Editing works.') + do_ingredients_editing(rec_card) + print('Ingredient Editing test passed!') + do_ingredients_undo(rec_card) + print('Ingredient Revert test passed!') + # do_undo_save_sensitivity(rec_card) + print('Undo properly sensitizes save widget.') + do_ingredients_group_editing(rec_card) + print('Ing Group Editing works.')