json-beans/src/test/java/net/java/html/beans/MapModelTest.java
author Jaroslav Tulach <jtulach@netbeans.org>
Fri, 12 Feb 2016 08:40:12 +0100
branchbeans
changeset 1036 05139f7b3629
parent 951 json/src/test/java/net/java/html/json/MapModelTest.java@5ce0aab2c03c
parent 808 json/src/test/java/net/java/html/json/MapModelTest.java@d116ca60ae79
permissions -rw-r--r--
Bringing the beans branch up-to-date with release-1.2.3
     1 /**
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     5  *
     6  * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     7  * Other names may be trademarks of their respective owners.
     8  *
     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]"
    26  *
    27  * Contributor(s):
    28  *
    29  * The Original Software is NetBeans. The Initial Developer of the Original
    30  * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    31  *
    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.
    42  */
    43 package net.java.html.json;
    44 
    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;
    52 import java.util.Map;
    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.*;
    62 
    63 /**
    64  *
    65  * @author Jaroslav Tulach
    66  */
    67 public class MapModelTest {
    68     private MapTechnology t;
    69     private BrwsrCtx c;
    70 
    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();
    75     }
    76     
    77     @Test public void isThereNoApplyBinding() throws Exception {
    78         try {
    79             Person.class.getMethod("applyBindings");
    80         } catch (NoSuchMethodException ex) {
    81             // OK
    82             return;
    83         }
    84         fail("There should be no applyBindings() method");
    85     }
    86     
    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");
    92         
    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");
    97         One o = (One)v;
    98         assertEquals(o.changes, 1, "One change so far");
    99         assertFalse(o.pb.isReadOnly(), "Mutable property");
   100         
   101         assertEquals(o.get(), "Jarda", "Value should be in the map");
   102         
   103         o.set("Karle");
   104         
   105         assertEquals(p.getFirstName(), "Karle", "Model value updated");
   106         assertEquals(o.changes, 2, "Snd change");
   107     }
   108     
   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");
   113     }
   114     
   115     @Test public void dontNotifySameProperty() throws Exception {
   116         Person p = Models.bind(new Person(), c);
   117         p.setFirstName("Jirka");
   118         
   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");
   123         One o = (One)v;
   124         assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
   125         
   126         p.setFirstName(new String("Jirka"));
   127         assertEquals(o.changes, 0, "No change so far, the value is the same");
   128         
   129         p.setFirstName("Jarda");
   130         assertFalse(o.pb.isReadOnly(), "Mutable property");
   131         
   132         assertEquals(o.get(), "Jarda", "Value should be in the map");
   133         
   134         o.set("Karle");
   135         
   136         assertEquals(p.getFirstName(), "Karle", "Model value updated");
   137         assertEquals(o.changes, 2, "Snd change");
   138     }
   139     
   140     @Test public void canSetEnumAsString() throws Exception {
   141         Person p = Models.bind(new Person(), c);
   142         p.setFirstName("Jirka");
   143         p.setSex(Sex.MALE);
   144         
   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");
   149         One o = (One)v;
   150         
   151         o.set("FEMALE");
   152 
   153         assertEquals(p.getSex(), Sex.FEMALE, "Changed to female");
   154     }
   155     
   156     @Test public void derivedProperty() throws Exception {
   157         Person p = Models.bind(new Person(), c);
   158         
   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");
   163         One o = (One)v;
   164         assertTrue(o.pb.isReadOnly(), "Mutable property");
   165     }
   166     
   167     @Test public void changeSex() {
   168         Person p = Models.bind(new Person(), c);
   169         p.setFirstName("Trans");
   170         p.setSex(Sex.MALE);
   171         
   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);
   176         
   177         One one = (One)o;
   178         assertNotNull(one.fb, "Function binding specified");
   179         
   180         one.fb.call(null, null);
   181         
   182         assertEquals(p.getSex(), Sex.FEMALE, "Changed");
   183     }
   184     
   185     @Test public void setSex() {
   186         Person p = Models.bind(new Person(), c);
   187         p.setFirstName("Trans");
   188         
   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);
   193         
   194         One one = (One)o;
   195         assertNotNull(one.fb, "Function binding specified");
   196         
   197         one.fb.call("FEMALE", new Object());
   198         
   199         assertEquals(p.getSex(), Sex.FEMALE, "Changed");
   200     }
   201 
   202     @Test public void changeComputedProperty() {
   203         Modelik p = Models.bind(new Modelik(), c);
   204         p.setValue(5);
   205 
   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);
   210 
   211         One one = (One)o;
   212         assertNotNull(one.pb, "Prop binding specified");
   213 
   214         assertEquals(one.pb.getValue(), 25, "Power of 5");
   215 
   216         one.pb.setValue(16);
   217         assertEquals(p.getValue(), 4, "Square root of 16");
   218     }
   219     
   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");
   225 
   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);
   230         One one = (One)o;
   231         
   232         
   233         assertEquals(one.changes, 0, "No change");
   234         
   235         Iterator<String> it = p.getNicknames().iterator();
   236         assertEquals(it.next(), "One");
   237         assertEquals(it.next(), "Two");
   238         it.remove();
   239         assertEquals(it.next(), "Three");
   240         assertFalse(it.hasNext());
   241         
   242         
   243         assertEquals(one.changes, 1, "One change");
   244     }
   245     
   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");
   251 
   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);
   256         One one = (One)o;
   257         
   258         
   259         assertEquals(one.changes, 0, "No change");
   260         
   261         ListIterator<String> it = p.getNicknames().listIterator(1);
   262         assertEquals(it.next(), "Two");
   263         it.remove();
   264         assertEquals(it.next(), "Three");
   265         assertFalse(it.hasNext());
   266         
   267         
   268         assertEquals(one.changes, 1, "One change");
   269         
   270         it.set("3");
   271         assertEquals(p.getNicknames().get(1), "3");
   272         
   273         assertEquals(one.changes, 2, "Snd change");
   274     }
   275 
   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");
   281 
   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);
   286         One one = (One)o;
   287         
   288         Map<String,Object> obj = new HashMap<String, Object>();
   289         obj.put("nick", "newNick");
   290         obj.put("x", 42);
   291         obj.put("y", 7.7f);
   292         final Person data = new Person("a", "b", Sex.MALE);
   293         
   294         one.fb.call(data, obj);
   295 
   296         assertEquals(p.getInfo().size(), 1, "a+b is there: " + p.getInfo());
   297         assertEquals(p.getInfo().get(0), data, "Expecting data: " + p.getInfo());
   298         
   299         assertEquals(p.getNicknames().size(), 4, "One more nickname: " + p.getNicknames());
   300         assertEquals(p.getNicknames().get(3), "newNick");
   301         
   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);
   305     }
   306     
   307     static final class One {
   308         int changes;
   309         final PropertyBinding pb;
   310         final FunctionBinding fb;
   311     
   312         One(Object m, PropertyBinding pb) throws NoSuchMethodException {
   313             this.pb = pb;
   314             this.fb = null;
   315         }
   316         One(Object m, FunctionBinding fb) throws NoSuchMethodException {
   317             this.pb = null;
   318             this.fb = fb;
   319         }
   320         
   321         Object get() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
   322             return pb.getValue();
   323         }
   324         
   325         void set(Object v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
   326             pb.setValue(v);
   327         }
   328     }
   329     
   330     static final class MapTechnology 
   331     implements Technology.ApplyId<Map<String,One>>, Transfer {
   332         private Map<String, One> appliedData;
   333         private String appliedId;
   334 
   335         @Override
   336         public Map<String, One> wrapModel(Object model) {
   337             return new HashMap<String, One>();
   338         }
   339 
   340         @Override
   341         public void valueHasMutated(Map<String, One> data, String propertyName) {
   342             One p = data.get(propertyName);
   343             if (p != null) {
   344                 p.changes++;
   345             }
   346         }
   347 
   348         @Override
   349         public void bind(PropertyBinding b, Object model, Map<String, One> data) {
   350             try {
   351                 One o = new One(model, b);
   352                 data.put(b.getPropertyName(), o);
   353             } catch (NoSuchMethodException ex) {
   354                 throw new IllegalStateException(ex);
   355             }
   356         }
   357 
   358         @Override
   359         public void expose(FunctionBinding fb, Object model, Map<String, One> data) {
   360             try {
   361                 data.put(fb.getFunctionName(), new One(model, fb));
   362             } catch (NoSuchMethodException ex) {
   363                 throw new IllegalStateException(ex);
   364             }
   365         }
   366 
   367         @Override
   368         public void applyBindings(Map<String, One> data) {
   369             throw new UnsupportedOperationException("Never called!");
   370         }
   371 
   372         @Override
   373         public Object wrapArray(Object[] arr) {
   374             return arr;
   375         }
   376 
   377         @Override
   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++) {
   381                 if (map == null) {
   382                     values[i] = null;
   383                 } else {
   384                     values[i] = map.get(props[i]);
   385                     if (values[i] instanceof One) {
   386                         values[i] = ((One)values[i]).pb.getValue();
   387                     }
   388                 }
   389             }
   390         }
   391 
   392         @Override
   393         public void loadJSON(JSONCall call) {
   394             call.notifyError(new UnsupportedOperationException());
   395         }
   396 
   397         @Override
   398         public <M> M toModel(Class<M> modelClass, Object data) {
   399             return modelClass.cast(data);
   400         }
   401 
   402         @Override
   403         public Object toJSON(InputStream is) throws IOException {
   404             throw new IOException();
   405         }
   406 
   407         @Override
   408         public void runSafe(Runnable r) {
   409             throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   410         }
   411 
   412         @Override
   413         public void applyBindings(String id, Map<String, One> data) {
   414             this.appliedId = id;
   415             this.appliedData = data;
   416         }
   417     }
   418 }