json/src/test/java/net/java/html/json/ModelTest.java
author Jaroslav Tulach <jaroslav.tulach@netbeans.org>
Fri, 07 Feb 2014 07:44:34 +0100
changeset 551 7ca2253fa86d
parent 453 5e90ec3cd61a
child 562 76a91ecf3ca9
permissions -rw-r--r--
Updating copyright headers to mention current year
jtulach@0
     1
/**
jaroslav@358
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jtulach@0
     3
 *
jaroslav@551
     4
 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
jtulach@0
     5
 *
jaroslav@358
     6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
jaroslav@358
     7
 * Other names may be trademarks of their respective owners.
jtulach@0
     8
 *
jaroslav@358
     9
 * The contents of this file are subject to the terms of either the GNU
jaroslav@358
    10
 * General Public License Version 2 only ("GPL") or the Common
jaroslav@358
    11
 * Development and Distribution License("CDDL") (collectively, the
jaroslav@358
    12
 * "License"). You may not use this file except in compliance with the
jaroslav@358
    13
 * License. You can obtain a copy of the License at
jaroslav@358
    14
 * http://www.netbeans.org/cddl-gplv2.html
jaroslav@358
    15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jaroslav@358
    16
 * specific language governing permissions and limitations under the
jaroslav@358
    17
 * License.  When distributing the software, include this License Header
jaroslav@358
    18
 * Notice in each file and include the License file at
jaroslav@358
    19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
jaroslav@358
    20
 * particular file as subject to the "Classpath" exception as provided
jaroslav@358
    21
 * by Oracle in the GPL Version 2 section of the License file that
jaroslav@358
    22
 * accompanied this code. If applicable, add the following below the
jaroslav@358
    23
 * License Header, with the fields enclosed by brackets [] replaced by
jaroslav@358
    24
 * your own identifying information:
jaroslav@358
    25
 * "Portions Copyrighted [year] [name of copyright owner]"
jaroslav@358
    26
 *
jaroslav@358
    27
 * Contributor(s):
jaroslav@358
    28
 *
jaroslav@358
    29
 * The Original Software is NetBeans. The Initial Developer of the Original
jaroslav@551
    30
 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
jaroslav@358
    31
 *
jaroslav@358
    32
 * If you wish your version of this file to be governed by only the CDDL
jaroslav@358
    33
 * or only the GPL Version 2, indicate your decision by adding
jaroslav@358
    34
 * "[Contributor] elects to include this software in this distribution
jaroslav@358
    35
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
jaroslav@358
    36
 * single choice of license, a recipient has the option to distribute
jaroslav@358
    37
 * your version of this file under either the CDDL, the GPL Version 2 or
jaroslav@358
    38
 * to extend the choice of license to its licensees as provided above.
jaroslav@358
    39
 * However, if you add GPL Version 2 code and therefore, elected the GPL
jaroslav@358
    40
 * Version 2 license, then the option applies only if the new code is
jaroslav@358
    41
 * made subject to such option by the copyright holder.
jtulach@0
    42
 */
jtulach@0
    43
package net.java.html.json;
jtulach@0
    44
jaroslav@110
    45
import net.java.html.BrwsrCtx;
jtulach@0
    46
import java.util.ArrayList;
jtulach@0
    47
import java.util.Collections;
jtulach@0
    48
import java.util.Iterator;
jtulach@0
    49
import java.util.List;
jtulach@0
    50
import java.util.ListIterator;
jaroslav@110
    51
import org.apidesign.html.context.spi.Contexts;
jaroslav@11
    52
import org.apidesign.html.json.spi.FunctionBinding;
jaroslav@9
    53
import org.apidesign.html.json.spi.PropertyBinding;
jaroslav@6
    54
import org.apidesign.html.json.spi.Technology;
jtulach@0
    55
import static org.testng.Assert.*;
jtulach@0
    56
import org.testng.annotations.BeforeMethod;
jtulach@0
    57
import org.testng.annotations.Test;
jtulach@0
    58
jtulach@0
    59
