During the API review process (bug 246133) the reviewers decided that in order to include html4j to NetBeans Platform, we need to stop using org.apidesign namespace and switch to NetBeans one. Repackaging all SPI packages into org.netbeans.html.smthng.spi.
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
6 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 * Other names may be trademarks of their respective owners.
9 * The contents of this file are subject to the terms of either the GNU
10 * General Public License Version 2 only ("GPL") or the Common
11 * Development and Distribution License("CDDL") (collectively, the
12 * "License"). You may not use this file except in compliance with the
13 * License. You can obtain a copy of the License at
14 * http://www.netbeans.org/cddl-gplv2.html
15 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 * specific language governing permissions and limitations under the
17 * License. When distributing the software, include this License Header
18 * Notice in each file and include the License file at
19 * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 * particular file as subject to the "Classpath" exception as provided
21 * by Oracle in the GPL Version 2 section of the License file that
22 * accompanied this code. If applicable, add the following below the
23 * License Header, with the fields enclosed by brackets [] replaced by
24 * your own identifying information:
25 * "Portions Copyrighted [year] [name of copyright owner]"
29 * The Original Software is NetBeans. The Initial Developer of the Original
30 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
32 * If you wish your version of this file to be governed by only the CDDL
33 * or only the GPL Version 2, indicate your decision by adding
34 * "[Contributor] elects to include this software in this distribution
35 * under the [CDDL or GPL Version 2] license." If you do not indicate a
36 * single choice of license, a recipient has the option to distribute
37 * your version of this file under either the CDDL, the GPL Version 2 or
38 * to extend the choice of license to its licensees as provided above.
39 * However, if you add GPL Version 2 code and therefore, elected the GPL
40 * Version 2 license, then the option applies only if the new code is
41 * made subject to such option by the copyright holder.
43 package net.java.html.json.tests;
45 import java.io.ByteArrayInputStream;
46 import java.io.ByteArrayOutputStream;
47 import java.io.PrintStream;
48 import net.java.html.BrwsrCtx;
49 import net.java.html.json.Model;
50 import net.java.html.json.ModelOperation;
51 import net.java.html.json.Models;
52 import net.java.html.json.OnReceive;
53 import net.java.html.json.Property;
54 import org.netbeans.html.json.tck.KOTest;
56 /** Need to verify that models produce reasonable JSON objects.
58 * @author Jaroslav Tulach
60 @Model(className = "JSONik", properties = {
61 @Property(name = "fetched", type = Person.class),
62 @Property(name = "fetchedCount", type = int.class),
63 @Property(name = "fetchedResponse", type = String.class),
64 @Property(name = "fetchedSex", type = Sex.class, array = true)
66 public final class JSONTest {
71 @ModelOperation static void assignFetched(JSONik m, Person p) {
76 @KOTest public void toJSONInABrowser() throws Throwable {
77 Person p = Models.bind(new Person(), newContext());
79 p.setFirstName("Jarda");
80 p.setLastName("Tulach");
84 json = parseJSON(p.toString());
85 } catch (Throwable ex) {
86 throw new IllegalStateException("Can't parse " + p).initCause(ex);
89 Person p2 = Models.fromRaw(newContext(), Person.class, json);
91 assert p2.getFirstName().equals(p.getFirstName()) :
92 "Should be the same: " + p.getFirstName() + " != " + p2.getFirstName();
95 @KOTest public void toJSONWithEscapeCharactersInABrowser() throws Throwable {
96 Person p = Models.bind(new Person(), newContext());
98 p.setFirstName("/*\n * Copyright (c) 2013");
101 final String txt = p.toString();
104 json = parseJSON(txt);
105 } catch (Throwable ex) {
106 throw new IllegalStateException("Can't parse " + txt).initCause(ex);
109 Person p2 = Models.fromRaw(newContext(), Person.class, json);
111 assert p2.getFirstName().equals(p.getFirstName()) :
112 "Should be the same: " + p.getFirstName() + " != " + p2.getFirstName();
115 @KOTest public void toJSONWithDoubleSlashInABrowser() throws Throwable {
116 Person p = Models.bind(new Person(), newContext());
118 p.setFirstName("/*\\n * Copyright (c) 2013");
121 final String txt = p.toString();
124 json = parseJSON(txt);
125 } catch (Throwable ex) {
126 throw new IllegalStateException("Can't parse " + txt).initCause(ex);
129 Person p2 = Models.fromRaw(newContext(), Person.class, json);
131 assert p2.getFirstName().equals(p.getFirstName()) :
132 "Should be the same: " + p.getFirstName() + " != " + p2.getFirstName();
135 @KOTest public void toJSONWithApostrophInABrowser() throws Throwable {
136 Person p = Models.bind(new Person(), newContext());
138 p.setFirstName("Jimmy 'Jim' Rambo");
141 final String txt = p.toString();
144 json = parseJSON(txt);
145 } catch (Throwable ex) {
146 throw new IllegalStateException("Can't parse " + txt).initCause(ex);
149 Person p2 = Models.fromRaw(newContext(), Person.class, json);
151 assert p2.getFirstName().equals(p.getFirstName()) :
152 "Should be the same: " + p.getFirstName() + " != " + p2.getFirstName();
155 private static BrwsrCtx onCallback;
157 @OnReceive(url="{url}")
158 static void fetch(JSONik model, Person p) {
160 onCallback = BrwsrCtx.findDefault(model.getClass());
163 @OnReceive(url="{url}", onError = "setMessage")
164 static void fetchArray(JSONik model, Person[] p) {
165 model.setFetchedCount(p.length);
166 model.setFetched(p[0]);
167 onCallback = BrwsrCtx.findDefault(model.getClass());
170 static void setMessage(JSONik m, Exception t) {
172 m.setFetchedResponse("Exception");
175 @OnReceive(url="{url}")
176 static void fetchPeople(JSONik model, People p) {
177 final int size = p.getInfo().size();
179 model.setFetched(p.getInfo().get(0));
181 model.setFetchedCount(size);
184 @OnReceive(url="{url}")
185 static void fetchPeopleAge(JSONik model, People p) {
187 for (int a : p.getAge()) {
190 model.setFetchedCount(sum);
193 @KOTest public void loadAndParseJSON() throws InterruptedException {
195 url = Utils.prepareURL(
196 JSONTest.class, "{'firstName': 'Sitar', 'sex': 'MALE'}",
199 js = Models.bind(new JSONik(), ctx = newContext());
206 Person p = js.getFetched();
208 throw new InterruptedException();
211 assert "Sitar".equals(p.getFirstName()) : "Expecting Sitar: " + p.getFirstName();
212 assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
214 assert ctx == onCallback;
217 @OnReceive(url="{url}?callme={me}", jsonp = "me")
218 static void fetchViaJSONP(JSONik model, Person p) {
222 @KOTest public void loadAndParseJSONP() throws InterruptedException, Exception {
224 url = Utils.prepareURL(
225 JSONTest.class, "$0({'firstName': 'Mitar', 'sex': 'MALE'})",
226 "application/javascript",
229 orig = scriptElements();
230 assert orig > 0 : "There should be some scripts on the page";
232 js = Models.bind(new JSONik(), newContext());
236 js.fetchViaJSONP(url);
239 Person p = js.getFetched();
241 throw new InterruptedException();
244 assert "Mitar".equals(p.getFirstName()) : "Unexpected: " + p.getFirstName();
245 assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
247 int now = scriptElements();
249 assert orig == now : "The set of elements is unchanged. Delta: " + (now - orig);
254 @OnReceive(url="{url}", method = "PUT", data = Person.class)
255 static void putPerson(JSONik model, String reply) {
256 model.setFetchedCount(1);
257 model.setFetchedResponse(reply);
260 @KOTest public void putPeopleUsesRightMethod() throws InterruptedException, Exception {
262 url = Utils.prepareURL(
263 JSONTest.class, "$0\n$1",
265 "http.method", "http.requestBody"
267 orig = scriptElements();
268 assert orig > 0 : "There should be some scripts on the page";
270 js = Models.bind(new JSONik(), newContext());
273 Person p = Models.bind(new Person(), BrwsrCtx.EMPTY);
274 p.setFirstName("Jarda");
275 js.putPerson(url, p);
278 int cnt = js.getFetchedCount();
280 throw new InterruptedException();
282 String res = js.getFetchedResponse();
283 int line = res.indexOf('\n');
286 msg = res.substring(line + 1);
287 res = res.substring(0, line);
292 assert "PUT".equals(res) : "Server was queried with PUT method: " + js.getFetchedResponse();
294 assert msg.contains("Jarda") : "Data transferred to the server: " + msg;
297 private static int scriptElements() throws Exception {
298 return ((Number)Utils.executeScript(
300 "return window.document.getElementsByTagName('script').length;")).intValue();
303 private static Object parseJSON(String s) throws Exception {
304 return Utils.executeScript(
306 "return window.JSON.parse(arguments[0]);", s);
309 @KOTest public void loadAndParseJSONSentToArray() throws InterruptedException {
311 url = Utils.prepareURL(
312 JSONTest.class, "{'firstName': 'Sitar', 'sex': 'MALE'}",
316 js = Models.bind(new JSONik(), newContext());
323 Person p = js.getFetched();
325 throw new InterruptedException();
328 assert "Sitar".equals(p.getFirstName()) : "Expecting Sitar: " + p.getFirstName();
329 assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex();
332 @KOTest public void loadAndParseJSONArraySingle() throws InterruptedException {
334 url = Utils.prepareURL(
335 JSONTest.class, "[{'firstName': 'Gitar', 'sex': 'FEMALE'}]",
338 js = Models.bind(new JSONik(), newContext());
345 Person p = js.getFetched();
347 throw new InterruptedException();
350 assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
351 assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
354 @KOTest public void loadAndParseArrayInPeople() throws InterruptedException {
356 url = Utils.prepareURL(
357 JSONTest.class, "{'info':[{'firstName': 'Gitar', 'sex': 'FEMALE'}]}",
360 js = Models.bind(new JSONik(), newContext());
366 if (0 == js.getFetchedCount()) {
367 throw new InterruptedException();
370 assert js.getFetchedCount() == 1 : "One person loaded: " + js.getFetchedCount();
372 Person p = js.getFetched();
374 assert p != null : "We should get our person back: " + p;
375 assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
376 assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
379 @KOTest public void loadAndParseArrayOfIntegers() throws InterruptedException {
381 url = Utils.prepareURL(
382 JSONTest.class, "{'age':[1, 2, 3]}",
385 js = Models.bind(new JSONik(), newContext());
388 js.fetchPeopleAge(url);
391 if (0 == js.getFetchedCount()) {
392 throw new InterruptedException();
395 assert js.getFetchedCount() == 6 : "1 + 2 + 3 is " + js.getFetchedCount();
398 @OnReceive(url="{url}")
399 static void fetchPeopleSex(JSONik model, People p) {
400 model.setFetchedCount(1);
401 model.getFetchedSex().addAll(p.getSex());
404 @KOTest public void loadAndParseArrayOfEnums() throws InterruptedException {
406 url = Utils.prepareURL(
407 JSONTest.class, "{'sex':['FEMALE', 'MALE', 'MALE']}",
410 js = Models.bind(new JSONik(), newContext());
413 js.fetchPeopleSex(url);
416 if (0 == js.getFetchedCount()) {
417 throw new InterruptedException();
420 assert js.getFetchedCount() == 1 : "Loaded";
422 assert js.getFetchedSex().size() == 3 : "Three values " + js.getFetchedSex();
423 assert js.getFetchedSex().get(0) == Sex.FEMALE : "Female first " + js.getFetchedSex();
424 assert js.getFetchedSex().get(1) == Sex.MALE : "male 2nd " + js.getFetchedSex();
425 assert js.getFetchedSex().get(2) == Sex.MALE : "male 3rd " + js.getFetchedSex();
428 @KOTest public void loadAndParseJSONArray() throws InterruptedException {
430 url = Utils.prepareURL(
431 JSONTest.class, "[{'firstName': 'Gitar', 'sex': 'FEMALE'},"
432 + "{'firstName': 'Peter', 'sex': 'MALE'}"
436 js = Models.bind(new JSONik(), newContext());
444 Person p = js.getFetched();
446 throw new InterruptedException();
449 assert js.getFetchedCount() == 2 : "We got two values: " + js.getFetchedCount();
450 assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName();
451 assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex();
454 @KOTest public void loadError() throws InterruptedException {
456 js = Models.bind(new JSONik(), newContext());
460 js.fetchArray("http://127.0.0.1:54253/does/not/exist.txt");
464 if (js.getFetchedResponse() == null) {
465 throw new InterruptedException();
468 assert "Exception".equals(js.getFetchedResponse()) : js.getFetchedResponse();
471 @Model(className = "NameAndValue", properties = {
472 @Property(name = "name", type = String.class),
473 @Property(name = "value", type = long.class),
474 @Property(name = "small", type = byte.class)
479 @KOTest public void parseNullNumber() throws Exception {
480 String txt = "{ \"name\":\"M\" }";
481 ByteArrayInputStream is = new ByteArrayInputStream(txt.getBytes("UTF-8"));
482 NameAndValue v = Models.parse(newContext(), NameAndValue.class, is);
483 assert "M".equals(v.getName()) : "Name is 'M': " + v.getName();
484 assert 0 == v.getValue() : "Value is empty: " + v.getValue();
485 assert 0 == v.getSmall() : "Small value is empty: " + v.getSmall();
488 @KOTest public void deserializeWrongEnum() throws Exception {
489 PrintStream prev = null;
490 ByteArrayOutputStream err = new ByteArrayOutputStream();
493 System.setErr(new PrintStream(err));
494 } catch (SecurityException e) {
497 } catch (LinkageError e) {
502 String str = "{ \"sex\" : \"unknown\" }";
503 ByteArrayInputStream is = new ByteArrayInputStream(str.getBytes("UTF-8"));
504 Person p = Models.parse(newContext(), Person.class, is);
505 assert p.getSex() == null : "Wrong sex means null, but was: " + p.getSex();
508 assert err.toString().contains("unknown") && err.toString().contains("Sex"): "Expecting error: " + err.toString();
513 } catch (LinkageError e) {
520 private static BrwsrCtx newContext() {
521 return Utils.newContext(JSONTest.class);