# HG changeset patch # User Jaroslav Tulach # Date 1358759202 -3600 # Node ID af027874f93e2f27ae90f76fe783d0e6c39d2823 # Parent 607f062485cc04a4424107b038b68cbce2d7327f Making the Knockout behavior testable diff -r 607f062485cc -r af027874f93e javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/Knockout.java --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/Knockout.java Mon Jan 21 07:00:56 2013 +0100 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/Knockout.java Mon Jan 21 10:06:42 2013 +0100 @@ -25,14 +25,21 @@ * @author Jaroslav Tulach */ @ExtraJavaScript(resource = "org/apidesign/bck2brwsr/htmlpage/knockout-2.2.1.js") -public final class Knockout { - private Knockout() { +public class Knockout { + /** used by tests */ + static Knockout next; + + Knockout() { } public static Knockout applyBindings( Class modelClass, M model, String[] propsGettersAndSetters ) { - Knockout bindings = new Knockout(); + Knockout bindings = next; + next = null; + if (bindings == null) { + bindings = new Knockout(); + } for (int i = 0; i < propsGettersAndSetters.length; i += 3) { bind(bindings, model, propsGettersAndSetters[i], propsGettersAndSetters[i + 1], diff -r 607f062485cc -r af027874f93e javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ModelTest.java --- a/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ModelTest.java Mon Jan 21 07:00:56 2013 +0100 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ModelTest.java Mon Jan 21 10:06:42 2013 +0100 @@ -17,6 +17,8 @@ */ package org.apidesign.bck2brwsr.htmlpage; +import java.util.ArrayList; +import java.util.List; import org.apidesign.bck2brwsr.htmlpage.api.ComputedProperty; import org.apidesign.bck2brwsr.htmlpage.api.Page; import org.apidesign.bck2brwsr.htmlpage.api.Property; @@ -28,7 +30,8 @@ * @author Jaroslav Tulach */ @Page(xhtml = "Empty.html", className = "Model", properties = { - @Property(name = "value", type = int.class) + @Property(name = "value", type = int.class), + @Property(name = "unrelated", type = long.class) }) public class ModelTest { @Test public void classGeneratedWithSetterGetter() { @@ -43,8 +46,36 @@ assertEquals(16, Model.getPowerValue()); } + @Test public void derivedPropertiesAreNotified() { + MockKnockout my = new MockKnockout(); + MockKnockout.next = my; + + Model.applyBindings(); + + Model.setValue(33); + + assertEquals(my.mutated.size(), 2, "Two properties changed: " + my.mutated); + assertTrue(my.mutated.contains("powerValue"), "Power value is in there: " + my.mutated); + assertTrue(my.mutated.contains("value"), "Simple value is in there: " + my.mutated); + + my.mutated.clear(); + + Model.setUnrelated(44); + assertEquals(my.mutated.size(), 1, "One property changed"); + assertTrue(my.mutated.contains("unrelated"), "Its name is unrelated"); + } + @ComputedProperty static int powerValue(int value) { return value * value; } + + static class MockKnockout extends Knockout { + List mutated = new ArrayList(); + + @Override + public void valueHasMutated(String prop) { + mutated.add(prop); + } + } }