json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 02 Aug 2014 12:59:31 +0200
changeset 790 30f20d9c0986
parent 758 0fff91d8e613
child 809 57c6bd4c5261
permissions -rw-r--r--
Fixing Javadoc to succeed on JDK8
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
jaroslav@34
    45
import java.util.List;
jaroslav@717
    46
import java.util.Timer;
jaroslav@717
    47
import java.util.TimerTask;
jaroslav@121
    48
import net.java.html.BrwsrCtx;
jaroslav@34
    49
import net.java.html.json.ComputedProperty;
jaroslav@34
    50
import net.java.html.json.Function;
jaroslav@34
    51
import net.java.html.json.Model;
jaroslav@115
    52
import net.java.html.json.Models;
jaroslav@34
    53
import net.java.html.json.Property;
jaroslav@137
    54
import org.apidesign.html.json.tck.KOTest;
jaroslav@34
    55
jaroslav@34
    56
/**
jaroslav@34
    57
 *
jtulach@790
    58
 * @author Jaroslav Tulach
jaroslav@34
    59
 */
jaroslav@34
    60
@Model(className="KnockoutModel", properties={
jaroslav@34
    61
    @Property(name="name", type=String.class),
jaroslav@34
    62
    @Property(name="results", type=String.class, array = true),
jaroslav@34
    63
    @Property(name="callbackCount", type=int.class),
jaroslav@94
    64
    @Property(name="people", type=PersonImpl.class, array = true),
jaroslav@197
    65
    @Property(name="enabled", type=boolean.class),
jtulach@758
    66
    @Property(name="latitude", type=double.class),
jtulach@758
    67
    @Property(name="choice", type=KnockoutTest.Choice.class),
jaroslav@34
    68
}) 
jaroslav@34
    69
public final class KnockoutTest {
jaroslav@717
    70
    private KnockoutModel js;
jaroslav@34
    71
    
jtulach@758
    72
    enum Choice {
jtulach@758
    73
        A, B;
jtulach@758
    74
    }
jtulach@758
    75
    
jtulach@758
    76
    @KOTest public void modifyValueAssertChangeInModelOnEnum() throws Throwable {
jtulach@758
    77
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jtulach@758
    78
            "Latitude: <input id='input' data-bind=\"value: choice\"></input>\n"
jtulach@758
    79
        );
jtulach@758
    80
        try {
jtulach@758
    81
jtulach@758
    82
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jtulach@758
    83
            m.setChoice(Choice.A);
jtulach@758
    84
            m.applyBindings();
jtulach@758
    85
jtulach@758
    86
            String v = getSetInput(null);
jtulach@758
    87
            assert "A".equals(v) : "Value is really A: " + v;
jtulach@758
    88
jtulach@758
    89
            getSetInput("B");
jtulach@758
    90
            triggerEvent("input", "change");
jtulach@758
    91
jtulach@758
    92
            assert Choice.B == m.getChoice(): "Enum property updated: " + m.getChoice();
jtulach@758
    93
        } catch (Throwable t) {
jtulach@758
    94
            throw t;
jtulach@758
    95
        } finally {
jtulach@758
    96
            Utils.exposeHTML(KnockoutTest.class, "");
jtulach@758
    97
        }
jtulach@758
    98
    }
jtulach@758
    99
    
jaroslav@197
   100
    @KOTest public void modifyValueAssertChangeInModelOnDouble() throws Throwable {
jaroslav@197
   101
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@197
   102
            "Latitude: <input id='input' data-bind=\"value: latitude\"></input>\n"
jaroslav@197
   103
        );
jaroslav@197
   104
        try {
jaroslav@197
   105
jaroslav@197
   106
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@197
   107
            m.setLatitude(50.5);
jaroslav@197
   108
            m.applyBindings();
jaroslav@197
   109
jaroslav@197
   110
            String v = getSetInput(null);
jaroslav@197
   111
            assert "50.5".equals(v) : "Value is really 50.5: " + v;
jaroslav@197
   112
jaroslav@197
   113
            getSetInput("49.5");
jaroslav@197
   114
            triggerEvent("input", "change");
jaroslav@197
   115
jaroslav@197
   116
            assert 49.5 == m.getLatitude() : "Double property updated: " + m.getLatitude();
jaroslav@197
   117
        } catch (Throwable t) {
jaroslav@197
   118
            throw t;
jaroslav@197
   119
        } finally {
jaroslav@197
   120
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@197
   121
        }
