New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ng-directive-compiler-helper

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ng-directive-compiler-helper - npm Package Compare versions

Comparing version 0.0.4 to 1.0.0

.nvmrc

45

lib/ng-directive-compiler-helper.js

@@ -7,8 +7,9 @@ /* global angular */

* createCompiler
* @param {string} template string representing the template of directive
* @param {object} $rootScope the rootScope service
* @param {object} $compile the compile service
* @return {function} compiler function
* @param {string} template string representing the template of directive
* @param {object} $rootScope the rootScope service
* @param {object} $compile the compile service
* @param [{object}] driver optional driver object literal
* @return {function} compiler function
*/
function createCompiler(template, $rootScope, $compile) {
function createCompiler(template, $rootScope, $compile, driver) {
/**

@@ -19,6 +20,7 @@ * directive template compiler

* @param {function} callback function to fire when template has been compiled
* @param {function} driver function to fire when template has been compiled
* @return {object} object with element and scope properties
*/
return function(/*parentScope, attrs, callback*/) {
var args = Array.prototype.slice.call(arguments, 0),
return function (/* parentScope, attrs, callback */) {
var args = [].slice.call(arguments),
callback = angular.isFunction(args[args.length - 1]) ? args.pop() : angular.noop,

@@ -35,6 +37,31 @@ parentScope = args.shift() || {},

callback(extendedScope.$$childHead, element);
if(driver) {
var tempDriver = angular.copy(driver);
return { scope: extendedScope.$$childHead, element: element };
tempDriver.$ = element;
var newDriver =
Object
.keys(tempDriver)
.reduce(function (acc, curr) {
acc[curr] = typeof tempDriver[curr] === 'function' ? function () {
return arguments.length ?
tempDriver[curr].apply(tempDriver, arguments) :
tempDriver[curr].call(tempDriver, element);
} : tempDriver[curr];
return acc;
}, {});
callback(extendedScope.$$childHead, element, newDriver);
} else {
callback(extendedScope.$$childHead, element);
}
return {
scope: extendedScope.$$childHead,
element: element,
driver: newDriver
};
};
}

2

package.json
{
"name": "ng-directive-compiler-helper",
"author": "Arijus Šukys <argshook@gmail.com> (http://arijus.net)",
"version": "0.0.4",
"version": "1.0.0",
"description": "helper function for easier angularJS 1.x directive compilation in unit tests",

@@ -6,0 +6,0 @@ "main": "lib/ng-directive-compiler-helper.js",

@@ -33,3 +33,3 @@ [![Build Status](https://travis-ci.org/argshook/ng-directive-compiler-helper.svg?branch=master)](https://travis-ci.org/argshook/ng-directive-compiler-helper)

`compile` is now a function which can be used in two major ways:
`compile` is now a function which can be used in two ways:

@@ -117,5 +117,74 @@ 1. using *callbackFn* which is called after directive is compiled. *callbackFn* is passed with *scope* and *element* arguments

1. working with drivers
```js
// 1. define driver
let driver = {
parent: e => e.find('.imaginary-parent-with-3-children'); // e - reference to element, passed if no other arguments given,
children: parent => parent.children;
alsoChildren: function() { return this.$.children; } // this.$ - also reference to element
};
// 2. hook driver when creating compiler (as last argument)
let compile = createCompiler(templateString, $rootScope, $compile, driver);
// 3. use in tests
it('should contain 3 items', () => {
compile(function(scope, element, driver) { // <-- driver is passed as third argument
expect(driver.parent().length).toBe(1);
expect(driver.children(element).length).toBe(3);
expect(driver.alsoChildren().length).toBe(3);
})
});
```
testing like this should be cool because:
* driver can be reused for multiple tests, drying up the test suite
* no need to repeat selectors everywhere
* other more complicated logic can be reused (e.g. do some component setup for assertions)
### Few notes about drivers
* if driver method is called without arguments, it automatically gets element reference (but ONLY if there are no
arguments given):
> Note: the following examples assume you have `let compile = createCompiler` setup with driver.
```js
let driver = {
myTitle: e => e.find('.title-element')
}
it('should have title', () => {
compile((scope, element, driver) {
expect(driver.myTitle().text()).toBe('some text');
});
});
```
* if driver method is called with arguments, element reference is available through `this.$`:
```js
let driver = {
myListItem: function(n) {
return this.$.find('.my-list').get(n);
}
};
it('should have correct item', () => {
compile(function(scope, element, driver) {
expect(driver.myListItem(2).text()).toBe('my list item #3');
});
});
```
# More examples
i use this helper thing to test one of mine angular projects, you can check here: [argshook/orodarius](https://github.com/argshook/orodarius)
# Contributing
Please provide test for pull requests.
Please provide tests for pull requests.

@@ -122,0 +191,0 @@ Testing with karma:

@@ -1,20 +0,22 @@

describe('createCompiler', function() {
var createdCompiler,
mockTemplate = '<my-directive></my-directive>',
mockIsolateTemplate = '<my-isolate-directive></my-isolate-directive>';
/* global jasmine, describe, angular, it, expect, beforeEach, inject, createCompiler */
describe('createCompiler', function () {
var createdCompiler;
var mockTemplate = '<my-directive></my-directive>';
var mockIsolateTemplate = '<my-isolate-directive></my-isolate-directive>';
angular
.module('mockModule', ['ngMock'])
.directive('myDirective', function() {
.directive('myDirective', function () {
return {
restrict: 'E',
scope: true,
template: '<div>directive</div>'
template: '<div id="directive">directive <div class="child">Child content</div></div>'
};
})
.directive('myIsolateDirective', function() {
.directive('myIsolateDirective', function () {
return {
restrict: 'E',
scope: { isolateProperty: '@' },
template: '<div>isolate directive</div>',
template: '<div id="isolate-directive">isolate directive <button ng-click="isolateProperty = \'changed\'">Click me</button><div class="child">Isolate child content</div></div>',
};

@@ -25,4 +27,4 @@ });

describe('createCompiler()', function() {
it('should return function', function() {
describe('createCompiler()', function () {
it('should return function', function () {
expect(typeof createCompiler()).toBe('function');

@@ -32,16 +34,17 @@ });

describe('compiler with non-isolate scope directive', function() {
beforeEach(inject(function($rootScope, $compile) {
describe('compiler with non-isolate scope directive', function () {
beforeEach(inject(function ($rootScope, $compile) {
createdCompiler = createCompiler(mockTemplate, $rootScope, $compile);
}));
it('should return object with scope and element properties', function() {
it('should return object with scope and element properties', function () {
var compiledDirective = createdCompiler();
expect(compiledDirective.scope).toBeDefined();
expect(compiledDirective.element.text()).toBe('directive');
expect(compiledDirective.element.text()).toMatch('directive');
expect(compiledDirective.element[0].querySelector('.child').innerText).toBe('Child content');
});
describe('when one argument given', function() {
describe('which is function', function() {
it('should call that one argument as if it was a callback function', function() {
describe('when one argument given', function () {
describe('which is function', function () {
it('should call that one argument as if it was a callback function', function () {
expectCallbackToBeCalled();

@@ -51,7 +54,8 @@ });

describe('which is object', function() {
it('should return object with scope and element properties where scope is extended with first argument', function() {
describe('which is object', function () {
it('should return object with scope and element properties where scope is extended with first argument', function () {
var compiledDirective = createdCompiler({ someProperty: 'someValue' });
expect(compiledDirective.scope.someProperty).toBe('someValue');
expect(compiledDirective.element.text()).toBe('directive');
expect(compiledDirective.element.text()).toMatch('directive');
expect(compiledDirective.element[0].querySelector('.child').innerText).toBe('Child content');
});

@@ -61,5 +65,5 @@ });

describe('when two arguments given', function() {
it('should set parent scope from first argument', function() {
createdCompiler({ parentScope: 'value' }, function(scope) {
describe('when two arguments given', function () {
it('should set parent scope from first argument', function () {
createdCompiler({ parentScope: 'value' }, function (scope) {
expect(scope.parentScope).toBe('value');

@@ -69,5 +73,5 @@ });

describe('when type of second argument is', function() {
describe('function', function() {
it('should call second argument as if it was a callback function', function() {
describe('when type of second argument is', function () {
describe('function', function () {
it('should call second argument as if it was a callback function', function () {
expectCallbackToBeCalled();

@@ -77,4 +81,4 @@ });

describe('object', function() {
it('should return object with scope and element properties where element has attributes set from second argument', function() {
describe('object', function () {
it('should return object with scope and element properties where element has attributes set from second argument', function () {
var compiledDirective = createdCompiler({}, { 'some-attribute': 'someAttributeValue' });

@@ -87,5 +91,5 @@ expect(compiledDirective.element.attr('some-attribute')).toBe('someAttributeValue');

describe('when three arguments given', function() {
it('should set parent scope from first argument', function() {
createdCompiler({ parentScope: 'value' }, {}, function(scope) {
describe('when three arguments given', function () {
it('should set parent scope from first argument', function () {
createdCompiler({ parentScope: 'value' }, {}, function (scope) {
expect(scope.parentScope).toBe('value');

@@ -95,4 +99,4 @@ });

it('should set directive attributes from second argument', function() {
createdCompiler({}, { moustache: 'french', 'big-phat': 'azz' }, function(scope, element) {
it('should set directive attributes from second argument', function () {
createdCompiler({}, { moustache: 'french', 'big-phat': 'azz' }, function (scope, element) {
expect(element.attr('moustache')).toBe('french');

@@ -103,9 +107,13 @@ expect(element.attr('big-phat')).toBe('azz');

it('should call third argument as if it was a callback function', function() {
it('should call third argument as if it was a callback function', function () {
expectCallbackToBeCalled();
});
it('should return object with scope and element properties that are extended from 1st and 2nd args', function() {
var callbackSpy = jasmine.createSpy('createdCompilerCallbackSpy'),
compiledDirective = createdCompiler({ someProperty: 'someValue' }, { 'some-attribute': 'someAttributeValue' }, callbackSpy);
it('should return object with scope and element properties that are extended from 1st and 2nd args', function () {
var callbackSpy = jasmine.createSpy('createdCompilerCallbackSpy');
var compiledDirective = createdCompiler(
{ someProperty: 'someValue' },
{ 'some-attribute': 'someAttributeValue' },
callbackSpy
);

@@ -119,16 +127,17 @@ expect(callbackSpy).toHaveBeenCalled();

describe('compiler with isolate scope directive', function() {
beforeEach(inject(function($rootScope, $compile) {
describe('compiler with isolate scope directive', function () {
beforeEach(inject(function ($rootScope, $compile) {
createdCompiler = createCompiler(mockIsolateTemplate, $rootScope, $compile);
}));
it('should return object with scope and element properties', function() {
it('should return object with scope and element properties', function () {
var compiledDirective = createdCompiler();
expect(compiledDirective.scope).toBeDefined();
expect(compiledDirective.element.text()).toBe('isolate directive');
expect(compiledDirective.element.text()).toMatch('isolate directive');
expect(compiledDirective.element[0].querySelector('.child').innerText).toBe('Isolate child content');
});
describe('when one argument given', function() {
describe('which is function', function() {
it('should call that one argument as if it was a callback function', function() {
describe('when one argument given', function () {
describe('which is function', function () {
it('should call that one argument as if it was a callback function', function () {
expectCallbackToBeCalled();

@@ -138,7 +147,8 @@ });

describe('which is object', function() {
it('should return object with scope and element properties where scope is NOT extended with first argument', function() {
describe('which is object', function () {
it('should return object with scope and element properties where scope is NOT extended with first argument', function () {
var compiledDirective = createdCompiler({ parentScopeProperty: 'someValue' });
expect(compiledDirective.scope.parentScopeProperty).not.toBe('someValue');
expect(compiledDirective.element.text()).toBe('isolate directive');
expect(compiledDirective.element.text()).toMatch('isolate directive');
expect(compiledDirective.element[0].querySelector('.child').innerText).toBe('Isolate child content');
});

@@ -148,5 +158,5 @@ });

describe('when two arguments given', function() {
it('should ignore parent scope from first argument', function() {
createdCompiler({ isolateProperty: 'value' }, function(scope, element) {
describe('when two arguments given', function () {
it('should ignore parent scope from first argument', function () {
createdCompiler({ isolateProperty: 'value' }, function (scope, element) {
expect(scope.isolateProperty).not.toBeDefined();

@@ -156,5 +166,5 @@ });

describe('when type of second argument is', function() {
describe('function', function() {
it('should call second argument as if it was a callback function', function() {
describe('when type of second argument is', function () {
describe('function', function () {
it('should call second argument as if it was a callback function', function () {
expectCallbackToBeCalled();

@@ -164,4 +174,4 @@ });

describe('object', function() {
it('should return object with scope and element properties where element has attributes set from second argument', function() {
describe('object', function () {
it('should return object with scope and element properties where element has attributes set from second argument', function () {
var compiledDirective = createdCompiler({}, { 'some-attribute': 'someAttributeValue' });

@@ -174,5 +184,5 @@ expect(compiledDirective.element.attr('some-attribute')).toBe('someAttributeValue');

describe('when three arguments given', function() {
it('should ignore parent scope from first argument', function() {
createdCompiler({ isolateProperty: 'value' }, function(scope, element) {
describe('when three arguments given', function () {
it('should ignore parent scope from first argument', function () {
createdCompiler({ isolateProperty: 'value' }, function (scope, element) {
expect(scope.isolateProperty).not.toBeDefined();

@@ -182,4 +192,4 @@ });

it('should set isolate scope properties from attributes object', function() {
createdCompiler({}, { 'isolate-property': 'value' }, function(scope, element) {
it('should set isolate scope properties from attributes object', function () {
createdCompiler({}, { 'isolate-property': 'value' }, function (scope, element) {
expect(scope.isolateProperty).toBe('value');

@@ -189,10 +199,14 @@ });

it('should call third argument as if it was a callback function', function() {
it('should call third argument as if it was a callback function', function () {
expectCallbackToBeCalled();
});
it('should return object with scope and element properties', function() {
var callbackSpy = jasmine.createSpy('createdCompilerCallbackSpy'),
// since it's isolate scope directive, first argument should not extend scope properties
compiledDirective = createdCompiler({ someProperty: 'someValue' }, { 'some-attribute': 'someAttributeValue' }, callbackSpy);
it('should return object with scope and element properties', function () {
var callbackSpy = jasmine.createSpy('createdCompilerCallbackSpy');
// since it's isolate scope directive, first argument should not extend scope properties
var compiledDirective = createdCompiler(
{ someProperty: 'someValue' },
{ 'some-attribute': 'someAttributeValue' },
callbackSpy
);

@@ -206,2 +220,61 @@ expect(callbackSpy).toHaveBeenCalled();

describe('when compiled with driver', function() {
var driver = {
text: function(element) {
return element[0].querySelector('.child').innerText;
},
driveMeCrazy: function(element, scope) {
var click = document.createEvent('MouseEvent');
click.initEvent('click', true, true);
element[0].querySelector('button').dispatchEvent(click);
scope.$digest();
},
testicle: 'shit',
goodbye: function() {
// matching since apparently depending on platform it's
// either HTMLElement or HTMLUnknownElement
// (e.g. on linux it's former whereas on osx it's the latter)
expect(this.$.toString()).toMatch('\[object HTML.*Element\]');
return 'you little ' + this.testicle;
},
uppercase: function(me) {
return me.toUpperCase();
}
};
beforeEach(inject(function($rootScope, $compile) {
createdCompiler = createCompiler(mockIsolateTemplate, $rootScope, $compile, driver);
}));
it('should use last argument as driver', function() {
createdCompiler(function(scope, element, driver) {
expect(driver.text()).toBe('Isolate child content')
driver.driveMeCrazy(element, scope);
expect(scope.isolateProperty).toBe('changed')
});
});
it('should pass arguments to driver methods', function() {
createdCompiler(function(scope, element, driver) {
expect(driver.uppercase('trick')).toBe('TRICK');
});
});
it('should set expected context to driver methods', function() {
createdCompiler(function (scope, element, driver) {
expect(driver.goodbye()).toBe('you little shit');
expect(driver.testicle).toBe('shit');
});
});
it('should not change original driver object', function() {
expect(driver.$).toBe(undefined);
});
});
function expectCallbackToBeCalled() {

@@ -213,1 +286,2 @@ var callbackSpy = jasmine.createSpy('callbackSpy');

});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc