1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.databinding.testapp;
17
18import android.databinding.ObservableArrayList;
19import android.databinding.testapp.databinding.BasicBindingBinding;
20
21import android.databinding.ObservableList;
22import android.databinding.ObservableList.OnListChangedCallback;
23
24import java.util.ArrayList;
25
26public class ObservableArrayListTest extends BaseDataBinderTest<BasicBindingBinding> {
27
28    private static final int ALL = 0;
29
30    private static final int CHANGE = 1;
31
32    private static final int INSERT = 2;
33
34    private static final int MOVE = 3;
35
36    private static final int REMOVE = 4;
37
38    private ObservableList<String> mObservable;
39
40    private ArrayList<ListChange> mNotifications = new ArrayList<>();
41
42    private OnListChangedCallback mListener = new OnListChangedCallback() {
43        @Override
44        public void onChanged(ObservableList sender) {
45            mNotifications.add(new ListChange(ALL, 0, 0));
46        }
47
48        @Override
49        public void onItemRangeChanged(ObservableList sender, int start, int count) {
50            mNotifications.add(new ListChange(CHANGE, start, count));
51        }
52
53        @Override
54        public void onItemRangeInserted(ObservableList sender, int start, int count) {
55            mNotifications.add(new ListChange(INSERT, start, count));
56        }
57
58        @Override
59        public void onItemRangeMoved(ObservableList sender, int from, int to, int count) {
60            mNotifications.add(new ListChange(MOVE, from, to, count));
61        }
62
63        @Override
64        public void onItemRangeRemoved(ObservableList sender, int start, int count) {
65            mNotifications.add(new ListChange(REMOVE, start, count));
66        }
67    };
68
69    private static class ListChange {
70
71        public ListChange(int change, int start, int count) {
72            this.start = start;
73            this.count = count;
74            this.from = 0;
75            this.to = 0;
76            this.change = change;
77        }
78
79        public ListChange(int change, int from, int to, int count) {
80            this.from = from;
81            this.to = to;
82            this.count = count;
83            this.start = 0;
84            this.change = change;
85        }
86
87        public final int start;
88
89        public final int count;
90
91        public final int from;
92
93        public final int to;
94
95        public final int change;
96    }
97
98    public ObservableArrayListTest() {
99        super(BasicBindingBinding.class);
100    }
101
102    @Override
103    protected void setUp() throws Exception {
104        mNotifications.clear();
105        mObservable = new ObservableArrayList<>();
106    }
107
108    public void testAddListener() {
109        mObservable.add("Hello");
110        assertTrue(mNotifications.isEmpty());
111        mObservable.addOnListChangedCallback(mListener);
112        mObservable.add("World");
113        assertFalse(mNotifications.isEmpty());
114    }
115
116    public void testRemoveListener() {
117        // test there is no exception when the listener isn't there
118        mObservable.removeOnListChangedCallback(mListener);
119
120        mObservable.addOnListChangedCallback(mListener);
121        mObservable.add("Hello");
122        mNotifications.clear();
123        mObservable.removeOnListChangedCallback(mListener);
124        mObservable.add("World");
125        assertTrue(mNotifications.isEmpty());
126
127        // test there is no exception when the listener isn't there
128        mObservable.removeOnListChangedCallback(mListener);
129    }
130
131    public void testAdd() {
132        OnListChangedCallback listChangedListener = new OnListChangedCallback() {
133            @Override
134            public void onChanged(ObservableList sender) {
135            }
136
137            @Override
138            public void onItemRangeChanged(ObservableList sender, int i, int i1) {
139
140            }
141
142            @Override
143            public void onItemRangeInserted(ObservableList sender, int i, int i1) {
144
145            }
146
147            @Override
148            public void onItemRangeMoved(ObservableList sender, int i, int i1, int i2) {
149
150            }
151
152            @Override
153            public void onItemRangeRemoved(ObservableList sender, int i, int i1) {
154            }
155        };
156        mObservable.addOnListChangedCallback(mListener);
157        mObservable.addOnListChangedCallback(listChangedListener);
158        mObservable.add("Hello");
159        assertEquals(1, mNotifications.size());
160        ListChange change = mNotifications.get(0);
161        assertEquals(INSERT, change.change);
162        assertEquals(0, change.start);
163        assertEquals(1, change.count);
164        assertEquals("Hello", mObservable.get(0));
165    }
166
167    public void testInsert() {
168        mObservable.addOnListChangedCallback(mListener);
169        mObservable.add("Hello");
170        mObservable.add(0, "World");
171        mObservable.add(1, "Dang");
172        mObservable.add(3, "End");
173        assertEquals(4, mObservable.size());
174        assertEquals("World", mObservable.get(0));
175        assertEquals("Dang", mObservable.get(1));
176        assertEquals("Hello", mObservable.get(2));
177        assertEquals("End", mObservable.get(3));
178        assertEquals(4, mNotifications.size());
179        ListChange change = mNotifications.get(1);
180        assertEquals(INSERT, change.change);
181        assertEquals(0, change.start);
182        assertEquals(1, change.count);
183    }
184
185    public void testAddAll() {
186        ArrayList<String> toAdd = new ArrayList<>();
187        toAdd.add("Hello");
188        toAdd.add("World");
189        mObservable.add("First");
190        mObservable.addOnListChangedCallback(mListener);
191        mObservable.addAll(toAdd);
192        assertEquals(3, mObservable.size());
193        assertEquals("Hello", mObservable.get(1));
194        assertEquals("World", mObservable.get(2));
195        assertEquals(1, mNotifications.size());
196        ListChange change = mNotifications.get(0);
197        assertEquals(INSERT, change.change);
198        assertEquals(1, change.start);
199        assertEquals(2, change.count);
200    }
201
202    public void testInsertAll() {
203        ArrayList<String> toAdd = new ArrayList<>();
204        toAdd.add("Hello");
205        toAdd.add("World");
206        mObservable.add("First");
207        mObservable.addOnListChangedCallback(mListener);
208        mObservable.addAll(0, toAdd);
209        assertEquals(3, mObservable.size());
210        assertEquals("Hello", mObservable.get(0));
211        assertEquals("World", mObservable.get(1));
212        assertEquals(1, mNotifications.size());
213        ListChange change = mNotifications.get(0);
214        assertEquals(INSERT, change.change);
215        assertEquals(0, change.start);
216        assertEquals(2, change.count);
217    }
218
219    public void testClear() {
220        mObservable.add("Hello");
221        mObservable.add("World");
222        mObservable.addOnListChangedCallback(mListener);
223        mObservable.clear();
224        assertEquals(1, mNotifications.size());
225        ListChange change = mNotifications.get(0);
226        assertEquals(REMOVE, change.change);
227        assertEquals(0, change.start);
228        assertEquals(2, change.count);
229
230        mObservable.clear();
231        // No notification when nothing is cleared.
232        assertEquals(1, mNotifications.size());
233    }
234
235    public void testRemoveIndex() {
236        mObservable.add("Hello");
237        mObservable.add("World");
238        mObservable.addOnListChangedCallback(mListener);
239        assertEquals("Hello", mObservable.remove(0));
240        assertEquals(1, mNotifications.size());
241        ListChange change = mNotifications.get(0);
242        assertEquals(REMOVE, change.change);
243        assertEquals(0, change.start);
244        assertEquals(1, change.count);
245    }
246
247    public void testRemoveObject() {
248        mObservable.add("Hello");
249        mObservable.add("World");
250        mObservable.addOnListChangedCallback(mListener);
251        assertTrue(mObservable.remove("Hello"));
252        assertEquals(1, mNotifications.size());
253        ListChange change = mNotifications.get(0);
254        assertEquals(REMOVE, change.change);
255        assertEquals(0, change.start);
256        assertEquals(1, change.count);
257
258        assertFalse(mObservable.remove("Hello"));
259        // nothing removed, don't notify
260        assertEquals(1, mNotifications.size());
261    }
262
263    public void testSet() {
264        mObservable.add("Hello");
265        mObservable.add("World");
266        mObservable.addOnListChangedCallback(mListener);
267        assertEquals("Hello", mObservable.set(0, "Goodbye"));
268        assertEquals("Goodbye", mObservable.get(0));
269        assertEquals(2, mObservable.size());
270        ListChange change = mNotifications.get(0);
271        assertEquals(CHANGE, change.change);
272        assertEquals(0, change.start);
273        assertEquals(1, change.count);
274    }
275}
276