diff --git a/lib/interface.js b/lib/interface.js index 473304c..b54bb1c 100644 --- a/lib/interface.js +++ b/lib/interface.js @@ -22,7 +22,8 @@ * @package core */ -var util = require( './util' ); +var util = require( './util' ), + Class = require( './class' ); /** @@ -51,6 +52,9 @@ function extend() base = args.pop() || Interface, prototype = new base(); + // sanity check + inheritCheck( prototype ); + var new_interface = function() {}; util.propCopy( props, prototype, { @@ -77,6 +81,39 @@ function extend() } +/** + * Assures that the parent object is a valid object to inherit from + * + * This method allows inheriting from any object (note that it will likely cause + * errors if not an interface), but will place restrictions on objects like + * Classes that do not make sense to inherit from. This will provide a more + * friendly error, with suggestions on how to resolve the issue, rather than a + * cryptic error resulting from inheritance problems. + * + * This method will throw an exception if there is a violation. + * + * @param {Object} prototype prototype to check for inheritance flaws + * + * @return {undefined} + */ +function inheritCheck( prototype ) +{ + // if we're inheriting from another interface, then we're good + if ( prototype instanceof Interface ) + { + return; + } + + if ( Class.isClassInstance( prototype ) ) + { + throw new TypeError( + "Interfaces cannot extend from classes. Try creating an " + + "abstract class instead." + ); + } +} + + /** * Attaches extend method to the given function (interface) * diff --git a/test/test-interface-extend-permitted.js b/test/test-interface-extend-permitted.js new file mode 100644 index 0000000..21de47b --- /dev/null +++ b/test/test-interface-extend-permitted.js @@ -0,0 +1,39 @@ +/** + * Tests to ensure interfaces can only extend from interfaces + * + * Interface can extend from any object, so long as it only contains abstract + * methods. However, the system checks for situations that don't make sense in + * order to provide more meaningful error messages. + * + * 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' ); + + +assert.throws( function() +{ + Interface.extend( Class.extend(), {} ); +}, TypeError, "Interfaces cannot extend from classes" ); +