jaroslav@197
   122
    }
jaroslav@197
   123
    
jaroslav@197
   124
    @KOTest public void modifyValueAssertChangeInModelOnBoolean() throws Throwable {
jaroslav@197
   125
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@197
   126
            "Latitude: <input id='input' data-bind=\"value: enabled\"></input>\n"
jaroslav@197
   127
        );
jaroslav@197
   128
        try {
jaroslav@197
   129
jaroslav@197
   130
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@197
   131
            m.setEnabled(true);
jaroslav@197
   132
            m.applyBindings();
jaroslav@197
   133
jaroslav@197
   134
            String v = getSetInput(null);
jaroslav@197
   135
            assert "true".equals(v) : "Value is really true: " + v;
jaroslav@197
   136
jaroslav@197
   137
            getSetInput("false");
jaroslav@197
   138
            triggerEvent("input", "change");
jaroslav@197
   139
jaroslav@197
   140
            assert false == m.isEnabled(): "Boolean property updated: " + m.isEnabled();
jaroslav@197
   141
        } catch (Throwable t) {
jaroslav@197
   142
            throw t;
jaroslav@197
   143
        } finally {
jaroslav@197
   144
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@197
   145
        }
jaroslav@197
   146
    }
jaroslav@197
   147
    
jaroslav@137
   148
    @KOTest public void modifyValueAssertChangeInModel() throws Exception {
jaroslav@137
   149
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   150
            "<h1 data-bind=\"text: helloMessage\">Loading Bck2Brwsr's Hello World...</h1>\n" +
jaroslav@137
   151
            "Your name: <input id='input' data-bind=\"value: name\"></input>\n" +
jaroslav@137
   152
            "<button id=\"hello\">Say Hello!</button>\n"
jaroslav@137
   153
        );
jaroslav@141
   154
        try {
jaroslav@137
   155
jaroslav@141
   156
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@141
   157
            m.setName("Kukuc");
jaroslav@141
   158
            m.applyBindings();
jaroslav@137
   159
jaroslav@141
   160
            String v = getSetInput(null);
jaroslav@141
   161
            assert "Kukuc".equals(v) : "Value is really kukuc: " + v;
jaroslav@137
   162
jaroslav@141
   163
            getSetInput("Jardo");
jaroslav@141
   164
            triggerEvent("input", "change");
jaroslav@137
   165
jaroslav@141
   166
            assert "Jardo".equals(m.getName()) : "Name property updated: " + m.getName();
jaroslav@141
   167
        } finally {
jaroslav@141
   168
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   169
        }
jaroslav@34
   170
    }
jaroslav@34
   171
    
jaroslav@717
   172
    @KOTest public void modifyValueAssertAsyncChangeInModel() throws Exception {
jaroslav@717
   173
        if (js == null) {
jaroslav@717
   174
            Utils.exposeHTML(KnockoutTest.class, 
jaroslav@717
   175
                "<h1 data-bind=\"text: helloMessage\">Loading Bck2Brwsr's Hello World...</h1>\n" +
jaroslav@717
   176
                "Your name: <input id='input' data-bind=\"value: name\"></input>\n" +
jaroslav@717
   177
                "<button id=\"hello\">Say Hello!</button>\n"
jaroslav@717
   178
            );
jaroslav@717
   179
            
jaroslav@717
   180
            js = Models.bind(new KnockoutModel(), newContext());
jaroslav@717
   181
            js.setName("Kukuc");
jaroslav@717
   182
            js.applyBindings();
jaroslav@717
   183
            
jaroslav@717
   184
            String v = getSetInput(null);
jaroslav@717
   185
            assert "Kukuc".equals(v) : "Value is really kukuc: " + v;
jaroslav@717
   186
            
jaroslav@717
   187
            Timer t = new Timer("Set to Jardo");
jaroslav@717
   188
            t.schedule(new TimerTask() {
jaroslav@717
   189
                @Override
jaroslav@717
   190
                public void run() {
jaroslav@717
   191
                    js.setName("Jardo");
jaroslav@717
   192
                }
jaroslav@717
   193
            }, 1);
jaroslav@717
   194
        }
jaroslav@717
   195
        
jaroslav@717
   196
        String v = getSetInput(null);
jaroslav@717
   197
        if (!"Jardo".equals(v)) {
jaroslav@717
   198
            throw new InterruptedException();
jaroslav@717
   199
        }
jaroslav@717
   200
        
jaroslav@717
   201
        Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@717
   202
    }
