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