javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/JSONTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 14 Dec 2014 16:29:46 +0100
changeset 1750 0b4afadbd494
parent 1412 a51c0d80ee24
permissions -rw-r--r--
Internet Explorer somehow caches values of person.json and people.json from previous runs. Let's use unique names to prevent that.
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 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.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.bck2brwsr.htmlpage;
    19 
    20 import java.util.Iterator;
    21 import org.apidesign.bck2brwsr.core.JavaScriptBody;
    22 import org.apidesign.bck2brwsr.htmlpage.api.OnReceive;
    23 import org.apidesign.bck2brwsr.htmlpage.api.Page;
    24 import org.apidesign.bck2brwsr.htmlpage.api.Property;
    25 import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
    26 import org.apidesign.bck2brwsr.vmtest.Http;
    27 import org.apidesign.bck2brwsr.vmtest.VMTest;
    28 import org.json.JSONException;
    29 import org.json.JSONObject;
    30 import org.json.JSONTokener;
    31 import org.testng.annotations.Test;
    32 import static org.testng.Assert.*;
    33 import org.testng.annotations.Factory;
    34 
    35 /** Need to verify that models produce reasonable JSON objects.
    36  *
    37  * @author Jaroslav Tulach <jtulach@netbeans.org>
    38  */
    39 @Page(xhtml = "Empty.html", className = "JSONik", properties = {
    40     @Property(name = "fetched", type = PersonImpl.class),
    41     @Property(name = "fetchedCount", type = int.class),
    42     @Property(name = "fetchedSex", type = Sex.class, array = true)
    43 })
    44 public class JSONTest {
    45     private JSONik js;
    46     private Integer orig;
    47     
    48     @Test public void personToString() throws JSONException {
    49         Person p = new Person();
    50         p.setSex(Sex.MALE);
    51         p.setFirstName("Jarda");
    52         p.setLastName("Tulach");
    53         
    54         JSONTokener t = new JSONTokener(p.toString());
    55         JSONObject o;
    56         try {
    57             o = new JSONObject(t);
    58         } catch (JSONException ex) {
    59             throw new AssertionError("Can't parse " + p.toString(), ex);
    60         }
    61         
    62         Iterator it = o.sortedKeys();
    63         assertEquals(it.next(), "firstName");
    64         assertEquals(it.next(), "lastName");
    65         assertEquals(it.next(), "sex");
    66         
    67         assertEquals(o.getString("firstName"), "Jarda");
    68         assertEquals(o.getString("lastName"), "Tulach");
    69         assertEquals(o.getString("sex"), "MALE");
    70     }
    71     
    72     @BrwsrTest public void toJSONInABrowser() throws Throwable {
    73         Person p = new Person();
    74         p.setSex(Sex.MALE);
    75         p.setFirstName("Jarda");
    76         p.setLastName("Tulach");
    77 
    78         Object json;
    79         try {
    80             json = parseJSON(p.toString());
    81         } catch (Throwable ex) {
    82             throw new IllegalStateException("Can't parse " + p).initCause(ex);
    83         }
    84         
    85         Person p2 = new Person(json);
    86         
    87         assert p2.getFirstName().equals(p.getFirstName()) : 
    88             "Should be the same: " + p.getFirstName() + " != " + p2.getFirstName();
    89     }
    90     
    91     @Test public void personWithWildCharactersAndNulls() throws JSONException {
    92         Person p = new Person();
    93         p.setFirstName("'\"\n");
    94         p.setLastName("\t\r\u0002");
    95         
    96         JSONTokener t = new JSONTokener(p.toString());
    97         JSONObject o;
    98         try {
    99             o = new JSONObject(t);
   100         } catch (JSONException ex) {
   101             throw new AssertionError("Can't parse " + p.toString(), ex);
   102         }
   103         
   104         Iterator it = o.sortedKeys();
   105         assertEquals(it.next(), "firstName");
   106         assertEquals(it.next(), "lastName");
   107         assertEquals(it.next(), "sex");
   108         
   109         assertEquals(o.getString("firstName"), p.getFirstName());
   110         assertEquals(o.getString("lastName"), p.getLastName());
   111         assertEquals(o.get("sex"), JSONObject.NULL);
   112     }
   113     
   114     @Test public void personsInArray() throws JSONException {
   115         Person p1 = new Person();
   116         p1.setFirstName("One");
   117 
   118         Person p2 = new Person();
   119         p2.setFirstName("Two");
   120         
   121         People arr = new People();
   122         arr.getInfo().add(p1);
   123         arr.getInfo().add(p2);
   124         arr.getNicknames().add("Prvn\u00ed k\u016f\u0148");
   125         final String n2 = "Druh\u00fd hlem\u00fd\u017e\u010f, star\u0161\u00ed";
   126         arr.getNicknames().add(n2);
   127         arr.getAge().add(33);
   128         arr.getAge().add(73);
   129         
   130         
   131         final String json = arr.toString();
   132         
   133         JSONTokener t = new JSONTokener(json);
   134         JSONObject o;
   135         try {
   136             o = new JSONObject(t);
   137         } catch (JSONException ex) {
   138             throw new AssertionError("Can't parse " + json, ex);
   139         }
   140 
   141         assertEquals(o.getJSONArray("info").getJSONObject(0).getString("firstName"), "One");
   142         assertEquals(o.getJSONArray("nicknames").getString(1), n2);
   143         assertEquals(o.getJSONArray("age").getInt(1), 73);
   144     }
   145     
   146     
   147     @OnReceive(url="/{url}")
   148     static void fetch(Person p, JSONik model) {
   149         model.setFetched(p);
   150     }
   151 
   152     @OnReceive(url="/{url}")
   153     static void fetchArray(Person[] p, JSONik model) {
   154         model.setFetchedCount(p.length);
   155         model.setFetched(p[0]);
   156     }
   157     
   158     @OnReceive(url="/{url}")
   159     static void fetchPeople(People p, JSONik model) {
   160         model.setFetchedCount(p.getInfo().size());
   161         model.setFetched(p.getInfo().get(0));
   162     }
   163 
   164     @OnReceive(url="/{url}")
   165     static void fetchPeopleAge(People p, JSONik model) {
   166         int sum = 0;
   167         for (int a : p.getAge()) {
   168             sum += a;
   169         }
   170         model.setFetchedCount(sum);
   171     }
   172     
   173     @Http(@Http.Resource(
   174         content = "{'firstName': 'Sitar', 'sex': 'MALE'}", 
   175         path="/person33.json", 
   176         mimeType = "application/json"
   177     ))
   178     @BrwsrTest public void loadAndParseJSON() throws InterruptedException {
   179         try { throw new Exception(); } catch (Exception ex) {
   180         }
   181         if (js == null) {
   182             js = new JSONik();
   183             js.applyBindings();
   184 
   185             js.fetch("person33.json");
   186         }
   187     
   188         Person p = js.getFetched();
   189         if (p == null) {
   190             throw new InterruptedException();
   191         }
   192         
   193         assert "Sitar".equals(p.getFirstName()) : "Expecting Sitar: " + p.getFirstName();
   194         assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
   195     }
   196     
   197     @OnReceive(url="/{url}?callme={me}", jsonp = "me")
   198     static void fetchViaJSONP(Person p, JSONik model) {
   199         model.setFetched(p);
   200     }
   201     
   202     @Http(@Http.Resource(
   203         content = "$0({'firstName': 'Mitar', 'sex': 'MALE'})", 
   204         path="/person22.json", 
   205         mimeType = "application/javascript",
   206         parameters = { "callme" }
   207     ))
   208     @BrwsrTest public void loadAndParseJSONP() throws InterruptedException {
   209         
   210         if (js == null) {
   211             orig = scriptElements();
   212             assert orig > 0 : "There should be some scripts on the page";
   213             
   214             js = new JSONik();
   215             js.applyBindings();
   216 
   217             js.fetchViaJSONP("person22.json");
   218         }
   219     
   220         Person p = js.getFetched();
   221         if (p == null) {
   222             throw new InterruptedException();
   223         }
   224         
   225         assert "Mitar".equals(p.getFirstName()) : "Unexpected: " + p.getFirstName();
   226         assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
   227         
   228         int now = scriptElements();
   229         
   230         assert orig == now : "The set of elements is unchanged. Delta: " + (now - orig);
   231     }
   232     
   233     @JavaScriptBody(args = {  }, body = "return window.document.getElementsByTagName('script').length;")
   234     private static native int scriptElements();
   235 
   236     @JavaScriptBody(args = { "s" }, body = "return window.JSON.parse(s);")
   237     private static native Object parseJSON(String s);
   238     
   239     @Http(@Http.Resource(
   240         content = "{'firstName': 'Sitar', 'sex': 'MALE'}", 
   241         path="/person15.json", 
   242         mimeType = "application/json"
   243     ))
   244     @BrwsrTest public void loadAndParseJSONSentToArray() throws InterruptedException {
   245         if (js == null) {
   246             js = new JSONik();
   247             js.applyBindings();
   248 
   249             js.fetchArray("person15.json");
   250         }
   251         
   252         Person p = js.getFetched();
   253         if (p == null) {
   254             throw new InterruptedException();
   255         }
   256         
   257         assert p != null : "We should get our person back: " + p;
   258         assert "Sitar".equals(p.getFirstName()) : "Expecting Sitar: " + p.getFirstName();
   259         assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
   260     }
   261     
   262     @Http(@Http.Resource(
   263         content = "[{'firstName': 'Gitar', 'sex': 'FEMALE'}]", 
   264         path="/person5.json", 
   265         mimeType = "application/json"
   266     ))
   267     @BrwsrTest public void loadAndParseJSONArraySingle() throws InterruptedException {
   268         if (js == null) {
   269             js = new JSONik();
   270             js.applyBindings();
   271         
   272             js.fetch("person5.json");
   273         }
   274         
   275         Person p = js.getFetched();
   276         if (p == null) {
   277             throw new InterruptedException();
   278         }
   279         
   280         assert p != null : "We should get our person back: " + p;
   281         assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
   282         assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
   283     }
   284     
   285 //    @Http(@Http.Resource(
   286 //        content = "{'info':[{'firstName': 'Gitar', 'sex': 'FEMALE'}]}", 
   287 //        path="/people.json", 
   288 //        mimeType = "application/json"
   289 //    ))
   290 //    @BrwsrTest public void loadAndParseArrayInPeople() throws InterruptedException {
   291 //        if (js == null) {
   292 //            js = new JSONik();
   293 //            js.applyBindings();
   294 //        
   295 //            js.fetchPeople("people.json");
   296 //        }
   297 //        
   298 //        if (0 == js.getFetchedCount()) {
   299 //            throw new InterruptedException();
   300 //        }
   301 //
   302 //        assert js.getFetchedCount() == 1 : "One person loaded: " + js.getFetchedCount();
   303 //        
   304 //        Person p = js.getFetched();
   305 //        
   306 //        assert p != null : "We should get our person back: " + p;
   307 //        assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
   308 //        assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
   309 //    }
   310     
   311     @Http(@Http.Resource(
   312         content = "{'age':[1, 2, 3]}", 
   313         path="/people8.json", 
   314         mimeType = "application/json"
   315     ))
   316     @BrwsrTest public void loadAndParseArrayOfIntegers() throws InterruptedException {
   317         if (js == null) {
   318             js = new JSONik();
   319             js.applyBindings();
   320         
   321             js.fetchPeopleAge("people8.json");
   322         }
   323         
   324         if (0 == js.getFetchedCount()) {
   325             throw new InterruptedException();
   326         }
   327 
   328         assert js.getFetchedCount() == 6 : "1 + 2 + 3 is " + js.getFetchedCount();
   329     }
   330     
   331     @OnReceive(url="/{url}")
   332     static void fetchPeopleSex(People p, JSONik model) {
   333         model.setFetchedCount(1);
   334         model.getFetchedSex().addAll(p.getSex());
   335     }
   336     
   337     
   338     @Http(@Http.Resource(
   339         content = "{'sex':['FEMALE', 'MALE', 'MALE']}", 
   340         path="/people11.json", 
   341         mimeType = "application/json"
   342     ))
   343     @BrwsrTest public void loadAndParseArrayOfEnums() throws InterruptedException {
   344         if (js == null) {
   345             js = new JSONik();
   346             js.applyBindings();
   347         
   348             js.fetchPeopleSex("people11.json");
   349         }
   350         
   351         if (0 == js.getFetchedCount()) {
   352             throw new InterruptedException();
   353         }
   354 
   355         assert js.getFetchedCount() == 1 : "Loaded";
   356         
   357         assert js.getFetchedSex().size() == 3 : "Three values " + js.getFetchedSex();
   358         assert js.getFetchedSex().get(0) == Sex.FEMALE : "Female first " + js.getFetchedSex();
   359         assert js.getFetchedSex().get(1) == Sex.MALE : "male 2nd " + js.getFetchedSex();
   360         assert js.getFetchedSex().get(2) == Sex.MALE : "male 3rd " + js.getFetchedSex();
   361     }
   362     
   363     @Http(@Http.Resource(
   364         content = "[{'firstName': 'Gitar', 'sex': 'FEMALE'},"
   365         + "{'firstName': 'Peter', 'sex': 'MALE'}"
   366         + "]", 
   367         path="/person13.json", 
   368         mimeType = "application/json"
   369     ))
   370     @BrwsrTest public void loadAndParseJSONArray() throws InterruptedException {
   371         if (js == null) {
   372             js = new JSONik();
   373             js.applyBindings();
   374             js.fetchArray("person13.json");
   375         }
   376         
   377         
   378         Person p = js.getFetched();
   379         if (p == null) {
   380             throw new InterruptedException();
   381         }
   382         
   383         assert js.getFetchedCount() == 2 : "We got two values: " + js.getFetchedCount();
   384         assert p != null : "We should get our person back: " + p;
   385         assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
   386         assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
   387     }
   388 
   389     @Factory public static Object[] create() {
   390         return VMTest.create(JSONTest.class);
   391     }
   392     
   393 }