jaroslav@717
   203
    
jaroslav@36
   204
    private static String getSetInput(String value) throws Exception {
jaroslav@36
   205
        String s = "var value = arguments[0];\n"
jaroslav@36
   206
        + "var n = window.document.getElementById('input'); \n "
jaroslav@34
   207
        + "if (value != null) n['value'] = value; \n "
jaroslav@36
   208
        + "return n['value'];";
jtulach@692
   209
        Object ret = Utils.executeScript(
jaroslav@121
   210
            KnockoutTest.class,
jaroslav@121
   211
            s, value
jaroslav@121
   212
        );
jtulach@692
   213
        return ret == null ? null : ret.toString();
jaroslav@34
   214
    }
jaroslav@34
   215
    
jaroslav@36
   216
    public static void triggerEvent(String id, String ev) throws Exception {
jaroslav@36
   217
        Utils.executeScript(
jaroslav@121
   218
            KnockoutTest.class,
jaroslav@36
   219
            "ko.utils.triggerEvent(window.document.getElementById(arguments[0]), arguments[1]);",
jaroslav@36
   220
            id, ev
jaroslav@36
   221
        );
jaroslav@34
   222
    }
jaroslav@34
   223
    
jaroslav@137
   224
    @KOTest public void displayContentOfArray() throws Exception {
jaroslav@137
   225
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   226
            "<ul id='ul' data-bind='foreach: results'>\n"
jaroslav@137
   227
            + "  <li data-bind='text: $data, click: $root.call'/>\n"
jaroslav@137
   228
            + "</ul>\n"
jaroslav@137
   229
        );
jaroslav@141
   230
        try {
jaroslav@141
   231
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@141
   232
            m.getResults().add("Ahoj");
jaroslav@141
   233
            m.applyBindings();
jaroslav@137
   234
jtulach@681
   235
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   236
            assert cnt == 1 : "One child, but was " + cnt;
jaroslav@137
   237
jaroslav@141
   238
            m.getResults().add("Hi");
jaroslav@137
   239
jtulach@681
   240
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   241
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@34
   242
jaroslav@141
   243
            triggerChildClick("ul", 1);
jaroslav@137
   244
jaroslav@141
   245
            assert 1 == m.getCallbackCount() : "One callback " + m.getCallbackCount();
jaroslav@141
   246
            assert "Hi".equals(m.getName()) : "We got callback from 2nd child " + m.getName();
jaroslav@141
   247
        } finally {
jaroslav@141
   248
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   249
        }
jaroslav@34
   250
    }
jaroslav@235
   251
    
jaroslav@719
   252
    @KOTest public void displayContentOfAsyncArray() throws Exception {
jaroslav@719
   253
        if (js == null) {
jaroslav@719
   254
            Utils.exposeHTML(KnockoutTest.class, 
jaroslav@719
   255
                "<ul id='ul' data-bind='foreach: results'>\n"
jaroslav@719
   256
                + "  <li data-bind='text: $data, click: $root.call'/>\n"
jaroslav@719
   257
                + "</ul>\n"
jaroslav@719
   258
            );
jaroslav@719
   259
            js = Models.bind(new KnockoutModel(), newContext());
jaroslav@719
   260
            js.getResults().add("Ahoj");
jaroslav@719
   261
            js.applyBindings();
jaroslav@719
   262
jaroslav@719
   263
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@719
   264
            assert cnt == 1 : "One child, but was " + cnt;
jaroslav@719
   265
            
jaroslav@719
   266
            Timer t = new Timer("add to array");
jaroslav@719
   267
            t.schedule(new TimerTask() {
jaroslav@719
   268
                @Override
jaroslav@719
   269
                public void run() {
jaroslav@719
   270
                    js.getResults().add("Hi");
jaroslav@719
   271
                }
jaroslav@719
   272
            }, 1);
jaroslav@719
   273
        }
jaroslav@719
   274
jaroslav@719
   275
jaroslav@719
   276
        int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@719
   277
        if (cnt != 2) {
jaroslav@719
   278
            throw new InterruptedException();
jaroslav@719
   279
        }
jaroslav@719
   280
jaroslav@719
   281
        try {
jaroslav@719
   282
            triggerChildClick("ul", 1);
jaroslav@719
   283
jaroslav@719
   284
            assert 1 == js.getCallbackCount() : "One callback " + js.getCallbackCount();
jaroslav@719
   285
            assert "Hi".equals(js.getName()) : "We got callback from 2nd child " + js.getName();
jaroslav@719
   286
        } finally {
jaroslav@719
   287
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@719
   288
        }
jaroslav@719
   289
    }
