From 459d5e967b5f4edb5a35f59ff230520ddc9a4f1c Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Wed, 29 Dec 2010 23:33:30 -0500 Subject: [PATCH] Classes now store implemented interfaces in a list (does not yet import methods) --- lib/class.js | 51 +++++++++++++++++++++++++++ test/test-class-implements.js | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 test/test-class-implements.js diff --git a/lib/class.js b/lib/class.js index 41c1a73..10c19be 100644 --- a/lib/class.js +++ b/lib/class.js @@ -39,6 +39,30 @@ exports.extend = function( base ) }; +/** + * Implements an interface or set of interfaces + * + * @param {...Interface} interfaces interfaces to implement + * + * @return {Class} new class containing interface abstractions + */ +exports.implements = function() +{ + var len = arguments.length, + dest = exports.extend(), + arg = null; + + // add each of the interfaces + for ( var i = 0; i < len; i++ ) + { + arg = arguments[ i ]; + dest.implemented.push( arg ); + } + + return dest; +}; + + /** * Determines whether the provided object is a class created through ease.js * @@ -102,6 +126,19 @@ exports.isInstanceOf = function( type, instance ) } catch ( e ) {} + var implemented = type.implemented; + if ( implemented instanceof Array ) + { + var i = implemented.length; + while ( i-- ) + { + if ( implemented[ i ] === type ) + { + return true; + } + } + } + return false; }; @@ -300,6 +337,7 @@ function setupProps( func, abstract_methods ) { attachAbstract( func, abstract_methods ); attachExtend( func ); + attachImplemented( func ); } @@ -399,6 +437,19 @@ function attachExtend( func ) } +/** + * Attaches empty list that may be populated with the implemented interfaces + * + * @param {Function} func function (class) to attach method to + * + * @return {undefined} + */ +function attachImplemented( func ) +{ + util.defineSecureProp( func, 'implemented', [] ); +} + + /** * Attaches partially applied isInstanceOf() method to class instance * diff --git a/test/test-class-implements.js b/test/test-class-implements.js new file mode 100644 index 0000000..7599e22 --- /dev/null +++ b/test/test-class-implements.js @@ -0,0 +1,65 @@ +/** + * Tests class interface implements method + * + * 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' ), + Class = common.require( 'class' ), + Interface = common.require( 'interface' ); + + +var Type = Interface.extend( { + 'abstract foo': [], +}); + +var Type2 = Interface.extend( { + 'abstract foo2': [], +}); + + +assert.ok( + ( Class.implements instanceof Function ), + "Class provides method to implement interfaces" +); + +var Foo = {}, + PlainFoo = Class.extend(); + +assert.ok( + ( PlainFoo.implemented instanceof Array ), + "Class contains empty list of implemented interfaces if " + + "none are implemented" +); + +assert.doesNotThrow( function() +{ + Foo = Class.implements( Type, Type2 ); +}, Error, "Class can implement interfaces" ); + +assert.ok( + ( ( Foo.implemented[ 0 ] === Type ) + && ( Foo.implemented[ 1 ] === Type2 ) + ), + "Class contains list of implemented interfaces" +); +