json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java
author Jaroslav Tulach <jtulach@netbeans.org>
Tue, 26 Aug 2014 18:13:30 +0200
changeset 838 bdc3d696dd4a
parent 830 861f15abe944
child 920 117b732d42d0
permissions -rw-r--r--
During the API review process (bug 246133) the reviewers decided that in order to include html4j to NetBeans Platform, we need to stop using org.apidesign namespace and switch to NetBeans one. Repackaging all SPI packages into org.netbeans.html.smthng.spi.
jaroslav@34
     1
/**
jaroslav@358
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jaroslav@34
     3
 *
jaroslav@551
     4
 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
jaroslav@34
     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.
jaroslav@34
     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.
jaroslav@34
    42
 */
jaroslav@34
    43
package net.java.html.json.tests;
jaroslav@34
    44
jtulach@830
    45
import java.util.Arrays;
jaroslav@34
    46
import java.util.List;
jaroslav@717
    47
import java.util.Timer;
jaroslav@717
    48
import java.util.TimerTask;
jaroslav@121
    49
import net.java.html.BrwsrCtx;
jaroslav@34
    50
import net.java.html.json.ComputedProperty;
jaroslav@34
    51
import net.java.html.json.Function;
jaroslav@34
    52
import net.java.html.json.Model;
jaroslav@115
    53
import net.java.html.json.Models;
jaroslav@34
    54
import net.java.html.json.Property;
jtulach@838
    55
import org.netbeans.html.json.tck.KOTest;
jaroslav@34
    56
jaroslav@34
    57
/**
jaroslav@34
    58
 *
jtulach@790
    59
 * @author Jaroslav Tulach
jaroslav@34
    60
 */
jaroslav@34
    61
@Model(className="KnockoutModel", properties={
jaroslav@34
    62
    @Property(name="name", type=String.class),
jaroslav@34
    63
    @Property(name="results", type=String.class, array = true),
jtulach@825
    64
    @Property(name="numbers", type=int.class, array = true),
jaroslav@34
    65
    @Property(name="callbackCount", type=int.class),
jaroslav@94
    66
    @Property(name="people", type=PersonImpl.class, array = true),
jaroslav@197
    67
    @Property(name="enabled", type=boolean.class),
jtulach@758
    68
    @Property(name="latitude", type=double.class),
jtulach@758
    69
    @Property(name="choice", type=KnockoutTest.Choice.class),
jtulach@809
    70
    @Property(name="archetype", type=ArchetypeData.class),
jtulach@809
    71
    @Property(name="archetypes", type=ArchetypeData.class, array = true),
jaroslav@34
    72
}) 
jaroslav@34
    73
public final class KnockoutTest {
jaroslav@717
    74
    private KnockoutModel js;
jaroslav@34
    75
    
jtulach@758
    76
    enum Choice {
jtulach@758
    77
        A, B;
jtulach@758
    78
    }
jtulach@758
    79
    
jtulach@830
    80
    @ComputedProperty static List<Integer> resultLengths(List<String> results) {
jtulach@830
    81
        Integer[] arr = new Integer[results.size()];
jtulach@830
    82
        for (int i = 0; i < arr.length; i++) {
jtulach@830
    83
            arr[i] = results.get(i).length();
jtulach@830
    84
        }
jtulach@830
    85
        return Arrays.asList(arr);
jtulach@830
    86
    }
jtulach@830
    87
    
jtulach@758
    88
    @KOTest public void modifyValueAssertChangeInModelOnEnum() throws Throwable {
jtulach@758
    89
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jtulach@758
    90
            "Latitude: <input id='input' data-bind=\"value: choice\"></input>\n"
jtulach@758
    91
        );
jtulach@758
    92
        try {
jtulach@758
    93
jtulach@758
    94
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jtulach@758
    95
            m.setChoice(Choice.A);
jtulach@758
    96
            m.applyBindings();
jtulach@758
    97
jtulach@758
    98
            String v = getSetInput(null);
jtulach@758
    99
            assert "A".equals(v) : "Value is really A: " + v;
jtulach@758
   100
jtulach@758
   101
            getSetInput("B");
jtulach@758
   102
            triggerEvent("input", "change");
jtulach@758
   103
jtulach@758
   104
            assert Choice.B == m.getChoice(): "Enum property updated: " + m.getChoice();
jtulach@758
   105
        } catch (Throwable t) {
jtulach@758
   106
            throw t;
jtulach@758
   107
        } finally {
jtulach@758
   108
            Utils.exposeHTML(KnockoutTest.class, "");
jtulach@758
   109
        }
jtulach@758
   110
    }
jtulach@758
   111
    
jaroslav@197
   112
    @KOTest public void modifyValueAssertChangeInModelOnDouble() throws Throwable {
jaroslav@197
   113
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@197
   114
            "Latitude: <input id='input' data-bind=\"value: latitude\"></input>\n"
jaroslav@197
   115
        );
