javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ModelTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 31 Mar 2013 12:01:38 +0200
branchmodel
changeset 909 e51a474fcf79
parent 879 af170d42b5b3
child 949 3bd43aa6f08d
permissions -rw-r--r--
Mutable properties on model classes
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.bck2brwsr.htmlpage;
    19 
    20 import java.util.ArrayList;
    21 import java.util.Collections;
    22 import java.util.Iterator;
    23 import java.util.List;
    24 import java.util.ListIterator;
    25 import org.apidesign.bck2brwsr.htmlpage.api.ComputedProperty;
    26 import org.apidesign.bck2brwsr.htmlpage.api.OnFunction;
    27 import org.apidesign.bck2brwsr.htmlpage.api.Page;
    28 import org.apidesign.bck2brwsr.htmlpage.api.Property;
    29 import static org.testng.Assert.*;
    30 import org.testng.annotations.BeforeMethod;
    31 import org.testng.annotations.Test;
    32 
    33 /**
    34  *
    35  * @author Jaroslav Tulach <jtulach@netbeans.org>
    36  */
    37 @Page(xhtml = "Empty.html", className = "Modelik", properties = {
    38     @Property(name = "value", type = int.class),
    39     @Property(name = "count", type = int.class),
    40     @Property(name = "unrelated", type = long.class),
    41     @Property(name = "names", type = String.class, array = true),
    42     @Property(name = "values", type = int.class, array = true),
    43     @Property(name = "people", type = PersonImpl.class, array = true)
    44 })
    45 public class ModelTest {
    46     private Modelik model;
    47     private static Modelik leakedModel;
    48     
    49     @BeforeMethod
    50     public void createModel() {
    51         model = new Modelik();
    52     }
    53     
    54     @Test public void classGeneratedWithSetterGetter() {
    55         model.setValue(10);
    56         assertEquals(10, model.getValue(), "Value changed");
    57     }
    58     
    59     @Test public void computedMethod() {
    60         model.setValue(4);
    61         assertEquals(16, model.getPowerValue());
    62     }
    63     
    64     @Test public void arrayIsMutable() {
    65         assertEquals(model.getNames().size(), 0, "Is empty");
    66         model.getNames().add("Jarda");
    67         assertEquals(model.getNames().size(), 1, "One element");
    68     }
    69     
    70     @Test public void arrayChangesNotified() {
    71         MockKnockout my = new MockKnockout();
    72         MockKnockout.next = my;
    73         
    74         model.applyBindings();
    75         
    76         model.getNames().add("Hello");
    77         
    78         assertFalse(my.mutated.isEmpty(), "There was a change" + my.mutated);
    79         assertTrue(my.mutated.contains("names"), "Change in names property: " + my.mutated);
    80 
    81         my.mutated.clear();
    82         
    83         Iterator<String> it = model.getNames().iterator();
    84         assertEquals(it.next(), "Hello");
    85         it.remove();
    86         
    87         assertFalse(my.mutated.isEmpty(), "There was a change" + my.mutated);
    88         assertTrue(my.mutated.contains("names"), "Change in names property: " + my.mutated);
    89 
    90         my.mutated.clear();
    91         
    92         ListIterator<String> lit = model.getNames().listIterator();
    93         lit.add("Jarda");
    94         
    95         assertFalse(my.mutated.isEmpty(), "There was a change" + my.mutated);
    96         assertTrue(my.mutated.contains("names"), "Change in names property: " + my.mutated);
    97     }
    98     
    99     @Test public void autoboxedArray() {
   100         MockKnockout my = new MockKnockout();
   101         MockKnockout.next = my;
   102         
   103         model.applyBindings();
   104         
   105         model.getValues().add(10);
   106         
   107         assertEquals(model.getValues().get(0), Integer.valueOf(10), "Really ten");
   108     }
   109 
   110     @Test public void derivedArrayProp() {
   111         MockKnockout my = new MockKnockout();
   112         MockKnockout.next = my;
   113         
   114         model.applyBindings();
   115         
   116         model.setCount(10);
   117         
   118         List<String> arr = model.getRepeat();
   119         assertEquals(arr.size(), 10, "Ten items: " + arr);
   120         
   121         my.mutated.clear();
   122         
   123         model.setCount(5);
   124         
   125         arr = model.getRepeat();
   126         assertEquals(arr.size(), 5, "Five items: " + arr);
   127 
   128         assertEquals(my.mutated.size(), 2, "Two properties changed: " + my.mutated);
   129         assertTrue(my.mutated.contains("repeat"), "Array is in there: " + my.mutated);
   130         assertTrue(my.mutated.contains("count"), "Count is in there: " + my.mutated);
   131     }
   132     
   133     @Test public void derivedPropertiesAreNotified() {
   134         MockKnockout my = new MockKnockout();
   135         MockKnockout.next = my;
   136         
   137         model.applyBindings();
   138         
   139         model.setValue(33);
   140         
   141         assertEquals(my.mutated.size(), 2, "Two properties changed: " + my.mutated);
   142         assertTrue(my.mutated.contains("powerValue"), "Power value is in there: " + my.mutated);
   143         assertTrue(my.mutated.contains("value"), "Simple value is in there: " + my.mutated);
   144         
   145         my.mutated.clear();
   146         
   147         model.setUnrelated(44);
   148         assertEquals(my.mutated.size(), 1, "One property changed");
   149         assertTrue(my.mutated.contains("unrelated"), "Its name is unrelated");
   150     }
   151     
   152     @Test public void computedPropertyCannotWriteToModel() {
   153         leakedModel = model;
   154         try {
   155             String res = model.getNotAllowedWrite();
   156             fail("We should not be allowed to write to the model: " + res);
   157         } catch (IllegalStateException ex) {
   158             // OK, we can't read
   159         }
   160     }
   161 
   162     @Test public void computedPropertyCannotReadToModel() {
   163         leakedModel = model;
   164         try {
   165             String res = model.getNotAllowedRead();
   166             fail("We should not be allowed to read from the model: " + res);
   167         } catch (IllegalStateException ex) {
   168             // OK, we can't read
   169         }
   170     }
   171     
   172     @OnFunction 
   173     static void doSomething() {
   174     }
   175     
   176     @ComputedProperty
   177     static int powerValue(int value) {
   178         return value * value;
   179     }
   180     
   181     @ComputedProperty
   182     static String notAllowedRead() {
   183         return "Not allowed callback: " + leakedModel.getUnrelated();
   184     }
   185 
   186     @ComputedProperty
   187     static String notAllowedWrite() {
   188         leakedModel.setUnrelated(11);
   189         return "Not allowed callback!";
   190     }
   191     
   192     @ComputedProperty
   193     static List<String> repeat(int count) {
   194         return Collections.nCopies(count, "Hello");
   195     }
   196     
   197     static class MockKnockout extends Knockout {
   198         List<String> mutated = new ArrayList<>();
   199         
   200         MockKnockout() {
   201             super(null);
   202         }
   203         
   204         @Override
   205         public void valueHasMutated(String prop) {
   206             mutated.add(prop);
   207         }
   208     }
   209     
   210     public @Test void hasPersonPropertyAndComputedFullName() {
   211         List<Person> arr = model.getPeople();
   212         assertEquals(arr.size(), 0, "By default empty");
   213         Person p = null;
   214         if (p != null) {
   215             String fullNameGenerated = p.getFullName();
   216             assertNotNull(fullNameGenerated);
   217         }
   218     }
   219 }