2010-11-10 19:21:53 -05:00
|
|
|
/**
|
2010-11-10 20:45:33 -05:00
|
|
|
* Tests class module constructor creation
|
2010-11-10 19:21:53 -05:00
|
|
|
*
|
2013-12-20 01:11:26 -05:00
|
|
|
* Copyright (C) 2010, 2011, 2012, 2013 Mike Gerwitz
|
2010-11-10 19:21:53 -05:00
|
|
|
*
|
2013-12-22 09:37:21 -05:00
|
|
|
* This file is part of GNU ease.js.
|
2010-11-10 19:21:53 -05:00
|
|
|
*
|
2010-11-10 22:07:03 -05:00
|
|
|
* ease.js is free software: you can redistribute it and/or modify it under the
|
Relicensed under the GPLv3+
This project was originally LGPLv+-licensed to encourage its use in a community
that is largely copyleft-phobic. After further reflection, that was a mistake,
as adoption is not the important factor here---software freedom is.
When submitting ease.js to the GNU project, it was asked if I would be willing
to relicense it under the GPLv3+; I agreed happily, because there is no reason
why we should provide proprietary software any sort of edge. Indeed, proprietary
JavaScript is a huge problem since it is automatically downloaded on the user's
PC generally without them even knowing, and is a current focus for the FSF. As
such, to remain firm in our stance against proprietary JavaScript, relicensing
made the most sense for GNU.
This is likely to upset current users of ease.js. I am not sure of their
number---I have only seen download counts periodically on npmjs.org---but I know
there are at least a small number. These users are free to continue using the
previous LGPL'd releases, but with the understanding that there will be no
further maintenance (not even bug fixes). If possible, users should use the
GPL-licensed versions and release their software as free software.
Here comes GNU ease.js.
2013-12-20 01:00:35 -05:00
|
|
|
* terms of the GNU General Public License as published by the Free Software
|
|
|
|
* Foundation, either version 3 of the License, or (at your option) any later
|
|
|
|
* version.
|
2010-11-10 19:21:53 -05:00
|
|
|
*
|
2010-11-10 22:07:03 -05:00
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
Relicensed under the GPLv3+
This project was originally LGPLv+-licensed to encourage its use in a community
that is largely copyleft-phobic. After further reflection, that was a mistake,
as adoption is not the important factor here---software freedom is.
When submitting ease.js to the GNU project, it was asked if I would be willing
to relicense it under the GPLv3+; I agreed happily, because there is no reason
why we should provide proprietary software any sort of edge. Indeed, proprietary
JavaScript is a huge problem since it is automatically downloaded on the user's
PC generally without them even knowing, and is a current focus for the FSF. As
such, to remain firm in our stance against proprietary JavaScript, relicensing
made the most sense for GNU.
This is likely to upset current users of ease.js. I am not sure of their
number---I have only seen download counts periodically on npmjs.org---but I know
there are at least a small number. These users are free to continue using the
previous LGPL'd releases, but with the understanding that there will be no
further maintenance (not even bug fixes). If possible, users should use the
GPL-licensed versions and release their software as free software.
Here comes GNU ease.js.
2013-12-20 01:00:35 -05:00
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
2010-11-10 22:07:03 -05:00
|
|
|
*
|
Relicensed under the GPLv3+
This project was originally LGPLv+-licensed to encourage its use in a community
that is largely copyleft-phobic. After further reflection, that was a mistake,
as adoption is not the important factor here---software freedom is.
When submitting ease.js to the GNU project, it was asked if I would be willing
to relicense it under the GPLv3+; I agreed happily, because there is no reason
why we should provide proprietary software any sort of edge. Indeed, proprietary
JavaScript is a huge problem since it is automatically downloaded on the user's
PC generally without them even knowing, and is a current focus for the FSF. As
such, to remain firm in our stance against proprietary JavaScript, relicensing
made the most sense for GNU.
This is likely to upset current users of ease.js. I am not sure of their
number---I have only seen download counts periodically on npmjs.org---but I know
there are at least a small number. These users are free to continue using the
previous LGPL'd releases, but with the understanding that there will be no
further maintenance (not even bug fixes). If possible, users should use the
GPL-licensed versions and release their software as free software.
Here comes GNU ease.js.
2013-12-20 01:00:35 -05:00
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
2010-11-10 19:21:53 -05:00
|
|
|
*
|
|
|
|
* @author Mike Gerwitz
|
|
|
|
*/
|
|
|
|
|
2010-12-21 23:25:12 -05:00
|
|
|
var common = require( './common' ),
|
|
|
|
assert = require( 'assert' ),
|
|
|
|
Class = common.require( 'class' );
|
2010-11-10 19:21:53 -05:00
|
|
|
|
|
|
|
// these two variables are declared outside of the class to ensure that they
|
|
|
|
// will still be set even if the context of the constructor is wrong
|
|
|
|
var construct_count = 0,
|
2011-03-02 20:43:24 -05:00
|
|
|
construct_context = null,
|
2011-12-10 11:06:34 -05:00
|
|
|
construct_args = null,
|
2010-11-10 19:21:53 -05:00
|
|
|
|
|
|
|
// create a basic test class
|
2011-03-02 20:43:24 -05:00
|
|
|
Foo = Class.extend(
|
2010-11-10 19:21:53 -05:00
|
|
|
{
|
2011-03-02 20:43:24 -05:00
|
|
|
__construct: function()
|
|
|
|
{
|
|
|
|
construct_count++;
|
|
|
|
construct_context = this;
|
|
|
|
construct_args = arguments;
|
|
|
|
},
|
|
|
|
})
|
|
|
|
;
|
2010-11-10 19:29:56 -05:00
|
|
|
|
2010-11-10 19:21:53 -05:00
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
( Foo.prototype.__construct instanceof Function ),
|
|
|
|
"Provided properties should be copied to the new class prototype"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
construct_count,
|
|
|
|
0,
|
|
|
|
"Constructor should not be called before class is instantiated"
|
|
|
|
);
|
|
|
|
|
2010-11-10 19:29:56 -05:00
|
|
|
var args = [ 'foo', 'bar' ],
|
|
|
|
obj = new Foo( args[0], args[1] );
|
2010-11-10 19:21:53 -05:00
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
construct_count,
|
|
|
|
1,
|
|
|
|
"Constructor should be invoked once the class is instantiated"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.equal(
|
2011-03-02 20:43:24 -05:00
|
|
|
construct_context.__iid,
|
|
|
|
obj.__iid,
|
2010-11-10 19:21:53 -05:00
|
|
|
"Constructor should be invoked within the context of the class instance"
|
|
|
|
);
|
2010-11-10 19:29:56 -05:00
|
|
|
|
|
|
|
assert.notEqual(
|
2011-03-02 20:43:24 -05:00
|
|
|
construct_args,
|
2010-11-10 19:29:56 -05:00
|
|
|
null,
|
|
|
|
"Constructor arguments should be passed to the constructor"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.equal(
|
2011-03-02 20:43:24 -05:00
|
|
|
construct_args.length,
|
2010-11-10 19:29:56 -05:00
|
|
|
args.length,
|
|
|
|
"All arguments should be passed to the constructor"
|
|
|
|
);
|
|
|
|
|
|
|
|
// check the argument values
|
|
|
|
for ( var i = 0, len = args.length; i < len; i++ )
|
|
|
|
{
|
|
|
|
assert.equal(
|
2011-03-02 20:43:24 -05:00
|
|
|
construct_args[ i ],
|
2010-11-10 19:29:56 -05:00
|
|
|
args[ i ],
|
|
|
|
"Arguments should be passed to the constructor: " + i
|
|
|
|
);
|
|
|
|
}
|
2010-12-23 15:57:45 -05:00
|
|
|
|
|
|
|
var SubFoo = Foo.extend(
|
|
|
|
{
|
|
|
|
args: [ 'should', 'be', 'overwritten' ],
|
|
|
|
} );
|
|
|
|
|
|
|
|
construct_count = 0;
|
|
|
|
construct_context = null;
|
|
|
|
|
|
|
|
var args2 = [ 'fried', 'pickle' ],
|
|
|
|
subobj = new SubFoo( args2[ 0 ], args2[ 1 ] );
|
|
|
|
|
|
|
|
assert.equal(
|
|
|
|
construct_count,
|
|
|
|
1,
|
|
|
|
"Parent constructor should be called for subtype if not overridden"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.equal(
|
2011-03-02 20:43:24 -05:00
|
|
|
construct_context.__iid,
|
|
|
|
subobj.__iid,
|
2010-12-23 15:57:45 -05:00
|
|
|
"Parent constructor is run in context of the subtype"
|
|
|
|
);
|
|
|
|
|
|
|
|
// this should be implied by the previous test, but let's add it for some peace
|
|
|
|
// of mind
|
|
|
|
assert.ok(
|
2011-03-02 20:43:24 -05:00
|
|
|
( ( construct_args[ 0 ] === args2[ 0 ] )
|
|
|
|
&& ( construct_args[ 1 ] == args2[ 1 ] )
|
2010-12-23 15:57:45 -05:00
|
|
|
),
|
|
|
|
"Parent constructor sets values on subtype"
|
|
|
|
);
|
|
|
|
|
2010-12-28 19:05:53 -05:00
|
|
|
|
|
|
|
var subobj2 = SubFoo( args2[ 0 ], args2[ 1 ] );
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
( subobj2 instanceof SubFoo ),
|
|
|
|
"Constructor is self-invoking"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.equal(
|
2011-03-02 20:43:24 -05:00
|
|
|
construct_context.__iid,
|
|
|
|
subobj2.__iid,
|
2010-12-28 19:05:53 -05:00
|
|
|
"Self-invoking constructor is run in the context of the new object"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.ok(
|
2011-03-02 20:43:24 -05:00
|
|
|
( ( construct_args[ 0 ] === args2[ 0 ] )
|
|
|
|
&& ( construct_args[ 1 ] == args2[ 1 ] )
|
2010-12-28 19:05:53 -05:00
|
|
|
),
|
|
|
|
"Self-invoking constructor receives arguments"
|
|
|
|
);
|
|
|
|
|
2011-03-23 21:35:25 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* In PHP, one would prevent a class from being instantiated by declaring the
|
|
|
|
* constructor as protected or private. To me, this is cryptic. A better method
|
|
|
|
* would simply be to throw an exception. Perhaps, in the future, an alternative
|
|
|
|
* will be provided for consistency.
|
|
|
|
*
|
|
|
|
* The constructor must be public.
|
|
|
|
*/
|
|
|
|
( function testConstructorCannotBeDeclaredAsProtectedOrPrivate()
|
|
|
|
{
|
2011-12-04 19:26:53 -05:00
|
|
|
assert['throws']( function()
|
2011-03-23 21:35:25 -04:00
|
|
|
{
|
|
|
|
Class( { 'protected __construct': function() {} } );
|
|
|
|
}, TypeError, "Constructor cannot be protected" );
|
|
|
|
|
2011-12-04 19:26:53 -05:00
|
|
|
assert['throws']( function()
|
2011-03-23 21:35:25 -04:00
|
|
|
{
|
|
|
|
Class( { 'private __construct': function() {} } );
|
|
|
|
}, TypeError, "Constructor cannot be private" );
|
|
|
|
} )();
|
|
|
|
|
2012-01-19 23:21:04 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* When a constructor is instantiated, the instance's 'constructor' property is
|
|
|
|
* set to the constructor that was used to instantiate it. The same should be
|
|
|
|
* true for class instances.
|
|
|
|
*
|
|
|
|
* This will also be important for reflection.
|
|
|
|
*/
|
|
|
|
( function testConsructorPropertyIsProperlySetToClass()
|
|
|
|
{
|
|
|
|
var Foo = Class( {} );
|
|
|
|
|
|
|
|
assert.ok( Foo().constructor === Foo,
|
|
|
|
"Instance constructor should be set to class"
|
|
|
|
);
|
|
|
|
} )();
|
|
|
|
|