jaroslav@197
   116
        try {
jaroslav@197
   117
jaroslav@197
   118
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@197
   119
            m.setLatitude(50.5);
jaroslav@197
   120
            m.applyBindings();
jaroslav@197
   121
jaroslav@197
   122
            String v = getSetInput(null);
jaroslav@197
   123
            assert "50.5".equals(v) : "Value is really 50.5: " + v;
jaroslav@197
   124
jaroslav@197
   125
            getSetInput("49.5");
jaroslav@197
   126
            triggerEvent("input", "change");
jaroslav@197
   127
jaroslav@197
   128
            assert 49.5 == m.getLatitude() : "Double property updated: " + m.getLatitude();
jaroslav@197
   129
        } catch (Throwable t) {
jaroslav@197
   130
            throw t;
jaroslav@197
   131
        } finally {
jaroslav@197
   132
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@197
   133
        }
jaroslav@197
   134
    }
jaroslav@197
   135
    
jaroslav@197
   136
    @KOTest public void modifyValueAssertChangeInModelOnBoolean() throws Throwable {
jaroslav@197
   137
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@197
   138
            "Latitude: <input id='input' data-bind=\"value: enabled\"></input>\n"
jaroslav@197
   139
        );
jaroslav@197
   140
        try {
jaroslav@197
   141
jaroslav@197
   142
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@197
   143
            m.setEnabled(true);
jaroslav@197
   144
            m.applyBindings();
jaroslav@197
   145
jaroslav@197
   146
            String v = getSetInput(null);
jaroslav@197
   147
            assert "true".equals(v) : "Value is really true: " + v;
jaroslav@197
   148
jaroslav@197
   149
            getSetInput("false");
jaroslav@197
   150
            triggerEvent("input", "change");
jaroslav@197
   151
jaroslav@197
   152
            assert false == m.isEnabled(): "Boolean property updated: " + m.isEnabled();
jaroslav@197
   153
        } catch (Throwable t) {
jaroslav@197
   154
            throw t;
jaroslav@197
   155
        } finally {
jaroslav@197
   156
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@197
   157
        }
jaroslav@197
   158
    }
jaroslav@197
   159
    
jaroslav@137
   160
    @KOTest public void modifyValueAssertChangeInModel() throws Exception {
jaroslav@137
   161
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   162
            "<h1 data-bind=\"text: helloMessage\">Loading Bck2Brwsr's Hello World...</h1>\n" +
jaroslav@137
   163
            "Your name: <input id='input' data-bind=\"value: name\"></input>\n" +
jaroslav@137
   164
            "<button id=\"hello\">Say Hello!</button>\n"
jaroslav@137
   165
        );
jaroslav@141
   166
        try {
jaroslav@137
   167
jaroslav@141
   168
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@141
   169
            m.setName("Kukuc");
jaroslav@141
   170
            m.applyBindings();
jaroslav@137
   171
jaroslav@141
   172
            String v = getSetInput(null);
jaroslav@141
   173
            assert "Kukuc".equals(v) : "Value is really kukuc: " + v;
jaroslav@137
   174
jaroslav@141
   175
            getSetInput("Jardo");
jaroslav@141
   176
            triggerEvent("input", "change");
jaroslav@137
   177
jaroslav@141
   178
            assert "Jardo".equals(m.getName()) : "Name property updated: " + m.getName();
jaroslav@141
   179
        } finally {
jaroslav@141
   180
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   181
        }
jaroslav@34
   182
    }
jaroslav@34
   183
    
jtulach@809
   184
    private static String getSetSelected(int index, Object value) throws Exception {
jtulach@809
   185
        String s = "var index = arguments[0];\n"
jtulach@809
   186
        + "var value = arguments[1];\n"
jtulach@809
   187
        + "var n = window.document.getElementById('input'); \n "
jtulach@809
   188
        + "if (value != null) {\n"
jtulach@809
   189
        + "  n.options[index].value = 'me'; \n"
jtulach@809
   190
        + "  n.value = 'me'; \n"
jtulach@809
   191
        + "  ko.dataFor(n.options[index]).archetype(value); // haven't found better way to trigger ko change yet \n"
jtulach@809
   192
        + "} \n "
jtulach@809
   193
        + "var op = n.options[n.selectedIndex]; \n"
jtulach@809
   194
        + "return op ? op.text : n.selectedIndex;\n";
jtulach@809
   195
        Object ret = Utils.executeScript(
jtulach@809
   196
            KnockoutTest.class,
jtulach@809
   197
            s, index, value
jtulach@809
   198
        );
jtulach@809
   199
        return ret == null ? null : ret.toString();
jtulach@809
   200
    }
jtulach@809
   201
    
jtulach@809
   202
    @Model(className = "ArchetypeData", properties = {
jtulach@809
   203
        @Property(name = "artifactId", type = String.class),
jtulach@809
   204
        @Property(name = "groupId", type = String.class),
jtulach@809
   205
        @Property(name = "version", type = String.class),
jtulach@809
   206
        @Property(name = "name", type = String.class),
jtulach@809
   207
        @Property(name = "description", type = String.class),
jtulach@809
   208
        @Property(name = "url", type = String.class),
jtulach@809
   209
    })
jtulach@809
   210
    static class ArchModel {
jtulach@809
   211
    }
jtulach@809
   212
    
