<foam>

  <object model="Model">
    <property name="id">TestContainer</property>
    <property name="name">TestContainer</property>
    <property name="requires">
      <i>foam.util.Base64Encoder</i>
      <i>foam.util.Base64Decoder</i>
      <i>foam.core.dao.ManuallyDelayedDAO</i>
    </property>
    <property name="tests">
      <object model="UITest">
        <property name="name">Autocomplete on TextFieldView</property>
        <property name="description">Tests the autocomplete functionality of a TextFieldView.</property>
        <property name="code" type="function">function anonymous() {

      MODEL({
        name: 'Contact',
        properties: [
          'id', 'first', 'last', 'email'
        ]
      });

      var ContactDAO = MDAO.create({ model: Contact });

      [Contact.create({ id: 1, first: 'Adam', last: 'Van Ymeren', email: 'adam...@google.com' }),
       Contact.create({ id: 2, first: 'Kevin', last: 'Greer', email: 'kg...@google.com' }),
       Contact.create({ id: 3, first: 'Alice', email: 'alice@alice.org' }),
       Contact.create({ id: 4, first: 'Bob', email: 'bob@bob.org' }),
       Contact.create({ id: 5, first: 'Test', last: 'Contact', email: 'test@test.test' }),
       Contact.create({ id: 6, first: 'John', last: 'Smith', email: 'j.smith@johnsmith.net' }),
       Contact.create({ id: 7, first: 'Somebody', last: 'Else', email: 'nobody@nowhere.org' }),
       Contact.create({ id: 8, first: 'Random', last: 'Joe', email: 'joe.random@there.ca' }),
       Contact.create({ id: 9, first: 'Frank', last: 'Ellis', email: 'frank@test.com' }),
      ].select(ContactDAO);

      MODEL({
        name: 'ContactEMailCompleter',

        properties: [
          {
            name: 'dao',
            factory: function() { return ContactDAO; }
          },
          {
            model_: 'foam.core.types.DAOProperty',
            name: 'autocompleteDao'
          }
        ],
        constants: {
          f: Contact.EMAIL
        },
        methods: {
          autocomplete: function(data) {
            this.autocompleteDao = this.dao.where(
              data ?
                OR(STARTS_WITH(Contact.EMAIL, data),
                  STARTS_WITH(Contact.FIRST, data),
                  STARTS_WITH(Contact.LAST, data)) :
                false);
          },
        }
      });


      MODEL({
        name: 'Message',
        properties: [
          {
            name: 'sender',
            autocompleter: 'ContactEMailCompleter'
          },
          {
            name: 'to',
            autocompleter: 'ContactEMailCompleter'
          },
          {
            name: 'cc',
            autocompleter: 'ContactEMailCompleter'
          },
          {
            name: 'bcc',
            autocompleter: 'ContactEMailCompleter'
          }
        ]
      });

      var view = DetailView.create({ data: Message.create() });
      this.render(view);

}
        </property>
        <property name="tags">
          <i>web</i>
          <i>ui</i>
        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Base64</property>
        <property name="description">Test FOAM's Base64 handling</property>
        <property name="code" type="function">function anonymous() {
        var Base64Decoder = this.foam.util.Base64Decoder;
        var Base64Encoder = this.foam.util.Base64Encoder;

      this.decode = function(str) {
        var decoder = Base64Decoder.create({ sink: [] });
        decoder.put(str);
        decoder.eof();
        return decoder.sink;
      };

      this.ab2String = function(buffer) {
        var view = new Uint8Array(buffer[0]);
        var result = '';
        for ( var i = 0 ; i &lt; buffer[0].byteLength ; ++i ) {
          result += String.fromCharCode(view[i]);
        }
        return result;
      };

      this.string2ab = function(str) {
        var buffer = new ArrayBuffer(str.length);
        var view = new Uint8Array(buffer);
        for ( var i = 0 ; i &lt; buffer.byteLength ; ++i ) {
          view[i] = str.charCodeAt(i);
        }
        return buffer;
      };

      this.encodingTest = function(input, expected) {
        var encodedString = Base64Encoder.create().encode(this.string2ab(input));
        var decodedString = this.ab2String(this.decode(encodedString));
        this.assert(expected === encodedString, 'Correctly encoded "' + input + '" as "' + expected + '" (== "' + encodedString + '")');
        this.assert(input    === decodedString, 'Correctly decoded "' + encodedString + '" back to "' + input + '" (== "' + decodedString + '")');
      };

}
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
        <property name="tests">
          <object model="UnitTest">
            <property name="name">0-char string</property>
            <property name="description">The encoding of an empty string is the empty string.</property>
            <property name="code" type="function">function anonymous() {

      this.encodingTest('', '');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">1-char string</property>
            <property name="description">Check the encoding and decoding of a length-1 string</property>
            <property name="code" type="function">function anonymous() {

      this.encodingTest('A', 'QQ==');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">2-char string</property>
            <property name="description">Check the encoding and decoding of a length-2 string</property>
            <property name="code" type="function">function anonymous() {

      this.encodingTest('AB', 'QUI=');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">3-char string</property>
            <property name="description">Check the encoding and decoding of a length-3 string</property>
            <property name="code" type="function">function anonymous() {

      this.encodingTest('ABC', 'QUJD');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">4-char string</property>
            <property name="description">Check the encoding and decoding of a length-4 string</property>
            <property name="code" type="function">function anonymous() {

      this.encodingTest('ABCD', 'QUJDRA==');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">All chars</property>
            <property name="description">Check the encoding and decoding of a sequence of all 256 chars.</property>
            <property name="code" type="function">function anonymous() {

      var buffer = new ArrayBuffer(256);
      var view = new Uint8Array(buffer);
      for ( var i = 0 ; i &lt; 256 ; ++i ) {
        view[i] = i;
      }

      var encodedString = this.foam.util.Base64Encoder.create().encode(buffer);
      var EXPECTED_RESULTS =
        'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj' +
        'JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH' +
        'SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr' +
        'bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P' +
        'kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz' +
        'tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX' +
        '2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7' +
        '/P3+/w==';

      this.assert(encodedString === EXPECTED_RESULTS, 'Correctly encoded');

      var decodedBuffer = this.decode(encodedString)[0];
      this.assert(decodedBuffer.byteLength === 256, 'Decoded buffer has correct length');
      var decodedView = new Uint8Array(decodedBuffer);
      for ( var i = 0 ; i &lt; 256 ; i++ ) {
        this.assert(i === decodedView[i], 'Index ' + i + ' matches');
      }

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">By-Name Value binding</property>
        <property name="description">Demonstrate the binding of $ values.</property>
        <property name="code" type="function">function anonymous() {

      MODEL({name: 'Test', properties: [ { name: 'x' } ]});
      var t1 = Test.create({x:1});
      var t2 = Test.create({x:2});

      t1.x$ = t2.x$;
      this.assert(t1.x === t2.x &amp;&amp; t1.x === 2, '$-binding should copy right-to-left');

      t1.x = 3;
      this.assert(t1.x === t2.x &amp;&amp; t2.x === 3, 'And should bind one way');

      t2.x = 4;
      this.assert(t1.x === t2.x &amp;&amp; t1.x === 4, 'And the other way');

      var t3 = Test.create({x$: t1.x$});
      this.assert(t3.x === t1.x &amp;&amp; t3.x === 4, 'Binding in create() works the same');

      t3.x = 5;
      this.assert(t3.x === t1.x &amp;&amp; t2.x === 5, 'And all three are now bound together');

}
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Context Examples</property>
        <property name="disabled">true</property>
        <property name="code" type="function">function anonymous() {

      X.a = 42;
      this.log(X.a);
      var Y = X.sub({a:1,b:2}, 'Y');
      this.log(Y);
      this.log(Y.a);
      MDAO.create({ model: UnitTest });
      var m1 = MDAO.create({ model: UnitTest });
      var m2 = Y.MDAO.create({ model: UnitTest });
      this.log('m2.X ', m2.X);
      this.log('m1.X ', m1.X);
      this.log(m2.X.a);
      var m3 = m2.X.MDAO.create({ model: UnitTest });
      this.log(m3.X);
      this.log(m3.X.a);
}
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
        <property name="tests">
          <object model="UnitTest">
            <property name="name">Context/SubTest1</property>
            <property name="code" type="function">function anonymous() {

      this.log('sub test 1, part 1');
      this.log('sub test 1, part 2');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Context/SubTest2</property>
            <property name="code" type="function">function anonymous() {

      this.log('sub test 2');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Contextualizing DAO Test.</property>
        <property name="description">Test functionality of ContextualizingDAO.</property>
        <property name="async">true</property>
        <property name="code" type="function">function (ret) {
      var Y = this.X.sub({
        a: true
      });
      MODEL({
        name: 'MyType',
        properties: ['id']
      });
      var dao = MDAO.create({ model: MyType });
      var objs = [
        MyType.create({ id: 1 }),
        MyType.create({ id: 2 })
      ];

      objs.select(dao);

      dao = Y.ContextualizingDAO.create({ delegate: dao });

      aseq(
        (function(ret) {
          dao.select()((function(a) {
            for ( var i = 0; i &lt; a.length ; i++ )
              this.assert(!a[i].X.a, 'Selected objects are unchanged.');
            ret();
          }).bind(this));
        }).bind(this),
        (function(ret) {
          dao.find(1, (function(a) {
            this.assert(a.X.a, 'Objects fetched with .find have the correct context.');
            ret();
          }).bind(this));
        }).bind(this))(ret);
    }
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
      </object>

      <object model="UnitTest">
        <property name="name">CloningDAO Test.</property>
        <property name="description">Test functionality of CloningDAO.</property>
        <property name="async">true</property>
        <property name="code" type="function">function (ret) {
      var Y = this.X.sub({
        a: true
      });
      MODEL({
        name: 'MyType',
        properties: ['id', 'foo']
      });
      var dao = MDAO.create({ model: MyType });
      var objs = [
        MyType.create({ id: 1, foo: 'original' }),
        MyType.create({ id: 2, foo: 'original' })
      ];

      objs.select(dao);

      aseq(
        arequire('foam.core.dao.CloningDAO'),
        function(ret, model) {
          dao = model.create({ delegate: dao });
          ret();
        },
        (function(ret) {
          dao.select()((function(a) {
            for ( var i = 0; i &lt; a.length ; i++ ) {
              a.foo = 'new';
              this.assert(objs[i].foo === 'original', 'Selected objects are unchanged.');
            }
            ret();
          }).bind(this));
        }).bind(this),
        (function(ret) {
          dao.find(1, (function(a) {
            this.assert(a.foo === 'original', 'find() also clones.');
            a.foo = 'new';
            this.assert(objs[0].foo === 'original', 'Objects fetched with .find are cloned');
            ret();
          }).bind(this));
        }).bind(this))(ret);
    }
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
      </object>

      <object model="RegressionTest">
        <property name="name">DAO Tests</property>
        <property name="description">Define the Model (like a schema) and create a DAO.</property>
        <property name="code" type="function">function anonymous() {

      Person = FOAM({
        model_: 'Model',
        name: 'Person',
        properties: [
          { name: 'id' },
          { name: 'name' },
          { name: 'sex', defaultValue: 'M' },
          { model_: 'IntProperty', name: 'age' }
        ]
      });

      dao = MDAO.create({model: Person})
        .addIndex(Person.NAME)
        .addIndex(Person.SEX, Person.AGE);

      this.log(dao);

}
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
        <property name="tests">
          <object model="RegressionTest">
            <property name="name">DAO Tests/SubTest1</property>
            <property name="description">Add some sample data and select to a 'sink'.</property>
            <property name="code" type="function">function anonymous() {

      dao.put(Person.create({id:'1', name:'John',  age:21}));
      dao.put(Person.create({id:'2', name:'Dave',  age:20}));
      dao.put(Person.create({id:'3', name:'Steve', age:19}));
      dao.put(Person.create({id:'4', name:'Andy',  age:18}));

      dao.select({put: function(p) { this.log('person: ', p.name); }.bind(this)});

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">person: John
person: Dave
person: Steve
person: Andy
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">DAO Tests/SubTest2</property>
            <property name="description">Select directly to an Array.</property>
            <property name="code" type="function">function anonymous() {

      var a = [];
      dao.select(a);
      this.jlog(a);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">[
   {
      "model_": "Person",
      "id": "1",
      "name": "John",
      "age": 21
   },
   {
      "model_": "Person",
      "id": "2",
      "name": "Dave",
      "sex": "M",
      "age": 20
   },
   {
      "model_": "Person",
      "id": "3",
      "name": "Steve",
      "sex": "M",
      "age": 19
   },
   {
      "model_": "Person",
      "id": "4",
      "name": "Andy",
      "sex": "M",
      "age": 18
   }
]
</property>
          </object>

        </property>
        <property name="master">MDAO(Person,Alt(TreeIndex(id, value),TreeIndex(name, TreeIndex(id, value)),TreeIndex(sex, TreeIndex(age, TreeIndex(id, value)))))
</property>
      </object>

      <object model="UnitTest">
        <property name="name">Event Tests</property>
        <property name="description">Tests for event handling.</property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
        <property name="tests">
          <object model="UnitTest">
            <property name="name">Direct property binding</property>
            <property name="description">Creates a two-way binding between two properties at object creation time.</property>
            <property name="code" type="function">function anonymous() {

      MODEL({
        name: 'Test',
        properties: ['foo', 'bar']
      });

      var x = Test.create({ foo: 1, bar: 'asdf' });
      var y = Test.create({ foo$: x.foo$ });

      this.log('y.foo now follows x.foo and vice versa. They can be considered the same property.');
      this.assert(y.foo === 1 &amp;&amp; !y.bar, 'y.foo immediately updated');

      x.foo = 3;
      this.assert(y.foo === 3, 'Changing x.foo updates y.foo');
      y.foo = 5;
      this.assert(x.foo === 5 &amp;&amp; y.foo === 5, 'And changing y.foo updates x.foo');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Event Merging</property>
            <property name="description">Events can be merged into a maximum of 1 event per unit time, or 1 event per animation frame.</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      var animationCount = 0;
      var otherCount = 0;

      MODEL({
        name: 'Test',
        listeners: [
          {
            name: 'animated',
            isFramed: true,
            code: function() {
              animationCount++;
            }
          },
          {
            name: 'other',
            isMerged: 20,
            code: function() {
              otherCount++;
            }
          }
        ]
      });

      var foo = Test.create({});
      this.assert(animationCount === 0 &amp;&amp; otherCount === 0, 'Counts start at 0');
      foo.animated();
      foo.animated();
      foo.animated();
      foo.animated();
      foo.other();
      foo.other();
      foo.other();
      foo.other();

      setTimeout(function() {
        this.assert(animationCount === 1 &amp;&amp; otherCount === 1, 'Both counts are 1 due to the merging');
        ret();
      }.bind(this), 50);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Event primitives</property>
            <property name="description">Tests the primitive event listeners and handlers</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      MODEL({name: 'Test', properties: [ { name: 'x' } ]});
      var t = Test.create();
      var intermediates = [];
      t.x$.addListener(function() { intermediates.push(t.x); });
      t.x = 1;
      t.x = 2;
      t.x = 3;
      Movement.animate(100, function() { t.x = 10; })();
      setTimeout(function() {
        this.assert(intermediates[0] === 1, 'First update is 1');
        this.assert(intermediates[1] === 2, 'Second update is 2');
        this.assert(intermediates[2] === 3, 'Third update is 3');
        this.assert(intermediates[intermediates.length-1] === 10, 'Final update is 10');
        this.assert(intermediates.length &gt;= 7, 'There should be several intermediate updates between 3 and 10');
        var correct = true;
        for ( var i = 3 ; i &lt; intermediates.length ; i++ ) {
          if ( intermediates[i-1] &gt;= intermediates[i] ) {
            correct = false;
            break;
          }
        }
        this.assert(correct, 'Updates should be in ascending order');
        ret();
      }.bind(this), 150);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Event topic chaining and wildcarding</property>
            <property name="description">Events can have paths, and wildcards will hit all sub-events</property>
            <property name="code" type="function">function anonymous() {

      MODEL({ name: 'Test' });
      var x = Test.create({});

      var barCount = 0;
      var bazCount = 0;
      x.subscribe(['foo', 'bar'], function() { barCount++; });
      x.subscribe(['foo', 'baz'], function() { bazCount++; });

      this.assert(barCount === 0 &amp;&amp; bazCount === 0, 'Both counts start at 0');

      x.publish(['foo', 'bar']);
      this.assert(barCount === 1 &amp;&amp; bazCount === 0, 'Bar was incremented');

      x.publish(['foo', 'baz']);
      this.assert(barCount === 1 &amp;&amp; bazCount === 1, 'Baz was incremented');

      x.publish(['foo']);
      this.assert(barCount === 1 &amp;&amp; bazCount === 1, 'Publishing on a prefix does nothing');

      x.publish(['foo', EventService.WILDCARD]);
      this.assert(barCount === 2 &amp;&amp; bazCount === 2, 'But publishing on WILDCARD hits all events in the subtree');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Events.follow()</property>
            <property name="description">Creates a one-way binding between two properties</property>
            <property name="code" type="function">function anonymous() {

      MODEL({
        name: 'Test',
        properties: ['foo', 'bar']
      });

      var x = Test.create({ foo: 1, bar: 'asdf' });
      var y = Test.create({});

      this.assert(!y.foo, 'y.foo is not set to start');

      Events.follow(x.foo$, y.foo$);
      this.log('y.foo now follows x.foo');
      this.assert(y.foo === 1 &amp;&amp; !y.bar, 'y.foo immediately updated');

      x.foo = 3;
      this.assert(y.foo === 3, 'Changing x.foo updates y.foo');
      y.foo = 5;
      this.assert(x.foo === 3 &amp;&amp; y.foo === 5, 'But changing y.foo does not update x.foo');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Events.link()</property>
            <property name="description">Creates a two-way binding between two properties</property>
            <property name="code" type="function">function anonymous() {

      MODEL({
        name: 'Test',
        properties: ['foo', 'bar']
      });

      var x = Test.create({ foo: 1, bar: 'asdf' });
      var y = Test.create({});

      this.assert(!y.foo, 'y.foo is not set to start');

      Events.link(x.foo$, y.foo$);
      this.log('y.foo now follows x.foo and vice versa');
      this.assert(y.foo === 1 &amp;&amp; !y.bar, 'y.foo immediately updated');

      x.foo = 3;
      this.assert(y.foo === 3, 'Changing x.foo updates y.foo');
      y.foo = 5;
      this.assert(x.foo === 5 &amp;&amp; y.foo === 5, 'And changing y.foo updates x.foo');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Events.map()</property>
            <property name="description">Creates a one-way binding between two properties, running a filter over the value in between</property>
            <property name="code" type="function">function anonymous() {

      MODEL({
        name: 'Test',
        properties: ['foo', 'bar']
      });

      var x = Test.create({ foo: 1, bar: 'asdf' });
      var y = Test.create({});

      this.assert(!y.foo, 'y.foo is not set to start');

      Events.map(x.foo$, y.foo$, function(x) { return 2*x; });
      this.log('y.foo now follows x.foo, storing double the value');
      this.assert(y.foo === 2 &amp;&amp; !y.bar, 'y.foo immediately updated');

      x.foo = 3;
      this.assert(y.foo === 6, 'Changing x.foo updates y.foo');
      y.foo = 5;
      this.assert(x.foo === 3 &amp;&amp; y.foo === 5, 'But changing y.foo does not update x.foo');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Events.relate()</property>
            <property name="description">Creates a two-way binding between two properties, converting with functions</property>
            <property name="code" type="function">function anonymous() {

      MODEL({
        name: 'Test',
        properties: ['foo', 'bar']
      });

      var x = Test.create({ foo: 1, bar: 'asdf' });
      var y = Test.create({});

      this.assert(!y.foo, 'y.foo is not set to start');

      Events.relate(x.foo$, y.foo$, function(x) { return x*2; }, function(x) { return x/2; });
      this.log('y.foo now follows x.foo and vice versa, where x.foo == y.foo*2');
      this.assert(y.foo === 2 &amp;&amp; !y.bar, 'y.foo immediately updated');

      x.foo = 3;
      this.assert(y.foo === 6, 'Changing x.foo updates y.foo');
      y.foo = 5;
      this.assert(x.foo === 2.5 &amp;&amp; y.foo === 5, 'And changing y.foo updates x.foo');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Pub/sub support</property>
            <property name="description">Every Modelled object is a pub/sub target. Also shows one-time listeners.</property>
            <property name="code" type="function">function anonymous() {

      MODEL({
        name: 'Test',
        properties: [
          {
            name: 'x',
            postSet: function(_, x) {
              if ( x === 7 ) {
                this.publish(['x7']);
              }
            }
          }
        ]
      });

      var foo = Test.create({ x: 3 });
      var sevensSeen = 0;
      var sevensSeenOneTime = 0;
      foo.subscribe(['x7'], function() { sevensSeen++; });
      foo.subscribe(['x7'], EventService.oneTime(function() { sevensSeenOneTime++; }));

      foo.x = 1;
      this.assert(sevensSeen === 0 &amp;&amp; sevensSeenOneTime === 0, 'No sevens yet');
      foo.x = 9;
      this.assert(sevensSeen === 0 &amp;&amp; sevensSeenOneTime === 0, 'Still none');
      foo.x = 7;
      this.assert(sevensSeen === 1 &amp;&amp; sevensSeenOneTime === 1, 'Found one');
      foo.x = 5;
      foo.x = 7;
      this.assert(sevensSeen === 2 &amp;&amp; sevensSeenOneTime === 1, 'And another, but the one-time listener has been removed');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Object Model tests</property>
        <property name="description">Tests for the basic Object model</property>
        <property name="code" type="function">function anonymous() {

      seq = [];
      MODEL({
        name: 'OMTestBase',
        properties: [
          { name: 'foo', defaultValue: 'rabbits' },
          'bar'
        ],
        methods: {
          doThings: function() {
            seq.push('doThings base');
          }
        }
      });

      seqMatches = function(gold) {
        if ( seq.length !== gold.length ) return false;
        for ( var i = 0; i &lt; seq.length ; i++ ) {
          if ( seq[i] != gold[i] ) return false;
        }
        return true;
      }

}
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
        <property name="tests">
          <object model="UnitTest">
            <property name="name">Constructor tests</property>
            <property name="description">Demonstrate various properties of FOAM object constructors</property>
            <property name="code" type="function">function anonymous() {

      var x = OMTestBase.create({ bar: 'baz' });
      this.assert(x.bar === 'baz', 'Constructors can set properties');
      this.assert(x.foo === 'rabbits', 'Default values are used if not given');

      x.foo = 'kittens';
      this.assert(x.foo === 'kittens', 'But the defaults can be overridden');

      var y = OMTestBase.create(x);
      this.assert(y.foo == x.foo, 'FOAM objects can be passed to constructors to copy');
      y.foo = 'puppies';
      this.assert(y.foo === 'puppies' &amp;&amp; x.foo === 'kittens', 'And it\'s really a copy');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Default values and factories</property>
            <property name="description">Exercises default values functions and factories</property>
            <property name="code" type="function">function anonymous() {

      var model = Model.create({
        name: 'OMTestDefaults',
        properties: [
          {
            name: 'foo',
            defaultValueFn: function(){ seq.push('foo dVF'); return 7; }
          },
          {
            name: 'bar',
            factory: function() { seq.push('bar factory'); return 9; }
          }
        ]
      });

      var x = model.create({});
      this.assert(seqMatches(['bar factory']), 'Factories are called once on init, but defaultValueFns are not');

      this.assert(x.foo === 7, 'DefaultValueFns work');
      this.assert(seqMatches(['bar factory', 'foo dVF']), 'Requesting x.foo calls the foo property\'s defaultValueFn');
      this.assert(x.foo === 7, 'Still just the defaultValueFn');
      this.assert(seqMatches(['bar factory', 'foo dVF', 'foo dVF']),
          'Requesting x.foo again calls its defaultValueFn again');
      this.assert(x.bar === 9, 'The factory property was correctly set too');
      this.assert(seqMatches(['bar factory', 'foo dVF', 'foo dVF']),
          'Requesting x.bar does not call the factory again');

      x.foo = 17;
      this.assert(seqMatches(['bar factory', 'foo dVF', 'foo dVF']),
          'Overwriting the value causes one more defaultValueFn call');

      this.assert(x.foo === 17, 'Overwriting the property with the defaultValueFn works');
      this.assert(seqMatches(['bar factory', 'foo dVF', 'foo dVF']),
          'And now requesting it does not call the defaultValueFn');
      x.foo = 7;
      this.assert(x.foo === 7, 'Setting the property to the default value still doesn\'t return to calling the defaultValueFn');
      this.assert(seqMatches(['bar factory', 'foo dVF', 'foo dVF']),
          'Requesting it still doesn\'t call defaultValueFn');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Inheritance Tests</property>
            <property name="description">Exercises Model inheritance and SUPER</property>
            <property name="code" type="function">function anonymous() {

      var sub = Model.create({
        name: 'OMTestSubclass',
        extendsModel: 'OMTestBase',
        properties: [
          { name: 'foo', defaultValue: 'kittens' },
          'baz'
        ],
        methods: {
          doThings: function() {
            seq.push('subclass pre');
            this.SUPER();
            seq.push('subclass post');
          }
        }
      });

      var x = sub.create({});
      this.assert(x.foo === 'kittens', 'Default values of base class properties can be overridden');
      this.assert(x.bar$, 'Properties not mentioned in the subclass still exist');
      this.assert(x.baz$, 'Properties added by the subclass exist too');

      seq = [];
      this.assert(seqMatches([]), 'seq starts empty');

      x.doThings();
      this.assert(seqMatches(['subclass pre', 'doThings base', 'subclass post']),
          'this.SUPER() calls the same method on the superclass, allowing you to add code before and after it');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Property update handlers</property>
            <property name="description">Exercises property updaters (preSet, postSet) and pseudo-properties (getter, setter)</property>
            <property name="code" type="function">function anonymous() {

      var model = Model.create({
        name: 'OMTestPropUpdaters',
        properties: [
          {
            name: 'foo',
            defaultValue: -1,
            preSet: function(old, nu) {
              // Foo allows only positive numbers.
              // If anything else is provided, it returns old to cause no change.
              // Note that postSet will still fire!
              seq.push('preSet');
              if ( typeof nu !== 'number' ) return old;
              if ( nu &lt; 0 ) return old;
              return nu;
            },
            postSet: function(old, nu) {
              seq.push('postSet ' + old + ' ' + nu);
            }
          },
          {
            name: 'bar',
            getter: function() { seq.push('bar getter'); return 'kittens'; },
            setter: function(nu) { seq.push('bar setter ' + nu); }
          }
        ]
      });

      seq = [];
      var x = model.create({});

      this.assert(seqMatches([]), 'Neither preSet, postSet, getter nor setter are called at creation time unless there are factories');

      this.assert(x.foo === -1, 'Default values that don\'t pass the preSet are possible!');
      this.assert(seqMatches([]), 'Accessing the defaultValue is not an update, so preSet and postSet don\'t fire');

      x.foo = -3;
      this.assert(x.foo === -1, 'Updates that are rejected by preSet are ignored');
      this.assert(seqMatches(['preSet', 'postSet -1 -1']), 'preSet is called, it returns the old value (-1), postSet is called with old == nu == -1');

      seq = [];
      x.foo = 7;
      this.assert(x.foo === 7, 'Updates that are allowed by preSet actually happen');
      this.assert(seqMatches(['preSet', 'postSet -1 7']), 'preSet is called, it returns the new value (7), and then postSet is called with old = -1, nu = 7');

      seq = [];
      this.assert(x.bar === 'kittens', 'bar, the pseudoproperty, calls its getter function when accessed and returns its result')
      this.assert(seqMatches(['bar getter']), 'the getter function was indeed called');

      seq = [];
      x.bar = 'puppies';
      this.assert(x.bar === 'kittens', 'bar is a pseudoproperty - if its setter does nothing with the value, the getter returns what it always does');
      this.assert(seqMatches(['bar setter puppies', 'bar getter']), 'setter was called properly');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">toFoo wrappers</property>
            <property name="description">Describes toString, toJSON and toXML default handlers</property>
            <property name="code" type="function">function anonymous() {

      var x = OMTestBase.create({});
      var s = x.toString();
      this.log(s);
      this.assert(typeof s === 'string', '.toString() produces strings');

      var json = x.toJSON();
      this.log(json);
      this.assert(typeof json === 'string', '.toJSON() produces JSON strings');
      var parsed = JSONUtil.parse(X, json);
      this.assert(typeof parsed === 'object', '.toJSON() output can be parsed by JSONUtil.parse()');
      this.assert(OMTestBase.isInstance(parsed), 'The parsed object should be an instance of the original Model');

      var xml = x.toXML();
      //this.log(xml);
      this.assert(typeof xml === 'string', '.toXML() produces XML strings');
      parsed = XMLUtil.parse(xml);
      this.assert(parsed instanceof Array, '.toXML() output can be parsed by XMLUtil.parse(), which returns an array of parsed objects');
      this.assert(OMTestBase.isInstance(parsed[0]), 'The parsed object should be an instance of the original Model');

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Property Type Conversions</property>
        <property name="description">Test that properties coerce values properly..</property>
        <property name="code" type="function">function anonymous() {

      o = FOAM({
        model_: 'Model',
        name: 'Test',
        properties: [
          { model_: 'StringProperty',  name: 's' },
          { model_: 'IntProperty', name: 'i' },
          { model_: 'FloatProperty',   name: 'f' }
        ]
      }).create();

      this.assert(o.s === '', 'Default value for String Properties should be empty string.');
      o.s = 'string'; this.assert(o.s === 'string', 'Setting String Properties should work.');
      o.s = undefined; this.assert(o.s === '', 'Setting String Properties to undefined should convert value to empty string.');
      o.s = 1; this.assert(o.s === '1', 'Setting String Properties to numbers should convert value to String.');

      this.assert(o.i === 0, 'Default value for Int Properties should be 0.');
      o.i = 1; this.assert(o.i === 1, 'Setting Int Properties should work.');
      o.i = undefined; this.assert(o.i === 0, 'Setting Int Properties to undefined should convert value to 0.');
      o.i = '1'; this.assert(o.i === 1, 'Setting Int Properties to a string should convert value to Int.');

      this.assert(o.f === 0.0, 'Default value for Float Properties should be 0.0.');
      o.f = 1.0; this.assert(o.f === 1.0, 'Setting Float Properties should work.');
      o.f = undefined; this.assert(o.f === 0.0, 'Setting Float Properties to undefined should convert value to 0.0.');
      o.f = '1.1'; this.assert(o.f === 1.1, 'Setting Float Properties to a string should convert value to Float.');

}
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
      </object>

      <object model="RegressionTest">
        <property name="name">Super Test</property>
        <property name="description">Test SUPER support.</property>
        <property name="code" type="function">function anonymous() {
      MODEL({name: 'A', methods: { foo: function() { console.log('a'); } }});
      MODEL({name: 'B', extendsModel: 'A', methods: { foo: function() { console.log('b.fore'); this.SUPER(); console.log('b.after'); } }});
      MODEL({name: 'B2', extendsModel: 'A', methods: { foo: function() { console.log('b2.fore'); this.SUPER(); console.log('b2.after'); } }});

      var a  = A.create();
      var b  = B.create();
      var b2 = B2.create();
      a.foo();
      b.foo();
      b2.foo();
    }
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
        <property name="master">a
b.fore
a
b.after
b2.fore
a
b2.after
</property>
      </object>

      <object model="UITest">
        <property name="name">TextFieldView</property>
        <property name="description">Test data-binding in TextFieldViews.</property>
        <property name="code" type="function">function anonymous() {

      var v1 = TextFieldView.create();
      var v2 = TextFieldView.create();

      this.render(v1);
      this.render(v2);

      v1.data$ = v2.data$;
    
}
        </property>
        <property name="tags">
          <i>web</i>
          <i>ui</i>
        </property>
      </object>

      <object model="UITest">
        <property name="name">TextFieldView/onKeyMode</property>
        <property name="description">Test data-binding in TextFieldViews with onKeyMode enabled.</property>
        <property name="code" type="function">function anonymous() {

      var v1 = TextFieldView.create({onKeyMode: true});
      var v2 = TextFieldView.create({onKeyMode: true});

      this.render(v1);
      this.render(v2);

      v1.data$ = v2.data$;
    
}
        </property>
        <property name="tags">
          <i>web</i>
          <i>ui</i>
        </property>
      </object>

      <object model="UITest">
        <property name="name">TextFieldView/readOnlyMode</property>
        <property name="description">Test data-binding in TextFieldViews with onKeyMode enabled.</property>
        <property name="code" type="function">function anonymous() {

      var v1 = TextFieldView.create({onKeyMode: true});
      var v2 = TextFieldView.create({mode: 'read-only'});

      this.render(v1);
      this.render(v2);

      v1.data$ = v2.data$;
    
}
        </property>
        <property name="tags">
          <i>web</i>
          <i>ui</i>
        </property>
      </object>

      <object model="UnitTest">
        <property name="name">aFunc Tests</property>
        <property name="description">Test FOAM's Asynchronous-Functions (aFunc's).</property>
        <property name="code" type="function">function anonymous() {

      this.f1 = function(ret) { this.log('f1() called.'); ret(1); };
      this.f2 = function(ret, a) { this.log('f2() called.'); ret(a,2); };
      this.aprint = function(ret) { this.log(argsToArray(arguments).slice(1).join(', ')); ret(); };

}
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
        <property name="tests">
          <object model="RegressionTest">
            <property name="name">Future Function</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.log('start');
      var functionFuture = afuture();
      var fn = futurefn(functionFuture);

      fn("hello");
      setTimeout(function() { fn(" world!"); ret(); }, 20);
      var log = this.log.bind(this);
      setTimeout(function() { functionFuture.set(log); }, 10);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">start
hello
 world!
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 0</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.aprint.bind(this).ao(this.f2.bind(this).ao(this.f1.bind(this)))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
f2() called.
1, 2
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 1</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.aprint.bind(this).ao(this.f2.bind(this).ao(this.f1.bind(this)))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
f2() called.
1, 2
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 2</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.f1.bind(this).aseq(this.f2.bind(this).aseq(this.aprint.bind(this)))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
f2() called.
1, 2
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 3</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.f1.bind(this).aseq(this.aprint.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
1
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 4</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      ao(this.aprint.bind(this), this.f2.bind(this), this.f1.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
1
f2() called.
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 5</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      aseq(this.f1.bind(this), this.aprint.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
1
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 6</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      aseq(this.f1.bind(this), this.f2.bind(this), this.aprint.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
f2() called.
1, 2
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 7</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      aseq(
        function(ret) { this.log('fB'); ret(1); }.bind(this),
        function(ret) { this.log('fC'); ret(2); }.bind(this),
        this.aprint.bind(this)
      )(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">fB
fC
2
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 8</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      apar(
        function(ret, a) { this.log('fB'); ret(1); }.bind(this),
        function(ret, a) { this.log('fC'); ret(2); }.bind(this)
      )(this.aprint.bind(this).aseq(ret));

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">fB
fC
2
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">aFunc Test 11</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      aseq(
        function(ret) { this.log('fA'); ret(1); }.bind(this),
        apar(
          function(ret, a) { this.log('fB', a); ret(1); }.bind(this),
          function(ret, a) { this.log('fC', a); ret(2); }.bind(this)
        ),
        this.aprint.bind(this)
      )(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">fA
fB1
fC1
1, 2
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">abind1</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      var boo = function() { console.log('boo'); };
      boo();
      boo.abind(null)(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">boo
boo
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">abind2</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      aseq(
        this.f1.bind(this),
        function() { this.log('sync fn'); }.abind(this),
        this.f2.bind(this)
      )(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
sync fn
f2() called.
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">alog</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.log('alog');
      alog('a message')(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">alog
a message
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">amemo</property>
            <property name="description">Test that amemo() only executes its delegate once.</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      m = amemo(function(ret) { this.log('Should only see this once.'); ret(1); }.bind(this));
      apar(m, m, m).aseq(this.aprint.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">Should only see this once.
1, 1, 1
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">anop</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.log('anop');
      aseq(alog('before'), anop, alog('after'))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">anop
before
after
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">arepeat 1</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      arepeat(5, this.f1.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">f1() called.
f1() called.
f1() called.
f1() called.
f1() called.
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">arepeat 2</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      arepeat(5, function(ret, a, b) { this.log(a); ret(1); }.bind(this)).aseq(this.aprint.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">0
1
2
3
4
1
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">arepeat 3</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      aseq(
        arepeat(5, function(ret, a, b) { this.log(a); ret(1); }.bind(this)),
        this.aprint.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">0
1
2
3
4
1
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">arepeatpar</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      arepeatpar(6, function(ret, a, b) {
        this.log(a + ' starting');
        aseq(
          asleep(20),
          function(ret) {
            this.log(a + ' done');
            ret();
          }.bind(this)
        )(ret);
      }.bind(this))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">0 starting
1 starting
2 starting
3 starting
4 starting
5 starting
0 done
1 done
2 done
3 done
4 done
5 done
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">asleep</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.log('**********');
      this.log('************** Beginning asleep2');
      aseq(alog('before'), asleep(10), alog('after'), asleep(10), alog('much after'))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">**********
************** Beginning asleep2
before
after
much after
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">asleep2</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      this.log('at the start');
      aseq(asleep(10), alog('a message'))(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">at the start
a message
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">asynchronized</property>
            <property name="code" type="function">function anonymous() {

      this.tlock = {};

      this.f1 = aseq(
        alog('f1 start'),
        asleep(20),
        alog('f1 end')
      );

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="tests">
              <object model="RegressionTest">
                <property name="name">With Synchronization</property>
                <property name="async">true</property>
                <property name="code" type="function">function (ret){

      var f1 = asynchronized(this.f1.bind(this));

      apar(f1, f1, f1)(ret);

}
                </property>
                <property name="tags">
                  <i>node</i>
                  <i>web</i>
                </property>
                <property name="master">f1 start
f1 end
f1 start
f1 end
f1 start
f1 end
</property>
              </object>

              <object model="RegressionTest">
                <property name="name">With Synchronization (Sequential)</property>
                <property name="async">true</property>
                <property name="code" type="function">function (ret){

      apar(aseq(this.f1, this.f1, this.f1), aseq(this.f1, this.f1, this.f1))(ret);

}
                </property>
                <property name="tags">
                  <i>node</i>
                  <i>web</i>
                </property>
                <property name="master">f1 start
f1 start
f1 end
f1 start
f1 end
f1 start
f1 end
f1 start
f1 end
f1 start
f1 end
f1 end
</property>
              </object>

              <object model="RegressionTest">
                <property name="name">Without Synchronization</property>
                <property name="async">true</property>
                <property name="code" type="function">function (ret){

      apar(this.f1, this.f1, this.f1)(ret);

}
                </property>
                <property name="tags">
                  <i>node</i>
                  <i>web</i>
                </property>
                <property name="master">f1 start
f1 start
f1 start
f1 end
f1 end
f1 end
</property>
              </object>

            </property>
          </object>

          <object model="UnitTest">
            <property name="name">mergeAsync</property>
            <property name="async">true</property>
            <property name="code" type="function">function (ret){

      var calls = [];
      var fdirty = mergeAsync(function(r, x) {
        calls.push(x);
        setTimeout(r, 20);
      });
      aseq(
        function(r) { fdirty(1); r(); },
        function(r) { fdirty(2); r(); },
        function(r) { fdirty(3); r(); },
        function(r) {
          this.assert(calls.length == 1 &amp;&amp; calls[0] == 1, 'Only one call should fire right away');
          r();
        }.bind(this),
        asleep(50),
        function(r) {
          this.assert(calls.length == 2 &amp;&amp; calls[0] == 1 &amp;&amp; calls[1] == 3,
              'Both calls should now have fired.');
          r();
        }.bind(this)
      )(ret);

}
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">LinearLayoutTrait test</property>
        <property name="description">Tests generic foam.graphics.LinearLayoutTrait layout handling</property>
        <property name="code" type="function">function anonymous() {
  // Prepare a trait host model with the bare essential properties
  MODEL({ name: 'LinLayTest', traits: [ 'foam.patterns.layout.LinearLayoutTrait' ],
    properties: [
      'width', 'height',
      {
        name: 'children',
        defaultValue: []
      }
    ]
  });
  // prepare a layout item trait host model
  MODEL({ name: 'LayItem', traits: [ 'foam.patterns.layout.LayoutItemHorizontalTrait', 'foam.patterns.layout.LayoutItemVerticalTrait'  ],
    properties: [
      'width', 'height', 'x', 'y'
    ]
  });

  // make some layout items to use
  this.item1 = this.X.LayItem.create({x:0, y:0, width:10, height: 10});
  this.item2 = this.X.LayItem.create({x:0, y:0, width:10, height: 10});
  this.item3 = this.X.LayItem.create({x:0, y:0, width:10, height: 10});
  this.item4 = this.X.LayItem.create({x:0, y:0, width:10, height: 10});

  this.item1.horizontalConstraints.min = 0;
  this.item2.horizontalConstraints.min = 10;
  this.item3.horizontalConstraints.min = 20;
  //this.item4.horizontalConstraints.min = 0;

  this.item1.horizontalConstraints.max = 100;
  this.item2.horizontalConstraints.max = 30;
  this.item3.horizontalConstraints.max = 50;
  //this.item4.horizontalConstraints.max = 9999999999;

  this.item1.horizontalConstraints.preferred = 5;
  this.item2.horizontalConstraints.preferred = 20;
  this.item3.horizontalConstraints.preferred = 30;
  this.item4.horizontalConstraints.preferred = 100;

  this.item1.horizontalConstraints.stretchFactor = 0;
  this.item2.horizontalConstraints.stretchFactor = 1;
  this.item3.horizontalConstraints.stretchFactor = 2;
  this.item4.horizontalConstraints.stretchFactor = 3;

  this.item1.horizontalConstraints.shrinkFactor = 1;
  this.item2.horizontalConstraints.shrinkFactor = 2;
  this.item3.horizontalConstraints.shrinkFactor = 3;
  this.item4.horizontalConstraints.shrinkFactor = 0;

  this.logItems = function() {
    var self = this;
    [self.item1, self.item2, self.item3, self.item4].forEach(function(item) {
      self.log("(",item.x, ", ", item.y, ") ", item.width, "x", item.height);
    });
  };

}
        </property>
        <property name="tags">
          <i>node</i>
          <i>web</i>
        </property>
        <property name="tests">
          <object model="RegressionTest">
            <property name="name">Shrinking Layout</property>
            <property name="code" type="function">function anonymous() {
                // make a layout
                var layout1 = this.X.LinLayTest.create();
                layout1.orientation = 'horizontal';
                layout1.width = 100;
                layout1.height = 10;

                layout1.children = [this.item1, this.item2, this.item3, this.item4];
                layout1.calculateLayout();

                this.logItems();
              }
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">(0, 0) 0x10
(0, 0) 10x10
(10, 0) 20x10
(30, 0) 70x10
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">Growing Layout</property>
            <property name="code" type="function">function anonymous() {
                // make a layout
                var layout1 = this.X.LinLayTest.create();
                layout1.orientation = 'horizontal';
                layout1.width = 300;
                layout1.height = 10;

                layout1.children = [this.item1, this.item2, this.item3, this.item4];
                layout1.calculateLayout();

                this.logItems();
              }
            </property>
            <property name="tags">
              <i>node</i>
              <i>web</i>
            </property>
            <property name="master">(0, 0) 5x10
(5, 0) 30x10
(35, 0) 50x10
(85, 0) 215x10
</property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Packages</property>
        <property name="description">Tests the package system: package, require, import, export</property>
        <property name="tags">
          <i>web</i>
          <i>node</i>
        </property>
        <property name="tests">
          <object model="UnitTest">
            <property name="name">Children import things I export</property>
            <property name="description">If I export 'foo', and have a factory that creates a require()d child that imports 'foo', that instance should get my 'foo'.</property>
            <property name="code" type="function">function anonymous() {
              CLASS({
                name: 'Parent',
                exports: ['foo'],
                requires: ['Child'],
                properties: [
                  { name: 'foo', defaultValue: 'bar' },
                  {
                    name: 'myChild',
                    lazyFactory: function() { return this.Child.create(); }
                  }
                ]
              });
              CLASS({
                name: 'Child',
                imports: ['foo'],
                methods: {
                  check: function() {
                    return this.foo;
                  }
                }
              });

              var parent = this.X.Parent.create();
              this.assert(parent.myChild.check() === parent.foo,
                  '"foo" should be imported into Child from Parent');

            }
            </property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Model-for-Model</property>
        <property name="description">Tests replacement of models at creation time based on the data type.</property>
        <property name="tags">
          <i>web</i>
          <i>node</i>
        </property>
        <property name="tests">
          <object model="UnitTest">
            <property name="name">Model replaced when a valid replacement is available</property>
            <property name="description">If a creation arg x.MyModel.create({model:SpecModel}) is supplied, and a model with the name SpecModelMyModel exists, it is created instead.</property>
            <property name="code" type="function">function anonymous() {
              CLASS({
                name: 'Base',
                properties: [
                  { name: 'model' },
                ]
              });
              CLASS({
                name: 'Specific',
              });
              CLASS({
                name: 'SpecificBase',
                extendsModel: 'Base'
              });

              var created = this.X.Base.create({ model:this.X.Specific });
              this.assert(created.model_.name === 'SpecificBase',
                  '"created" should be of type SpecificBase, not '+created.model_.name);

            }
            </property>
            <property name="tags">
              <i>web</i>
              <i>node</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Model in a package replaced when a valid replacement is available</property>
            <property name="description">If a creation arg X.myPackage.MyModel.create({model:SpecModel}) is supplied, and a model with the name myPackage.SpecModelMyModel exists, it is created instead.</property>
            <property name="code" type="function">function anonymous() {
              CLASS({
                name: 'Base',
                package: 'myPackage',
                properties: [
                  { name: 'model' },
                ]
              });
              CLASS({
                name: 'Specific',
                package: 'other'
              });
              CLASS({
                name: 'SpecificBase',
                extendsModel: 'Base',
                package: 'myPackage'
              });

              var created = this.X.myPackage.Base.create({ model:this.X.other.Specific });
              this.assert(created.model_.id === 'myPackage.SpecificBase',
                  '"created" should be of type myPackage.SpecificBase, not '+created.model_.id);

            }
            </property>
            <property name="tags">
              <i>web</i>
              <i>node</i>
            </property>
          </object>

          <object model="UnitTest">
            <property name="name">Model not replaced when no model arg present</property>
            <property name="description">If a creation arg X.myPackage.MyModel.create({model:SpecModel}) is NOT supplied, and a model with the name myPackage.SpecModelMyModel exists, it is ignored.</property>
            <property name="code" type="function">function anonymous() {
              CLASS({
                name: 'Base',
                package: 'myPackage',
                properties: [
                  { name: 'model' },
                ]
              });
              CLASS({
                name: 'Specific',
                package: 'other'
              });
              CLASS({
                name: 'SpecificBase',
                extendsModel: 'Base',
                package: 'myPackage'
              });

              var created = this.X.myPackage.Base.create({ });
              this.assert(created.model_.id === 'myPackage.Base',
                  '"created" should be of type myPackage.Base, not '+created.model_.id);

            }
            </property>
            <property name="tags">
              <i>web</i>
              <i>node</i>
            </property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Traits</property>
        <property name="description">Tests handling of traits.</property>
        <property name="code" type="function">function anonymous() {
          CLASS({
            name: 'TraitA',
            package: 'different.package',
            properties: [
              { name: 'a', defaultValue: 1 },
            ]
          });
          CLASS({
            name: 'TraitB',
            package: 'different.package',
            properties: [
              { name: 'b', defaultValue: 2 },
            ]
          });
          CLASS({
            name: 'TraitH',
            package: 'different.package',
            properties: [
              { name: 'h1', defaultValue: 3 },
            ]
          });
          CLASS({
            name: 'HostBase',
            package: 'nested.package.levels',
            properties: [
              { name: 'h1', defaultValue: 4 },
              { name: 'h2', defaultValue: 'tada' },
            ]
          });

          this.logItems = function(result) {
            this.log(result.h1);
            this.log(result.h2);
            this.log(result.a);
            this.log(result.b);
          }
        }
        </property>
        <property name="tags">
          <i>web</i>
          <i>node</i>
        </property>
        <property name="tests">
          <object model="RegressionTest">
            <property name="name">Trait added to host class adds properties</property>
            <property name="description">The class resulting from a class with a trait added should have the combined set of properties of both.</property>
            <property name="code" type="function">function anonymous() {
              CLASS({
                name: 'Host',
                package: 'nested.package.levels',
                extendsModel: 'nested.package.levels.HostBase',
                traits: ['different.package.TraitA']
              });
              var result = this.X.nested.package.levels.Host.create();

              this.logItems(result);
            }
            </property>
            <property name="tags">
              <i>web</i>
              <i>node</i>
            </property>
            <property name="master">4
tada
1
undefined
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">Trait added to host class overrides properties</property>
            <property name="description">The class resulting from a class with a trait added should have the combined set of properties of both, with the trait overriding properties of the host's extendsModel.</property>
            <property name="code" type="function">function anonymous() {
              CLASS({
                name: 'Host',
                package: 'nested.package.levels',
                extendsModel: 'nested.package.levels.HostBase',
                traits: ['different.package.TraitH']
              });
              var result = this.X.nested.package.levels.Host.create();

              this.logItems(result);
            }
            </property>
            <property name="tags">
              <i>web</i>
              <i>node</i>
            </property>
            <property name="master">3
tada
undefined
undefined
</property>
          </object>

          <object model="RegressionTest">
            <property name="name">Multiple Traits added to host class</property>
            <property name="description">The class resulting from a class with two traits added should have the combined set of properties of all three.</property>
            <property name="code" type="function">function anonymous() {
              CLASS({
                name: 'Host',
                package: 'nested.package.levels',
                extendsModel: 'nested.package.levels.HostBase',
                traits: ['different.package.TraitA', 'different.package.TraitB']
              });
              var result = this.X.nested.package.levels.Host.create();

              this.logItems(result);
            }
            </property>
            <property name="tags">
              <i>web</i>
              <i>node</i>
            </property>
            <property name="master">4
tada
1
2
</property>
          </object>

        </property>
      </object>

      <object model="UnitTest">
        <property name="name">Lazy DAO Test</property>
        <property name="async">true</property>
        <property name="code" type="function">function (ret) {
              var Abc = Model.create({
                name: 'Abc',
                properties: [
                  'a',
                  'b'
                ]
              });
                
              var src = this.foam.core.dao.ManuallyDelayedDAO.create({ delegate: [
                Abc.create({ a: 1, b: 'a'}),
                Abc.create({ a: 2, b: 'a'}),
                Abc.create({ a: 3, b: 'b'}),
                Abc.create({ a: 4, b: 'b'}),
                Abc.create({ a: 5, b: 'c'}),
                Abc.create({ a: 6, b: 'c'}),
                Abc.create({ a: 7, b: 'd'}),
                Abc.create({ a: 8, b: 'd'})
              ]});
      
              var cache = MDAO.create({ model: Abc });
      
              var dao = LazyCacheDAO.create({
                cache: cache,
                delegate: src,
                cacheOnSelect: true
              });

              function doJoin(ret) { src.join(ret); }
      
              var self = this;
              aseq(
                function(ret) {
                  cache.select(COUNT())(function(c) {
                    self.assert(c.count === 0, 'Cache should start empty.');
                    ret();
                  });
                },
                function(ret) {
                  dao.where(EQ(Abc.B, "a")).select(COUNT())(function(c) {
                    self.assert(c.count === 2, 'First select should get full results from network.');
                    ret();
                  });
                  src.join(function(){});
                },
                function(ret) {
                  cache.select(COUNT())(function(c) {
                    self.assert(c.count === 2, 'Cache should now contain all fetched rows from before.');
                    ret();
                  });
                },
                function(ret) {
                  dao.select(COUNT())(function(c) {
                    self.assert(c.count === 2, 'Select should return cache results if there are any.');
                    ret();
                  });
                },
                function(ret) {
                  // Wait till the "network" dao is finished.
                  src.join(ret)
                },
                function(ret) {
                  dao.select(COUNT())(function(c) {
                    self.assert(c.count === 8, 'Select should return the full set now.');
                    ret();
                  });
                  src.join(function(){});
                },
                function(ret) {
                  dao.delegate = NullDAO.create({});
                  dao.where(EQ(Abc.B, "c")).select(COUNT())(function(c) {
                    self.assert(c.count === 2, 'Should be able to answer a query even if the src dao is offline.');
                    ret();
                  });
                })(ret);
            }
        </property>
        <property name="tags">
          <i>web</i>
          <i>node</i>
        </property>
      </object>

    </property>
  </object>

</foam>
