attribute.html revision 98c1ab155c0e2148f69291b1abe1007c9d5a08e8
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore <script type="text/javascript" src="/build/yui/yui.js"></script>
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore #console .yui3-console-entry {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore padding:2px;
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore min-height:0;
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore #console .yui3-console-entry-fail .yui3-console-entry-cat {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore background-color:red;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore #console .yui3-console-entry-pass .yui3-console-entry-cat {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore background-color:green;
9cdb1aa8d3a7901f789c2ad7a6ea00e804a9abebAdam Moore #console .yui3-console-entry-perf .yui3-console-entry-cat {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore background-color:blue;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore position:static;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore html, body {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore height:100%;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore YUI({useBrowserConsole:false}).use("dump", "attribute-complex", "base", "console", "test", function(Y) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore function areObjectsReallyEqual(o1, o2) {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore function Test(cfg, lazy, silentInit) {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore this._lazyAddAttrs = lazy;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore this._silentInit = silentInit;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Test.superclass.constructor.apply(this, arguments);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: "Foo",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore setter: function(n) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: "Bar",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore setter: function(n) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: false,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore setter: function(lock) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return lock;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: false
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: false
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: false
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: false
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: false,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore setter: function(val) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: null,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore setter: function(val) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return false;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: ['default'],
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore getter: function() {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return false;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore setter: function(g) {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore value: null,
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore setter: function(g) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore writeOnce: true,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore writeOnce: true,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore writeOnce: true,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore foo: function() {}
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore function AttrHost(config) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore AttrHost.superclass.constructor.apply(this, arguments);
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore value:"AVal",
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore validator: function(value) {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore return (value === undefined || Y.Lang.isString(value) || Y.Lang.isNumber(value));
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore writeOnce: true
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value:"DVal",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore readOnly: true
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value:"EVal",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore writeOnce: true
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore valueFn: function() {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore initOnly : {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore writeOnce:"initOnly"
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore function ExtendedAttrHost(config) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore AttrHost.superclass.constructor.apply(this, arguments);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore ExtendedAttrHost.NAME = "extendedAttrHost";
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore value:"ExtAVal"
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore value:"ExtBVal",
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore validator: function(value) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return ((value == undefined) || Y.Lang.isString(value));
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore value:"ExtDVal",
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore setter: function(val) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return (Y.Lang.isString(val)) ? val.toUpperCase() : val;
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore value:"ExtEVal",
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore getter: function(val) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return (Y.Lang.isString(val)) ? val.toLowerCase() : val;
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore value:"ExtFVal",
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore setter: function(val) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return (Y.Lang.isString(val)) ? val : Y.Attribute.INVALID_VALUE;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: 2222,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore setter: function(val) { // Should be ignored. Can't set setters for complex sub vals
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore return val + 10000;
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore valueFn:function(val) {
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore // Referring to H before it's set up
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return this.get("H") + 10;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore getter: function(val) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return val*5;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore getter: "_getI",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore setter: "_setI",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore validator: "_validateI"
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore PassThrough : {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore value: "passthrough",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore getter: function(val) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return this._passthrough;
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore setter: function(val) {
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore this._passthrough = val;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore getter: function(val) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.extend(ExtendedAttrHost, AttrHost, {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore _validateI : function(val, name) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if (name.indexOf(".") == -1) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return true;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore _getI : function(val, name) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if (name.indexOf(".") == -1) {
df39d9c816a02c79aa6a3436784de5bba0ef7075Adam Moore _setI : function(val, name) {
df39d9c816a02c79aa6a3436784de5bba0ef7075Adam Moore if (name.indexOf(".") == -1) {
2f03ba9e07559709925bfe6cb1b40c83aa810672Adam Moore var sharedEventTests = {
2f03ba9e07559709925bfe6cb1b40c83aa810672Adam Moore testEventPrevent : function() {
2f03ba9e07559709925bfe6cb1b40c83aa810672Adam Moore var expectedEvents = ["BeforeMyNewAVal", "AfterMyNewAVal", "BeforePREVENT"];
2f03ba9e07559709925bfe6cb1b40c83aa810672Adam Moore var actualEvents = [];
2f03ba9e07559709925bfe6cb1b40c83aa810672Adam Moore h.on("AChange", function(e) {
2f03ba9e07559709925bfe6cb1b40c83aa810672Adam Moore if (e.newVal == "PREVENT") {
03f9aefec605c500b64625110a955e65b900b100Adam Moore h.after("AChange", function(e) {
03f9aefec605c500b64625110a955e65b900b100Adam Moore h.set("A", "MyNewAVal");
03f9aefec605c500b64625110a955e65b900b100Adam Moore h.set("A", "PREVENT");
03f9aefec605c500b64625110a955e65b900b100Adam Moore Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
03f9aefec605c500b64625110a955e65b900b100Adam Moore testEventBasic : function() {
03f9aefec605c500b64625110a955e65b900b100Adam Moore var h = this.createHost({A:"MyAVal"});
03f9aefec605c500b64625110a955e65b900b100Adam Moore var expectedEvents = ["BeforeMyNewAVal", "AfterMyNewAVal"];
03f9aefec605c500b64625110a955e65b900b100Adam Moore var actualEvents = [];
f89b4dd628000da1b003539c3c181e6b9880de00Adam Moore h.on("AChange", function(e) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore h.after("AChange", function(e) {
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.set("A", "MyNewAVal");
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore testEventStopImmediatePropagation: function() {
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore var expectedEvents = ["Before1MyNewAVal", "Before2MyNewAVal", "After1MyNewAVal", "After2MyNewAVal", "Before1STOPAFTER", "Before2STOPAFTER", "After1STOPAFTER", "Before1STOPBEFORE"];
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore var actualEvents = [];
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.on("AChange", function(e) {
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore if (e.newVal == "STOPBEFORE") {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore h.after("AChange", function(e) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if (e.newVal == "STOPAFTER") {
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.on("AChange", function(e) {
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.after("AChange", function(e) {
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.set("A", "MyNewAVal");
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.set("A", "STOPAFTER");
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.set("A", "STOPBEFORE");
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore testEventValidationReadonlyWriteOnce : function() {
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore var h = this.createHost({A:"MyAVal", C:"MyCVal", D:"MyDVal"});
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore var expectedEvents = ["BeforeAChange"];
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore var actualEvents = [];
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.on("AChange", function() {
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore actualEvents.push("BeforeAChange");
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore h.after("AChange", function() {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore actualEvents.push("AfterAChange");
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore h.on("CChange", function() {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore actualEvents.push("BeforeCChange");
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.on("CChange", function() {
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore actualEvents.push("BeforeCChange");
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.on("DChange", function() {
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore actualEvents.push("BeforeDChange");
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.on("DChange", function() {
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore actualEvents.push("BeforeDChange");
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.set("A", 200); // Invalid - before fired, after not fired [ value can be changed to be made valid ]
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.set("C", "MyNewCVal"); // Write Once - neither before nor after are fired
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.set("D", "MyNewDVal"); // Read Only - neither before not after are fired
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore testEventModify : function() {
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore var h = this.createHost({A:"MyAVal"});
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.on("AChange", function(e) {
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.after("AChange", function(e) {
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore h.set("A", "MyNewAVal");
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore testEventSameValue : function() {
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore var h = this.createHost({A:"MyAVal"});
bc8660dcb747bedc141ca9061de83f6f32f8018fAdam Moore var expectedEvents = ["BeforeAChange",
5cbcc8e7f5c3e4ad283e5cb76520840300f81a0aAdam Moore "BeforeAChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforeAChange", "AfterAChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforeComplexChange", "AfterComplexChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforeComplexChange", "AfterComplexChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforeComplexChange", "AfterComplexChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforeComplexChange", "AfterComplexChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforeComplexChange", "AfterComplexChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforeComplexChange", "AfterComplexChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforePassThroughChange", "AfterPassThroughChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforePassThroughChange",
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore "BeforePassThroughChange", "AfterPassThroughChange"
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore var actualEvents = [];
h.on("AChange", function(e) {
actualEvents.push("BeforeAChange");
h.after("AChange", function(e) {
actualEvents.push("AfterAChange");
h.on("complexChange", function(e) {
actualEvents.push("BeforeComplexChange");
h.after("complexChange", function(e) {
actualEvents.push("AfterComplexChange");
if (!e.subAttrName) {
h.on("PassThroughChange", function(e) {
actualEvents.push("BeforePassThroughChange");
h.after("PassThroughChange", function(e) {
actualEvents.push("AfterPassThroughChange");
h.set("A", "MyAVal"); // No Change
h.set("A", "MyNewAVal"); // Change
h.set("complex.Z.A", 3); // Change, even though value of complex is unchanged, we don't deep compare objects.
h.set("complex", {A:1, B:2, C:3}); // Change, obj reference differs
h.set("complex", a); // Change, value changed
a.push("B");
h.set("complex", a); // Change, same object ref, but we don't know if contents changed, so fire event
h.set("PassThrough", "MyPassThrough");
h.set("PassThrough", "MyPassThrough");
h.set("PassThrough", "MyNewPassThrough");
Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
var h = this.createHost({
actualEvents.push("OnAChange");
actualEvents.push("OnInit");
actualEvents.push("AfterAChange");
actualEvents.push("AfterInit");
h.set("A", "Foo");
Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
var h = this.createHost();
var h = this.createHost({A:"MyAVal", B:"MyBVal", C:"MyCVal", D:"MyDVal", E:"MyEVal", DE:"MyDEVal"});
h.set("C", "MyNewCVal");
h.set("D", "MyNewDVal");
h.set("E", "MyNewEVal");
var h = this.createHost();
h.set("A", "MyNewAVal");
h.set("B", "MyNewBVal");
h.set("C", "MyNewCVal");
h.set("D", "MyNewDVal");
h.set("E", "MyNewEVal");
h.set("DE", "MyNewDEVal");
var h = this.createHost();
h.set("E", "MyNewEVal");
h.set("C", "MyNewCVal");
var h = this.createHost({E:"MyEVal"});
h.set("E", "MyNewEVal");
var h = this.createHost({ initOnly: "initOnlyVal"});
h.set("initOnly", "NewInitOnlyVal");
var h1 = this.createHost();
h1.set("initOnly", "InitOnlyVal");
var h = this.createHost();
h.set("AdHoc", "TestAdHoc");
h.addAttr("AdHoc", {
return val.toUpperCase();
h.set("AdHoc", "TestAdHocConfigured");
var h = this.createHost({A:"MyAVal", B:"MyBVal", C:"MyCVal", D:"MyDVal", E:"MyEVal", DE:"MyDEVal"});
h.set("A", "MyNewAVal");
h.set("B", "MyNewBVal");
h.set("C", "MyNewCVal");
h.set("D", "MyNewDVal");
h.set("E", "MyNewEVal");
h.set("DE", "MyNewDEVal");
h.reset("A");
h.reset("D");
h.reset();
var h = this.createHost();
areObjectsReallyEqual(expectedVals, h.getAttrs());
var h = this.createHost();
areObjectsReallyEqual(expectedVals, h.getAttrs(true));
var h = this.createHost();
h.set("A", "MyAVal");
h.set("A", 100);
h.set("B", "two");
h.set("B", 2);
h.set("B", false);
var h = this.createHost();
h.on("DChange", function(e) {
h.on("EChange", function(e) {
h.after("DChange", function(e) {
h.after("EChange", function(e) {
h.set("D", "MyNewDVal");
h.set("E", "MyNewEVal");
var h = this.createHost();
var val = h.get("complex");
Y.each(val, function(v, k) {
var h = this.createHost({
"complex.X.A": 11,
"complex.Y.A": 12,
"complex.Z.A": 13,
"complex.W.A": 14 // Does not exist, not allowed to set
var h = this.createHost();
var h = this.createHost();
var expectedEvents = ["Beforecomplex.X.A", "Aftercomplex.X.A", "Beforecomplex.Y.A", "Aftercomplex.Y.A", "Beforecomplex.Y", "Aftercomplex.Y"];
h.on("complexChange", function(e) {
h.after("complexChange", function(e) {
var h = this.createHost();
var expectedEvents = ["On AChange Y Broadcast", "After AChange Y Broadcast", "On BChange Y Broadcast", "After BChange Y Broadcast", "On BChange YUI Broadcast", "After BChange YUI Broadcast", "On CChange", "After CChange"];
Y.Global.on("attrHost:AChange", function() {
actualEvents.push("On AChange YUI Broadcast");
Y.Global.after("attrHost:AChange", function() {
actualEvents.push("After AChange YUI Broadcast");
Y.on("attrHost:AChange", function() {
actualEvents.push("On AChange Y Broadcast");
Y.after("attrHost:AChange", function() {
actualEvents.push("After AChange Y Broadcast");
Y.Global.on("attrHost:BChange", function() {
actualEvents.push("On BChange YUI Broadcast");
Y.Global.after("attrHost:BChange", function() {
actualEvents.push("After BChange YUI Broadcast");
Y.on("attrHost:BChange", function() {
actualEvents.push("On BChange Y Broadcast");
h.on("CChange", function() {
actualEvents.push("On CChange");
h.after("CChange", function() {
actualEvents.push("After CChange");
Y.after("attrHost:BChange", function() {
actualEvents.push("After BChange Y Broadcast");
Y.Global.on("attrHost:CChange", function() {
actualEvents.push("On CChange YUI Broadcast");
Y.Global.after("attrHost:CChange", function() {
actualEvents.push("After CChange YUI Broadcast");
Y.on("attrHost:CChange", function() {
actualEvents.push("On CChange Y Broadcast");
Y.after("attrHost:CChange", function() {
actualEvents.push("After CChange Y Broadcast");
h.set("A", "NewA");
h.set("B", "NewB");
h.set("C", "NewC");
Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
var h = this.createHost({A:5});
Y.Assert.areEqual("AVal", h.get("A")); // Numerical value validation failure should revert to default value
var h = this.createHost();
Y.on("attrHost:AChange", function() {
actualEvents.push("On AChange Y Broadcast");
Y.after("attrHost:AChange", function() {
actualEvents.push("After AChange Y Broadcast");
h.set("A", "NewA");
h.modifyAttr("A", {
return val.toUpperCase();
Y.Assert.fail("Setter should not be called");
Y.Assert.fail("Validator should not be called");
h.set("A", "NewAAfterGetterBroadCast");
h.set("A", 5);
h.modifyAttr("A", {
h.set("A", "NewAAfterReadOnly");
Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
var h = this.createHost();
var q = h._protectAttrs(AttrHost.ATTRS);
q.A.newprop = "new prop value";
q.A.value = "modified value";
basicTemplate = Y.merge(basicTemplate, sharedEventTests);
var h = this.createHost();
var h = this.createHost({A:"MyAVal", B:"MyBVal", C:"MyCVal", D:"MyDVal", E:"MyEVal", F:"MyFVal"});
h.set("C", "MyNewCVal");
h.set("D", "MyNewDVal");
h.set("E", "MyNewEVal");
var h = this.createHost();
h.set("A", "MyNewAVal");
h.set("B", "MyNewBVal");
h.set("C", "MyNewCVal");
h.set("D", "MyNewDVal");
h.set("E", "MyNewEVal");
h.set("F", "MyNewFVal");
h.set("DE", "MyNewDEVal");
var h = this.createHost();
h.set("AdHoc", "TestAdHoc");
var h = this.createHost({A:"MyAVal", B:"MyBVal", C:"MyCVal", D:"MyDVal", E:"MyEVal", F:"MyFVal", DE:"MyDEVal"});
h.set("A", "MyNewAVal");
h.set("B", "MyNewBVal");
h.set("C", "MyNewCVal");
h.set("D", "MyNewDVal");
h.set("E", "MyNewEVal");
h.set("F", "MyNewFVal");
h.set("DE", "MyNewDEVal");
h.reset("A");
h.reset("D");
h.reset();
var h = this.createHost();
areObjectsReallyEqual(expectedVals, h.getAttrs());
var h = this.createHost();
areObjectsReallyEqual(expectedVals, h.getAttrs(true));
var h = this.createHost();
h.set("A", "MyAVal");
h.set("A", 100);
h.set("B", "two");
h.set("B", 2);
h.set("B", true);
h.set("F", "MyNewFVal");
h.set("F", 3);
Y.Assert.areEqual("MyNewFVal", h.get("F")); // Validation should prevent the attribute from being set
var h = this.createHost();
var expectedEvents = ["BeforeTryDAgain", "AfterTRYDAGAIN", "BeforeTryEAgain", "Aftertryeagain" ]; // Last entry: e.newVal is not "get" normalized
h.on("DChange", function(e) {
h.on("EChange", function(e) {
h.after("DChange", function(e) {
h.after("EChange", function(e) {
h.set("D", "MyNewDVal");
h.set("E", "MyNewEVal");
Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
var h = this.createHost();
var val = h.get("complex");
Y.each(val, function(v, k) {
var h = this.createHost({
"complex.X.A": 11,
"complex.Y.A": 12,
"complex.Z.A": 13,
"complex.W.A": 14 // Does not exist, not allowed to set
var h = this.createHost();
var h = this.createHost();
var expectedEvents = ["Beforecomplex.X.A", "Aftercomplex.X.A", "Beforecomplex.Y.A", "Aftercomplex.Y.A", "Beforecomplex.Y", "Aftercomplex.Y"];
h.on("complexChange", function(e) {
h.after("complexChange", function(e) {
var h = this.createHost();
var h = this.createHost();
h.set("I", {a:7, b:8});
var h = this.createHost();
var expectedEvents = ["On AChange Y Broadcast", "After AChange Y Broadcast", "On BChange Y Broadcast", "After BChange Y Broadcast", "On BChange YUI Broadcast", "After BChange YUI Broadcast", "On CChange", "After CChange"];
Y.Global.on("extendedAttrHost:AChange", function() {
actualEvents.push("On AChange YUI Broadcast");
Y.Global.after("extendedAttrHost:AChange", function() {
actualEvents.push("After AChange YUI Broadcast");
Y.on("extendedAttrHost:AChange", function() {
actualEvents.push("On AChange Y Broadcast");
Y.after("extendedAttrHost:AChange", function() {
actualEvents.push("After AChange Y Broadcast");
Y.Global.on("extendedAttrHost:BChange", function() {
actualEvents.push("On BChange YUI Broadcast");
Y.Global.after("extendedAttrHost:BChange", function() {
actualEvents.push("After BChange YUI Broadcast");
Y.on("extendedAttrHost:BChange", function() {
actualEvents.push("On BChange Y Broadcast");
Y.after("extendedAttrHost:BChange", function() {
actualEvents.push("After BChange Y Broadcast");
h.on("CChange", function() {
actualEvents.push("On CChange");
h.after("CChange", function() {
actualEvents.push("After CChange");
Y.Global.on("extendedAttrHost:CChange", function() {
actualEvents.push("On CChange YUI Broadcast");
Y.Global.after("extendedAttrHost:CChange", function() {
actualEvents.push("After CChange YUI Broadcast");
Y.on("extendedAttrHost:CChange", function() {
actualEvents.push("On CChange Y Broadcast");
Y.after("extendedAttrHost:CChange", function() {
actualEvents.push("After CChange Y Broadcast");
h.set("A", "NewA");
h.set("B", "NewB");
h.set("C", "NewC");
Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
var h = this.createHost();
Y.on("extendedAttrHost:AChange", function() {
actualEvents.push("On AChange Y Broadcast");
Y.after("extendedAttrHost:AChange", function() {
actualEvents.push("After AChange Y Broadcast");
h.set("A", "NewA");
h.modifyAttr("A", {
return val.toUpperCase();
Y.Assert.fail("Setter should not be called");
Y.Assert.fail("Validator should not be called");
h.set("A", "NewAAfterGetterBroadCast");
h.set("A", 5);
h.modifyAttr("A", {
h.set("A", "NewAAfterReadOnly");
Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
var h = this.createHost();
h.on("ZChange", function() {
actualEvents.push("BeforeZChange");
h.after("ZChange", function() {
actualEvents.push("AfterZChange");
h.set("Z", "MyZ");
h.set("Z", "MYZ");
Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
extendedTemplate = Y.merge(extendedTemplate, sharedEventTests);
t.getAttrs();
t.getAttrs();
Y.log("Construction Time Populated (lazy): " + ((end-start)/n), "perf");
Y.log("Construction Time (lazy and silent init): " + ((end-start)/n), "perf");
suite.add(new Y.Test.Case(extendedTemplate)); // run twice, just to make sure static class state not modified