jtulach@809
   213
    @KOTest public void selectWorksOnModels() throws Exception {
jtulach@809
   214
        if (js == null) {
jtulach@809
   215
            Utils.exposeHTML(KnockoutTest.class, 
jtulach@809
   216
                "<select id='input' data-bind=\"options: archetypes,\n" +
jtulach@809
   217
"                       optionsText: 'name',\n" +
jtulach@809
   218
"                       value: archetype\">\n" +
jtulach@809
   219
"                  </select>\n" +
jtulach@809
   220
""
jtulach@809
   221
            );
jtulach@809
   222
            
jtulach@809
   223
            js = Models.bind(new KnockoutModel(), newContext());
jtulach@809
   224
            js.getArchetypes().add(new ArchetypeData("ko4j", "org.netbeans.html", "0.8.3", "ko4j", "ko4j", null));
jtulach@809
   225
            js.getArchetypes().add(new ArchetypeData("crud", "org.netbeans.html", "0.8.3", "crud", "crud", null));
jtulach@809
   226
            js.getArchetypes().add(new ArchetypeData("3rd", "org.netbeans.html", "0.8.3", "3rd", "3rd", null));
jtulach@809
   227
            js.setArchetype(js.getArchetypes().get(1));
jtulach@809
   228
            js.applyBindings();
jtulach@809
   229
            
jtulach@809
   230
            String v = getSetSelected(0, null);
jtulach@809
   231
            assert "crud".equals(v) : "Second index (e.g. crud) is selected: " + v;
jtulach@809
   232
            
jtulach@809
   233
            String sel = getSetSelected(2, Models.toRaw(js.getArchetypes().get(2)));
jtulach@809
   234
            assert "3rd".equals(sel) : "3rd is selected now: " + sel;
jtulach@809
   235
        }
jtulach@809
   236
        
jtulach@809
   237
        if (js.getArchetype() != js.getArchetypes().get(2)) {
jtulach@809
   238
            throw new InterruptedException();
jtulach@809
   239
        }
jtulach@809
   240
        
jtulach@809
   241
        Utils.exposeHTML(KnockoutTest.class, "");
jtulach@809
   242
    }
jtulach@809
   243
    
jaroslav@717
   244
    @KOTest public void modifyValueAssertAsyncChangeInModel() throws Exception {
jaroslav@717
   245
        if (js == null) {
jaroslav@717
   246
            Utils.exposeHTML(KnockoutTest.class, 
jaroslav@717
   247
                "<h1 data-bind=\"text: helloMessage\">Loading Bck2Brwsr's Hello World...</h1>\n" +
jaroslav@717
   248
                "Your name: <input id='input' data-bind=\"value: name\"></input>\n" +
jaroslav@717
   249
                "<button id=\"hello\">Say Hello!</button>\n"
jaroslav@717
   250
            );
jaroslav@717
   251
            
jaroslav@717
   252
            js = Models.bind(new KnockoutModel(), newContext());
jaroslav@717
   253
            js.setName("Kukuc");
jaroslav@717
   254
            js.applyBindings();
jaroslav@717
   255
            
jaroslav@717
   256
            String v = getSetInput(null);
jaroslav@717
   257
            assert "Kukuc".equals(v) : "Value is really kukuc: " + v;
jaroslav@717
   258
            
jaroslav@717
   259
            Timer t = new Timer("Set to Jardo");
jaroslav@717
   260
            t.schedule(new TimerTask() {
jaroslav@717
   261
                @Override
jaroslav@717
   262
                public void run() {
jaroslav@717
   263
                    js.setName("Jardo");
jaroslav@717
   264
                }
jaroslav@717
   265
            }, 1);
jaroslav@717
   266
        }
jaroslav@717
   267
        
jaroslav@717
   268
        String v = getSetInput(null);
jaroslav@717
   269
        if (!"Jardo".equals(v)) {
jaroslav@717
   270
            throw new InterruptedException();
jaroslav@717
   271
        }
jaroslav@717
   272
        
jaroslav@717
   273
        Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@717
   274
    }
jaroslav@717
   275
    
jaroslav@36
   276
    private static String getSetInput(String value) throws Exception {
jaroslav@36
   277
        String s = "var value = arguments[0];\n"
jaroslav@36
   278
        + "var n = window.document.getElementById('input'); \n "
jaroslav@34
   279
        + "if (value != null) n['value'] = value; \n "
jaroslav@36
   280
        + "return n['value'];";
jtulach@692
   281
        Object ret = Utils.executeScript(
jaroslav@121
   282
            KnockoutTest.class,
jaroslav@121
   283
            s, value
jaroslav@121
   284
        );
jtulach@692
   285
        return ret == null ? null : ret.toString();
jaroslav@34
   286
    }
jaroslav@34
   287
    
jaroslav@36
   288
    public static void triggerEvent(String id, String ev) throws Exception {
jaroslav@36
   289
        Utils.executeScript(
jaroslav@121
   290
            KnockoutTest.class,
jaroslav@36
   291
            "ko.utils.triggerEvent(window.document.getElementById(arguments[0]), arguments[1]);",
jaroslav@36
   292
            id, ev
jaroslav@36
   293
        );
jaroslav@34
   294
    }
jaroslav@34
   295
    
jaroslav@137
   296
    @KOTest public void displayContentOfArray() throws Exception {
jaroslav@137
   297
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   298
            "<ul id='ul' data-bind='foreach: results'>\n"
jaroslav@137
   299
            + "  <li data-bind='text: $data, click: $root.call'/>\n"
jaroslav@137
   300
            + "</ul>\n"
jaroslav@137
   301
        );
