1.1 --- a/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java Fri Jul 12 12:21:53 2013 +0200
1.2 +++ b/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java Fri Jul 12 14:25:50 2013 +0200
1.3 @@ -38,10 +38,59 @@
1.4 @Property(name="results", type=String.class, array = true),
1.5 @Property(name="callbackCount", type=int.class),
1.6 @Property(name="people", type=PersonImpl.class, array = true),
1.7 - @Property(name="enabled", type=boolean.class)
1.8 + @Property(name="enabled", type=boolean.class),
1.9 + @Property(name="latitude", type=double.class)
1.10 })
1.11 public final class KnockoutTest {
1.12
1.13 + @KOTest public void modifyValueAssertChangeInModelOnDouble() throws Throwable {
1.14 + Object exp = Utils.exposeHTML(KnockoutTest.class,
1.15 + "Latitude: <input id='input' data-bind=\"value: latitude\"></input>\n"
1.16 + );
1.17 + try {
1.18 +
1.19 + KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
1.20 + m.setLatitude(50.5);
1.21 + m.applyBindings();
1.22 +
1.23 + String v = getSetInput(null);
1.24 + assert "50.5".equals(v) : "Value is really 50.5: " + v;
1.25 +
1.26 + getSetInput("49.5");
1.27 + triggerEvent("input", "change");
1.28 +
1.29 + assert 49.5 == m.getLatitude() : "Double property updated: " + m.getLatitude();
1.30 + } catch (Throwable t) {
1.31 + throw t;
1.32 + } finally {
1.33 + Utils.exposeHTML(KnockoutTest.class, "");
1.34 + }
1.35 + }
1.36 +
1.37 + @KOTest public void modifyValueAssertChangeInModelOnBoolean() throws Throwable {
1.38 + Object exp = Utils.exposeHTML(KnockoutTest.class,
1.39 + "Latitude: <input id='input' data-bind=\"value: enabled\"></input>\n"
1.40 + );
1.41 + try {
1.42 +
1.43 + KnockoutModel m = Models.bind(new KnockoutModel(), newContext());
1.44 + m.setEnabled(true);
1.45 + m.applyBindings();
1.46 +
1.47 + String v = getSetInput(null);
1.48 + assert "true".equals(v) : "Value is really true: " + v;
1.49 +
1.50 + getSetInput("false");
1.51 + triggerEvent("input", "change");
1.52 +
1.53 + assert false == m.isEnabled(): "Boolean property updated: " + m.isEnabled();
1.54 + } catch (Throwable t) {
1.55 + throw t;
1.56 + } finally {
1.57 + Utils.exposeHTML(KnockoutTest.class, "");
1.58 + }
1.59 + }
1.60 +
1.61 @KOTest public void modifyValueAssertChangeInModel() throws Exception {
1.62 Object exp = Utils.exposeHTML(KnockoutTest.class,
1.63 "<h1 data-bind=\"text: helloMessage\">Loading Bck2Brwsr's Hello World...</h1>\n" +
2.1 --- a/json/src/main/java/org/apidesign/html/json/impl/JSON.java Fri Jul 12 12:21:53 2013 +0200
2.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/JSON.java Fri Jul 12 14:25:50 2013 +0200
2.3 @@ -20,7 +20,6 @@
2.4 */
2.5 package org.apidesign.html.json.impl;
2.6
2.7 -import org.apidesign.html.context.impl.CtxAccssr;
2.8 import java.io.IOException;
2.9 import java.io.InputStream;
2.10 import java.util.HashMap;
2.11 @@ -101,6 +100,41 @@
2.12 return aClass.cast(o);
2.13 }
2.14
2.15 + public static <T> T extractValue(Class<T> type, Object val) {
2.16 + if (Number.class.isAssignableFrom(type)) {
2.17 + val = numberValue(val);
2.18 + }
2.19 + if (Boolean.class == type) {
2.20 + val = boolValue(val);
2.21 + }
2.22 + return type.cast(val);
2.23 + }
2.24 +
2.25 + public static String stringValue(Object val) {
2.26 + return (String)val;
2.27 + }
2.28 +
2.29 + public static Number numberValue(Object val) {
2.30 + if (val instanceof String) {
2.31 + try {
2.32 + return Double.valueOf((String)val);
2.33 + } catch (NumberFormatException ex) {
2.34 + return Double.NaN;
2.35 + }
2.36 + }
2.37 + return (Number)val;
2.38 + }
2.39 +
2.40 + public static Character charValue(Object val) {
2.41 + return (Character)val;
2.42 + }
2.43 +
2.44 + public static Boolean boolValue(Object val) {
2.45 + if (val instanceof String) {
2.46 + return Boolean.parseBoolean((String)val);
2.47 + }
2.48 + return Boolean.TRUE.equals(val);
2.49 + }
2.50
2.51 public static void loadJSON(
2.52 BrwsrCtx c, Runnable whenDone, Object[] result,
3.1 --- a/json/src/main/java/org/apidesign/html/json/impl/ModelProcessor.java Fri Jul 12 12:21:53 2013 +0200
3.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/ModelProcessor.java Fri Jul 12 14:25:50 2013 +0200
3.3 @@ -227,7 +227,7 @@
3.4 }
3.5 }
3.6 if (set != null) {
3.7 - w.append(" case " + (i / 5) + ": data." + strip(set) + "((" + tn + ")value); return;\n");
3.8 + w.append(" case " + (i / 5) + ": data." + strip(set) + "(org.apidesign.html.json.impl.JSON.extractValue(" + tn + ".class, value)); return;\n");
3.9 }
3.10 }
3.11 w.append(" }\n");
3.12 @@ -296,10 +296,10 @@
3.13 } else if (isEnum[0]) {
3.14 w.append(" this.prop_").append(pn);
3.15 w.append(".add(e == null ? null : ");
3.16 - w.append(type).append(".valueOf((String)e));\n");
3.17 + w.append(type).append(".valueOf(org.apidesign.html.json.impl.JSON.stringValue(e)));\n");
3.18 } else {
3.19 if (isPrimitive(type)) {
3.20 - w.append(" this.prop_").append(pn).append(".add(((Number)e).");
3.21 + w.append(" this.prop_").append(pn).append(".add(org.apidesign.html.json.impl.JSON.numberValue(e).");
3.22 w.append(type).append("Value());\n");
3.23 } else {
3.24 w.append(" this.prop_").append(pn).append(".add((");
3.25 @@ -312,18 +312,18 @@
3.26 if (isEnum[0]) {
3.27 w.append(" this.prop_").append(pn);
3.28 w.append(" = ret[" + cnt + "] == null ? null : ");
3.29 - w.append(type).append(".valueOf((String)ret[" + cnt + "]);\n");
3.30 + w.append(type).append(".valueOf(org.apidesign.html.json.impl.JSON.stringValue(ret[" + cnt + "]));\n");
3.31 } else if (isPrimitive(type)) {
3.32 w.append(" this.prop_").append(pn);
3.33 w.append(" = ret[" + cnt + "] == null ? ");
3.34 if ("char".equals(type)) {
3.35 - w.append("0 : ((Character)");
3.36 + w.append("0 : (org.apidesign.html.json.impl.JSON.charValue(");
3.37 } else if ("boolean".equals(type)) {
3.38 - w.append("false : ((Boolean)");
3.39 + w.append("false : (org.apidesign.html.json.impl.JSON.boolValue(");
3.40 } else {
3.41 - w.append("0 : ((Number)");
3.42 + w.append("0 : (org.apidesign.html.json.impl.JSON.numberValue(");
3.43 }
3.44 - w.append("ret[" + cnt + "]).");
3.45 + w.append("ret[" + cnt + "])).");
3.46 w.append(type).append("Value();\n");
3.47 } else if (isModel[0]) {
3.48 w.append(" this.prop_").append(pn).append(" = org.apidesign.html.json.impl.JSON.read");