2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
6 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 * Other names may be trademarks of their respective owners.
9 * The contents of this file are subject to the terms of either the GNU
10 * General Public License Version 2 only ("GPL") or the Common
11 * Development and Distribution License("CDDL") (collectively, the
12 * "License"). You may not use this file except in compliance with the
13 * License. You can obtain a copy of the License at
14 * http://www.netbeans.org/cddl-gplv2.html
15 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 * specific language governing permissions and limitations under the
17 * License. When distributing the software, include this License Header
18 * Notice in each file and include the License file at
19 * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 * particular file as subject to the "Classpath" exception as provided
21 * by Oracle in the GPL Version 2 section of the License file that
22 * accompanied this code. If applicable, add the following below the
23 * License Header, with the fields enclosed by brackets [] replaced by
24 * your own identifying information:
25 * "Portions Copyrighted [year] [name of copyright owner]"
29 * The Original Software is NetBeans. The Initial Developer of the Original
30 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
32 * If you wish your version of this file to be governed by only the CDDL
33 * or only the GPL Version 2, indicate your decision by adding
34 * "[Contributor] elects to include this software in this distribution
35 * under the [CDDL or GPL Version 2] license." If you do not indicate a
36 * single choice of license, a recipient has the option to distribute
37 * your version of this file under either the CDDL, the GPL Version 2 or
38 * to extend the choice of license to its licensees as provided above.
39 * However, if you add GPL Version 2 code and therefore, elected the GPL
40 * Version 2 license, then the option applies only if the new code is
41 * made subject to such option by the copyright holder.
43 package net.java.html.json;
45 import net.java.html.BrwsrCtx;
46 import java.io.IOException;
47 import java.io.InputStream;
48 import java.lang.reflect.InvocationTargetException;
49 import java.util.HashMap;
50 import java.util.Iterator;
51 import java.util.ListIterator;
53 import org.netbeans.html.context.spi.Contexts;
54 import org.netbeans.html.json.spi.FunctionBinding;
55 import org.netbeans.html.json.spi.JSONCall;
56 import org.netbeans.html.json.spi.PropertyBinding;
57 import org.netbeans.html.json.spi.Technology;
58 import org.netbeans.html.json.spi.Transfer;
59 import org.testng.annotations.BeforeMethod;
60 import org.testng.annotations.Test;
61 import static org.testng.Assert.*;
65 * @author Jaroslav Tulach
67 public class MapModelTest {
68 private MapTechnology t;
71 @BeforeMethod public void initTechnology() {
72 t = new MapTechnology();
73 c = Contexts.newBuilder().register(Technology.class, t, 1).
74 register(Transfer.class, t, 1).build();
77 @Test public void isThereNoApplyBinding() throws Exception {
79 Person.class.getMethod("applyBindings");
80 } catch (NoSuchMethodException ex) {
84 fail("There should be no applyBindings() method");
87 @Test public void isThereABinding() throws Exception {
88 Person p = Models.bind(new Person(), c);
89 Models.applyBindings(p);
90 assertNull(t.appliedId, "Applied globally");
91 p.setFirstName("Jarda");
93 Map m = (Map)Models.toRaw(p);
94 Object v = m.get("firstName");
95 assertNotNull(v, "Value should be in the map");
96 assertEquals(v.getClass(), One.class, "It is instance of One");
98 assertEquals(o.changes, 1, "One change so far");
99 assertFalse(o.pb.isReadOnly(), "Mutable property");
101 assertEquals(o.get(), "Jarda", "Value should be in the map");
105 assertEquals(p.getFirstName(), "Karle", "Model value updated");
106 assertEquals(o.changes, 2, "Snd change");
109 @Test public void applyLocally() throws Exception {
110 Person p = Models.bind(new Person(), c);
111 Models.applyBindings(p, "local");
112 assertEquals(t.appliedId, "local", "Applied locally");
115 @Test public void dontNotifySameProperty() throws Exception {
116 Person p = Models.bind(new Person(), c);
117 p.setFirstName("Jirka");
119 Map m = (Map)Models.toRaw(p);
120 Object v = m.get("firstName");
121 assertNotNull(v, "Value should be in the map");
122 assertEquals(v.getClass(), One.class, "It is instance of One");
124 assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
126 p.setFirstName(new String("Jirka"));
127 assertEquals(o.changes, 0, "No change so far, the value is the same");
129 p.setFirstName("Jarda");
130 assertFalse(o.pb.isReadOnly(), "Mutable property");
132 assertEquals(o.get(), "Jarda", "Value should be in the map");
136 assertEquals(p.getFirstName(), "Karle", "Model value updated");
137 assertEquals(o.changes, 2, "Snd change");
140 @Test public void canSetEnumAsString() throws Exception {
141 Person p = Models.bind(new Person(), c);
142 p.setFirstName("Jirka");
145 Map m = (Map)Models.toRaw(p);
146 Object v = m.get("sex");
147 assertNotNull(v, "Value should be in the map");
148 assertEquals(v.getClass(), One.class, "It is instance of One");
153 assertEquals(p.getSex(), Sex.FEMALE, "Changed to female");
156 @Test public void derivedProperty() throws Exception {
157 Person p = Models.bind(new Person(), c);
159 Map m = (Map)Models.toRaw(p);
160 Object v = m.get("fullName");
161 assertNotNull(v, "Value should be in the map");
162 assertEquals(v.getClass(), One.class, "It is instance of One");
164 assertTrue(o.pb.isReadOnly(), "Mutable property");
167 @Test public void changeSex() {
168 Person p = Models.bind(new Person(), c);
169 p.setFirstName("Trans");
172 Map m = (Map)Models.toRaw(p);
173 Object o = m.get("changeSex");
174 assertNotNull(o, "Function registered in the model");
175 assertEquals(o.getClass(), One.class);
178 assertNotNull(one.fb, "Function binding specified");
180 one.fb.call(null, null);
182 assertEquals(p.getSex(), Sex.FEMALE, "Changed");
185 @Test public void setSex() {
186 Person p = Models.bind(new Person(), c);
187 p.setFirstName("Trans");
189 Map m = (Map)Models.toRaw(p);
190 Object o = m.get("changeSex");
191 assertNotNull(o, "Function registered in the model");
192 assertEquals(o.getClass(), One.class);
195 assertNotNull(one.fb, "Function binding specified");
197 one.fb.call("FEMALE", new Object());
199 assertEquals(p.getSex(), Sex.FEMALE, "Changed");
202 @Test public void changeComputedProperty() {
203 Modelik p = Models.bind(new Modelik(), c);
206 Map m = (Map)Models.toRaw(p);
207 Object o = m.get("powerValue");
208 assertNotNull(o, "Value is there");
209 assertEquals(o.getClass(), One.class);
212 assertNotNull(one.pb, "Prop binding specified");
214 assertEquals(one.pb.getValue(), 25, "Power of 5");
217 assertEquals(p.getValue(), 4, "Square root of 16");
220 @Test public void removeViaIterator() {
221 People p = Models.bind(new People(), c);
222 p.getNicknames().add("One");
223 p.getNicknames().add("Two");
224 p.getNicknames().add("Three");
226 Map m = (Map)Models.toRaw(p);
227 Object o = m.get("nicknames");
228 assertNotNull(o, "List registered in the model");
229 assertEquals(o.getClass(), One.class);
233 assertEquals(one.changes, 0, "No change");
235 Iterator<String> it = p.getNicknames().iterator();
236 assertEquals(it.next(), "One");
237 assertEquals(it.next(), "Two");
239 assertEquals(it.next(), "Three");
240 assertFalse(it.hasNext());
243 assertEquals(one.changes, 1, "One change");
246 @Test public void removeViaListIterator() {
247 People p = Models.bind(new People(), c);
248 p.getNicknames().add("One");
249 p.getNicknames().add("Two");
250 p.getNicknames().add("Three");
252 Map m = (Map)Models.toRaw(p);
253 Object o = m.get("nicknames");
254 assertNotNull(o, "List registered in the model");
255 assertEquals(o.getClass(), One.class);
259 assertEquals(one.changes, 0, "No change");
261 ListIterator<String> it = p.getNicknames().listIterator(1);
262 assertEquals(it.next(), "Two");
264 assertEquals(it.next(), "Three");
265 assertFalse(it.hasNext());
268 assertEquals(one.changes, 1, "One change");
271 assertEquals(p.getNicknames().get(1), "3");
273 assertEquals(one.changes, 2, "Snd change");
276 @Test public void functionWithParameters() {
277 People p = Models.bind(new People(), c);
278 p.getNicknames().add("One");
279 p.getNicknames().add("Two");
280 p.getNicknames().add("Three");
282 Map m = (Map)Models.toRaw(p);
283 Object o = m.get("inInnerClass");
284 assertNotNull(o, "functiton is available");
285 assertEquals(o.getClass(), One.class);
288 Map<String,Object> obj = new HashMap<String, Object>();
289 obj.put("nick", "newNick");
292 final Person data = new Person("a", "b", Sex.MALE);
294 one.fb.call(data, obj);
296 assertEquals(p.getInfo().size(), 1, "a+b is there: " + p.getInfo());
297 assertEquals(p.getInfo().get(0), data, "Expecting data: " + p.getInfo());
299 assertEquals(p.getNicknames().size(), 4, "One more nickname: " + p.getNicknames());
300 assertEquals(p.getNicknames().get(3), "newNick");
302 assertEquals(p.getAge().size(), 2, "Two new values: " + p.getAge());
303 assertEquals(p.getAge().get(0).intValue(), 42);
304 assertEquals(p.getAge().get(1).intValue(), 7);
307 static final class One {
309 final PropertyBinding pb;
310 final FunctionBinding fb;
312 One(Object m, PropertyBinding pb) throws NoSuchMethodException {
316 One(Object m, FunctionBinding fb) throws NoSuchMethodException {
321 Object get() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
322 return pb.getValue();
325 void set(Object v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
330 static final class MapTechnology
331 implements Technology.ApplyId<Map<String,One>>, Transfer {
332 private Map<String, One> appliedData;
333 private String appliedId;
336 public Map<String, One> wrapModel(Object model) {
337 return new HashMap<String, One>();
341 public void valueHasMutated(Map<String, One> data, String propertyName) {
342 One p = data.get(propertyName);
349 public void bind(PropertyBinding b, Object model, Map<String, One> data) {
351 One o = new One(model, b);
352 data.put(b.getPropertyName(), o);
353 } catch (NoSuchMethodException ex) {
354 throw new IllegalStateException(ex);
359 public void expose(FunctionBinding fb, Object model, Map<String, One> data) {
361 data.put(fb.getFunctionName(), new One(model, fb));
362 } catch (NoSuchMethodException ex) {
363 throw new IllegalStateException(ex);
368 public void applyBindings(Map<String, One> data) {
369 throw new UnsupportedOperationException("Never called!");
373 public Object wrapArray(Object[] arr) {
378 public void extract(Object obj, String[] props, Object[] values) {
379 Map<?,?> map = obj instanceof Map ? (Map<?,?>)obj : null;
380 for (int i = 0; i < Math.min(props.length, values.length); i++) {
384 values[i] = map.get(props[i]);
385 if (values[i] instanceof One) {
386 values[i] = ((One)values[i]).pb.getValue();
393 public void loadJSON(JSONCall call) {
394 call.notifyError(new UnsupportedOperationException());
398 public <M> M toModel(Class<M> modelClass, Object data) {
399 return modelClass.cast(data);
403 public Object toJSON(InputStream is) throws IOException {
404 throw new IOException();
408 public void runSafe(Runnable r) {
409 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
413 public void applyBindings(String id, Map<String, One> data) {
415 this.appliedData = data;