Skip to content

Commit

Permalink
feat(facade/lang): add ES6 Array ponyfills
Browse files Browse the repository at this point in the history
  • Loading branch information
Hotell committed Jan 3, 2016
1 parent b4699fa commit fd953de
Show file tree
Hide file tree
Showing 3 changed files with 228 additions and 2 deletions.
1 change: 1 addition & 0 deletions ng-metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import './test/di/decorators.spec';
import './test/di/povider.spec';
import './test/util/decorators.spec';
import './test/reflection/reflection.spec';
import './test/facade/lang.spec';

describe( 'ng-metadata', ()=> {

Expand Down
62 changes: 60 additions & 2 deletions src/facade/lang.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,20 +149,78 @@ function _getFuncName( func: Function ): string {
const parsedFnStatement = /function\s*([^\s(]+)/.exec(stringify(func));
const [,name=''] = parsedFnStatement || [];

// if Function.name doesn't exist exec will find match otherwise return name property
return name || stringify(func);

}

/**
* controller instance of directive is exposed on jqLiteElement.data()
* under the name: `$` + Ctor + `Controller`
* @param name
* @returns {string}
*/
export function controllerKey( name: string ): string {
return '$' + name + 'Controller';
}
export function hasCtorInjectables( Type ): boolean {
return (Array.isArray( Type.$inject ) && Type.$inject.length !== 0);
}
export function firstToLowerCase( value: string ): string {
return value.charAt( 0 ).toLocaleLowerCase() + value.substring( 1 );
return _firstTo(value,String.prototype.toLowerCase);
}
export function firstToUpperCase( value: string ): string {
return value.charAt( 0 ).toUpperCase() + value.substring( 1 );
return _firstTo(value,String.prototype.toUpperCase);
}
function _firstTo( value: string, cb: Function ): string {
return cb.call( value.charAt( 0 ) ) + value.substring( 1 );
}


export function find(arr, predicate, ctx?) {
if ( isFunction( Array.prototype[ 'find' ] ) ) {
return arr.find( predicate, ctx );
}

ctx = ctx || this;
var length = arr.length;
var i;

if (!isFunction(predicate)) {
throw new TypeError(`${predicate} is not a function`);
}

for (i = 0; i < length; i++) {
if (predicate.call(ctx, arr[i], i, arr)) {
return arr[i];
}
}

return undefined;

}

export function findIndex(arr, predicate, ctx?) {
if (isFunction(Array.prototype['findIndex'])) {
return arr.findIndex(predicate, ctx);
}

if (!isFunction(predicate)) {
throw new TypeError('predicate must be a function');
}

var list = Object(arr);
var len = list.length;

if (len === 0) {
return -1;
}

for (var i = 0; i < len; i++) {
if (predicate.call(ctx, list[i], i, list)) {
return i;
}
}

return -1;
}
167 changes: 167 additions & 0 deletions test/facade/lang.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import {expect} from 'chai';
import {
resolveDirectiveNameFromSelector,
assign,
stringify,
hasCtorInjectables,
firstToLowerCase,
firstToUpperCase,
find,
findIndex
} from '../../src/facade/lang';

describe.only( `facade`, ()=> {

describe( 'makeSelector', ()=> {

it( 'should accept element selector and create camelCase from it', ()=> {

const selector = 'hello-world';
expect( resolveDirectiveNameFromSelector( selector ) ).to.equal( 'helloWorld' );

} );
it( 'should accept attribute selector and create camelCase from it', ()=> {

const selector = '[im-your-father]';
expect( resolveDirectiveNameFromSelector( selector ) ).to.equal( 'imYourFather' );

} );
it( 'should throw error when not valid element or attribute selector provided', ()=> {

let selector = 'yabba daba';

expect( ()=>resolveDirectiveNameFromSelector( selector ) ).to
.throw( 'Only selectors matching element names or base attributes are supported, got: yabba daba' );

} );

} );
describe( `assign`, ()=> {

it( `should extend object exactly as Object.assign`, ()=> {

const one = {foo:'yay'};
const two = {foo:'nay',boo:'low'};

const actual = assign(one,two);
const expected = {foo:'nay',boo:'low'};

expect( actual ).to.deep.equal( expected );
expect( assign( {}, { one: 1 }, { two: 2 } ) ).to.deep.equal( { one: 1, two: 2 } );

} );

} );

describe( 'stringify', ()=> {

it( 'should return name property if it exist on provided type', ()=> {

function foo() {}

function boo() {
return 'hello';
}

class Moo {}

expect( stringify( foo ) ).to.equal( 'foo' );
expect( stringify( boo ) ).to.equal( 'boo' );
expect( stringify( Moo ) ).to.equal( 'Moo' );

} );

it( 'should return first line string of function definition if the function is anonymous', ()=> {

let anonFn = function () {};
let anonFnMultiLine = function () {
console.log( 'yoo' );
return null;
};

expect( stringify(anonFn) ).to.equal( 'function () { }' );
expect( stringify(anonFnMultiLine) ).to.equal( 'function () {' );

} );

it( `should return string of provided type if it isn't a function`, ()=> {

const obj = { hello: 'world' };

expect( stringify( 'hello' ) ).to.equal( 'hello' );
expect( stringify( null ) ).to.equal( 'null' );
expect( stringify( undefined ) ).to.equal( 'undefined' );
expect( stringify( [ 1, 2 ] ) ).to.equal( `1,2` );
expect( stringify( obj ) ).to.equal( '[object Object]' );

} );

} );

describe( 'hasInjectables', ()=> {

it( 'should check if Type has $inject as array and its not empty', ()=> {

class Moo {
static $inject = [ 'hello' ];
}
class NoMames {
static $inject = [];
}
const obj = { $inject: null };
const name = 'jabba';

expect( hasCtorInjectables( Moo ) ).to.equal( true );
expect( hasCtorInjectables( NoMames ) ).to.equal( false );
expect( hasCtorInjectables( obj ) ).to.equal( false );
expect( hasCtorInjectables( name ) ).to.equal( false );

} );


} );

describe( 'firstLowerCase', function () {

it( 'should return string with first char lowercase', ()=> {

expect( firstToLowerCase( 'JediMaster' ) ).to.equal( 'jediMaster' );

} );

} );
describe( 'firstUpperCase', function () {

it( 'should return string with first char uppercase', ()=> {

expect( firstToUpperCase( 'jediMaster' ) ).to.equal( 'JediMaster' );

} );

} );

describe( `ES6 Array ponyfills`, ()=> {

it( `should find array item or undefined if not found`, ()=> {

let arr:any[] = [ 1, 2, 3, 4, 5 ];
let found = find( arr, ( el )=> el === 2 );
expect( found ).equal( 2 );

arr = [{name: 'adam'}, {name: 'eve'}, {name: 'john'}];
found = find(arr, (el)=>el.name === 'eve');
expect(found).to.deep.equal({name: 'eve'});

} );
it( `should find array item position or -1 if not found`, ()=> {

const arr = [10, 20, 30, 40];

expect( findIndex( arr, ( x )=>x === 30 ) ).to.equal( 2 );
expect( findIndex( arr, ( x )=>x === 'noop' ) ).to.equal( -1 );

} );

} );

} );

0 comments on commit fd953de

Please sign in to comment.