Skip to content

Commit 96c449a

Browse files
committed
Merge pull request #157 from Stabzs/master
Merge from Stabzs/master for #152
2 parents 2dd9b05 + 7861518 commit 96c449a

7 files changed

+310
-18
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
node_modules
22
components
33
bower_components
4+
coverage
45

56
# IntelliJ
67
.idea/

README.md

+29-6
Original file line numberDiff line numberDiff line change
@@ -105,22 +105,45 @@ There are four types of body renderings: trustedHtml', 'template', 'templateWith
105105
- directive
106106
- Will use the `toast.body` argument to represent the name of a directive that you want to render as the toast's body, else it will fallback to the template bound to the `'body-template': 'toasterBodyTmpl.html'` configuration option.
107107

108-
```js
108+
```js
109109
// The toast pop call, passing in a directive name to be rendered
110110
toaster.pop({
111-
type: 'info',
112-
body: 'bind-unsafe-html',
113-
bodyOutputType: 'directive'
111+
type: 'info',
112+
body: 'bind-unsafe-html',
113+
bodyOutputType: 'directive'
114114
});
115-
```
116-
```js
115+
```
116+
117+
```js
117118
// The directive that will be dynamically rendered
118119
.directive('bindUnsafeHtml', [function () {
119120
return {
120121
template: "<span style='color:orange'>Orange directive text!</span>"
121122
};
122123
}])
123124
```
125+
- Will use the `toast.directiveData` argument to accept data that will be bound to the directive's scope.
126+
127+
```js
128+
// The toast pop call, passing in a directive name to be rendered
129+
toaster.pop({
130+
type: 'info',
131+
body: 'bind-name',
132+
bodyOutputType: 'directive',
133+
directiveData: { name: 'Bob' }
134+
});
135+
```
136+
137+
```js
138+
// The directive that will be dynamically rendered
139+
.directive('bindName', [function () {
140+
return {
141+
template: "<span style='color:orange'>Hi {{directiveData.name}}!</span>"
142+
};
143+
}])
144+
```
145+
146+
There are additional documented use cases in these [tests](test/directiveTemplateSpec.js).
124147

125148
All four options can be configured either globally for all toasts or individually per toast.pop() call. If the `body-output-type` option is configured on the toast, it will take precedence over the global configuration for that toast instance.
126149

karma.conf.js

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Karma configuration
2+
// Generated on Wed Oct 21 2015 12:37:04 GMT-0600 (Mountain Daylight Time)
3+
4+
module.exports = function (config) {
5+
config.set({
6+
7+
// base path that will be used to resolve all patterns (eg. files, exclude)
8+
basePath: '',
9+
10+
11+
// frameworks to use
12+
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
13+
frameworks: ['jasmine'],
14+
15+
16+
// list of files / patterns to load in the browser
17+
files: [
18+
'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js',
19+
'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-mocks.js',
20+
'toaster.js',
21+
'test/**/*Spec.js'
22+
],
23+
24+
25+
// list of files to exclude
26+
exclude: [
27+
],
28+
29+
30+
// preprocess matching files before serving them to the browser
31+
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
32+
preprocessors: {
33+
'toaster.js': ['coverage']
34+
},
35+
36+
37+
// test results reporter to use
38+
// possible values: 'dots', 'progress'
39+
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
40+
reporters: ['progress', 'coverage'],
41+
42+
43+
// web server port
44+
port: 9876,
45+
46+
47+
// enable / disable colors in the output (reporters and logs)
48+
colors: true,
49+
50+
51+
// level of logging
52+
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
53+
logLevel: config.LOG_INFO,
54+
55+
56+
// enable / disable watching file and executing tests whenever any file changes
57+
autoWatch: true,
58+
59+
60+
// start these browsers
61+
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
62+
browsers: ['Chrome'],
63+
64+
plugins: [
65+
'karma-chrome-launcher',
66+
'karma-coverage',
67+
'karma-jasmine'
68+
],
69+
70+
// Continuous Integration mode
71+
// if true, Karma captures browsers, runs the tests and exits
72+
singleRun: false,
73+
74+
coverageReporter: {
75+
type: 'html',
76+
dir: 'coverage/'
77+
}
78+
});
79+
};

package.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@
1111
"type": "git",
1212
"url": "https://github.com/jirikavi/AngularJS-Toaster.git"
1313
},
14-
"dependencies": {
15-
},
14+
"dependencies": {},
1615
"devDependencies": {
1716
"angular": ">1.2.6",
18-
"angular-animate": "~1.2.8"
17+
"angular-animate": "~1.2.8",
18+
"angular-mocks": "^1.4.7",
19+
"karma": "^0.13.14",
20+
"karma-coverage": "^0.5.3",
21+
"karma-jasmine": "^0.3.6"
1922
}
2023
}

test/directiveTemplateSpec.js

+170
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/* global describe global it global beforeEach global angular global inject global expect */
2+
3+
'use strict';
4+
5+
describe('directiveTemplate', function () {
6+
createDirectives();
7+
8+
var toaster, scope, $compile;
9+
10+
beforeEach(function () {
11+
// load dependencies
12+
module('testApp');
13+
module('toaster')
14+
15+
// inject the toaster service
16+
inject(function (_toaster_, _$rootScope_, _$compile_) {
17+
toaster = _toaster_;
18+
scope = _$rootScope_;
19+
$compile = _$compile_;
20+
});
21+
});
22+
23+
it('should load and render the referenced directive template text', function () {
24+
var container = compileContainer();
25+
pop({ type: 'info', body: 'bind-template-only', bodyOutputType: 'directive' });
26+
27+
expect(container[0].innerText).toBe('×here is some great new text! It was brought in via directive!');
28+
});
29+
30+
it('should bind directiveData to the directive template', function () {
31+
var container = compileContainer();
32+
pop({ type: 'info', body: 'bind-template-with-data', bodyOutputType: 'directive', directiveData: { name: 'Bob' } });
33+
34+
expect(container[0].innerText).toBe('×Hello Bob');
35+
});
36+
37+
it('should parse type string directiveData to an object', function () {
38+
var container = compileContainer();
39+
pop({ type: 'info', body: 'bind-template-with-data', bodyOutputType: 'directive', directiveData: '{ "name": "Bob" }' });
40+
41+
expect(container[0].innerText).toBe('×Hello Bob');
42+
});
43+
44+
it('should render type number directiveData', function () {
45+
var container = compileContainer();
46+
pop({ type: 'info', body: 'bind-template-with-numeric-data', bodyOutputType: 'directive', directiveData: 2 });
47+
48+
expect(container[0].innerText).toBe('×1 + 1 = 2');
49+
});
50+
51+
it('should bind Attribute-restricted templates', function () {
52+
var container = compileContainer();
53+
pop({ type: 'info', body: 'bind-template-only', bodyOutputType: 'directive', directiveData: { name: 'Bob' } });
54+
55+
expect(container[0].innerText).toBe('×here is some great new text! It was brought in via directive!');
56+
});
57+
58+
it('should bind unrestricted templates', function () {
59+
var container = compileContainer();
60+
pop({ type: 'info', body: 'unrestricted-template', bodyOutputType: 'directive' });
61+
62+
expect(container[0].innerText).toBe('×Unrestricted Template');
63+
});
64+
65+
it('should not bind Element-restricted templates', function () {
66+
var container = compileContainer();
67+
pop({ type: 'info', body: 'element-template', bodyOutputType: 'directive' });
68+
69+
expect(container[0].innerText).toBe('×');
70+
expect(container[0].innerText).not.toBe('×Element Template');
71+
});
72+
73+
it('should not bind Class-restricted templates', function () {
74+
var container = compileContainer();
75+
pop({ type: 'info', body: 'class-template', bodyOutputType: 'directive' });
76+
77+
expect(container[0].innerText).toBe('×');
78+
expect(container[0].innerText).not.toBe('×Class Template');
79+
});
80+
81+
it('should throw an error if directiveName argument is not passed via body', function () {
82+
var container = compileContainer();
83+
var hasError = false;
84+
85+
expect(container[0].innerText).toBe('');
86+
87+
try {
88+
pop({ type: 'info', bodyOutputType: 'directive' });
89+
} catch (e) {
90+
expect(e.message).toBe('A valid directive name must be provided via the toast body argument when using bodyOutputType: directive');
91+
hasError = true;
92+
}
93+
94+
expect(container[0].innerText).toBe('×');
95+
expect(hasError).toBe(true);
96+
});
97+
98+
it('should throw an error if directiveName argument is an empty string', function () {
99+
var container = compileContainer();
100+
var hasError = false;
101+
102+
expect(container[0].innerText).toBe('');
103+
104+
try {
105+
pop({ type: 'info', body: '', bodyOutputType: 'directive' });
106+
} catch (e) {
107+
expect(e.message).toBe('A valid directive name must be provided via the toast body argument when using bodyOutputType: directive');
108+
hasError = true;
109+
}
110+
111+
expect(container[0].innerText).toBe('×');
112+
expect(hasError).toBe(true);
113+
});
114+
115+
it('should throw an error if the directive could not be found', function () {
116+
var hasError = false;
117+
118+
compileContainer();
119+
120+
try {
121+
pop({ type: 'info', body: 'non-existent-directive', bodyOutputType: 'directive' });
122+
} catch (e) {
123+
expect(e.message).toBe('non-existent-directive could not be found.');
124+
hasError = true;
125+
}
126+
127+
expect(hasError).toBe(true);
128+
});
129+
130+
131+
function compileContainer() {
132+
var element = angular.element('<toaster-container></toaster-container>');
133+
$compile(element)(scope);
134+
scope.$digest();
135+
136+
return element;
137+
}
138+
139+
function pop(params) {
140+
toaster.pop(params);
141+
142+
// force new toast to be rendered
143+
scope.$digest();
144+
}
145+
146+
function createDirectives() {
147+
angular.module('testApp', [])
148+
.directive('bindTemplateOnly', function () {
149+
return {
150+
restrict: 'A',
151+
template: 'here is some great new text! <span style="color:orange">It was brought in via directive!</span>'
152+
}
153+
})
154+
.directive('bindTemplateWithData', function () {
155+
return { template: 'Hello {{directiveData.name}}' }
156+
})
157+
.directive('bindTemplateWithNumericData', function () {
158+
return { template: '1 + 1 = {{directiveData}}' }
159+
})
160+
.directive('elementTemplate', function () {
161+
return { restrict: 'E', template: 'Element Template' }
162+
})
163+
.directive('classTemplate', function () {
164+
return { restrict: 'C', template: 'Class Template' }
165+
})
166+
.directive('unrestrictedTemplate', function () {
167+
return { template: 'Unrestricted Template' }
168+
});
169+
}
170+
})

0 commit comments

Comments
 (0)