/**
jtulach@0
    60
 *
jtulach@0
    61
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jtulach@0
    62
 */
jtulach@0
    63
@Model(className = "Modelik", properties = {
jtulach@0
    64
    @Property(name = "value", type = int.class),
jtulach@0
    65
    @Property(name = "count", type = int.class),
jtulach@0
    66
    @Property(name = "unrelated", type = long.class),
jtulach@0
    67
    @Property(name = "names", type = String.class, array = true),
jtulach@0
    68
    @Property(name = "values", type = int.class, array = true),
jtulach@0
    69
    @Property(name = "people", type = Person.class, array = true),
jtulach@0
    70
    @Property(name = "changedProperty", type=String.class)
jtulach@0
    71
})
jtulach@0
    72
public class ModelTest {
jaroslav@7
    73
    private MockTechnology my;
jtulach@0
    74
    private Modelik model;
jtulach@0
    75
    private static Modelik leakedModel;
jtulach@0
    76
    
jtulach@0
    77
    @BeforeMethod
jtulach@0
    78
    public void createModel() {
jaroslav@7
    79
        my = new MockTechnology();
jaroslav@111
    80
        final BrwsrCtx c = Contexts.newBuilder().register(Technology.class, my, 1).build();
jaroslav@111
    81
        model = Models.bind(new Modelik(), c);
jtulach@0
    82
    }
jtulach@0
    83
    
jtulach@0
    84
    @Test public void classGeneratedWithSetterGetter() {
jtulach@0
    85
        model.setValue(10);
jtulach@0
    86
        assertEquals(10, model.getValue(), "Value changed");
jtulach@0
    87
    }
jtulach@0
    88
    
jtulach@0
    89
    @Test public void computedMethod() {
jtulach@0
    90
        model.setValue(4);
jtulach@0
    91
        assertEquals(16, model.getPowerValue());
jtulach@0
    92
    }
jtulach@0
    93
    
jaroslav@281
    94
    @Test public void equalsAndHashCode() {
jaroslav@281
    95
        Modelik m1 = new Modelik(10, 20, 30, "changed", "firstName");
jaroslav@281
    96
        Modelik m2 = new Modelik(10, 20, 30, "changed", "firstName");
jaroslav@281
    97
        
jaroslav@281
    98
        assertTrue(m1.equals(m2), "They are the same");
jaroslav@281
    99
        assertEquals(m1.hashCode(), m2.hashCode(), "Hashcode is the same");
jaroslav@281
   100
        
jaroslav@281
   101
        m1.setCount(33);
jaroslav@281
   102
        
jaroslav@281
   103
        assertFalse(m1.equals(m2), "No longer the same");
jaroslav@281
   104
        assertFalse(m1.hashCode() == m2.hashCode(), "No longe is hashcode is the same");
jaroslav@281
   105
    }
jaroslav@281
   106
    
jtulach@0
   107
    @Test public void arrayIsMutable() {
jtulach@0
   108
        assertEquals(model.getNames().size(), 0, "Is empty");
jtulach@0
   109
        model.getNames().add("Jarda");
jtulach@0
   110
        assertEquals(model.getNames().size(), 1, "One element");
jtulach@0
   111
    }
jaroslav@6
   112
jaroslav@278
   113
    @Test public void arrayChangesNotNotifiedUntilInitied() {
jaroslav@278
   114
        model.getNames().add("Hello");
jaroslav@278
   115
        assertTrue(my.mutated.isEmpty(), "No change now " + my.mutated);
jaroslav@278
   116
        model.getNames().remove("Hello");
jaroslav@278
   117
        assertTrue(my.mutated.isEmpty(), "No change still " + my.mutated);
jaroslav@278
   118
        assertTrue(model.getNames().isEmpty(), "No empty");
jaroslav@278
   119
    }
jaroslav@278
   120
    
jtulach@0
   121
    @Test public void arrayChangesNotified() {
jaroslav@453
   122
        Models.applyBindings(model);
jtulach@0
   123
        model.getNames().add("Hello");
jtulach@0
   124
        
jtulach@0
   125
        assertFalse(my.mutated.isEmpty(), "There was a change" + my.mutated);
jtulach@0
   126
        assertTrue(my.mutated.contains("names"), "Change in names property: " + my.mutated);
jtulach@0
   127
jtulach@0
   128
        my.mutated.clear();
jtulach@0
   129
        
jtulach@0
   130
        Iterator<String> it = model.getNames().iterator();
jtulach@0
   131
        assertEquals(it.next(), "Hello");
jtulach@0
   132
        it.remove();
jtulach@0
   133
        
jtulach@0
   134
        assertFalse(my.mutated.isEmpty(), "There was a change" + my.mutated);
jtulach@0
   135
        assertTrue(my.mutated.contains("names"), "Change in names property: " + my.mutated);
jtulach@0
   136
jtulach@0
   137
        my.mutated.clear();
jtulach@0
   138
        
jtulach@0
   139
        ListIterator<String> lit = model.getNames().listIterator();
jtulach@0
   140
        lit.add("Jarda");
jtulach@0
   141
        
jtulach@0
   142
        assertFalse(my.mutated.isEmpty(), "There was a change" + my.mutated);
jtulach@0
   143
        assertTrue(my.mutated.contains("names"), "Change in names property: " + my.mutated);
jtulach@0
   144
    }
jaroslav@7
   145
jtulach@0
   146
    @Test public void autoboxedArray() {
jtulach@0
   147
        model.getValues().add(10);
jtulach@0
   148
        
jtulach@0
   149
        assertEquals(model.getValues().get(0), Integer.valueOf(10), "Really ten");
jtulach@0
   150
    }
jtulach@0
   151
jtulach@0
   152
    @Test public void derivedArrayProp() {
jaroslav@280
   153
        model.applyBindings();
jtulach@0
   154
        model.setCount(10);
jtulach@0
   155
        
jtulach@0
   156
        List<String> arr = model.getRepeat();
jtulach@0
   157
        assertEquals(arr.size(), 10, "Ten items: " + arr);
jtulach@0
   158
        
jtulach@0
   159
        my.mutated.clear();
jtulach@0
   160
        
jtulach@0
   161
        model.setCount(5);
jtulach@0
   162
        
jtulach@0
   163
        arr = model.getRepeat();
jtulach@0
   164
        assertEquals(arr.size(), 5, "Five items: " + arr);
jtulach@0
   165
jtulach@0
   166
        assertEquals(my.mutated.size(), 2, "Two properties changed: " + my.mutated);
jtulach@0
   167
        assertTrue(my.mutated.contains("repeat"), "Array is in there: " + my.mutated);
jtulach@0
   168
        assertTrue(my.mutated.contains("count"), "Count is in there: " + my.mutated);
jtulach@0
   169
    }
jtulach@0
   170
    
jtulach@0
   171
    @Test public void derivedPropertiesAreNotified() {
jaroslav@280
   172
        model.applyBindings();
jaroslav@280
   173
        
jtulach@0
   174
        model.setValue(33);
jtulach@0
   175
        
jtulach@0
   176
        // not interested in change of this property
jtulach@0
   177
        my.mutated.remove("changedProperty");
jtulach@0
   178
        
jtulach@0
   179
        assertEquals(my.mutated.size(), 2, "Two properties changed: " + my.mutated);
jtulach@0
   180
        assertTrue(my.mutated.contains("powerValue"), "Power value is in there: " + my.mutated);
jtulach@0
   181
        assertTrue(my.mutated.contains("value"), "Simple value is in there: " + my.mutated);
jtulach@0
   182
        
jtulach@0
   183
        my.mutated.clear();
jtulach@0
   184
        
jtulach@0
   185
        model.setUnrelated(44);
jtulach@0
   186
        
jtulach@0
   187
        
jtulach@0
   188
        // not interested in change of this property
jtulach@0
   189
        my.mutated.remove("changedProperty");
jtulach@0
   190
        assertEquals(my.mutated.size(), 1, "One property changed: " + my.mutated);
jtulach@0
   191
        assertTrue(my.mutated.contains("unrelated"), "Its name is unrelated");
jtulach@0
   192
    }
jaroslav@8
   193
jtulach@0
   194
    @Test public void computedPropertyCannotWriteToModel() {
jtulach@0
   195
        leakedModel = model;
jtulach@0
   196
        try {
jtulach@0
   197
            String res = model.getNotAllowedWrite();
jtulach@0
   198
            fail("We should not be allowed to write to the model: " + res);
jtulach@0
   199
        } catch (IllegalStateException ex) {
jtulach@0
   200
            // OK, we can't read
jtulach@0
   201
        }
jtulach@0
   202
    }
jtulach@0
   203
jtulach@0
   204
    @Test public void computedPropertyCannotReadToModel() {
jtulach@0
   205
        leakedModel = model;
jtulach@0
   206
        try {
jtulach@0
   207
            String res = model.getNotAllowedRead();
jtulach@0
   208
            fail("We should not be allowed to read from the model: " + res);
jtulach@0
   209
        } catch (IllegalStateException ex) {
jtulach@0
   210
            // OK, we can't read
jtulach@0
   211
        }
jtulach@0
   212
    }
jtulach@0
   213
    
jaroslav@245
   214
    @OnReceive(url = "{protocol}://{host}?query={query}", data = Person.class, onError = "errorState")
jaroslav@13
   215
    static void loadPeople(Modelik thiz, People p) {
jaroslav@12
   216
        Modelik m = null;
jaroslav@14
   217
        m.applyBindings();
jaroslav@111
   218
        m.loadPeople("http", "apidesign.org", "query", new Person());
jaroslav@12
   219
    }
jaroslav@245
   220
    
jaroslav@245
   221
    static void errorState(Modelik thiz, Exception ex) {
jaroslav@245
   222
        
jaroslav@245
   223
    }
jaroslav@24
   224
jaroslav@24
   225
    @OnReceive(url = "{protocol}://{host}?callback={back}&query={query}", jsonp = "back")
jaroslav@24
   226
    static void loadPeopleViaJSONP(Modelik thiz, People p) {
jaroslav@24
   227
        Modelik m = null;
jaroslav@24
   228
        m.applyBindings();
jaroslav@24
   229
        m.loadPeopleViaJSONP("http", "apidesign.org", "query");
jaroslav@24
   230
    }
jaroslav@12
   231
    
jtulach@0
   232
    @Function 
jtulach@0
   233
    static void doSomething() {
jtulach@0
   234
    }
jtulach@0
   235
    
jtulach@0
   236
    @ComputedProperty
jtulach@0
   237
    static int powerValue(int value) {
jtulach@0
   238
        return value * value;
jtulach@0
   239
    }
jtulach@0
   240
    
jtulach@0
   241
    @OnPropertyChange({ "powerValue", "unrelated" })
jtulach@0
   242
    static void aPropertyChanged(Modelik m, String name) {
jtulach@0
   243
        m.setChangedProperty(name);
jtulach@0
   244
    }
jtulach@0
   245
jtulach@0
   246
    @OnPropertyChange({ "values" })
jtulach@0
   247
    static void anArrayPropertyChanged(String name, Modelik m) {
jtulach@0
   248
        m.setChangedProperty(name);
jtulach@0
   249
    }
jtulach@0
   250
    
jtulach@0
   251
    @Test public void changeAnything() {
jtulach@0
   252
        model.setCount(44);
jtulach@0
   253
        assertNull(model.getChangedProperty(), "No observed value change");
jtulach@0
   254
    }
jtulach@0
   255
    @Test public void changeValue() {
jtulach@0
   256
        model.setValue(33);
jtulach@0
   257
        assertEquals(model.getChangedProperty(), "powerValue", "power property changed");
jtulach@0
   258
    }
jtulach@0
   259
    @Test public void changeUnrelated() {
jtulach@0
   260
        model.setUnrelated(333);
jtulach@0
   261
        assertEquals(model.getChangedProperty(), "unrelated", "unrelated changed");
jtulach@0
   262
    }
jtulach@0
   263
jtulach@0
   264
    @Test public void changeInArray() {
jtulach@0
   265
        model.getValues().add(10);
jaroslav@278
   266
        assertNull(model.getChangedProperty(), "No change before applyBindings");
jaroslav@278
   267
        model.applyBindings();
jaroslav@278
   268
        model.getValues().add(10);
jtulach@0
   269
        assertEquals(model.getChangedProperty(), "values", "Something added into the array");
jtulach@0
   270
    }
jtulach@0
   271
    
jtulach@0
   272
    @ComputedProperty
jtulach@0
   273
    static String notAllowedRead() {
jtulach@0
   274
        return "Not allowed callback: " + leakedModel.getUnrelated();
jtulach@0
   275
    }
jtulach@0
   276
jtulach@0
   277
    @ComputedProperty
jtulach@0
   278
    static String notAllowedWrite() {
jtulach@0
   279
        leakedModel.setUnrelated(11);
jtulach@0
   280
        return "Not allowed callback!";
jtulach@0
   281
    }
jtulach@0
   282
    
jtulach@0
   283
    @ComputedProperty
jtulach@0
   284
    static List<String> repeat(int count) {
jtulach@0
   285
        return Collections.nCopies(count, "Hello");
jtulach@0
   286
    }
jtulach@0
   287
    
jtulach@0
   288
    public @Test void hasPersonPropertyAndComputedFullName() {
jtulach@0
   289
        List<Person> arr = model.getPeople();
jtulach@0
   290
        assertEquals(arr.size(), 0, "By default empty");
jtulach@0
   291
        Person p = null;
jtulach@0
   292
        if (p != null) {
jtulach@0
   293
            String fullNameGenerated = p.getFullName();
jtulach@0
   294
            assertNotNull(fullNameGenerated);
jtulach@0
   295
        }
jtulach@0
   296
    }
jaroslav@7
   297
    
jaroslav@7
   298
    private static class MockTechnology implements Technology<Object> {
jaroslav@100
   299
        private final List<String> mutated = new ArrayList<String>();
jaroslav@7
   300
jaroslav@7
   301
        @Override
jaroslav@7
   302
        public Object wrapModel(Object model) {
jaroslav@7
   303
            return this;
jaroslav@7
   304
        }
jaroslav@7
   305
jaroslav@7
   306
        @Override
jaroslav@7
   307
        public void valueHasMutated(Object data, String propertyName) {
jaroslav@7
   308
            mutated.add(propertyName);
jaroslav@7
   309
        }
jaroslav@9
   310
jaroslav@9
   311
        @Override
jaroslav@9
   312
        public void bind(PropertyBinding b, Object model, Object data) {
jaroslav@9
   313
        }
jaroslav@11
   314
jaroslav@11
   315
        @Override
jaroslav@11
   316
        public void expose(FunctionBinding fb, Object model, Object d) {
jaroslav@11
   317
        }
jaroslav@14
   318
jaroslav@14
   319
        @Override
jaroslav@14
   320
        public void applyBindings(Object data) {
jaroslav@14
   321
        }
jaroslav@17
   322
jaroslav@17
   323
        @Override
jaroslav@17
   324
        public Object wrapArray(Object[] arr) {
jaroslav@17
   325
            return arr;
jaroslav@17
   326
        }
jaroslav@38
   327
jaroslav@38
   328
        @Override
jaroslav@38
   329
        public <M> M toModel(Class<M> modelClass, Object data) {
jaroslav@38
   330
            return modelClass.cast(data);
jaroslav@38
   331
        }
jaroslav@240
   332
jaroslav@240
   333
        @Override
jaroslav@240
   334
        public void runSafe(Runnable r) {
jaroslav@240
   335
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
jaroslav@240
   336
        }
jaroslav@7
   337
    }
jtulach@0
   338
}