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