jaroslav@141
   302
        try {
jaroslav@141
   303
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@141
   304
            m.getResults().add("Ahoj");
jaroslav@141
   305
            m.applyBindings();
jaroslav@137
   306
jtulach@681
   307
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   308
            assert cnt == 1 : "One child, but was " + cnt;
jaroslav@137
   309
jaroslav@141
   310
            m.getResults().add("Hi");
jaroslav@137
   311
jtulach@681
   312
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   313
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@34
   314
jaroslav@141
   315
            triggerChildClick("ul", 1);
jaroslav@137
   316
jaroslav@141
   317
            assert 1 == m.getCallbackCount() : "One callback " + m.getCallbackCount();
jaroslav@141
   318
            assert "Hi".equals(m.getName()) : "We got callback from 2nd child " + m.getName();
jaroslav@141
   319
        } finally {
jaroslav@141
   320
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   321
        }
jaroslav@34
   322
    }
jaroslav@235
   323
    
jaroslav@719
   324
    @KOTest public void displayContentOfAsyncArray() throws Exception {
jaroslav@719
   325
        if (js == null) {
jaroslav@719
   326
            Utils.exposeHTML(KnockoutTest.class, 
jaroslav@719
   327
                "<ul id='ul' data-bind='foreach: results'>\n"
jaroslav@719
   328
                + "  <li data-bind='text: $data, click: $root.call'/>\n"
jaroslav@719
   329
                + "</ul>\n"
jaroslav@719
   330
            );
jaroslav@719
   331
            js = Models.bind(new KnockoutModel(), newContext());
jaroslav@719
   332
            js.getResults().add("Ahoj");
jaroslav@719
   333
            js.applyBindings();
jaroslav@719
   334
jaroslav@719
   335
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@719
   336
            assert cnt == 1 : "One child, but was " + cnt;
jaroslav@719
   337
            
jaroslav@719
   338
            Timer t = new Timer("add to array");
jaroslav@719
   339
            t.schedule(new TimerTask() {
jaroslav@719
   340
                @Override
jaroslav@719
   341
                public void run() {
jaroslav@719
   342
                    js.getResults().add("Hi");
jaroslav@719
   343
                }
jaroslav@719
   344
            }, 1);
jaroslav@719
   345
        }
jaroslav@719
   346
jaroslav@719
   347
jaroslav@719
   348
        int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@719
   349
        if (cnt != 2) {
jaroslav@719
   350
            throw new InterruptedException();
jaroslav@719
   351
        }
jaroslav@719
   352
jaroslav@719
   353
        try {
jaroslav@719
   354
            triggerChildClick("ul", 1);
jaroslav@719
   355
jaroslav@719
   356
            assert 1 == js.getCallbackCount() : "One callback " + js.getCallbackCount();
jaroslav@719
   357
            assert "Hi".equals(js.getName()) : "We got callback from 2nd child " + js.getName();
jaroslav@719
   358
        } finally {
jaroslav@719
   359
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@719
   360
        }
jaroslav@719
   361
    }
jaroslav@719
   362
    
jaroslav@235
   363
    @KOTest public void displayContentOfComputedArray() throws Exception {
jaroslav@235
   364
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@235
   365
            "<ul id='ul' data-bind='foreach: bothNames'>\n"
jaroslav@235
   366
            + "  <li data-bind='text: $data, click: $root.assignFirstName'/>\n"
jaroslav@235
   367
            + "</ul>\n"
jaroslav@235
   368
        );
jaroslav@235
   369
        try {
jaroslav@236
   370
            Pair m = Models.bind(new Pair("First", "Last", null), newContext());
jaroslav@236
   371
            m.applyBindings();
jaroslav@236
   372
jtulach@681
   373
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@236
   374
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@236
   375
jaroslav@236
   376
            triggerChildClick("ul", 1);
jaroslav@236
   377
jaroslav@236
   378
            assert "Last".equals(m.getFirstName()) : "We got callback from 2nd child " + m.getFirstName();
jtulach@626
   379
            
jtulach@626
   380
            m.setLastName("Verylast");
jtulach@626
   381
jtulach@681
   382
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@626
   383
            assert cnt == 2 : "Two children now, but was " + cnt;
jtulach@626
   384
            
jtulach@626
   385
            triggerChildClick("ul", 1);
jtulach@626
   386
jtulach@626
   387
            assert "Verylast".equals(m.getFirstName()) : "We got callback from 2nd child " + m.getFirstName();
jtulach@626
   388
            
jaroslav@236
   389
        } finally {
jaroslav@236
   390
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@236
   391
        }
jaroslav@236
   392
    }
jaroslav@236
   393
    
jaroslav@236
   394
    @KOTest public void displayContentOfComputedArrayOnASubpair() throws Exception {
jaroslav@236
   395
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@236
   396
              "<div data-bind='with: next'>\n"
jaroslav@236
   397
            + "<ul id='ul' data-bind='foreach: bothNames'>\n"
jaroslav@236
   398
            + "  <li data-bind='text: $data, click: $root.assignFirstName'/>\n"
jaroslav@236
   399
            + "</ul>"
jaroslav@236
   400
            + "</div>\n"
jaroslav@236
   401
        );
