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