jaroslav@719
   290
    
jaroslav@235
   291
    @KOTest public void displayContentOfComputedArray() throws Exception {
jaroslav@235
   292
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@235
   293
            "<ul id='ul' data-bind='foreach: bothNames'>\n"
jaroslav@235
   294
            + "  <li data-bind='text: $data, click: $root.assignFirstName'/>\n"
jaroslav@235
   295
            + "</ul>\n"
jaroslav@235
   296
        );
jaroslav@235
   297
        try {
jaroslav@236
   298
            Pair m = Models.bind(new Pair("First", "Last", null), newContext());
jaroslav@236
   299
            m.applyBindings();
jaroslav@236
   300
jtulach@681
   301
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@236
   302
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@236
   303
jaroslav@236
   304
            triggerChildClick("ul", 1);
jaroslav@236
   305
jaroslav@236
   306
            assert "Last".equals(m.getFirstName()) : "We got callback from 2nd child " + m.getFirstName();
jtulach@626
   307
            
jtulach@626
   308
            m.setLastName("Verylast");
jtulach@626
   309
jtulach@681
   310
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jtulach@626
   311
            assert cnt == 2 : "Two children now, but was " + cnt;
jtulach@626
   312
            
jtulach@626
   313
            triggerChildClick("ul", 1);
jtulach@626
   314
jtulach@626
   315
            assert "Verylast".equals(m.getFirstName()) : "We got callback from 2nd child " + m.getFirstName();
jtulach@626
   316
            
jaroslav@236
   317
        } finally {
jaroslav@236
   318
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@236
   319
        }
jaroslav@236
   320
    }
jaroslav@236
   321
    
jaroslav@236
   322
    @KOTest public void displayContentOfComputedArrayOnASubpair() throws Exception {
jaroslav@236
   323
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@236
   324
              "<div data-bind='with: next'>\n"
jaroslav@236
   325
            + "<ul id='ul' data-bind='foreach: bothNames'>\n"
jaroslav@236
   326
            + "  <li data-bind='text: $data, click: $root.assignFirstName'/>\n"
jaroslav@236
   327
            + "</ul>"
jaroslav@236
   328
            + "</div>\n"
jaroslav@236
   329
        );
jaroslav@236
   330
        try {
jtulach@569
   331
            final BrwsrCtx ctx = newContext();
jtulach@569
   332
            Pair m = Models.bind(new Pair(null, null, new Pair("First", "Last", null)), ctx);
jaroslav@236
   333
            m.applyBindings();
jaroslav@236
   334
jtulach@681
   335
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@236
   336
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@236
   337
jaroslav@236
   338
            triggerChildClick("ul", 1);
jtulach@569
   339
            
jaroslav@571
   340
            assert PairModel.ctx == ctx : "Context remains the same";
jaroslav@236
   341
jaroslav@236
   342
            assert "Last".equals(m.getFirstName()) : "We got callback from 2nd child " + m.getFirstName();
jaroslav@236
   343
        } finally {
jaroslav@236
   344
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@236
   345
        }
jaroslav@236
   346
    }
jaroslav@236
   347
    
jaroslav@236
   348
    @KOTest public void displayContentOfComputedArrayOnComputedASubpair() throws Exception {
jaroslav@236
   349
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@236
   350
              "<div data-bind='with: nextOne'>\n"
jaroslav@236
   351
            + "<ul id='ul' data-bind='foreach: bothNames'>\n"
jaroslav@236
   352
            + "  <li data-bind='text: $data, click: $root.assignFirstName'/>\n"
jaroslav@236
   353
            + "</ul>"
jaroslav@236
   354
            + "</div>\n"
jaroslav@236
   355
        );