jaroslav@236
   402
        try {
jtulach@569
   403
            final BrwsrCtx ctx = newContext();
jtulach@569
   404
            Pair m = Models.bind(new Pair(null, null, new Pair("First", "Last", null)), ctx);
jaroslav@236
   405
            m.applyBindings();
jaroslav@236
   406
jtulach@681
   407
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@236
   408
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@236
   409
jaroslav@236
   410
            triggerChildClick("ul", 1);
jtulach@569
   411
            
jaroslav@571
   412
            assert PairModel.ctx == ctx : "Context remains the same";
jaroslav@236
   413
jaroslav@236
   414
            assert "Last".equals(m.getFirstName()) : "We got callback from 2nd child " + m.getFirstName();
jaroslav@236
   415
        } finally {
jaroslav@236
   416
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@236
   417
        }
jaroslav@236
   418
    }
jaroslav@236
   419
    
jaroslav@236
   420
    @KOTest public void displayContentOfComputedArrayOnComputedASubpair() throws Exception {
jaroslav@236
   421
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@236
   422
              "<div data-bind='with: nextOne'>\n"
jaroslav@236
   423
            + "<ul id='ul' data-bind='foreach: bothNames'>\n"
jaroslav@236
   424
            + "  <li data-bind='text: $data, click: $root.assignFirstName'/>\n"
jaroslav@236
   425
            + "</ul>"
jaroslav@236
   426
            + "</div>\n"
jaroslav@236
   427
        );
jaroslav@236
   428
        try {
jaroslav@236
   429
            Pair m = Models.bind(new Pair(null, null, new Pair("First", "Last", null)), newContext());
jaroslav@235
   430
            m.applyBindings();
jaroslav@235
   431
jtulach@681
   432
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@235
   433
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@235
   434
jaroslav@235
   435
            triggerChildClick("ul", 1);
jaroslav@235
   436
jaroslav@235
   437
            assert "Last".equals(m.getFirstName()) : "We got callback from 2nd child " + m.getFirstName();
jaroslav@235
   438
        } finally {
jaroslav@235
   439
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@235
   440
        }
jaroslav@235
   441
    }
jaroslav@94
   442
jaroslav@137
   443
    @KOTest public void checkBoxToBooleanBinding() throws Exception {
jaroslav@137
   444
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   445
            "<input type='checkbox' id='b' data-bind='checked: enabled'></input>\n"
jaroslav@137
   446
        );
jaroslav@141
   447
        try {
jaroslav@141
   448
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@141
   449
            m.applyBindings();
jaroslav@137
   450
jaroslav@141
   451
            assert !m.isEnabled() : "Is disabled";
jaroslav@137
   452
jaroslav@141
   453
            triggerClick("b");
jaroslav@94
   454
jaroslav@141
   455
            assert m.isEnabled() : "Now the model is enabled";
jaroslav@141
   456
        } finally {
jaroslav@141
   457
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   458
        }
jaroslav@94
   459
    }
jaroslav@94
   460
    
jaroslav@94
   461
    
jaroslav@34
   462
    
jaroslav@137
   463
    @KOTest public void displayContentOfDerivedArray() throws Exception {
jaroslav@137
   464
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   465
            "<ul id='ul' data-bind='foreach: cmpResults'>\n"
jaroslav@137
   466
            + "  <li><b data-bind='text: $data'></b></li>\n"
jaroslav@137
   467
            + "</ul>\n"
jaroslav@137
   468
        );
jaroslav@141
   469
        try {
jaroslav@141
   470
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@141
   471
            m.getResults().add("Ahoj");
jaroslav@141
   472
            m.applyBindings();
jaroslav@137
   473
jtulach@681
   474
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   475
            assert cnt == 1 : "One child, but was " + cnt;
jaroslav@137
   476
jaroslav@141
   477
            m.getResults().add("hello");
jaroslav@137
   478
jtulach@681
   479
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   480
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@141
   481
        } finally {
jaroslav@141
   482
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   483
        }
jaroslav@34
   484
    }
jaroslav@34
   485
    
jaroslav@137
   486
    @KOTest public void displayContentOfArrayOfPeople() throws Exception {
jaroslav@137
   487
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   488
            "<ul id='ul' data-bind='foreach: people'>\n"
jaroslav@137
   489
            + "  <li data-bind='text: $data.firstName, click: $root.removePerson'></li>\n"
jaroslav@137
   490
            + "</ul>\n"
jaroslav@137
   491
        );
jaroslav@141
   492
        try {
jaroslav@424
   493
            final BrwsrCtx c = newContext();
jaroslav@424
   494
            KnockoutModel m = Models.bind(new KnockoutModel(), c);
jaroslav@137
   495
jaroslav@424
   496
            final Person first = Models.bind(new Person(), c);
jaroslav@141
   497
            first.setFirstName("first");
jaroslav@141
   498
            m.getPeople().add(first);
jaroslav@137
   499
jaroslav@141
   500
            m.applyBindings();
jaroslav@137
   501
jtulach@681
   502
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   503
            assert cnt == 1 : "One child, but was " + cnt;
jaroslav@137
   504
jaroslav@424
   505
            final Person second = Models.bind(new Person(), c);
jaroslav@141
   506
            second.setFirstName("second");
jaroslav@141
   507
            m.getPeople().add(second);
jaroslav@137
   508
jtulach@681
   509
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   510
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@34
   511
jaroslav@141
   512
            triggerChildClick("ul", 1);
jaroslav@34
   513
jaroslav@141
   514
            assert 1 == m.getCallbackCount() : "One callback " + m.getCallbackCount();
jaroslav@137
   515
jtulach@681
   516
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   517
            assert cnt == 1 : "Again one child, but was " + cnt;
jaroslav@34
   518
jaroslav@141
   519
            String txt = childText("ul", 0);
jaroslav@141
   520
            assert "first".equals(txt) : "Expecting 'first': " + txt;
jaroslav@137
   521
jaroslav@141
   522
            first.setFirstName("changed");
jaroslav@137
   523
jaroslav@141
   524
            txt = childText("ul", 0);
jaroslav@141
   525
            assert "changed".equals(txt) : "Expecting 'changed': " + txt;
jaroslav@141
   526
        } finally {
jaroslav@141
   527
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   528
        }
