1
0
Fork 0
easejs/test/ClassBuilder/ErrorExtendTest.js

195 lines
5.7 KiB
JavaScript

/**
* Tests special handling of Error subtyping
*
* Copyright (C) 2016 Free Software Foundation, Inc.
*
* This file is part of GNU ease.js.
*
* ease.js is free software: you can redistribute it and/or modify
* it under the 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.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
require( 'common' ).testCase(
{
caseSetUp: function()
{
this.Sut = this.require( 'ClassBuilder' );
this.MethodWrapperFactory = this.require( 'MethodWrapperFactory' );
this.wrappers = this.require( 'MethodWrappers' ).standard;
this.util = this.require( 'util' );
this.errtypes = [
Error,
TypeError,
SyntaxError,
ReferenceError,
EvalError,
RangeError,
URIError,
];
this.ctors = [ '__construct', 'constructor' ];
},
setUp: function()
{
this.stubEctor = {
createCtor: function() {},
isError: function() { return true; },
};
// XXX: get rid of this disgusting mess; we're mid-refactor and all
// these dependencies should not be necessary for testing
this.builder = this.Sut(
this.require( 'warn' ).DismissiveHandler(),
this.require( '/MemberBuilder' )(
this.MethodWrapperFactory( this.wrappers.wrapNew ),
this.MethodWrapperFactory( this.wrappers.wrapOverride ),
this.MethodWrapperFactory( this.wrappers.wrapProxy ),
this.getMock( 'MemberBuilderValidator' )
),
this.require( '/VisibilityObjectFactoryFactory' ).fromEnvironment(),
this.stubEctor
);
},
/**
* Any determination as to whether we're extending an error should be
* left to the error constructor.
*
* Note that this test only ensures that the SUT will recognizs
* non-errors as such; the other tests that follow implicitly test the
* reverse.
*/
'Uses constructor generator for error extension determination': function()
{
var called = false;
this.stubEctor.isError = function() { return false; };
// should not be called
this.stubEctor.createCtor = function()
{
called = true;
};
// will invoke createCtor if the isError check fails
this.builder.build( Error, {} )();
this.assertOk( !called );
},
/**
* Simple verification that we're passing the correct data to the error
* constructor.
*/
'@each(errtypes) Produces error constructor': function( Type )
{
this.stubEctor.createCtor = function( supertype, name )
{
return function()
{
this.givenSupertype = supertype;
this.givenName = name;
};
};
var expected_name = 'ename',
result = this.builder.build( Type, {
__name: expected_name,
givenSupertype: '',
givenName: '',
} )();
this.assertEqual( Type, result.givenSupertype );
this.assertEqual( expected_name, result.givenName );
},
/**
* This is obvious, but since Error is a special case, let's just be
* sure.
*/
'@each(errtypes) Error subtype is instanceof parent': function( Type )
{
this.assertOk(
this.builder.build( Type, {} )() instanceof Type
);
},
/**
* By default, in ES5+ environments that support visibility objects will
* write to the private visibility object by default, unless the property
* is declared public.
*/
'Message and stack are public': function()
{
var expected_msg = 'expected msg',
expected_stack = 'expected stack';
this.stubEctor.createCtor = function( supertype, name )
{
return function()
{
this.message = expected_msg;
this.stack = expected_stack;
};
};
var result = this.builder.build( {}, {} )();
// will only be visible (in ES5 environments at least) if the
// properties are actually public
this.assertEqual( expected_msg, result.message );
this.assertEqual( expected_stack, result.stack );
},
/**
* The default constructor cannot be overridden---it isn't a method on
* the supertype at all; it's rather just a default
* implementation. However, a user can provide a method to be invoked
* after the generated constructor.
*/
'@each(ctors) Can override generated constructor': function( ctor )
{
var called_gen = false,
called_own = false;
this.stubEctor.createCtor = function( supertype, name, after )
{
return function()
{
called_gen = true;
after();
};
};
var dfn = {};
dfn[ ctor ] = function()
{
called_own = true;
};
var result = this.builder.build( {}, dfn )();
this.assertOk( called_gen );
this.assertOk( called_own );
},
} );