jaroslav@236
   356
        try {
jaroslav@236
   357
            Pair m = Models.bind(new Pair(null, null, new Pair("First", "Last", null)), newContext());
jaroslav@235
   358
            m.applyBindings();
jaroslav@235
   359
jtulach@681
   360
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@235
   361
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@235
   362
jaroslav@235
   363
            triggerChildClick("ul", 1);
jaroslav@235
   364
jaroslav@235
   365
            assert "Last".equals(m.getFirstName()) : "We got callback from 2nd child " + m.getFirstName();
jaroslav@235
   366
        } finally {
jaroslav@235
   367
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@235
   368
        }
jaroslav@235
   369
    }
jaroslav@94
   370
jaroslav@137
   371
    @KOTest public void checkBoxToBooleanBinding() throws Exception {
jaroslav@137
   372
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   373
            "<input type='checkbox' id='b' data-bind='checked: enabled'></input>\n"
jaroslav@137
   374
        );
jaroslav@141
   375
        try {
jaroslav@141
   376
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@141
   377
            m.applyBindings();
jaroslav@137
   378
jaroslav@141
   379
            assert !m.isEnabled() : "Is disabled";
jaroslav@137
   380
jaroslav@141
   381
            triggerClick("b");
jaroslav@94
   382
jaroslav@141
   383
            assert m.isEnabled() : "Now the model is enabled";
jaroslav@141
   384
        } finally {
jaroslav@141
   385
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   386
        }
jaroslav@94
   387
    }
jaroslav@94
   388
    
jaroslav@94
   389
    
jaroslav@34
   390
    
jaroslav@137
   391
    @KOTest public void displayContentOfDerivedArray() throws Exception {
jaroslav@137
   392
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   393
            "<ul id='ul' data-bind='foreach: cmpResults'>\n"
jaroslav@137
   394
            + "  <li><b data-bind='text: $data'></b></li>\n"
jaroslav@137
   395
            + "</ul>\n"
jaroslav@137
   396
        );
jaroslav@141
   397
        try {
jaroslav@141
   398
            KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@141
   399
            m.getResults().add("Ahoj");
jaroslav@141
   400
            m.applyBindings();
jaroslav@137
   401
jtulach@681
   402
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   403
            assert cnt == 1 : "One child, but was " + cnt;
jaroslav@137
   404
jaroslav@141
   405
            m.getResults().add("hello");
jaroslav@137
   406
jtulach@681
   407
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   408
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@141
   409
        } finally {
jaroslav@141
   410
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   411
        }
jaroslav@34
   412
    }
jaroslav@34
   413
    
jaroslav@137
   414
    @KOTest public void displayContentOfArrayOfPeople() throws Exception {
jaroslav@137
   415
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   416
            "<ul id='ul' data-bind='foreach: people'>\n"
jaroslav@137
   417
            + "  <li data-bind='text: $data.firstName, click: $root.removePerson'></li>\n"
jaroslav@137
   418
            + "</ul>\n"
jaroslav@137
   419
        );
jaroslav@141
   420
        try {
jaroslav@424
   421
            final BrwsrCtx c = newContext();
jaroslav@424
   422
            KnockoutModel m = Models.bind(new KnockoutModel(), c);
jaroslav@137
   423
jaroslav@424
   424
            final Person first = Models.bind(new Person(), c);
jaroslav@141
   425
            first.setFirstName("first");
jaroslav@141
   426
            m.getPeople().add(first);
jaroslav@137
   427
jaroslav@141
   428
            m.applyBindings();
jaroslav@137
   429
jtulach@681
   430
            int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   431
            assert cnt == 1 : "One child, but was " + cnt;
jaroslav@137
   432
jaroslav@424
   433
            final Person second = Models.bind(new Person(), c);
jaroslav@141
   434
            second.setFirstName("second");
jaroslav@141
   435
            m.getPeople().add(second);
jaroslav@137
   436
jtulach@681
   437
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   438
            assert cnt == 2 : "Two children now, but was " + cnt;
jaroslav@34
   439
jaroslav@141
   440
            triggerChildClick("ul", 1);
jaroslav@34
   441
jaroslav@141
   442
            assert 1 == m.getCallbackCount() : "One callback " + m.getCallbackCount();
jaroslav@137
   443
jtulach@681
   444
            cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@141
   445
            assert cnt == 1 : "Again one child, but was " + cnt;
jaroslav@34
   446
jaroslav@141
   447
            String txt = childText("ul", 0);
jaroslav@141
   448
            assert "first".equals(txt) : "Expecting 'first': " + txt;
jaroslav@137
   449
jaroslav@141
   450
            first.setFirstName("changed");
jaroslav@137
   451
jaroslav@141
   452
            txt = childText("ul", 0);
jaroslav@141
   453
            assert "changed".equals(txt) : "Expecting 'changed': " + txt;
jaroslav@141
   454
        } finally {
jaroslav@141
   455
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   456
        }
