json-tck/src/main/java/net/java/html/json/tests/JSONTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 28 May 2013 20:01:30 +0200
branchcontext
changeset 115 b236fc0949e0
parent 110 21bf4126e3a9
child 121 81e976eb0fc2
permissions -rw-r--r--
Create default instances and just bind them to unit testing context
jaroslav@34
     1
/**
jaroslav@34
     2
 * HTML via Java(tm) Language Bindings
jaroslav@34
     3
 * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@34
     4
 *
jaroslav@34
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@34
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@34
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@34
     8
 *
jaroslav@34
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@34
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@34
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@34
    12
 * GNU General Public License for more details. apidesign.org
jaroslav@34
    13
 * designates this particular file as subject to the
jaroslav@34
    14
 * "Classpath" exception as provided by apidesign.org
jaroslav@34
    15
 * in the License file that accompanied this code.
jaroslav@34
    16
 *
jaroslav@34
    17
 * You should have received a copy of the GNU General Public License
jaroslav@34
    18
 * along with this program. Look for COPYING file in the top folder.
jaroslav@34
    19
 * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
jaroslav@34
    20
 */
jaroslav@34
    21
package net.java.html.json.tests;
jaroslav@34
    22
jaroslav@77
    23
import java.io.ByteArrayInputStream;
jaroslav@110
    24
import net.java.html.BrwsrCtx;
jaroslav@34
    25
import net.java.html.json.Model;
jaroslav@77
    26
import net.java.html.json.Models;
jaroslav@34
    27
import net.java.html.json.OnReceive;
jaroslav@34
    28
import net.java.html.json.Property;
jaroslav@34
    29
import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
jaroslav@34
    30
import org.apidesign.bck2brwsr.vmtest.Http;
jaroslav@34
    31
import org.apidesign.bck2brwsr.vmtest.VMTest;
jaroslav@34
    32
import org.apidesign.html.json.impl.JSON;
jaroslav@34
    33
jaroslav@34
    34
/** Need to verify that models produce reasonable JSON objects.
jaroslav@34
    35
 *
jaroslav@34
    36
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@34
    37
 */
jaroslav@34
    38
@Model(className = "JSONik", properties = {
jaroslav@34
    39
    @Property(name = "fetched", type = Person.class),
jaroslav@34
    40
    @Property(name = "fetchedCount", type = int.class),
jaroslav@73
    41
    @Property(name = "fetchedResponse", type = String.class),
jaroslav@34
    42
    @Property(name = "fetchedSex", type = Sex.class, array = true)
jaroslav@34
    43
})
jaroslav@34
    44