jaroslav@34
   529
    }
jaroslav@34
   530
    
jaroslav@34
   531
    @ComputedProperty
jaroslav@34
   532
    static Person firstPerson(List<Person> people) {
jaroslav@34
   533
        return people.isEmpty() ? null : people.get(0);
jaroslav@34
   534
    }
jaroslav@34
   535
    
jaroslav@137
   536
    @KOTest public void accessFirstPersonWithOnFunction() throws Exception {
jaroslav@137
   537
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   538
            "<p id='ul' data-bind='with: firstPerson'>\n"
jaroslav@137
   539
            + "  <span data-bind='text: firstName, click: changeSex'></span>\n"
jaroslav@137
   540
            + "</p>\n"
jaroslav@137
   541
        );
jaroslav@141
   542
        try {
jaroslav@141
   543
            trasfertToFemale();
jaroslav@141
   544
        } finally {
jaroslav@141
   545
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   546
        }
jaroslav@34
   547
    }
jaroslav@34
   548
    
jaroslav@137
   549
    @KOTest public void onPersonFunction() throws Exception {
jaroslav@137
   550
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   551
            "<ul id='ul' data-bind='foreach: people'>\n"
jaroslav@137
   552
            + "  <li data-bind='text: $data.firstName, click: changeSex'></li>\n"
jaroslav@137
   553
            + "</ul>\n"
jaroslav@137
   554
        );
jaroslav@141
   555
        try {
jaroslav@141
   556
            trasfertToFemale();
jaroslav@141
   557
        } finally {
jaroslav@141
   558
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   559
        }
jaroslav@34
   560
    }
jaroslav@34
   561
    
jaroslav@36
   562
    private void trasfertToFemale() throws Exception {
jaroslav@121
   563
        KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@34
   564
jaroslav@121
   565
        final Person first = Models.bind(new Person(), newContext());
jaroslav@34
   566
        first.setFirstName("first");
jaroslav@34
   567
        first.setSex(Sex.MALE);
jaroslav@34
   568
        m.getPeople().add(first);
jaroslav@34
   569
jaroslav@34
   570
jaroslav@34
   571
        m.applyBindings();
jaroslav@34
   572
jtulach@681
   573
        int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@34
   574
        assert cnt == 1 : "One child, but was " + cnt;
jaroslav@34
   575
jaroslav@34
   576
jaroslav@34
   577
        triggerChildClick("ul", 0);
jaroslav@34
   578
jaroslav@34
   579
        assert first.getSex() == Sex.FEMALE : "Transverted to female: " + first.getSex();
jaroslav@34
   580
    }
jaroslav@34
   581
    
jtulach@824
   582
    @KOTest public void stringArrayModificationVisible() throws Exception {
jtulach@824
   583
        Object exp = Utils.exposeHTML(KnockoutTest.class,
jtulach@824
   584
                "<div>\n"
jtulach@824
   585
                + "<ul id='ul' data-bind='foreach: results'>\n"
jtulach@824
   586
                + "  <li data-bind='text: $data'></li>\n"
jtulach@824
   587
                + "</ul>\n"
jtulach@824
   588
              + "</div>\n"
jtulach@824
   589
        );
jtulach@824
   590
        try {
jtulach@824
   591
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jtulach@824
   592
            m.getResults().add("Ahoj");
jtulach@824
   593
            m.getResults().add("Hello");
jtulach@824
   594
            m.applyBindings();
jtulach@824
   595
            
jtulach@824
   596
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@824
   597
            assert cnt == 2 : "Two children " + cnt;
jtulach@824
   598
            
jtulach@825
   599
            Object arr = Utils.addChildren(KnockoutTest.class, "ul", "results", "Hi");
jtulach@824
   600
            assert arr instanceof Object[] : "Got back an array: " + arr;
jtulach@824
   601
            final int len = ((Object[])arr).length;
jtulach@824
   602
            
jtulach@824
   603
            assert len == 3 : "Three elements in the array " + len;
jtulach@824
   604
            
jtulach@824
   605
            int newCnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@824
   606
            assert newCnt == 3 : "Three children in the DOM: " + newCnt;
jtulach@824
   607
            
jtulach@824
   608
            assert m.getResults().size() == 3 : "Three java strings: " + m.getResults();
jtulach@824
   609
        } finally {
jtulach@824
   610
            Utils.exposeHTML(KnockoutTest.class, "");
jtulach@824
   611
        }
jtulach@824
   612
    }
jtulach@830
   613