jaroslav@34
   457
    }
jaroslav@34
   458
    
jaroslav@34
   459
    @ComputedProperty
jaroslav@34
   460
    static Person firstPerson(List<Person> people) {
jaroslav@34
   461
        return people.isEmpty() ? null : people.get(0);
jaroslav@34
   462
    }
jaroslav@34
   463
    
jaroslav@137
   464
    @KOTest public void accessFirstPersonWithOnFunction() throws Exception {
jaroslav@137
   465
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   466
            "<p id='ul' data-bind='with: firstPerson'>\n"
jaroslav@137
   467
            + "  <span data-bind='text: firstName, click: changeSex'></span>\n"
jaroslav@137
   468
            + "</p>\n"
jaroslav@137
   469
        );
jaroslav@141
   470
        try {
jaroslav@141
   471
            trasfertToFemale();
jaroslav@141
   472
        } finally {
jaroslav@141
   473
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   474
        }
jaroslav@34
   475
    }
jaroslav@34
   476
    
jaroslav@137
   477
    @KOTest public void onPersonFunction() throws Exception {
jaroslav@137
   478
        Object exp = Utils.exposeHTML(KnockoutTest.class, 
jaroslav@137
   479
            "<ul id='ul' data-bind='foreach: people'>\n"
jaroslav@137
   480
            + "  <li data-bind='text: $data.firstName, click: changeSex'></li>\n"
jaroslav@137
   481
            + "</ul>\n"
jaroslav@137
   482
        );
jaroslav@141
   483
        try {
jaroslav@141
   484
            trasfertToFemale();
jaroslav@141
   485
        } finally {
jaroslav@141
   486
            Utils.exposeHTML(KnockoutTest.class, "");
jaroslav@141
   487
        }
jaroslav@34
   488
    }
jaroslav@34
   489
    
jaroslav@36
   490
    private void trasfertToFemale() throws Exception {
jaroslav@121
   491
        KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
jaroslav@34
   492
jaroslav@121
   493
        final Person first = Models.bind(new Person(), newContext());
jaroslav@34
   494
        first.setFirstName("first");
jaroslav@34
   495
        first.setSex(Sex.MALE);
jaroslav@34
   496
        m.getPeople().add(first);
jaroslav@34
   497
jaroslav@34
   498
jaroslav@34
   499
        m.applyBindings();
jaroslav@34
   500
jtulach@681
   501
        int cnt = Utils.countChildren(KnockoutTest.class, "ul");
jaroslav@34
   502
        assert cnt == 1 : "One child, but was " + cnt;
jaroslav@34
   503
jaroslav@34
   504
jaroslav@34
   505
        triggerChildClick("ul", 0);
jaroslav@34
   506
jaroslav@34
   507
        assert first.getSex() == Sex.FEMALE : "Transverted to female: " + first.getSex();
jaroslav@34
   508
    }
jaroslav@34
   509
    
jaroslav@34
   510
    @Function
jaroslav@34
   511
    static void call(KnockoutModel m, String data) {
jaroslav@34
   512
        m.setName(data);
jaroslav@34
   513
        m.setCallbackCount(m.getCallbackCount() + 1);
jaroslav@34
   514
    }
jaroslav@34
   515
jaroslav@34
   516
    @Function
