def test_execute(self):
        d = DataContext()
        d['a'] = 1
        d['b'] = 3
        d['g'] = 5
        rce = RestrictingCodeExecutable(code=CODE)
        ec = AsyncExecutingContext(subcontext=d, executable=rce)
        ec.on_trait_change(self._items_modified_fired, 'items_modified')

        ec.execute()
        ec._wait()
        self.assertEqual(self.events[0].added, ['c', 'd', 'f'])
        self.assertEqual(len(self.events), 1)
    def test_execute_for_names(self):
        """`execute_for_names()` is part of the ExecutingContext interface """

        d = DataContext()
        d['a'] = 1
        d['b'] = 3
        d['g'] = 5
        rce = RestrictingCodeExecutable(code=CODE)
        ec = AsyncExecutingContext(subcontext=d, executable=rce)
        ec.on_trait_change(self._items_modified_fired, 'items_modified')

        ec.execute_for_names(['g'])
        ec._wait()
        self.assertEqual(self.events[0].added, ['f'])
class TestRestrictingCodeExecutable(unittest.TestCase):
    def setUp(self):
        self.restricting_exec = RestrictingCodeExecutable(code=CODE)
        self.context = {'a': 1, 'b': 10}
        self.events = []

    def test_execute(self):
        self.restricting_exec.execute(self.context)
        expected_context = {'a': 1, 'b': 10, 'aa': 2, 'bb': 20, 'c': 33}
        self.assertEqual(self.context, expected_context)

    def test_restrict_on_inputs(self):
        context = {'a': 1, 'b': 10, 'bb': 100}
        self.restricting_exec.execute(context, inputs=['a'])
        #Check if `bb` was incorrectly overwritten by the codeblock
        self.assertEqual(context['bb'], 100)

    def test_restrict_on_outputs(self):
        context = {'b': 10, 'bb': 100}
        self.restricting_exec.execute(context, outputs=['bb'])
        self.assertEqual(context, {'b': 10, 'bb': 20})

    def test_code_exists(self):
        self.assertEqual(self.restricting_exec.code, CODE)
        self.assertEqual(self.restricting_exec._block.codestring, CODE)

    def test_code_changing(self):
        self.restricting_exec.on_trait_change(self._change_detect, '_block')
        self.restricting_exec.code = "c = a + b"
        self.assertEqual(self.events, ['fired'])

    def test_api_compatibility(self):
        executing_context = ExecutingContext(executable=self.restricting_exec,
                                             subcontext=self.context)
        self.assertIs(self.context, executing_context.subcontext.subcontext)
        executing_context.execute_for_names(None)
        executing_context.on_trait_change(self._change_detect,
                                          'items_modified')
        executing_context['bb'] = 5
        self.assertEqual(self.events, ['fired', 'fired'])
        expected_context = {'a': 1, 'b': 10, 'aa': 2, 'bb': 5, 'c': 18}
        self.assertEqual(self.context, expected_context)

    def _change_detect(self):
        self.events.append('fired')
class TestRestrictingCodeExecutable(unittest.TestCase):

    def setUp(self):
        self.restricting_exec = RestrictingCodeExecutable(code=CODE)
        self.context = {'a': 1, 'b': 10}
        self.events = []

    def test_execute(self):
        self.restricting_exec.execute(self.context)
        expected_context = {'a': 1, 'b': 10, 'aa': 2, 'bb': 20, 'c': 33}
        self.assertEqual(self.context, expected_context)

    def test_restrict_on_inputs(self):
        context = {'a': 1, 'b': 10, 'bb': 100}
        self.restricting_exec.execute(context, inputs=['a'])
        #Check if `bb` was incorrectly overwritten by the codeblock
        self.assertEqual(context['bb'], 100)

    def test_restrict_on_outputs(self):
        context = {'b': 10, 'bb': 100}
        self.restricting_exec.execute(context, outputs=['bb'])
        self.assertEqual(context, {'b': 10, 'bb': 20})

    def test_code_exists(self):
        self.assertEqual(self.restricting_exec.code, CODE)
        self.assertEqual(self.restricting_exec._block.codestring, CODE)

    def test_code_changing(self):
        self.restricting_exec.on_trait_change(self._change_detect, '_block')
        self.restricting_exec.code = "c = a + b"
        self.assertEqual(self.events, ['fired'])

    def test_api_compatibility(self):
        executing_context = ExecutingContext(executable=self.restricting_exec,
                subcontext=self.context)
        self.assertIs(self.context, executing_context.subcontext.subcontext)
        executing_context.execute_for_names(None)
        executing_context.on_trait_change(self._change_detect, 'items_modified')
        executing_context['bb'] = 5
        self.assertEqual(self.events, ['fired', 'fired'])
        expected_context = {'a': 1, 'b': 10, 'aa': 2, 'bb': 5, 'c': 18}
        self.assertEqual(self.context, expected_context)

    def _change_detect(self, new):
        self.events.append('fired')
 def setUp(self):
     self.restricting_exec = RestrictingCodeExecutable(code=CODE)
     self.context = {'a': 1, 'b': 10}
     self.events = []
 def setUp(self):
     self.restricting_exec = RestrictingCodeExecutable(code=CODE)
     self.context = {'a': 1, 'b': 10}
     self.events = []