From c0a8a8b3c3b06c71067d3c854d4c59611a0e96e3 Mon Sep 17 00:00:00 2001 From: Ioannis Tziakos Date: Fri, 21 Feb 2014 14:09:50 +0000 Subject: [PATCH 1/3] add support to listen on list items changes --- traits_enaml/tests/test_trait_operators.py | 30 +++++++++++++++++++--- traits_enaml/traits_tracer.py | 3 +++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/traits_enaml/tests/test_trait_operators.py b/traits_enaml/tests/test_trait_operators.py index 1ed5783..49c7a85 100644 --- a/traits_enaml/tests/test_trait_operators.py +++ b/traits_enaml/tests/test_trait_operators.py @@ -13,7 +13,7 @@ #---------------------------------------------------------------------------- import unittest -from traits.api import Event, HasTraits, Str +from traits.api import Event, HasTraits, Str, List from traits_enaml.testing.enaml_test_assistant import EnamlTestAssistant @@ -23,6 +23,7 @@ class TraitModel(HasTraits): value_update = Str() value_simple = Str('simple_text') value_notify = Event() + list_values = List(Str) class TraitOperatorsTestCase(EnamlTestAssistant, unittest.TestCase): @@ -52,6 +53,9 @@ def setUp(self): name = 'test_op_notify' text :: model.value_notify = True + Field: + name = 'test_list_subscribe' + text << str(model.list_values) """ self.model = TraitModel() view, toolkit_view = self.parse_and_create( @@ -74,7 +78,7 @@ def test_op_delegate(self): self.assertEquals(self.model.value_delegate, 'new_value') - with self.assertAtomChanges(enaml_widget, 'text'): + with self.assertAtomChanges(enaml_widget, 'text', count=1): self.model.value_delegate = 'updated_trait' self.assertEquals(enaml_widget.text, 'updated_trait') @@ -86,7 +90,7 @@ def test_op_subscribe(self): with self.assertTraitDoesNotChange(self.model, 'value_subscribe'): enaml_widget.text = 'new_value' - with self.assertAtomChanges(enaml_widget, 'text'): + with self.assertAtomChanges(enaml_widget, 'text', count=1): self.model.value_subscribe = 'updated_trait' self.assertEquals(enaml_widget.text, 'updated_trait') @@ -127,5 +131,23 @@ def test_op_notify(self): with self.assertTraitDoesNotChange(self.model, 'value_notify'): enaml_widget.text = 'changing text' - with self.assertTraitChanges(self.model, 'value_notify'): + with self.assertTraitChanges(self.model, 'value_notify', count=1): enaml_widget.text = 'new text' + + def test_list_subscribe(self): + + enaml_widget = self.view.find('test_list_subscribe') + + with self.assertTraitDoesNotChange(self.model, 'list_values'): + enaml_widget.text = 'new_value' + + # check on replace + with self.assertAtomChanges(enaml_widget, 'text'): + self.model.list_values = ['1'] + self.assertEquals(enaml_widget.text, "['1']") + + # check on append + with self.assertAtomChanges(enaml_widget, 'text'): + self.model.list_values.append('2') + self.assertEquals(enaml_widget.text, "['1', '2']") + diff --git a/traits_enaml/traits_tracer.py b/traits_enaml/traits_tracer.py index 4d4627a..3e446b7 100644 --- a/traits_enaml/traits_tracer.py +++ b/traits_enaml/traits_tracer.py @@ -61,6 +61,9 @@ def _trace_trait(self, obj, name): trait = obj.trait(name) if trait is not None and trait.trait_type is not Disallow: self.traced_traits.add((obj, name)) + # Check for lists + if obj._is_list_trait(name): + self.traced_traits.add((obj, '{}_items'.format(name))) #-------------------------------------------------------------------------- # AbstractScopeListener Interface From b6d853efd90cd56d149a1e1478a6fbe2f84c6e8c Mon Sep 17 00:00:00 2001 From: Ioannis Tziakos Date: Fri, 21 Feb 2014 15:08:23 +0000 Subject: [PATCH 2/3] make sure that item changes will trigger an update when collection traits are subscribed to enaml component attributes --- traits_enaml/tests/test_trait_operators.py | 63 ++++++++++++++++++++-- traits_enaml/traits_tracer.py | 2 +- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/traits_enaml/tests/test_trait_operators.py b/traits_enaml/tests/test_trait_operators.py index 49c7a85..0dee781 100644 --- a/traits_enaml/tests/test_trait_operators.py +++ b/traits_enaml/tests/test_trait_operators.py @@ -13,7 +13,7 @@ #---------------------------------------------------------------------------- import unittest -from traits.api import Event, HasTraits, Str, List +from traits.api import Event, HasTraits, Str, List, Dict, Set from traits_enaml.testing.enaml_test_assistant import EnamlTestAssistant @@ -24,6 +24,8 @@ class TraitModel(HasTraits): value_simple = Str('simple_text') value_notify = Event() list_values = List(Str) + dict_values = Dict(Str, Str) + set_values = Set(Str) class TraitOperatorsTestCase(EnamlTestAssistant, unittest.TestCase): @@ -56,6 +58,12 @@ def setUp(self): Field: name = 'test_list_subscribe' text << str(model.list_values) + Field: + name = 'test_dict_subscribe' + text << str(model.dict_values) + Field: + name = 'test_set_subscribe' + text << str(model.set_values) """ self.model = TraitModel() view, toolkit_view = self.parse_and_create( @@ -142,12 +150,61 @@ def test_list_subscribe(self): enaml_widget.text = 'new_value' # check on replace - with self.assertAtomChanges(enaml_widget, 'text'): + with self.assertAtomChanges(enaml_widget, 'text', count=1): self.model.list_values = ['1'] self.assertEquals(enaml_widget.text, "['1']") # check on append - with self.assertAtomChanges(enaml_widget, 'text'): + with self.assertAtomChanges(enaml_widget, 'text', count=1): self.model.list_values.append('2') self.assertEquals(enaml_widget.text, "['1', '2']") + # check on remove + with self.assertAtomChanges(enaml_widget, 'text', count=1): + self.model.list_values.remove('1') + self.assertEquals(enaml_widget.text, "['2']") + + def test_dict_subscribe(self): + + enaml_widget = self.view.find('test_dict_subscribe') + + with self.assertTraitDoesNotChange(self.model, 'list_values'): + enaml_widget.text = 'new_value' + + # check on replace + with self.assertAtomChanges(enaml_widget, 'text', count=1): + self.model.dict_values = {'one': '1'} + self.assertEquals(enaml_widget.text, "{'one': '1'}") + + # check on append + with self.assertAtomChanges(enaml_widget, 'text', count=1): + self.model.dict_values['two'] = '2' + self.assertEquals( + enaml_widget.text, str({'one': '1', 'two': '2'})) + + # check on remove + with self.assertAtomChanges(enaml_widget, 'text', count=1): + del self.model.dict_values['one'] + self.assertEquals(enaml_widget.text, "{'two': '2'}") + + def test_set_subscribe(self): + + enaml_widget = self.view.find('test_set_subscribe') + + with self.assertTraitDoesNotChange(self.model, 'list_values'): + enaml_widget.text = 'new_value' + + # check on replace + with self.assertAtomChanges(enaml_widget, 'text', count=1): + self.model.set_values = {'1'} + self.assertEquals(enaml_widget.text, "TraitSetObject(['1'])") + + # check on append + with self.assertAtomChanges(enaml_widget, 'text', count=1): + self.model.set_values.add('2') + self.assertEquals(enaml_widget.text, "TraitSetObject(['1', '2'])") + + # check on remove + with self.assertAtomChanges(enaml_widget, 'text', count=1): + self.model.set_values.remove('1') + self.assertEquals(enaml_widget.text, "TraitSetObject(['2'])") diff --git a/traits_enaml/traits_tracer.py b/traits_enaml/traits_tracer.py index 3e446b7..a72a7e3 100644 --- a/traits_enaml/traits_tracer.py +++ b/traits_enaml/traits_tracer.py @@ -62,7 +62,7 @@ def _trace_trait(self, obj, name): if trait is not None and trait.trait_type is not Disallow: self.traced_traits.add((obj, name)) # Check for lists - if obj._is_list_trait(name): + if trait.handler.has_items: self.traced_traits.add((obj, '{}_items'.format(name))) #-------------------------------------------------------------------------- From c64689ea451519d41c8f51fa6f2efe902c819c62 Mon Sep 17 00:00:00 2001 From: Ioannis Tziakos Date: Fri, 21 Feb 2014 15:11:10 +0000 Subject: [PATCH 3/3] fix comment --- traits_enaml/traits_tracer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traits_enaml/traits_tracer.py b/traits_enaml/traits_tracer.py index a72a7e3..f5d5df5 100644 --- a/traits_enaml/traits_tracer.py +++ b/traits_enaml/traits_tracer.py @@ -61,7 +61,7 @@ def _trace_trait(self, obj, name): trait = obj.trait(name) if trait is not None and trait.trait_type is not Disallow: self.traced_traits.add((obj, name)) - # Check for lists + # Check for collections. if trait.handler.has_items: self.traced_traits.add((obj, '{}_items'.format(name)))