jaroslav@34
   517
    static void removePerson(KnockoutModel model, Person data) {
jaroslav@34
   518
        model.setCallbackCount(model.getCallbackCount() + 1);
jaroslav@34
   519
        model.getPeople().remove(data);
jaroslav@34
   520
    }
jaroslav@34
   521
    
jaroslav@34
   522
    
jaroslav@34
   523
    @ComputedProperty
jaroslav@34
   524
    static String helloMessage(String name) {
jaroslav@34
   525
        return "Hello " + name + "!";
jaroslav@34
   526
    }
jaroslav@34
   527
    
jaroslav@34
   528
    @ComputedProperty
jaroslav@34
   529
    static List<String> cmpResults(List<String> results) {
jaroslav@34
   530
        return results;
jaroslav@34
   531
    }
jaroslav@34
   532
    
jaroslav@94
   533
    private static void triggerClick(String id) throws Exception {
jaroslav@94
   534
        String s = "var id = arguments[0];"
jaroslav@94
   535
            + "var e = window.document.getElementById(id);\n "
jtulach@695
   536
            + "if (e.checked) throw 'It should not be checked yet: ' + e;\n "
jaroslav@94
   537
            + "var ev = window.document.createEvent('MouseEvents');\n "
jaroslav@94
   538
            + "ev.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n "
jtulach@695
   539
            + "e.dispatchEvent(ev);\n "
jtulach@695
   540
            + "if (!e.checked) {\n"
jtulach@695
   541
            + "  e.checked = true;\n "
jtulach@695
   542
            + "  e.dispatchEvent(ev);\n "
jtulach@695
   543
            + "}\n";
jaroslav@121
   544
        Utils.executeScript(
jaroslav@121
   545
            KnockoutTest.class,
jaroslav@121
   546
            s, id);
jaroslav@94
   547
    }
jaroslav@36
   548
    private static void triggerChildClick(String id, int pos) throws Exception {
jtulach@684
   549
        String s = 
jtulach@684
   550
            "var id = arguments[0]; var pos = arguments[1];\n" +
jtulach@684
   551
            "var e = window.document.getElementById(id);\n " +
jtulach@684
   552
            "var ev = window.document.createEvent('MouseEvents');\n " +
jtulach@684
   553
            "ev.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n " +
jtulach@684
   554
            "var list = e.childNodes;\n" +
jtulach@684
   555
            "var cnt = -1;\n" + 
jtulach@684
   556
            "for (var i = 0; i < list.length; i++) {\n" + 
jtulach@684
   557
            "  if (list[i].nodeType == 1) cnt++;\n" + 
jtulach@704
   558
            "  if (cnt == pos) return list[i].dispatchEvent(ev);\n" + 
jtulach@684
   559
            "}\n" + 
jtulach@684
   560
            "return null;\n";
jaroslav@121
   561
        Utils.executeScript(
jaroslav@121
   562
            KnockoutTest.class,
jaroslav@121
   563
            s, id, pos);
jaroslav@36
   564
    }
jaroslav@34
   565
jaroslav@36
   566
    private static String childText(String id, int pos) throws Exception {
jtulach@683
   567
        String s = 
jtulach@683
   568
            "var id = arguments[0]; var pos = arguments[1];" +
jtulach@683
   569
            "var e = window.document.getElementById(id);\n" +
jtulach@683
   570
            "var list = e.childNodes;\n" +
jtulach@683
   571
            "var cnt = -1;\n" + 
jtulach@683
   572
            "for (var i = 0; i < list.length; i++) {\n" + 
jtulach@683
   573
            "  if (list[i].nodeType == 1) cnt++;\n" + 
jtulach@705
   574
            "  if (cnt == pos) return list[i].innerHTML;\n" + 
jtulach@683
   575
            "}\n" + 
jtulach@683
   576
            "return null;\n";
jaroslav@121
   577
        return (String)Utils.executeScript(
jaroslav@121
   578
            KnockoutTest.class,
jaroslav@121
   579
            s, id, pos);
jaroslav@121
   580
    }
jaroslav@121
   581
jaroslav@121
   582
    private static BrwsrCtx newContext() {
jaroslav@121
   583
        return Utils.newContext(KnockoutTest.class);
jaroslav@36
   584
    }
jaroslav@34
   585
}