public final class JSONTest {
jaroslav@34
    45
    private JSONik js;
jaroslav@34
    46
    private Integer orig;
jaroslav@34
    47
    
jaroslav@34
    48
    @BrwsrTest public void toJSONInABrowser() throws Throwable {
jaroslav@115
    49
        Person p = Models.bind(new Person(), Utils.newContext());
jaroslav@34
    50
        p.setSex(Sex.MALE);
jaroslav@34
    51
        p.setFirstName("Jarda");
jaroslav@34
    52
        p.setLastName("Tulach");
jaroslav@34
    53
jaroslav@34
    54
        Object json;
jaroslav@34
    55
        try {
jaroslav@34
    56
            json = parseJSON(p.toString());
jaroslav@34
    57
        } catch (Throwable ex) {
jaroslav@34
    58
            throw new IllegalStateException("Can't parse " + p).initCause(ex);
jaroslav@34
    59
        }
jaroslav@34
    60
        
jaroslav@35
    61
        Person p2 = JSON.read(Utils.newContext(), Person.class, json);
jaroslav@34
    62
        
jaroslav@34
    63
        assert p2.getFirstName().equals(p.getFirstName()) : 
jaroslav@34
    64
            "Should be the same: " + p.getFirstName() + " != " + p2.getFirstName();
jaroslav@34
    65
    }
jaroslav@34
    66
    
jaroslav@34
    67
    @OnReceive(url="/{url}")
jaroslav@34
    68
    static void fetch(Person p, JSONik model) {
jaroslav@34
    69
        model.setFetched(p);
jaroslav@34
    70
    }
jaroslav@34
    71
jaroslav@34
    72
    @OnReceive(url="/{url}")
jaroslav@34
    73
    static void fetchArray(Person[] p, JSONik model) {
jaroslav@34
    74
        model.setFetchedCount(p.length);
jaroslav@34
    75
        model.setFetched(p[0]);
jaroslav@34
    76
    }
jaroslav@34
    77
    
jaroslav@34
    78
    @OnReceive(url="/{url}")
jaroslav@34
    79
    static void fetchPeople(People p, JSONik model) {
jaroslav@34
    80
        model.setFetchedCount(p.getInfo().size());
jaroslav@34
    81
        model.setFetched(p.getInfo().get(0));
jaroslav@34
    82
    }
jaroslav@34
    83
jaroslav@34
    84
    @OnReceive(url="/{url}")
jaroslav@34
    85
    static void fetchPeopleAge(People p, JSONik model) {
jaroslav@34
    86
        int sum = 0;
jaroslav@34
    87
        for (int a : p.getAge()) {
jaroslav@34
    88
            sum += a;
jaroslav@34
    89
        }
jaroslav@34
    90
        model.setFetchedCount(sum);
jaroslav@34
    91
    }
jaroslav@34
    92
    
jaroslav@34
    93
    @Http(@Http.Resource(
jaroslav@34
    94
        content = "{'firstName': 'Sitar', 'sex': 'MALE'}", 
jaroslav@34
    95
        path="/person.json", 
jaroslav@34
    96
        mimeType = "application/json"
jaroslav@34
    97
    ))
jaroslav@34
    98
    @BrwsrTest public void loadAndParseJSON() throws InterruptedException {
jaroslav@34
    99
        if (js == null) {
jaroslav@115
   100
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@34
   101
            js.applyBindings();
jaroslav@34
   102
jaroslav@34
   103
            js.fetch("person.json");
jaroslav@34
   104
        }
jaroslav@34
   105
    
jaroslav@34
   106
        Person p = js.getFetched();
jaroslav@34
   107
        if (p == null) {
jaroslav@34
   108
            throw new InterruptedException();
jaroslav@34
   109
        }
jaroslav@34
   110
        
jaroslav@34
   111
        assert "Sitar".equals(p.getFirstName()) : "Expecting Sitar: " + p.getFirstName();
jaroslav@34
   112
        assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
jaroslav@34
   113
    }
jaroslav@34
   114
    
jaroslav@34
   115
    @OnReceive(url="/{url}?callme={me}", jsonp = "me")
jaroslav@34
   116
    static void fetchViaJSONP(Person p, JSONik model) {
jaroslav@34
   117
        model.setFetched(p);
jaroslav@34
   118
    }
jaroslav@34
   119
    
jaroslav@34
   120
    @Http(@Http.Resource(
jaroslav@34
   121
        content = "$0({'firstName': 'Mitar', 'sex': 'MALE'})", 
jaroslav@34
   122
        path="/person.json", 
jaroslav@34
   123
        mimeType = "application/javascript",
jaroslav@34
   124
        parameters = { "callme" }
jaroslav@34
   125
    ))
jaroslav@36
   126
    @BrwsrTest public void loadAndParseJSONP() throws InterruptedException, Exception {
jaroslav@34
   127
        
jaroslav@34
   128
        if (js == null) {
jaroslav@34
   129
            orig = scriptElements();
jaroslav@34
   130
            assert orig > 0 : "There should be some scripts on the page";
jaroslav@34
   131
            
jaroslav@115
   132
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@34
   133
            js.applyBindings();
jaroslav@34
   134
jaroslav@34
   135
            js.fetchViaJSONP("person.json");
jaroslav@34
   136
        }
jaroslav@34
   137
    
jaroslav@34
   138
        Person p = js.getFetched();
jaroslav@34
   139
        if (p == null) {
jaroslav@34
   140
            throw new InterruptedException();
jaroslav@34
   141
        }
jaroslav@34
   142
        
jaroslav@34
   143
        assert "Mitar".equals(p.getFirstName()) : "Unexpected: " + p.getFirstName();
jaroslav@34
   144
        assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
jaroslav@34
   145
        
jaroslav@34
   146
        int now = scriptElements();
jaroslav@34
   147
        
jaroslav@34
   148
        assert orig == now : "The set of elements is unchanged. Delta: " + (now - orig);
jaroslav@34
   149
    }
jaroslav@34
   150
    
jaroslav@72
   151
    
jaroslav@72
   152
    
jaroslav@72
   153
    @OnReceive(url="{url}", method = "PUT", data = Person.class)
jaroslav@72
   154
    static void putPerson(JSONik model, String reply) {
jaroslav@72
   155
        model.setFetchedCount(1);
jaroslav@73
   156
        model.setFetchedResponse(reply);
jaroslav@72
   157
    }
jaroslav@72
   158
    @Http(@Http.Resource(
jaroslav@73
   159
        content = "$0\n$1", 
jaroslav@72
   160
        path="/person.json", 
jaroslav@72
   161
        mimeType = "text/plain",
jaroslav@73
   162
        parameters = { "http.method", "http.requestBody" }
jaroslav@72
   163
    ))
jaroslav@73
   164
    @BrwsrTest public void putPeopleUsesRightMethod() throws InterruptedException, Exception {
jaroslav@72
   165
        if (js == null) {
jaroslav@72
   166
            orig = scriptElements();
jaroslav@72
   167
            assert orig > 0 : "There should be some scripts on the page";
jaroslav@72
   168
            
jaroslav@115
   169
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@72
   170
            js.applyBindings();
jaroslav@72
   171
jaroslav@115
   172
            Person p = Models.bind(new Person(), BrwsrCtx.EMPTY);
jaroslav@72
   173
            p.setFirstName("Jarda");
jaroslav@72
   174
            js.putPerson("person.json", p);
jaroslav@72
   175
        }
jaroslav@72
   176
    
jaroslav@72
   177
        int cnt = js.getFetchedCount();
jaroslav@72
   178
        if (cnt == 0) {
jaroslav@72
   179
            throw new InterruptedException();
jaroslav@72
   180
        }
jaroslav@73
   181
        String res = js.getFetchedResponse();
jaroslav@73
   182
        int line = res.indexOf('\n');
jaroslav@73
   183
        String msg;
jaroslav@73
   184
        if (line >= 0) {
jaroslav@75
   185
            msg = res.substring(line + 1);
jaroslav@73
   186
            res = res.substring(0, line);
jaroslav@73
   187
        } else {
jaroslav@73
   188
            msg = res;
jaroslav@73
   189
        }
jaroslav@73
   190
        
jaroslav@73
   191
        assert "PUT".equals(res) : "Server was queried with PUT method: " + js.getFetchedResponse();
jaroslav@73
   192
        
jaroslav@73
   193
        assert msg.contains("Jarda") : "Data transferred to the server: " + msg;
jaroslav@72
   194
    }
jaroslav@72
   195
    
jaroslav@36
   196
    private static int scriptElements() throws Exception {
jaroslav@36
   197
        return ((Number)Utils.executeScript("return window.document.getElementsByTagName('script').length;")).intValue();
jaroslav@36
   198
    }
jaroslav@34
   199
jaroslav@36
   200
    private static Object parseJSON(String s) throws Exception {
jaroslav@36
   201
        return Utils.executeScript("return window.JSON.parse(arguments[0]);", s);
jaroslav@36
   202
    }
jaroslav@34
   203
    
jaroslav@34
   204
    @Http(@Http.Resource(
jaroslav@34
   205
        content = "{'firstName': 'Sitar', 'sex': 'MALE'}", 
jaroslav@34
   206
        path="/person.json", 
jaroslav@34
   207
        mimeType = "application/json"
jaroslav@34
   208
    ))
jaroslav@34
   209
    @BrwsrTest public void loadAndParseJSONSentToArray() throws InterruptedException {
jaroslav@34
   210
        if (js == null) {
jaroslav@115
   211
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@34
   212
            js.applyBindings();
jaroslav@34
   213
jaroslav@34
   214
            js.fetchArray("person.json");
jaroslav@34
   215
        }
jaroslav@34
   216
        
jaroslav@34
   217
        Person p = js.getFetched();
jaroslav@34
   218
        if (p == null) {
jaroslav@34
   219
            throw new InterruptedException();
jaroslav@34
   220
        }
jaroslav@34
   221
        
jaroslav@34
   222
        assert "Sitar".equals(p.getFirstName()) : "Expecting Sitar: " + p.getFirstName();
jaroslav@34
   223
        assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
jaroslav@34
   224
    }
jaroslav@34
   225
    
jaroslav@34
   226
    @Http(@Http.Resource(
jaroslav@34
   227
        content = "[{'firstName': 'Gitar', 'sex': 'FEMALE'}]", 
jaroslav@34
   228
        path="/person.json", 
jaroslav@34
   229
        mimeType = "application/json"
jaroslav@34
   230
    ))
jaroslav@34
   231
    @BrwsrTest public void loadAndParseJSONArraySingle() throws InterruptedException {
jaroslav@34
   232
        if (js == null) {
jaroslav@115
   233
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@34
   234
            js.applyBindings();
jaroslav@34
   235
        
jaroslav@34
   236
            js.fetch("person.json");
jaroslav@34
   237
        }
jaroslav@34
   238
        
jaroslav@34
   239
        Person p = js.getFetched();
jaroslav@34
   240
        if (p == null) {
jaroslav@34
   241
            throw new InterruptedException();
jaroslav@34
   242
        }
jaroslav@34
   243
        
jaroslav@34
   244
        assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
jaroslav@34
   245
        assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
jaroslav@34
   246
    }
jaroslav@34
   247
    
jaroslav@34
   248
    @Http(@Http.Resource(
jaroslav@34
   249
        content = "{'info':[{'firstName': 'Gitar', 'sex': 'FEMALE'}]}", 
jaroslav@34
   250
        path="/people.json", 
jaroslav@34
   251
        mimeType = "application/json"
jaroslav@34
   252
    ))
jaroslav@34
   253
    @BrwsrTest public void loadAndParseArrayInPeople() throws InterruptedException {
jaroslav@34
   254
        if (js == null) {
jaroslav@115
   255
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@34
   256
            js.applyBindings();
jaroslav@34
   257
        
jaroslav@34
   258
            js.fetchPeople("people.json");
jaroslav@34
   259
        }
jaroslav@34
   260
        
jaroslav@34
   261
        if (0 == js.getFetchedCount()) {
jaroslav@34
   262
            throw new InterruptedException();
jaroslav@34
   263
        }
jaroslav@34
   264
jaroslav@34
   265
        assert js.getFetchedCount() == 1 : "One person loaded: " + js.getFetchedCount();
jaroslav@34
   266
        
jaroslav@34
   267
        Person p = js.getFetched();
jaroslav@34
   268
        
jaroslav@34
   269
        assert p != null : "We should get our person back: " + p;
jaroslav@34
   270
        assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
jaroslav@34
   271
        assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
jaroslav@34
   272
    }
jaroslav@34
   273
    
jaroslav@34
   274
    @Http(@Http.Resource(
jaroslav@34
   275
        content = "{'age':[1, 2, 3]}", 
jaroslav@34
   276
        path="/people.json", 
jaroslav@34
   277
        mimeType = "application/json"
jaroslav@34
   278
    ))
jaroslav@34
   279
    @BrwsrTest public void loadAndParseArrayOfIntegers() throws InterruptedException {
jaroslav@34
   280
        if (js == null) {
jaroslav@115
   281
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@34
   282
            js.applyBindings();
jaroslav@34
   283
        
jaroslav@34
   284
            js.fetchPeopleAge("people.json");
jaroslav@34
   285
        }
jaroslav@34
   286
        
jaroslav@34
   287
        if (0 == js.getFetchedCount()) {
jaroslav@34
   288
            throw new InterruptedException();
jaroslav@34
   289
        }
jaroslav@34
   290
jaroslav@34
   291
        assert js.getFetchedCount() == 6 : "1 + 2 + 3 is " + js.getFetchedCount();
jaroslav@34
   292
    }
jaroslav@34
   293
    
jaroslav@34
   294
    @OnReceive(url="/{url}")
jaroslav@34
   295
    static void fetchPeopleSex(People p, JSONik model) {
jaroslav@34
   296
        model.setFetchedCount(1);
jaroslav@34
   297
        model.getFetchedSex().addAll(p.getSex());
jaroslav@34
   298
    }
jaroslav@34
   299
    
jaroslav@34
   300
    
jaroslav@34
   301
    @Http(@Http.Resource(
jaroslav@34
   302
        content = "{'sex':['FEMALE', 'MALE', 'MALE']}", 
jaroslav@34
   303
        path="/people.json", 
jaroslav@34
   304
        mimeType = "application/json"
jaroslav@34
   305
    ))
jaroslav@34
   306
    @BrwsrTest public void loadAndParseArrayOfEnums() throws InterruptedException {
jaroslav@34
   307
        if (js == null) {
jaroslav@115
   308
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@34
   309
            js.applyBindings();
jaroslav@34
   310
        
jaroslav@34
   311
            js.fetchPeopleSex("people.json");
jaroslav@34
   312
        }
jaroslav@34
   313
        
jaroslav@34
   314
        if (0 == js.getFetchedCount()) {
jaroslav@34
   315
            throw new InterruptedException();
jaroslav@34
   316
        }
jaroslav@34
   317
jaroslav@34
   318
        assert js.getFetchedCount() == 1 : "Loaded";
jaroslav@34
   319
        
jaroslav@34
   320
        assert js.getFetchedSex().size() == 3 : "Three values " + js.getFetchedSex();
jaroslav@34
   321
        assert js.getFetchedSex().get(0) == Sex.FEMALE : "Female first " + js.getFetchedSex();
jaroslav@34
   322
        assert js.getFetchedSex().get(1) == Sex.MALE : "male 2nd " + js.getFetchedSex();
jaroslav@34
   323
        assert js.getFetchedSex().get(2) == Sex.MALE : "male 3rd " + js.getFetchedSex();
jaroslav@34
   324
    }
jaroslav@34
   325
    
jaroslav@34
   326
    @Http(@Http.Resource(
jaroslav@34
   327
        content = "[{'firstName': 'Gitar', 'sex': 'FEMALE'},"
jaroslav@34
   328
        + "{'firstName': 'Peter', 'sex': 'MALE'}"
jaroslav@34
   329
        + "]", 
jaroslav@34
   330
        path="/person.json", 
jaroslav@34
   331
        mimeType = "application/json"
jaroslav@34
   332
    ))
jaroslav@34
   333
    @BrwsrTest public void loadAndParseJSONArray() throws InterruptedException {
jaroslav@34
   334
        if (js == null) {
jaroslav@115
   335
            js = Models.bind(new JSONik(), Utils.newContext());
jaroslav@34
   336
            js.applyBindings();
jaroslav@34
   337
            js.fetchArray("person.json");
jaroslav@34
   338
        }
jaroslav@34
   339
        
jaroslav@34
   340
        
jaroslav@34
   341
        Person p = js.getFetched();
jaroslav@34
   342
        if (p == null) {
jaroslav@34
   343
            throw new InterruptedException();
jaroslav@34
   344
        }
jaroslav@34
   345
        
jaroslav@34
   346
        assert js.getFetchedCount() == 2 : "We got two values: " + js.getFetchedCount();
jaroslav@34
   347
        assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
jaroslav@34
   348
        assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
jaroslav@34
   349
    }
jaroslav@77
   350
    
jaroslav@77
   351
    @Model(className = "NameAndValue", properties = {
jaroslav@77
   352
        @Property(name = "name", type = String.class),
jaroslav@77
   353
        @Property(name = "value", type = long.class),
jaroslav@77
   354
        @Property(name = "small", type = byte.class)
jaroslav@77
   355
    })
jaroslav@77
   356
    static class NandV {
jaroslav@77
   357
    }
jaroslav@77
   358
    
jaroslav@77
   359
    @BrwsrTest public void parseNullNumber() throws Exception {
jaroslav@77
   360
        String txt = "{ \"name\":\"M\" }";
jaroslav@77
   361
        ByteArrayInputStream is = new ByteArrayInputStream(txt.getBytes("UTF-8"));
jaroslav@77
   362
        NameAndValue v = Models.parse(Utils.newContext(), NameAndValue.class, is);
jaroslav@77
   363
        assert "M".equals(v.getName()) : "Name is 'M': " + v.getName();
jaroslav@77
   364
        assert 0 == v.getValue() : "Value is empty: " + v.getValue();
jaroslav@77
   365
        assert 0 == v.getSmall() : "Small value is empty: " + v.getSmall();
jaroslav@77
   366
    }
jaroslav@77
   367
    
jaroslav@34
   368
    static Object[] create() {
jaroslav@34
   369
        return VMTest.create(JSONTest.class);
jaroslav@34
   370
    }
jaroslav@34
   371
    
jaroslav@34
   372
}