jtulach@825
   614
    @KOTest public void intArrayModificationVisible() throws Exception {
jtulach@825
   615
        Object exp = Utils.exposeHTML(KnockoutTest.class,
jtulach@825
   616
                "<div>\n"
jtulach@825
   617
                + "<ul id='ul' data-bind='foreach: numbers'>\n"
jtulach@825
   618
                + "  <li data-bind='text: $data'></li>\n"
jtulach@825
   619
                + "</ul>\n"
jtulach@825
   620
              + "</div>\n"
jtulach@825
   621
        );
jtulach@825
   622
        try {
jtulach@825
   623
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jtulach@825
   624
            m.getNumbers().add(1);
jtulach@825
   625
            m.getNumbers().add(31);
jtulach@825
   626
            m.applyBindings();
jtulach@825
   627
            
jtulach@825
   628
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@825
   629
            assert cnt == 2 : "Two children " + cnt;
jtulach@825
   630
            
jtulach@825
   631
            Object arr = Utils.addChildren(KnockoutTest.class, "ul", "numbers", 42);
jtulach@825
   632
            assert arr instanceof Object[] : "Got back an array: " + arr;
jtulach@825
   633
            final int len = ((Object[])arr).length;
jtulach@825
   634
            
jtulach@825
   635
            assert len == 3 : "Three elements in the array " + len;
jtulach@825
   636
            
jtulach@825
   637
            int newCnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@825
   638
            assert newCnt == 3 : "Three children in the DOM: " + newCnt;
jtulach@825
   639
            
jtulach@825
   640
            assert m.getNumbers().size() == 3 : "Three java ints: " + m.getNumbers();
jtulach@825
   641
            assert m.getNumbers().get(2) == 42 : "Meaning of world: " + m.getNumbers();
jtulach@825
   642
        } finally {
jtulach@825
   643
            Utils.exposeHTML(KnockoutTest.class, "");
jtulach@825
   644
        }
jtulach@825
   645
    }
jtulach@830
   646
jtulach@830
   647
    @KOTest public void derivedIntArrayModificationVisible() throws Exception {
jtulach@830
   648
        Object exp = Utils.exposeHTML(KnockoutTest.class,
jtulach@830
   649
                "<div>\n"
jtulach@830
   650
                + "<ul id='ul' data-bind='foreach: resultLengths'>\n"
jtulach@830
   651
                + "  <li data-bind='text: $data'></li>\n"
jtulach@830
   652
                + "</ul>\n"
jtulach@830
   653
              + "</div>\n"
jtulach@830
   654
        );
jtulach@830
   655
        try {
jtulach@830
   656
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jtulach@830
   657
            m.getResults().add("Ahoj");
jtulach@830
   658
            m.getResults().add("Hello");
jtulach@830
   659
            m.applyBindings();
jtulach@830
   660
            
jtulach@830
   661
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@830
   662
            assert cnt == 2 : "Two children " + cnt;
jtulach@830
   663
            
jtulach@830
   664
            Object arr = Utils.addChildren(KnockoutTest.class, "ul", "results", "Hi");
jtulach@830
   665
            assert arr instanceof Object[] : "Got back an array: " + arr;
jtulach@830
   666
            final int len = ((Object[])arr).length;
jtulach@830
   667
            
jtulach@830
   668
            assert len == 3 : "Three elements in the array " + len;
jtulach@830
   669
            
jtulach@830
   670
            int newCnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@830
   671
            assert newCnt == 3 : "Three children in the DOM: " + newCnt;
jtulach@830
   672
            
jtulach@830
   673
            assert m.getResultLengths().size() == 3 : "Three java ints: " + m.getResultLengths();
jtulach@830
   674
            assert m.getResultLengths().get(2) == 2 : "Size is two: " + m.getResultLengths();
jtulach@830
   675
        } finally {
jtulach@830
   676
            Utils.exposeHTML(KnockoutTest.class, "");
jtulach@830
   677
        }
jtulach@830
   678
    }
jtulach@826
   679
    
jtulach@826
   680
    @KOTest public void archetypeArrayModificationVisible() throws Exception {
jtulach@826
   681
        Object exp = Utils.exposeHTML(KnockoutTest.class,
jtulach@826
   682
                "<div>\n"
jtulach@826
   683
                + "<ul id='ul' data-bind='foreach: archetypes'>\n"
jtulach@826
   684
                + "  <li data-bind='text: artifactId'></li>\n"
jtulach@826
   685
                + "</ul>\n"
jtulach@826
   686
              + "</div>\n"
jtulach@826
   687
        );
jtulach@826
   688
        try {
jtulach@826
   689
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jtulach@826
   690
            m.applyBindings();
jtulach@826
   691
            
jtulach@826
   692
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@826
   693
            assert cnt == 0 : "No children " + cnt;
jtulach@826
   694
            
jtulach@826
   695
            Object arr = Utils.addChildren(KnockoutTest.class, "ul", "archetypes", new ArchetypeData("aid", "gid", "v", "n", "d", "u"));
jtulach@826
   696
            assert arr instanceof Object[] : "Got back an array: " + arr;
jtulach@826
   697
            final int len = ((Object[])arr).length;
jtulach@826
   698
            
jtulach@826
   699
            assert len == 1 : "One element in the array " + len;
jtulach@826
   700
            
jtulach@826
   701
            int newCnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@826
   702
            assert newCnt == 1 : "One child in the DOM: " + newCnt;
jtulach@826
   703
            
jtulach@826
   704
            assert m.getArchetypes().size() == 1 : "One archetype: " + m.getArchetypes();
jtulach@826
   705
            assert m.getArchetypes().get(0) != null : "Not null: " + m.getArchetypes();
jtulach@826
   706
            assert m.getArchetypes().get(0).getArtifactId().equals("aid") : "'aid' == " + m.getArchetypes();
jtulach@826
   707
        } finally {
jtulach@826
   708
            Utils.exposeHTML(KnockoutTest.class, "");
jtulach@826
   709
        }
jtulach@826
   710
    }
