diff --git a/lib/FallbackVisibilityObjectFactory.js b/lib/FallbackVisibilityObjectFactory.js index 84d5f98..20c880c 100644 --- a/lib/FallbackVisibilityObjectFactory.js +++ b/lib/FallbackVisibilityObjectFactory.js @@ -22,3 +22,62 @@ * @package core */ + +/** + * Initializes fallback visibility object factory + * + * Unlike the standard visibility object, fallback does not create various + * layers. This is for the simple fact that setting a value on one of the layers + * is not visible to layers beneath it (its prototypes). Fallback is necessary + * if proxy support or emulation (via ES5 getters/setters) is unavailable. + */ +module.exports = exports = function FallbackVisibilityObjectFactory() +{ + // permit omitting 'new' keyword + if ( !( this instanceof exports ) ) + { + return new exports(); + } +}; + + +/** + * "Inherit" from VisibilityObjectFactory + */ +exports.prototype = require( __dirname + '/VisibilityObjectFactory' )(); + + +/** + * Do not create private visibility layer + * + * We're likely falling back because we cannot properly support the private + * visibility layer. Therefore, it will be omitted. + * + * @param {Object} atop_of will be returned, unmodified + * @param {Object} properties ignored + * + * @return {Object} provided object with no additional layer + */ +exports.prototype._createPrivateLayer = function( atop_of, properties ) +{ + return atop_of; +}; + + +/** + * Does not create property proxy + * + * The fallback implementation is used because proxies are not supported and + * cannot be emulated with getters/setters. + * + * @param {Object} base will be returned, unmodified + * @param {Object} dest ignored + * @param {Object} props ignored + * + * @return {Object} given base + */ +exports.prototype.createPropProxy = function( base, dest, props ) +{ + return base; +}; + diff --git a/lib/VisibilityObjectFactory.js b/lib/VisibilityObjectFactory.js index 963a678..da017e3 100644 --- a/lib/VisibilityObjectFactory.js +++ b/lib/VisibilityObjectFactory.js @@ -95,7 +95,8 @@ exports.prototype.setup = function setup( dest, properties, methods ) * Subtypes may override this method to alter the functionality of the private * visibility object (e.g. to prevent it from being created). * - * @param {Object} atop_of object to add private layer atop of + * @param {Object} atop_of object to add private layer atop of + * @param {Object} properties properties * * @return {Object} private layer with given object as prototype */ diff --git a/test/FallbackVisibilityObjectFactoryTest.js b/test/FallbackVisibilityObjectFactoryTest.js new file mode 100644 index 0000000..ab3faa5 --- /dev/null +++ b/test/FallbackVisibilityObjectFactoryTest.js @@ -0,0 +1,112 @@ +/** + * Tests fallback visibility object factory + * + * Copyright (C) 2010 Mike Gerwitz + * + * This file is part of ease.js. + * + * ease.js is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * @author Mike Gerwitz + * @package test + */ + + +var common = require( './common' ), + assert = require( 'assert' ), + + // SUT + FallbackVisibilityObjectFactory = + common.require( 'FallbackVisibilityObjectFactory' ), + + // parent of SUT + VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ), + + sut = FallbackVisibilityObjectFactory(), + + props = methods = { + 'public': {}, + 'protected': {}, + 'private': {}, + } +; + + +/** + * To keep with the spirit of ease.js, we should be able to instantiate + * VisibilityObjectFactory both with and without the 'new' keyword + * + * Consistency is key with these sorts of things. + */ +( function testCanInstantiateWithAndWithoutNewKeyword() +{ + // with 'new' keyword + assert.ok( + ( new FallbackVisibilityObjectFactory() ) + instanceof FallbackVisibilityObjectFactory, + "Should be able to instantiate FallbackVisibilityObjectFactory with " + + "'new' keyword" + ); + + // without 'new' keyword + assert.ok( + FallbackVisibilityObjectFactory() + instanceof FallbackVisibilityObjectFactory, + "Should be able to instantiate FallbackVisibilityObjectFactory " + + "without 'new' keyword" + ); +} )(); + + +/** + * VisibilityObjectFactory should be part of our prototype chain. + */ +( function testInheritsFromVisibilityObjectFactory() +{ + // check an instance, rather than __proto__, because older engines do not + // support it + assert.ok( + FallbackVisibilityObjectFactory() instanceof VisibilityObjectFactory, + "Fallback should inherit from VisibilityObjectFactory" + ); +} )(); + + +/** + * We're falling back because we do not support the private visibility layer (or + * any layers, for that matter). Ensure it's not created. + */ +( function testSetupMethodShouldNotAddPrivateLayer() +{ + var dest = {}, + obj = sut.setup( dest, props, methods ); + + assert.strictEqual( dest, obj, + "Private visibility layer is not added atop destination" + ); +} )(); + + +( function testCreatingPropertyProxyShouldSimplyReturnSelf() +{ + var base = {}, + dest = {}; + + assert.strictEqual( + sut.createPropProxy( base, dest, props ), + base, + "Creating property proxy should simply return original object" + ); +} )(); +