diff --git a/test/autotests/widgets-browser/state-freeze/index.marko b/test/autotests/widgets-browser/state-freeze/index.marko new file mode 100644 index 000000000..460152d88 --- /dev/null +++ b/test/autotests/widgets-browser/state-freeze/index.marko @@ -0,0 +1,9 @@ +class { + onInput(input) { + this.state = {} + } +} + +
+ Hello ${state.name || ''}! +
\ No newline at end of file diff --git a/test/autotests/widgets-browser/state-freeze/test.js b/test/autotests/widgets-browser/state-freeze/test.js new file mode 100644 index 000000000..8af6f140a --- /dev/null +++ b/test/autotests/widgets-browser/state-freeze/test.js @@ -0,0 +1,11 @@ +'use strict'; + +var expect = require('chai').expect; + +module.exports = function(helpers) { + var widget = helpers.mount(require('./index'), {}); + + expect(() => { + widget.state.foo = 'bar'; + }).to.throw(TypeError, 'Can\'t add property foo'); +}; \ No newline at end of file diff --git a/widgets/State.js b/widgets/State.js index 8ed4cc9e1..bccd968b8 100644 --- a/widgets/State.js +++ b/widgets/State.js @@ -2,7 +2,7 @@ var extend = require('raptor-util/extend'); function ensure(state, propertyName) { var proto = state.constructor.prototype; - if (!proto.hasOwnProperty(propertyName)) { + if (!(propertyName in proto)) { Object.defineProperty(proto, propertyName, { get: function() { return this.$__raw[propertyName]; @@ -25,11 +25,13 @@ function State(widget, initialState) { if (initialState) { for(var key in initialState) { - if (initialState.hasOwnProperty(key)) { + if (initialState[HAS_OWN_PROP](key)) { ensure(this, key); } } } + + Object.seal(this); } State.prototype = { @@ -49,15 +51,13 @@ State.prototype = { var rawState = this.$__raw; for (key in rawState) { - if (rawState.hasOwnProperty(key) && !newState.hasOwnProperty(key)) { + if (!(key in newState)) { state.$__set(key, undefined, false /* ensure:false */, false /* forceDirty:false */); } } for (key in newState) { - if (newState.hasOwnProperty(key)) { - state.$__set(key, newState[key], true /* ensure:true */, false /* forceDirty:false */); - } + state.$__set(key, newState[key], true /* ensure:true */, false /* forceDirty:false */); } }, $__set: function(name, value, shouldEnsure, forceDirty) {