1# (C) Copyright 2007-2019 Enthought, Inc., Austin, TX
2# All rights reserved.
3#
4# This software is provided without warranty under the terms of the BSD
5# license included in LICENSE.txt and may be redistributed only
6# under the conditions described in the aforementioned license.  The license
7# is also available online at http://www.enthought.com/licenses/BSD.txt
8# Thanks for using Enthought open source!
9""" Tests to help find out how trait list events work.
10
11These tests exist because when we are using the 'ExtensionPoint' trait type
12we try to mimic trait list events when extensions are added or removed.
13
14"""
15
16
17# Enthought library imports.
18from traits.api import HasTraits, List
19from traits.testing.unittest_tools import unittest
20
21
22# The starting list for all tests.
23TEST_LIST = [7, 9, 2, 3, 4, 1, 6, 5, 8, 0]
24
25
26def listener(obj, trait_name, old, event):
27    """ Recreate a list operation from a trait list event. """
28
29    clone = TEST_LIST[:]
30
31    # If nothing was added then this is a 'del' or 'remove' operation.
32    if len(event.added) == 0:
33        if isinstance(event.index, slice):
34            del clone[event.index]
35
36        else:
37            # workaroud for traits bug in Python 3
38            # https://github.com/enthought/traits/issues/334
39            index = event.index if event.index is not None else 0
40            del clone[index:index + len(event.removed)]
41
42    # If nothing was removed then it is an 'append', 'insert' or 'extend'
43    # operation.
44    elif len(event.removed) == 0:
45        if isinstance(event.index, slice):
46            clone[event.index] = event.added[0]
47
48        else:
49            clone.insert(event.index, event.added[0])
50
51    # Otherwise, it is an assigment ('sort' and 'reverse' fall into this
52    # category).
53    else:
54        if isinstance(event.index, slice):
55            clone[event.index] = event.added[0]
56
57        else:
58            clone[event.index : event.index + len(event.added)] = event.added
59
60    listener.clone = clone
61
62
63class SliceTestCase(unittest.TestCase):
64    """ Tests to help find out how trait list events work. """
65
66    def setUp(self):
67        """ Prepares the test fixture before each test method is called. """
68
69        class Foo(HasTraits):
70            l = List
71
72        self.f = Foo(l=TEST_LIST)
73        self.f.on_trait_change(listener, 'l_items')
74
75    def test_append(self):
76        """ append """
77
78        self.f.l.append(99)
79        # Make sure we successfully recreated the operation.
80        self.assertEqual(self.f.l, listener.clone)
81
82    def test_insert(self):
83        """ insert """
84
85        self.f.l.insert(3, 99)
86        # Make sure we successfully recreated the operation.
87        self.assertEqual(self.f.l, listener.clone)
88
89    def test_extend(self):
90        """ extend """
91
92        self.f.l.append([99, 100])
93        # Make sure we successfully recreated the operation.
94        self.assertEqual(self.f.l, listener.clone)
95
96    def test_remove(self):
97        """ remove """
98
99        self.f.l.remove(5)
100        # Make sure we successfully recreated the operation.
101        self.assertEqual(self.f.l, listener.clone)
102
103    def test_reverse(self):
104        """ reverse """
105
106        self.f.l.reverse()
107        # Make sure we successfully recreated the operation.
108        self.assertEqual(self.f.l, listener.clone)
109
110    def test_sort(self):
111        """ sort """
112
113        self.f.l.sort()
114        # Make sure we successfully recreated the operation.
115        self.assertEqual(self.f.l, listener.clone)
116
117    def test_pop(self):
118        """ remove """
119
120        self.f.l.pop()
121        # Make sure we successfully recreated the operation.
122        self.assertEqual(self.f.l, listener.clone)
123
124    def test_del_all(self):
125        """ del all """
126
127        del self.f.l[:]
128        # Make sure we successfully recreated the operation.
129        self.assertEqual(self.f.l, listener.clone)
130
131    def test_assign_item(self):
132        """ assign item """
133
134        self.f.l[3] = 99
135        # Make sure we successfully recreated the operation.
136        self.assertEqual(self.f.l, listener.clone)
137
138    def test_del_item(self):
139        """ del item """
140
141        del self.f.l[3]
142        # Make sure we successfully recreated the operation.
143        self.assertEqual(self.f.l, listener.clone)
144
145    def test_assign_slice(self):
146        """ assign slice """
147
148        self.f.l[2:4] = [88, 99]
149        # Make sure we successfully recreated the operation.
150        self.assertEqual(self.f.l, listener.clone)
151
152    def test_del_slice(self):
153        """ del slice """
154
155        del self.f.l[2:5]
156        # Make sure we successfully recreated the operation.
157        self.assertEqual(self.f.l, listener.clone)
158
159    def test_assign_extended_slice(self):
160        """ assign extended slice """
161
162        self.f.l[2:6:2] = [88, 99]
163        # Make sure we successfully recreated the operation.
164        self.assertEqual(self.f.l, listener.clone)
165
166    def test_del_extended_slice(self):
167        """ del extended slice """
168
169        del self.f.l[2:6:2]
170        # Make sure we successfully recreated the operation.
171        self.assertEqual(self.f.l, listener.clone)
172