jtulach@824
   711
jaroslav@34
   712
    @Function
jaroslav@34
   713
    static void call(KnockoutModel m, String data) {
jaroslav@34
   714
        m.setName(data);
jaroslav@34
   715
        m.setCallbackCount(m.getCallbackCount() + 1);
jaroslav@34
   716
    }
jaroslav@34
   717
jaroslav@34
   718
    @Function
jaroslav@34
   719
    static void removePerson(KnockoutModel model, Person data) {
jaroslav@34
   720
        model.setCallbackCount(model.getCallbackCount() + 1);
jaroslav@34
   721
        model.getPeople().remove(data);
jaroslav@34
   722
    }
jaroslav@34
   723
    
jaroslav@34
   724
    
jaroslav@34
   725
    @ComputedProperty
jaroslav@34
   726
    static String helloMessage(String name) {
jaroslav@34
   727
        return "Hello " + name + "!";
jaroslav@34
   728
    }
jaroslav@34
   729
    
jaroslav@34
   730
    @ComputedProperty
jaroslav@34
   731
    static List<String> cmpResults(List<String> results) {
jaroslav@34
   732
        return results;
jaroslav@34
   733
    }
jaroslav@34
   734
    
jaroslav@94
   735
    private static void triggerClick(String id) throws Exception {
jaroslav@94
   736
        String s = "var id = arguments[0];"
jaroslav@94
   737
            + "var e = window.document.getElementById(id);\n "
jtulach@695
   738
            + "if (e.checked) throw 'It should not be checked yet: ' + e;\n "
jaroslav@94
   739
            + "var ev = window.document.createEvent('MouseEvents');\n "
jaroslav@94
   740
            + "ev.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n "
jtulach@695
   741
            + "e.dispatchEvent(ev);\n "
jtulach@695
   742
            + "if (!e.checked) {\n"
jtulach@695
   743
            + "  e.checked = true;\n "
jtulach@695
   744
            + "  e.dispatchEvent(ev);\n "
jtulach@695
   745
            + "}\n";
jaroslav@121
   746
        Utils.executeScript(
jaroslav@121
   747
            KnockoutTest.class,
jaroslav@121
   748
            s, id);
jaroslav@94
   749
    }
jaroslav@36
   750
    private static void triggerChildClick(String id, int pos) throws Exception {
jtulach@684
   751
        String s = 
jtulach@684
   752
            "var id = arguments[0]; var pos = arguments[1];\n" +
jtulach@684
   753
            "var e = window.document.getElementById(id);\n " +
jtulach@684
   754
            "var ev = window.document.createEvent('MouseEvents');\n " +
jtulach@684
   755
            "ev.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n " +
jtulach@684
   756
            "var list = e.childNodes;\n" +
jtulach@684
   757
            "var cnt = -1;\n" + 
jtulach@684
   758
            "for (var i = 0; i < list.length; i++) {\n" + 
jtulach@684
   759
            "  if (list[i].nodeType == 1) cnt++;\n" + 
jtulach@704
   760
            "  if (cnt == pos) return list[i].dispatchEvent(ev);\n" + 
jtulach@684
   761
            "}\n" + 
jtulach@684
   762
            "return null;\n";
jaroslav@121
   763
        Utils.executeScript(
jaroslav@121
   764
            KnockoutTest.class,
jaroslav@121
   765
            s, id, pos);
jaroslav@36
   766
    }
jaroslav@34
   767
jaroslav@36
   768
    private static String childText(String id, int pos) throws Exception {
jtulach@683
   769
        String s = 
jtulach@683
   770
            "var id = arguments[0]; var pos = arguments[1];" +
jtulach@683
   771
            "var e = window.document.getElementById(id);\n" +
jtulach@683
   772
            "var list = e.childNodes;\n" +
jtulach@683
   773
            "var cnt = -1;\n" + 
jtulach@683
   774
            "for (var i = 0; i < list.length; i++) {\n" + 
jtulach@683
   775
            "  if (list[i].nodeType == 1) cnt++;\n" + 
jtulach@705
   776
            "  if (cnt == pos) return list[i].innerHTML;\n" + 
jtulach@683
   777
            "}\n" + 
jtulach@683
   778
            "return null;\n";
jaroslav@121
   779
        return (String)Utils.executeScript(
jaroslav@121
   780
            KnockoutTest.class,
jaroslav@121
   781
            s, id, pos);
jaroslav@121
   782
    }
jaroslav@121
   783
jaroslav@121
   784
    private static BrwsrCtx newContext() {
jaroslav@121
   785
        return Utils.newContext(KnockoutTest.class);
jaroslav@36
   786
    }
jaroslav@34
   787
}