diff --git a/docs/angular.filter.ngdoc b/docs/angular.filter.ngdoc
index 9d1191c5..5d4f5940 100644
--- a/docs/angular.filter.ngdoc
+++ b/docs/angular.filter.ngdoc
@@ -46,12 +46,13 @@ You can use these variables in the function:
the DOM in addition to transforming the input.
-@exampleDescription
+@example
The following example filter reverses a text string. In addition, it conditionally makes the
text upper-case (to demonstrate optional arguments) and assigns color (to demonstrate DOM
modification).
-@example
+
+ Formatted:
+
+
-Stored:
-
-{{data}}
+ Stored:
+
+ {{data}}
+
Let's try this simple notify service, injected into the controller...
- - -Let's try this simple notify service, injected into the controller...
+ + +src\n' + - '
src'); - }); - }); - describe('h', function(){ it('should render using function', function(){ diff --git a/docs/spec/ngdocSpec.js b/docs/spec/ngdocSpec.js index d912bf3a..69bb5db3 100644 --- a/docs/spec/ngdocSpec.js +++ b/docs/spec/ngdocSpec.js @@ -74,12 +74,6 @@ describe('ngdoc', function(){ }); }); - it('should not remove extra line breaks', function(){ - var doc = new Doc('@example\nA\n\nB'); - doc.parse(); - expect(doc.example).toEqual('A\n\nB'); - }); - it('should parse filename', function(){ var doc = new Doc('@name friendly name', 'docs/a.b.ngdoc', 1); doc.parse(0); @@ -128,32 +122,14 @@ describe('ngdoc', function(){ }); }); - describe('scenario', function(){ - it('should render from @example/@scenario and
<angular/>
'); }); it('should not replace anything in, but escape the html escape the content', function(){
- expect(markdown('bah x\n\nangular.k\n
\n asdf x')).
+ expect(new Doc().markdown('bah x\n\nangular.k\n
\n asdf x')).
toEqual(
'bah x
' +
'\n' +
@@ -163,7 +139,7 @@ describe('ngdoc', function(){
});
it('should replace text between two tags', function() {
- expect(markdown('x
# Oneb
')).
+ expect(new Doc().markdown('x
# Oneb
')).
toMatch('One
some\n text');
+ expect(doc.example).toEqual('text {{ abc }}
');
});
- it('should alias @exampleDescription to @exampleDesc', function(){
- var doc = new Doc('@exampleDesc some\n text');
- doc.ngdoc = "filter";
- doc.parse();
- expect(doc.html()).toContain('some\n text');
+ it('should support doc:example', function(){
+ var doc = new Doc('@ngdoc overview\n@example \n' +
+ '\n' +
+ ' \n' +
+ ' \n' +
+ ' ').parse();
+ var html = doc.html();
+ expect(html).toContain('<escapeme> ');
+ expect(html).toContain('<scenario> ');
+ expect(doc.scenarios).toEqual(['']);
});
-
- it('should render description in related method', function(){
- var doc = new Doc('').parse();
- doc.ngdoc = 'service';
- doc.methods = [
- new Doc('@ngdoc method\n@exampleDescription MDesc\n@example MExmp').parse()];
- doc.properties = [
- new Doc('@ngdoc property\n@exampleDescription PDesc\n@example PExmp').parse()];
- expect(doc.html()).toContain('MDesc
' +
- 'MExmp
');
- expect(doc.html()).toContain('PDesc
' +
- 'PExmp
');
- });
-
});
describe('@depricated', function() {
diff --git a/docs/src/dom.js b/docs/src/dom.js
index 7708cbc9..4210d687 100644
--- a/docs/src/dom.js
+++ b/docs/src/dom.js
@@ -74,25 +74,8 @@ DOM.prototype = {
});
},
- example: function(description, source, scenario) {
- if (description || source || scenario) {
- this.h('Example', function(){
- if (description)
- this.html(description);
- if (scenario === false) {
- this.code(source);
- } else {
- this.tag('doc:example', function(){
- if (source) this.tag('doc:source', source);
- if (scenario) this.tag('doc:scenario', scenario);
- });
- }
- });
- }
- },
-
h: function(heading, content, fn){
- if (content==undefined || content && content.legth == 0) return;
+ if (content==undefined || (content instanceof Array && content.length == 0)) return;
this.headingDepth++;
this.tag('h' + this.headingDepth, heading);
var className = typeof heading == 'string'
diff --git a/docs/src/ngdoc.js b/docs/src/ngdoc.js
index a3a037cd..d90f8d3d 100644
--- a/docs/src/ngdoc.js
+++ b/docs/src/ngdoc.js
@@ -7,7 +7,6 @@ var DOM = require('dom.js').DOM;
var htmlEscape = require('dom.js').htmlEscape;
var NEW_LINE = /\n\r?/;
-exports.markdown = markdown;
exports.trim = trim;
exports.metadata = metadata;
exports.scenarios = scenarios;
@@ -25,6 +24,11 @@ function Doc(text, file, line) {
this.file = file;
this.line = line;
}
+ this.scenarios = this.scenarios || [];
+ this.requires = this.requires || [];
+ this.param = this.param || [];
+ this.properties = this.properties || [];
+ this.methods = this.methods || [];
}
Doc.METADATA_IGNORE = (function(){
var words = require('fs').readFileSync(__dirname + '/ignore.words', 'utf8');
@@ -53,16 +57,53 @@ Doc.prototype = {
return words.join(' ');
},
+ markdown: function (text) {
+ var self = this;
+ var IS_URL = /^(https?:\/\/|ftps?:\/\/|mailto:)/;
+ var IS_ANGULAR = /^angular\./;
+ if (!text) return text;
+ var parts = text.split(/([\s\S]*?<\/pre>|[\s\S]*?<\/doc:example>)/),
+ match;
+
+ parts.forEach(function(text, i){
+ if (text.match(/^/)) {
+ text = text.replace(/^([\s\S]*)<\/pre>/mi, function(_, content){
+ return '' +
+ content.replace(//g, '>') +
+ '
';
+ });
+ } else if (text.match(/^/)) {
+ text = text.replace(/()([\s\S]*)(<\/doc:source>)/mi,
+ function(_, before, content, after){
+ return before + htmlEscape(content) + after;
+ });
+ text = text.replace(/()([\s\S]*)(<\/doc:scenario>)/mi,
+ function(_, before, content, after){
+ self.scenarios.push(content);
+ return before + htmlEscape(content) + after;
+ });
+ } else {
+ text = text.replace(/ /gm, '<angular/>');
+ text = text.replace(/{@link ([^\s}]+)((\s|\n)+(.+?))?\s*}/gm,
+ function(_all, url, _2, _3, title){
+ return ''
+ + (url.match(IS_ANGULAR) ? '' : '')
+ + (title || url)
+ + (url.match(IS_ANGULAR) ? '' : '')
+ + '';
+ });
+ text = new Showdown.converter().makeHtml(text);
+ }
+ parts[i] = text;
+ });
+ return parts.join('');
+ },
+
parse: function(){
var atName;
var atText;
var match;
var self = this;
- this.scenarios = [];
- this.requires = [];
- this.param = [];
- this.properties = [];
- this.methods = [];
self.text.split(NEW_LINE).forEach(function(line){
if (match = line.match(/^\s*@(\w+)(\s+(.*))?/)) {
// we found @name ...
@@ -82,9 +123,9 @@ Doc.prototype = {
this.id = this.id // if we have an id just use it
|| (((this.file||'').match(/.*\/([^\/]*)\.ngdoc/)||{})[1]) // try to extract it from file name
|| this.name; // default to name
- this.description = markdown(this.description);
- this['this'] = markdown(this['this']);
- this.exampleDescription = markdown(this.exampleDescription || this.exampleDesc);
+ this.description = this.markdown(this.description);
+ this.example = this.markdown(this.example);
+ this['this'] = this.markdown(this['this']);
return this;
function flush(){
@@ -98,7 +139,7 @@ Doc.prototype = {
}
var param = {
name: match[5] || match[4],
- description:markdown(text.replace(match[0], match[7])),
+ description:self.markdown(text.replace(match[0], match[7])),
type: match[1],
optional: !!match[2],
'default':match[6]
@@ -111,18 +152,10 @@ Doc.prototype = {
}
self.returns = {
type: match[1],
- description: markdown(text.replace(match[0], match[2]))
+ description: self.markdown(text.replace(match[0], match[2]))
};
- } else if(atName == 'description') {
- text.replace(/([\s\S]*?)<\/doc:scenario>/gmi,
- function(_, scenario){
- self.scenarios.push(scenario);
- });
- self.description = text;
} else if(atName == 'requires') {
self.requires.push(text);
- } else if(atName == 'scenario') {
- self.scenarios.push(text);
} else if(atName == 'property') {
var match = text.match(/^({(\S+)}\s*)?(\S+)(\s+(.*))?/);
if (!match) {
@@ -154,7 +187,7 @@ Doc.prototype = {
throw new Error("Don't know how to format @ngdoc: " + self.ngdoc);
}).call(self, dom);
- dom.example(self.exampleDescription, self.example, self.scenarios[0]);
+ dom.h('Example', self.example, dom.html);
});
return dom.toString();
@@ -407,13 +440,13 @@ Doc.prototype = {
dom.h(method.shortName + '(' + signature.join(', ') + ')', method, function(){
dom.html(method.description);
method.html_usage_parameters(dom);
- dom.example(method.exampleDescription, method.example, false);
+ dom.h('Example', method.example, dom.html);
});
});
dom.h('Properties', this.properties, function(property){
dom.h(property.name, function(){
dom.text(property.description);
- dom.example(property.exampleDescription, property.example, false);
+ dom.h('Example', property.example, dom.html);
});
});
},
@@ -436,47 +469,6 @@ Doc.prototype = {
//////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////
-function markdown (text) {
- var IS_URL = /^(https?:\/\/|ftps?:\/\/|mailto:)/;
- var IS_ANGULAR = /^angular\./;
- if (!text) return text;
- var parts = text.split(/([\s\S]*?<\/pre>|[\s\S]*?<\/doc:example>)/),
- match;
-
- parts.forEach(function(text, i){
- if (text.match(/^/)) {
- text = text.replace(/^([\s\S]*)<\/pre>/mi, function(_, content){
- return '' +
- content.replace(//g, '>') +
- '
';
- });
- } else if (text.match(/^/)) {
- text = text.replace(/()([\s\S]*)(<\/doc:source>)/mi,
- function(_, before, content, after){
- return before + htmlEscape(content) + after;
- });
- text = text.replace(/()([\s\S]*)(<\/doc:scenario>)/mi,
- function(_, before, content, after){
- return before + htmlEscape(content) + after;
- });
- } else {
- text = text.replace(/ /gm, '<angular/>');
- text = text.replace(/{@link ([^\s}]+)((\s|\n)+(.+?))?\s*}/gm,
- function(_all, url, _2, _3, title){
- return ''
- + (url.match(IS_ANGULAR) ? '' : '')
- + (title || url)
- + (url.match(IS_ANGULAR) ? '' : '')
- + '';
- });
- text = new Showdown.converter().makeHtml(text);
- }
- parts[i] = text;
- });
- return parts.join('');
-};
-
//////////////////////////////////////////////////////////
function scenarios(docs){
var specs = [];
diff --git a/src/Angular.js b/src/Angular.js
index 2812c926..de2de30d 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -484,14 +484,18 @@ function map(obj, iterator, context) {
* @returns {number} The size of `obj` or `0` if `obj` is neither an object or an array.
*
* @example
- * Number of items in array: {{ [1,2].$size() }}
- * Number of items in object: {{ {a:1, b:2, c:3}.$size() }}
- *
- * @scenario
- it('should print correct sizes for an array and an object', function() {
- expect(binding('[1,2].$size()')).toBe('2');
- expect(binding('{a:1, b:2, c:3}.$size()')).toBe('3');
- });
+ *
+ *
+ * Number of items in array: {{ [1,2].$size() }}
+ * Number of items in object: {{ {a:1, b:2, c:3}.$size() }}
+ *
+ *
+ * it('should print correct sizes for an array and an object', function() {
+ * expect(binding('[1,2].$size()')).toBe('2');
+ * expect(binding('{a:1, b:2, c:3}.$size()')).toBe('3');
+ * });
+ *
+ *
*/
function size(obj) {
var size = 0, key;
@@ -556,17 +560,19 @@ function isLeafNode (node) {
* @returns {*} The copy or updated `destination` if `destination` was specified.
*
* @example
- Salutation:
- Name:
-
-
+ *
+ *
+ Salutation:
+ Name:
+
+
- The master object is NOT equal to the form object.
+ The master object is NOT equal to the form object.
- master={{master}}
- form={{form}}
-
- * @scenario
+ master={{master}}
+ form={{form}}
+ *
+ *
it('should print that initialy the form object is NOT equal to master', function() {
expect(element('.doc-example input[name=master.salutation]').val()).toBe('Hello');
expect(element('.doc-example input[name=master.name]').val()).toBe('world');
@@ -577,6 +583,8 @@ function isLeafNode (node) {
element('.doc-example button').click();
expect(element('.doc-example span').css('display')).toBe('none');
});
+ *
+ *
*/
function copy(source, destination){
if (!destination) {
@@ -633,27 +641,31 @@ function copy(source, destination){
* @returns {boolean} True if arguments are equal.
*
* @example
- Salutation:
- Name:
-
+ *
+ *
+ Salutation:
+ Name:
+
- The greeting object is
- NOT equal to
- {salutation:'Hello', name:'world'}.
+ The greeting object is
+ NOT equal to
+ {salutation:'Hello', name:'world'}.
- greeting={{greeting}}
+ greeting={{greeting}}
+ *
+ *
+ it('should print that initialy greeting is equal to the hardcoded value object', function() {
+ expect(element('.doc-example input[name=greeting.salutation]').val()).toBe('Hello');
+ expect(element('.doc-example input[name=greeting.name]').val()).toBe('world');
+ expect(element('.doc-example span').css('display')).toBe('none');
+ });
- @scenario
- it('should print that initialy greeting is equal to the hardcoded value object', function() {
- expect(element('.doc-example input[name=greeting.salutation]').val()).toBe('Hello');
- expect(element('.doc-example input[name=greeting.name]').val()).toBe('world');
- expect(element('.doc-example span').css('display')).toBe('none');
- });
-
- it('should say that the objects are not equal when the form is modified', function() {
- input('greeting.name').enter('kitty');
- expect(element('.doc-example span').css('display')).toBe('inline');
- });
+ it('should say that the objects are not equal when the form is modified', function() {
+ input('greeting.name').enter('kitty');
+ expect(element('.doc-example span').css('display')).toBe('inline');
+ });
+ *
+ *
*/
function equals(o1, o2) {
if (o1 == o2) return true;
diff --git a/src/Compiler.js b/src/Compiler.js
index c2c56650..472ec625 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -139,40 +139,44 @@ Compiler.prototype = {
* @element ANY
* @param {integer|string=} [priority=0] priority integer, or FIRST, LAST constant
*
- * @exampleDescription
+ * @example
* try changing the invoice and see that the Total will lag in evaluation
* @example
- TOTAL: without ng:eval-order {{ items.$sum('total') | currency }}
- TOTAL: with ng:eval-order {{ items.$sum('total') | currency }}
-
-
- QTY
- Description
- Cost
- Total
-
-
-
-
-
-
- {{item.total = item.qty * item.cost | currency}}
- X
-
-
- add
- {{ items.$sum('total') | currency }}
-
-
- *
- * @scenario
- it('should check ng:format', function(){
- expect(using('.doc-example-live div:first').binding("items.$sum('total')")).toBe('$9.99');
- expect(using('.doc-example-live div:last').binding("items.$sum('total')")).toBe('$9.99');
- input('item.qty').enter('2');
- expect(using('.doc-example-live div:first').binding("items.$sum('total')")).toBe('$9.99');
- expect(using('.doc-example-live div:last').binding("items.$sum('total')")).toBe('$19.98');
- });
+
+
+ TOTAL: without ng:eval-order {{ items.$sum('total') | currency }}
+ TOTAL: with ng:eval-order {{ items.$sum('total') | currency }}
+
+
+ QTY
+ Description
+ Cost
+ Total
+
+
+
+
+
+
+ {{item.total = item.qty * item.cost | currency}}
+ X
+
+
+ add
+ {{ items.$sum('total') | currency }}
+
+
+
+
+ it('should check ng:format', function(){
+ expect(using('.doc-example-live div:first').binding("items.$sum('total')")).toBe('$9.99');
+ expect(using('.doc-example-live div:last').binding("items.$sum('total')")).toBe('$9.99');
+ input('item.qty').enter('2');
+ expect(using('.doc-example-live div:first').binding("items.$sum('total')")).toBe('$9.99');
+ expect(using('.doc-example-live div:last').binding("items.$sum('total')")).toBe('$19.98');
+ });
+
+
*/
templatize: function(element, elementIndex, priority){
diff --git a/src/Scope.js b/src/Scope.js
index aef2706e..a73375ab 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -202,7 +202,7 @@ function errorHandlerFor(element, error) {
* @returns {Object} Newly created scope.
*
*
- * @exampleDescription
+ * @example
* This example demonstrates scope inheritance and property overriding.
*
* In this example, the root scope encompasses the whole HTML DOM tree. This scope has `salutation`,
@@ -216,27 +216,29 @@ function errorHandlerFor(element, error) {
* - The child scope inherits the salutation property from the root scope.
* - The $index property does not leak from the child scope to the root scope.
*
- * @example
-
- -
- {{$index}}: {{salutation}} {{name}}!
-
-
-
- $index={{$index}}
- salutation={{salutation}}
- name={{name}}
-
- @scenario
- it('should inherit the salutation property and override the name property', function() {
- expect(using('.doc-example-live').repeater('li').row(0)).
- toEqual(['0', 'Hello', 'World']);
- expect(using('.doc-example-live').repeater('li').row(1)).
- toEqual(['1', 'Hello', 'Earth']);
- expect(using('.doc-example-live').element('pre').text()).
- toBe('$index=\nsalutation=Hello\nname=Misko');
- });
-
+
+
+
+ -
+ {{$index}}: {{salutation}} {{name}}!
+
+
+
+ $index={{$index}}
+ salutation={{salutation}}
+ name={{name}}
+
+
+ it('should inherit the salutation property and override the name property', function() {
+ expect(using('.doc-example-live').repeater('li').row(0)).
+ toEqual(['0', 'Hello', 'World']);
+ expect(using('.doc-example-live').repeater('li').row(1)).
+ toEqual(['1', 'Hello', 'Earth']);
+ expect(using('.doc-example-live').element('pre').text()).
+ toBe('$index=\nsalutation=Hello\nname=Misko');
+ });
+
+
*/
function createScope(parent, providers, instanceCache) {
function Parent(){}
diff --git a/src/angular-mocks.js b/src/angular-mocks.js
index fe0fb011..71a18d06 100644
--- a/src/angular-mocks.js
+++ b/src/angular-mocks.js
@@ -239,10 +239,10 @@ angular.service('$exceptionHandler', function(e) {
*/
angular.service('$log', function() {
var $log = {
- log: function(){ $log.logs.push(arguments) },
- warn: function(){ $log.logs.push(arguments) },
- info: function(){ $log.logs.push(arguments) },
- error: function(){ $log.logs.push(arguments) }
+ log: function(){ $log.logs.push(arguments); },
+ warn: function(){ $log.logs.push(arguments); },
+ info: function(){ $log.logs.push(arguments); },
+ error: function(){ $log.logs.push(arguments); }
};
$log.log.logs = [];
@@ -265,15 +265,6 @@ angular.service('$log', function() {
* @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
*
* @example
- * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
- * newYearInBratislava.getTimezoneOffset() => -60;
- * newYearInBratislava.getFullYear() => 2010;
- * newYearInBratislava.getMonth() => 0;
- * newYearInBratislava.getDate() => 1;
- * newYearInBratislava.getHours() => 0;
- * newYearInBratislava.getMinutes() => 0;
- *
- *
* !!!! WARNING !!!!!
* This is not a complete Date object so only methods that were implemented can be called safely.
* To make matters worse, TzDate instances inherit stuff from Date via a prototype.
@@ -281,6 +272,17 @@ angular.service('$log', function() {
* We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
* incomplete we might be missing some non-standard methods. This can result in errors like:
* "Date.prototype.foo called on incompatible Object".
+ *
+ *
+ * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
+ * newYearInBratislava.getTimezoneOffset() => -60;
+ * newYearInBratislava.getFullYear() => 2010;
+ * newYearInBratislava.getMonth() => 0;
+ * newYearInBratislava.getDate() => 1;
+ * newYearInBratislava.getHours() => 0;
+ * newYearInBratislava.getMinutes() => 0;
+ *
+ *
*/
function TzDate(offset, timestamp) {
if (angular.isString(timestamp)) {
diff --git a/src/apis.js b/src/apis.js
index 35e3a92f..437cd6e0 100644
--- a/src/apis.js
+++ b/src/apis.js
@@ -79,22 +79,26 @@ var angularArray = {
* @returns {number} The position of the element in `array`. The position is 0-based. `-1` is returned if the value can't be found.
*
* @example
-
-
- Index of '{{bookName}}' in the list {{books}} is {{books.$indexOf(bookName)}}.
+
+
+
+
+ Index of '{{bookName}}' in the list {{books}} is {{books.$indexOf(bookName)}}.
+
+
+ it('should correctly calculate the initial index', function() {
+ expect(binding('books.$indexOf(bookName)')).toBe('2');
+ });
- @scenario
- it('should correctly calculate the initial index', function() {
- expect(binding('books.$indexOf(bookName)')).toBe('2');
- });
+ it('should recalculate', function() {
+ input('bookName').enter('foo');
+ expect(binding('books.$indexOf(bookName)')).toBe('-1');
- it('should recalculate', function() {
- input('bookName').enter('foo');
- expect(binding('books.$indexOf(bookName)')).toBe('-1');
-
- input('bookName').enter('Moby Dick');
- expect(binding('books.$indexOf(bookName)')).toBe('0');
- });
+ input('bookName').enter('Moby Dick');
+ expect(binding('books.$indexOf(bookName)')).toBe('0');
+ });
+
+
*/
'indexOf': indexOf,
@@ -117,42 +121,46 @@ var angularArray = {
* @returns {number} Sum of items in the array.
*
* @example
-
- Qty Description Cost Total
-
-
-
-
- {{item.qty * item.cost | currency}}
- [X]
-
-
- add item
-
- Total:
- {{invoice.items.$sum('qty*cost') | currency}}
-
-
+
+
+
+ Qty Description Cost Total
+
+
+
+
+ {{item.qty * item.cost | currency}}
+ [X]
+
+
+ add item
+
+ Total:
+ {{invoice.items.$sum('qty*cost') | currency}}
+
+
+
+
+ //TODO: these specs are lame because I had to work around issues #164 and #167
+ it('should initialize and calculate the totals', function() {
+ expect(repeater('.doc-example-live table tr', 'item in invoice.items').count()).toBe(3);
+ expect(repeater('.doc-example-live table tr', 'item in invoice.items').row(1)).
+ toEqual(['$99.50']);
+ expect(binding("invoice.items.$sum('qty*cost')")).toBe('$99.50');
+ expect(binding("invoice.items.$sum('qty*cost')")).toBe('$99.50');
+ });
- @scenario
- //TODO: these specs are lame because I had to work around issues #164 and #167
- it('should initialize and calculate the totals', function() {
- expect(repeater('.doc-example-live table tr', 'item in invoice.items').count()).toBe(3);
- expect(repeater('.doc-example-live table tr', 'item in invoice.items').row(1)).
- toEqual(['$99.50']);
- expect(binding("invoice.items.$sum('qty*cost')")).toBe('$99.50');
- expect(binding("invoice.items.$sum('qty*cost')")).toBe('$99.50');
- });
+ it('should add an entry and recalculate', function() {
+ element('.doc-example a:contains("add item")').click();
+ using('.doc-example-live tr:nth-child(3)').input('item.qty').enter('20');
+ using('.doc-example-live tr:nth-child(3)').input('item.cost').enter('100');
- it('should add an entry and recalculate', function() {
- element('.doc-example a:contains("add item")').click();
- using('.doc-example-live tr:nth-child(3)').input('item.qty').enter('20');
- using('.doc-example-live tr:nth-child(3)').input('item.cost').enter('100');
-
- expect(repeater('.doc-example-live table tr', 'item in invoice.items').row(2)).
- toEqual(['$2,000.00']);
- expect(binding("invoice.items.$sum('qty*cost')")).toBe('$2,099.50');
- });
+ expect(repeater('.doc-example-live table tr', 'item in invoice.items').row(2)).
+ toEqual(['$2,000.00']);
+ expect(binding("invoice.items.$sum('qty*cost')")).toBe('$2,099.50');
+ });
+
+
*/
'sum':function(array, expression) {
var fn = angular['Function']['compile'](expression);
@@ -185,33 +193,37 @@ var angularArray = {
* @returns {*} The removed element.
*
* @example
-
- -
- {{task}} [X]
-
-
-
- tasks = {{tasks}}
+
+
+
+ -
+ {{task}} [X]
+
+
+
+ tasks = {{tasks}}
+
+
+ it('should initialize the task list with for tasks', function() {
+ expect(repeater('.doc-example ul li', 'task in tasks').count()).toBe(4);
+ expect(repeater('.doc-example ul li', 'task in tasks').column('task')).
+ toEqual(['Learn Angular', 'Read Documentation', 'Check out demos',
+ 'Build cool applications']);
+ });
- @scenario
- it('should initialize the task list with for tasks', function() {
- expect(repeater('.doc-example ul li', 'task in tasks').count()).toBe(4);
- expect(repeater('.doc-example ul li', 'task in tasks').column('task')).
- toEqual(['Learn Angular', 'Read Documentation', 'Check out demos',
- 'Build cool applications']);
- });
+ it('should initialize the task list with for tasks', function() {
+ element('.doc-example ul li a:contains("X"):first').click();
+ expect(repeater('.doc-example ul li', 'task in tasks').count()).toBe(3);
- it('should initialize the task list with for tasks', function() {
- element('.doc-example ul li a:contains("X"):first').click();
- expect(repeater('.doc-example ul li', 'task in tasks').count()).toBe(3);
+ element('.doc-example ul li a:contains("X"):last').click();
+ expect(repeater('.doc-example ul li', 'task in tasks').count()).toBe(2);
- element('.doc-example ul li a:contains("X"):last').click();
- expect(repeater('.doc-example ul li', 'task in tasks').count()).toBe(2);
-
- expect(repeater('.doc-example ul li', 'task in tasks').column('task')).
- toEqual(['Read Documentation', 'Check out demos']);
- });
+ expect(repeater('.doc-example ul li', 'task in tasks').column('task')).
+ toEqual(['Read Documentation', 'Check out demos']);
+ });
+
+
*/
'remove':function(array, value) {
var index = indexOf(array, value);
@@ -254,48 +266,52 @@ var angularArray = {
* the predicate returned true for.
*
* @example
-
+
+
+
- Search:
-
- Name Phone
-
- {{friend.name}}
- {{friend.phone}}
-
-
-
- Any:
- Name only
- Phone only
-
- Name Phone
-
- {{friend.name}}
- {{friend.phone}}
-
-
+ Search:
+
+ Name Phone
+
+ {{friend.name}}
+ {{friend.phone}}
+
+
+
+ Any:
+ Name only
+ Phone only
+
+ Name Phone
+
+ {{friend.name}}
+ {{friend.phone}}
+
+
+
+
+ it('should search across all fields when filtering with a string', function() {
+ input('searchText').enter('m');
+ expect(repeater('#searchTextResults tr', 'friend in friends').column('name')).
+ toEqual(['Mary', 'Mike', 'Adam']);
- @scenario
- it('should search across all fields when filtering with a string', function() {
- input('searchText').enter('m');
- expect(repeater('#searchTextResults tr', 'friend in friends').column('name')).
- toEqual(['Mary', 'Mike', 'Adam']);
+ input('searchText').enter('76');
+ expect(repeater('#searchTextResults tr', 'friend in friends').column('name')).
+ toEqual(['John', 'Julie']);
+ });
- input('searchText').enter('76');
- expect(repeater('#searchTextResults tr', 'friend in friends').column('name')).
- toEqual(['John', 'Julie']);
- });
-
- it('should search in specific fields when filtering with a predicate object', function() {
- input('search.$').enter('i');
- expect(repeater('#searchObjResults tr', 'friend in friends').column('name')).
- toEqual(['Mary', 'Mike', 'Julie']);
- });
+ it('should search in specific fields when filtering with a predicate object', function() {
+ input('search.$').enter('i');
+ expect(repeater('#searchObjResults tr', 'friend in friends').column('name')).
+ toEqual(['Mary', 'Mike', 'Julie']);
+ });
+
+
*/
'filter':function(array, expression) {
var predicates = [];
@@ -398,53 +414,55 @@ var angularArray = {
*
* @TODO simplify the example.
*
- * @exampleDescription
+ * @example
* This example shows how an initially empty array can be filled with objects created from user
* input via the `$add` method.
- *
- * @example
- [add empty]
- [add 'John']
- [add 'Mary']
+
+
+ [add empty]
+ [add 'John']
+ [add 'Mary']
-
- -
-
-
- [X]
-
-
- people = {{people}}
+
+ -
+
+
+ [X]
+
+
+ people = {{people}}
+
+
+ beforeEach(function() {
+ expect(binding('people')).toBe('people = []');
+ });
- @scenario
- beforeEach(function() {
- expect(binding('people')).toBe('people = []');
- });
+ it('should create an empty record when "add empty" is clicked', function() {
+ element('.doc-example a:contains("add empty")').click();
+ expect(binding('people')).toBe('people = [{\n "name":"",\n "sex":null}]');
+ });
- it('should create an empty record when "add empty" is clicked', function() {
- element('.doc-example a:contains("add empty")').click();
- expect(binding('people')).toBe('people = [{\n "name":"",\n "sex":null}]');
- });
+ it('should create a "John" record when "add \'John\'" is clicked', function() {
+ element('.doc-example a:contains("add \'John\'")').click();
+ expect(binding('people')).toBe('people = [{\n "name":"John",\n "sex":"male"}]');
+ });
- it('should create a "John" record when "add \'John\'" is clicked', function() {
- element('.doc-example a:contains("add \'John\'")').click();
- expect(binding('people')).toBe('people = [{\n "name":"John",\n "sex":"male"}]');
- });
+ it('should create a "Mary" record when "add \'Mary\'" is clicked', function() {
+ element('.doc-example a:contains("add \'Mary\'")').click();
+ expect(binding('people')).toBe('people = [{\n "name":"Mary",\n "sex":"female"}]');
+ });
- it('should create a "Mary" record when "add \'Mary\'" is clicked', function() {
- element('.doc-example a:contains("add \'Mary\'")').click();
- expect(binding('people')).toBe('people = [{\n "name":"Mary",\n "sex":"female"}]');
- });
-
- it('should delete a record when "X" is clicked', function() {
- element('.doc-example a:contains("add empty")').click();
- element('.doc-example li a:contains("X"):first').click();
- expect(binding('people')).toBe('people = []');
- });
+ it('should delete a record when "X" is clicked', function() {
+ element('.doc-example a:contains("add empty")').click();
+ element('.doc-example li a:contains("X"):first').click();
+ expect(binding('people')).toBe('people = []');
+ });
+
+
*/
'add':function(array, value) {
array.push(isUndefined(value)? {} : value);
@@ -471,29 +489,33 @@ var angularArray = {
* @returns {number} Number of elements in the array (for which the condition evaluates to true).
*
* @example
-
-
- -
- {{item.name}}: points=
-
-
-
- Number of items which have one point: {{ items.$count('points==1') }}
- Number of items which have more than one point: {{items.$count('points>1')}}
+
+
+
+
+ -
+ {{item.name}}: points=
+
+
+
+ Number of items which have one point: {{ items.$count('points==1') }}
+ Number of items which have more than one point: {{items.$count('points>1')}}
+
+
+ it('should calculate counts', function() {
+ expect(binding('items.$count(\'points==1\')')).toEqual(2);
+ expect(binding('items.$count(\'points>1\')')).toEqual(1);
+ });
- @scenario
- it('should calculate counts', function() {
- expect(binding('items.$count(\'points==1\')')).toEqual(2);
- expect(binding('items.$count(\'points>1\')')).toEqual(1);
- });
-
- it('should recalculate when updated', function() {
- using('.doc-example li:first-child').input('item.points').enter('23');
- expect(binding('items.$count(\'points==1\')')).toEqual(1);
- expect(binding('items.$count(\'points>1\')')).toEqual(2);
- });
+ it('should recalculate when updated', function() {
+ using('.doc-example li:first-child').input('item.points').enter('23');
+ expect(binding('items.$count(\'points==1\')')).toEqual(1);
+ expect(binding('items.$count(\'points>1\')')).toEqual(2);
+ });
+
+
*/
'count':function(array, condition) {
if (!condition) return array.length;
@@ -535,52 +557,56 @@ var angularArray = {
* @returns {Array} Sorted copy of the source array.
*
* @example
-
+
+
+
- Sorting predicate = {{predicate}}
-
-
-
- Name
- (^)
- Phone
- (^)
- Age
- (^)
-
-
- {{friend.name}}
- {{friend.phone}}
- {{friend.age}}
-
-
+ Sorting predicate = {{predicate}}
+
+
+
+ Name
+ (^)
+ Phone
+ (^)
+ Age
+ (^)
+
+
+ {{friend.name}}
+ {{friend.phone}}
+ {{friend.age}}
+
+
+
+
+ it('should be reverse ordered by aged', function() {
+ expect(binding('predicate')).toBe('Sorting predicate = -age');
+ expect(repeater('.doc-example table', 'friend in friends').column('friend.age')).
+ toEqual(['35', '29', '21', '19', '10']);
+ expect(repeater('.doc-example table', 'friend in friends').column('friend.name')).
+ toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']);
+ });
- @scenario
- it('should be reverse ordered by aged', function() {
- expect(binding('predicate')).toBe('Sorting predicate = -age');
- expect(repeater('.doc-example table', 'friend in friends').column('friend.age')).
- toEqual(['35', '29', '21', '19', '10']);
- expect(repeater('.doc-example table', 'friend in friends').column('friend.name')).
- toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']);
- });
+ it('should reorder the table when user selects different predicate', function() {
+ element('.doc-example a:contains("Name")').click();
+ expect(repeater('.doc-example table', 'friend in friends').column('friend.name')).
+ toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']);
+ expect(repeater('.doc-example table', 'friend in friends').column('friend.age')).
+ toEqual(['35', '10', '29', '19', '21']);
- it('should reorder the table when user selects different predicate', function() {
- element('.doc-example a:contains("Name")').click();
- expect(repeater('.doc-example table', 'friend in friends').column('friend.name')).
- toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']);
- expect(repeater('.doc-example table', 'friend in friends').column('friend.age')).
- toEqual(['35', '10', '29', '19', '21']);
-
- element('.doc-example a:contains("Phone")+a:contains("^")').click();
- expect(repeater('.doc-example table', 'friend in friends').column('friend.phone')).
- toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']);
- expect(repeater('.doc-example table', 'friend in friends').column('friend.name')).
- toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']);
- });
+ element('.doc-example a:contains("Phone")+a:contains("^")').click();
+ expect(repeater('.doc-example table', 'friend in friends').column('friend.phone')).
+ toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']);
+ expect(repeater('.doc-example table', 'friend in friends').column('friend.name')).
+ toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']);
+ });
+
+
*/
//TODO: WTH is descend param for and how/when it should be used, how is it affected by +/- in
// predicate? the code below is impossible to read and specs are not very good.
@@ -648,21 +674,25 @@ var angularArray = {
* @returns {Array} A new sub-array of length `limit`.
*
* @example
-
- Limit [1,2,3,4,5,6,7,8,9] to:
- Output: {{ numbers.$limitTo(limit) | json }}
-
+
+
+
+ Limit [1,2,3,4,5,6,7,8,9] to:
+ Output: {{ numbers.$limitTo(limit) | json }}
+
+
+
+ it('should limit the numer array to first three items', function() {
+ expect(element('.doc-example input[name=limit]').val()).toBe('3');
+ expect(binding('numbers.$limitTo(limit) | json')).toEqual('[1,2,3]');
+ });
- * @scenario
- it('should limit the numer array to first three items', function() {
- expect(element('.doc-example input[name=limit]').val()).toBe('3');
- expect(binding('numbers.$limitTo(limit) | json')).toEqual('[1,2,3]');
- });
-
- it('should update the output when -3 is entered', function() {
- input('limit').enter(-3);
- expect(binding('numbers.$limitTo(limit) | json')).toEqual('[7,8,9]');
- });
+ it('should update the output when -3 is entered', function() {
+ input('limit').enter(-3);
+ expect(binding('numbers.$limitTo(limit) | json')).toEqual('[7,8,9]');
+ });
+
+
*/
limitTo: function(array, limit) {
limit = parseInt(limit, 10);
diff --git a/src/directives.js b/src/directives.js
index 104ff9c8..5ca7c2ec 100644
--- a/src/directives.js
+++ b/src/directives.js
@@ -4,22 +4,26 @@
* @name angular.directive.ng:init
*
* @description
- * `ng:init` attribute allows the for initialization tasks to be executed
+ * `ng:init` attribute allows the for initialization tasks to be executed
* before the template enters execution mode during bootstrap.
*
* @element ANY
* @param {expression} expression to eval.
*
* @example
+
+
{{greeting}} {{person}}!
- *
- * @scenario
- it('should check greeting', function(){
- expect(binding('greeting')).toBe('Hello');
- expect(binding('person')).toBe('World');
- });
+
+
+ it('should check greeting', function(){
+ expect(binding('greeting')).toBe('Hello');
+ expect(binding('person')).toBe('World');
+ });
+
+
*/
angularDirective("ng:init", function(expression){
return function(element){
@@ -33,66 +37,70 @@ angularDirective("ng:init", function(expression){
* @name angular.directive.ng:controller
*
* @description
- * To support the Model-View-Controller design pattern, it is possible
- * to assign behavior to a scope through `ng:controller`. The scope is
- * the MVC model. The HTML (with data bindings) is the MVC view.
+ * To support the Model-View-Controller design pattern, it is possible
+ * to assign behavior to a scope through `ng:controller`. The scope is
+ * the MVC model. The HTML (with data bindings) is the MVC view.
* The `ng:controller` directive specifies the MVC controller class
*
* @element ANY
* @param {expression} expression to eval.
*
* @example
-
-
- *
- * @scenario
- it('should check controller', function(){
- expect(element('.doc-example-live div>:input').val()).toBe('John Smith');
- expect(element('.doc-example-live li[ng\\:repeat-index="0"] input').val()).toBe('408 555 1212');
- expect(element('.doc-example-live li[ng\\:repeat-index="1"] input').val()).toBe('john.smith@example.org');
- element('.doc-example-live li:first a:contains("clear")').click();
- expect(element('.doc-example-live li:first input').val()).toBe('');
- element('.doc-example-live li:last a:contains("add")').click();
- expect(element('.doc-example-live li[ng\\:repeat-index="2"] input').val()).toBe('yourname@example.org');
- });
+
+
+
+
+
+
+ it('should check controller', function(){
+ expect(element('.doc-example-live div>:input').val()).toBe('John Smith');
+ expect(element('.doc-example-live li[ng\\:repeat-index="0"] input').val()).toBe('408 555 1212');
+ expect(element('.doc-example-live li[ng\\:repeat-index="1"] input').val()).toBe('john.smith@example.org');
+ element('.doc-example-live li:first a:contains("clear")').click();
+ expect(element('.doc-example-live li:first input').val()).toBe('');
+ element('.doc-example-live li:last a:contains("add")').click();
+ expect(element('.doc-example-live li[ng\\:repeat-index="2"] input').val()).toBe('yourname@example.org');
+ });
+
+
*/
angularDirective("ng:controller", function(expression){
this.scope(true);
@@ -112,36 +120,38 @@ angularDirective("ng:controller", function(expression){
* @name angular.directive.ng:eval
*
* @description
- * The `ng:eval` allows you to execute a binding which has side effects
+ * The `ng:eval` allows you to execute a binding which has side effects
* without displaying the result to the user.
*
* @element ANY
* @param {expression} expression to eval.
*
- * @exampleDescription
- * Notice that `{{` `obj.multiplied = obj.a * obj.b` `}}` has a side effect of assigning
- * a value to `obj.multiplied` and displaying the result to the user. Sometimes,
- * however, it is desirable to execute a side effect without showing the value to
- * the user. In such a case `ng:eval` allows you to execute code without updating
- * the display.
- *
* @example
- *
- * *
- * = {{obj.multiplied = obj.a * obj.b}}
- *
- *
- * obj.divide = {{obj.divide}}
- * obj.updateCount = {{obj.updateCount}}
- *
- * @scenario
- it('should check eval', function(){
- expect(binding('obj.divide')).toBe('3');
- expect(binding('obj.updateCount')).toBe('2');
- input('obj.a').enter('12');
- expect(binding('obj.divide')).toBe('6');
- expect(binding('obj.updateCount')).toBe('3');
- });
+ * Notice that `{{` `obj.multiplied = obj.a * obj.b` `}}` has a side effect of assigning
+ * a value to `obj.multiplied` and displaying the result to the user. Sometimes,
+ * however, it is desirable to execute a side effect without showing the value to
+ * the user. In such a case `ng:eval` allows you to execute code without updating
+ * the display.
+
+
+
+ *
+ = {{obj.multiplied = obj.a * obj.b}}
+
+
+ obj.divide = {{obj.divide}}
+ obj.updateCount = {{obj.updateCount}}
+
+
+ it('should check eval', function(){
+ expect(binding('obj.divide')).toBe('3');
+ expect(binding('obj.updateCount')).toBe('2');
+ input('obj.a').enter('12');
+ expect(binding('obj.divide')).toBe('6');
+ expect(binding('obj.updateCount')).toBe('3');
+ });
+
+
*/
angularDirective("ng:eval", function(expression){
return function(element){
@@ -155,27 +165,30 @@ angularDirective("ng:eval", function(expression){
* @name angular.directive.ng:bind
*
* @description
- * The `ng:bind` attribute asks to replace the text content of this
- * HTML element with the value of the given expression and kept it up to
- * date when the expression's value changes. Usually you just write
- * {{expression}} and let compile it into
+ * The `ng:bind` attribute asks to replace the text content of this
+ * HTML element with the value of the given expression and kept it up to
+ * date when the expression's value changes. Usually you just write
+ * {{expression}} and let compile it into
* `` at bootstrap time.
- *
+ *
* @element ANY
* @param {expression} expression to eval.
*
- * @exampleDescription
- * Try it here: enter text in text box and watch the greeting change.
* @example
- * Enter name: .
- * Hello !
- *
- * @scenario
- it('should check ng:bind', function(){
- expect(using('.doc-example-live').binding('name')).toBe('Whirled');
- using('.doc-example-live').input('name').enter('world');
- expect(using('.doc-example-live').binding('name')).toBe('world');
- });
+ * Try it here: enter text in text box and watch the greeting change.
+
+
+ Enter name: .
+ Hello !
+
+
+ it('should check ng:bind', function(){
+ expect(using('.doc-example-live').binding('name')).toBe('Whirled');
+ using('.doc-example-live').input('name').enter('world');
+ expect(using('.doc-example-live').binding('name')).toBe('world');
+ });
+
+
*/
angularDirective("ng:bind", function(expression, element){
element.addClass('ng-binding');
@@ -259,32 +272,35 @@ function compileBindTemplate(template){
* @name angular.directive.ng:bind-template
*
* @description
- * The `ng:bind-template` attribute specifies that the element
- * text should be replaced with the template in ng:bind-template.
- * Unlike ng:bind the ng:bind-template can contain multiple `{{` `}}`
- * expressions. (This is required since some HTML elements
+ * The `ng:bind-template` attribute specifies that the element
+ * text should be replaced with the template in ng:bind-template.
+ * Unlike ng:bind the ng:bind-template can contain multiple `{{` `}}`
+ * expressions. (This is required since some HTML elements
* can not have SPAN elements such as TITLE, or OPTION to name a few.
- *
+ *
* @element ANY
* @param {string} template of form
* {{ expression }} to eval.
*
- * @exampleDescription
- * Try it here: enter text in text box and watch the greeting change.
* @example
- Salutation:
- Name:
-
- *
- * @scenario
- it('should check ng:bind', function(){
- expect(using('.doc-example-live').binding('{{salutation}} {{name}}')).
- toBe('Hello World!');
- using('.doc-example-live').input('salutation').enter('Greetings');
- using('.doc-example-live').input('name').enter('user');
- expect(using('.doc-example-live').binding('{{salutation}} {{name}}')).
- toBe('Greetings user!');
- });
+ * Try it here: enter text in text box and watch the greeting change.
+
+
+ Salutation:
+ Name:
+
+
+
+ it('should check ng:bind', function(){
+ expect(using('.doc-example-live').binding('{{salutation}} {{name}}')).
+ toBe('Hello World!');
+ using('.doc-example-live').input('salutation').enter('Greetings');
+ using('.doc-example-live').input('name').enter('user');
+ expect(using('.doc-example-live').binding('{{salutation}} {{name}}')).
+ toBe('Greetings user!');
+ });
+
+
*/
angularDirective("ng:bind-template", function(expression, element){
element.addClass('ng-binding');
@@ -313,49 +329,52 @@ var REMOVE_ATTRIBUTES = {
* @name angular.directive.ng:bind-attr
*
* @description
- * The `ng:bind-attr` attribute specifies that the element attributes
- * which should be replaced by the expression in it. Unlike `ng:bind`
- * the `ng:bind-attr` contains a JSON key value pairs representing
- * which attributes need to be changed. You don’t usually write the
- * `ng:bind-attr` in the HTML since embedding
- * {{expression}} into the
+ * The `ng:bind-attr` attribute specifies that the element attributes
+ * which should be replaced by the expression in it. Unlike `ng:bind`
+ * the `ng:bind-attr` contains a JSON key value pairs representing
+ * which attributes need to be changed. You don’t usually write the
+ * `ng:bind-attr` in the HTML since embedding
+ * {{expression}} into the
* attribute directly is the preferred way. The attributes get
* translated into `` at
* bootstrap time.
- *
+ *
* This HTML snippet is preferred way of working with `ng:bind-attr`
*
* Google
*
- *
+ *
* The above gets translated to bellow during bootstrap time.
*
* Google
*
- *
+ *
* @element ANY
- * @param {string} attribute_json a JSON key-value pairs representing
- * the attributes to replace. Each key matches the attribute
- * which needs to be replaced. Each value is a text template of
- * the attribute with embedded
- * {{expression}}s. Any number of
+ * @param {string} attribute_json a JSON key-value pairs representing
+ * the attributes to replace. Each key matches the attribute
+ * which needs to be replaced. Each value is a text template of
+ * the attribute with embedded
+ * {{expression}}s. Any number of
* key-value pairs can be specified.
*
- * @exampleDescription
- * Try it here: enter text in text box and click Google.
* @example
- Google for:
-
- Google
- *
- * @scenario
- it('should check ng:bind-attr', function(){
- expect(using('.doc-example-live').element('a').attr('href')).
- toBe('http://www.google.com/search?q=AngularJS');
- using('.doc-example-live').input('query').enter('google');
- expect(using('.doc-example-live').element('a').attr('href')).
- toBe('http://www.google.com/search?q=google');
- });
+ * Try it here: enter text in text box and click Google.
+
+
+ Google for:
+
+ Google
+
+
+ it('should check ng:bind-attr', function(){
+ expect(using('.doc-example-live').element('a').attr('href')).
+ toBe('http://www.google.com/search?q=AngularJS');
+ using('.doc-example-live').input('query').enter('google');
+ expect(using('.doc-example-live').element('a').attr('href')).
+ toBe('http://www.google.com/search?q=google');
+ });
+
+
*/
angularDirective("ng:bind-attr", function(expression){
return function(element){
@@ -396,23 +415,28 @@ angularDirective("ng:bind-attr", function(expression){
* @name angular.directive.ng:click
*
* @description
- * The ng:click allows you to specify custom behavior when
+ * The ng:click allows you to specify custom behavior when
* element is clicked.
- *
+ *
* @element ANY
* @param {expression} expression to eval upon click.
*
* @example
-
- count: {{count}}
- * @scenario
- it('should check ng:click', function(){
- expect(binding('count')).toBe('0');
- element('.doc-example-live :button').click();
- expect(binding('count')).toBe('1');
- });
+
+
+
+ count: {{count}}
+
+
+ it('should check ng:click', function(){
+ expect(binding('count')).toBe('0');
+ element('.doc-example-live :button').click();
+ expect(binding('count')).toBe('1');
+ });
+
+
*/
/*
* A directive that allows creation of custom onclick handlers that are defined as angular
@@ -440,35 +464,37 @@ angularDirective("ng:click", function(expression, element){
* @name angular.directive.ng:submit
*
* @description
- *
- * @element form
- * @param {expression} expression to eval.
- *
- * @exampleDescription
- * @example
- *
- * list={{list}}
- * @scenario
- it('should check ng:submit', function(){
- expect(binding('list')).toBe('list=[]');
- element('.doc-example-live form input').click();
- this.addFutureAction('submit from', function($window, $document, done) {
- $window.angular.element(
- $document.elements('.doc-example-live form')).
- trigger('submit');
- done();
- });
- expect(binding('list')).toBe('list=["hello"]');
- });
- */
-/**
* Enables binding angular expressions to onsubmit events.
*
* Additionally it prevents the default action (which for form means sending the request to the
* server and reloading the current page).
+ *
+ * @element form
+ * @param {expression} expression to eval.
+ *
+ * @example
+
+
+
+ list={{list}}
+
+
+ it('should check ng:submit', function(){
+ expect(binding('list')).toBe('list=[]');
+ element('.doc-example-live form input').click();
+ this.addFutureAction('submit from', function($window, $document, done) {
+ $window.angular.element(
+ $document.elements('.doc-example-live form')).
+ trigger('submit');
+ done();
+ });
+ expect(binding('list')).toBe('list=["hello"]');
+ });
+
+
*/
angularDirective("ng:submit", function(expression, element) {
return injectUpdateView(function($updateView, element) {
@@ -488,26 +514,30 @@ angularDirective("ng:submit", function(expression, element) {
* @name angular.directive.ng:watch
*
* @description
- * The `ng:watch` allows you watch a variable and then execute
+ * The `ng:watch` allows you watch a variable and then execute
* an evaluation on variable change.
- *
+ *
* @element ANY
* @param {expression} expression to eval.
*
- * @exampleDescription
- * Notice that the counter is incremented
- * every time you change the text.
* @example
-
-
- Change counter: {{counter}} Name: {{name}}
-
- * @scenario
- it('should check ng:watch', function(){
- expect(using('.doc-example-live').binding('counter')).toBe('2');
- using('.doc-example-live').input('name').enter('abc');
- expect(using('.doc-example-live').binding('counter')).toBe('3');
- });
+ * Notice that the counter is incremented
+ * every time you change the text.
+
+
+
+
+ Change counter: {{counter}} Name: {{name}}
+
+
+
+ it('should check ng:watch', function(){
+ expect(using('.doc-example-live').binding('counter')).toBe('2');
+ using('.doc-example-live').input('name').enter('abc');
+ expect(using('.doc-example-live').binding('counter')).toBe('3');
+ });
+
+
*/
//TODO: delete me, since having watch in UI is logic in UI. (leftover form getangular)
angularDirective("ng:watch", function(expression, element){
@@ -544,34 +574,37 @@ function ngClass(selector) {
* @name angular.directive.ng:class
*
* @description
- * The `ng:class` allows you to set CSS class on HTML element
+ * The `ng:class` allows you to set CSS class on HTML element
* conditionally.
- *
+ *
* @element ANY
* @param {expression} expression to eval.
*
- * @exampleDescription
* @example
-
-
-
- Sample Text
- *
- * @scenario
- it('should check ng:class', function(){
- expect(element('.doc-example-live span').attr('className')).not().
- toMatch(/ng-input-indicator-wait/);
+
+
+
+
+
+ Sample Text
+
+
+ it('should check ng:class', function(){
+ expect(element('.doc-example-live span').attr('className')).not().
+ toMatch(/ng-input-indicator-wait/);
- using('.doc-example-live').element(':button:first').click();
+ using('.doc-example-live').element(':button:first').click();
- expect(element('.doc-example-live span').attr('className')).
- toMatch(/ng-input-indicator-wait/);
+ expect(element('.doc-example-live span').attr('className')).
+ toMatch(/ng-input-indicator-wait/);
- using('.doc-example-live').element(':button:last').click();
-
- expect(element('.doc-example-live span').attr('className')).not().
- toMatch(/ng-input-indicator-wait/);
- });
+ using('.doc-example-live').element(':button:last').click();
+
+ expect(element('.doc-example-live span').attr('className')).not().
+ toMatch(/ng-input-indicator-wait/);
+ });
+
+
*/
angularDirective("ng:class", ngClass(function(){return true;}));
@@ -581,33 +614,35 @@ angularDirective("ng:class", ngClass(function(){return true;}));
* @name angular.directive.ng:class-odd
*
* @description
- * The `ng:class-odd` and `ng:class-even` works exactly as
- * `ng:class`, except it works in conjunction with `ng:repeat`
+ * The `ng:class-odd` and `ng:class-even` works exactly as
+ * `ng:class`, except it works in conjunction with `ng:repeat`
* and takes affect only on odd (even) rows.
*
* @element ANY
- * @param {expression} expression to eval. Must be inside
+ * @param {expression} expression to eval. Must be inside
* `ng:repeat`.
-
*
- * @exampleDescription
* @example
-
- -
-
- {{name}}
-
-
-
- *
- * @scenario
- it('should check ng:class-odd and ng:class-even', function(){
- expect(element('.doc-example-live li:first span').attr('className')).
- toMatch(/ng-format-negative/);
- expect(element('.doc-example-live li:last span').attr('className')).
- toMatch(/ng-input-indicator-wait/);
- });
+
+
+
+ -
+
+ {{name}}
+
+
+
+
+
+ it('should check ng:class-odd and ng:class-even', function(){
+ expect(element('.doc-example-live li:first span').attr('className')).
+ toMatch(/ng-format-negative/);
+ expect(element('.doc-example-live li:last span').attr('className')).
+ toMatch(/ng-input-indicator-wait/);
+ });
+
+
*/
angularDirective("ng:class-odd", ngClass(function(i){return i % 2 === 0;}));
@@ -617,33 +652,35 @@ angularDirective("ng:class-odd", ngClass(function(i){return i % 2 === 0;}));
* @name angular.directive.ng:class-even
*
* @description
- * The `ng:class-odd` and `ng:class-even` works exactly as
- * `ng:class`, except it works in conjunction with `ng:repeat`
+ * The `ng:class-odd` and `ng:class-even` works exactly as
+ * `ng:class`, except it works in conjunction with `ng:repeat`
* and takes affect only on odd (even) rows.
*
* @element ANY
- * @param {expression} expression to eval. Must be inside
+ * @param {expression} expression to eval. Must be inside
* `ng:repeat`.
-
*
- * @exampleDescription
* @example
-
- -
-
- {{name}}
-
-
-
- *
- * @scenario
- it('should check ng:class-odd and ng:class-even', function(){
- expect(element('.doc-example-live li:first span').attr('className')).
- toMatch(/ng-format-negative/);
- expect(element('.doc-example-live li:last span').attr('className')).
- toMatch(/ng-input-indicator-wait/);
- });
+
+
+
+ -
+
+ {{name}}
+
+
+
+
+
+ it('should check ng:class-odd and ng:class-even', function(){
+ expect(element('.doc-example-live li:first span').attr('className')).
+ toMatch(/ng-format-negative/);
+ expect(element('.doc-example-live li:last span').attr('className')).
+ toMatch(/ng-input-indicator-wait/);
+ });
+
+
*/
angularDirective("ng:class-even", ngClass(function(i){return i % 2 === 1;}));
@@ -655,27 +692,30 @@ angularDirective("ng:class-even", ngClass(function(i){return i % 2 === 1;}));
* @description
* The `ng:show` and `ng:hide` allows you to show or hide a portion
* of the HTML conditionally.
- *
+ *
* @element ANY
- * @param {expression} expression if truthy then the element is
+ * @param {expression} expression if truthy then the element is
* shown or hidden respectively.
*
- * @exampleDescription
* @example
- Click me:
- Show: I show up when you checkbox is checked?
- Hide: I hide when you checkbox is checked?
- *
- * @scenario
- it('should check ng:show / ng:hide', function(){
- expect(element('.doc-example-live span:first:hidden').count()).toEqual(1);
- expect(element('.doc-example-live span:last:visible').count()).toEqual(1);
-
- input('checked').check();
-
- expect(element('.doc-example-live span:first:visible').count()).toEqual(1);
- expect(element('.doc-example-live span:last:hidden').count()).toEqual(1);
- });
+
+
+ Click me:
+ Show: I show up when you checkbox is checked?
+ Hide: I hide when you checkbox is checked?
+
+
+ it('should check ng:show / ng:hide', function(){
+ expect(element('.doc-example-live span:first:hidden').count()).toEqual(1);
+ expect(element('.doc-example-live span:last:visible').count()).toEqual(1);
+
+ input('checked').check();
+
+ expect(element('.doc-example-live span:first:visible').count()).toEqual(1);
+ expect(element('.doc-example-live span:last:hidden').count()).toEqual(1);
+ });
+
+
*/
angularDirective("ng:show", function(expression, element){
return function(element){
@@ -693,27 +733,30 @@ angularDirective("ng:show", function(expression, element){
* @description
* The `ng:show` and `ng:hide` allows you to show or hide a portion
* of the HTML conditionally.
- *
+ *
* @element ANY
- * @param {expression} expression if truthy then the element is
+ * @param {expression} expression if truthy then the element is
* shown or hidden respectively.
*
- * @exampleDescription
* @example
- Click me:
- Show: I show up when you checkbox is checked?
- Hide: I hide when you checkbox is checked?
- *
- * @scenario
- it('should check ng:show / ng:hide', function(){
- expect(element('.doc-example-live span:first:hidden').count()).toEqual(1);
- expect(element('.doc-example-live span:last:visible').count()).toEqual(1);
-
- input('checked').check();
-
- expect(element('.doc-example-live span:first:visible').count()).toEqual(1);
- expect(element('.doc-example-live span:last:hidden').count()).toEqual(1);
- });
+
+
+ Click me:
+ Show: I show up when you checkbox is checked?
+ Hide: I hide when you checkbox is checked?
+
+
+ it('should check ng:show / ng:hide', function(){
+ expect(element('.doc-example-live span:first:hidden').count()).toEqual(1);
+ expect(element('.doc-example-live span:last:visible').count()).toEqual(1);
+
+ input('checked').check();
+
+ expect(element('.doc-example-live span:first:visible').count()).toEqual(1);
+ expect(element('.doc-example-live span:last:hidden').count()).toEqual(1);
+ });
+
+
*/
angularDirective("ng:hide", function(expression, element){
return function(element){
@@ -730,28 +773,31 @@ angularDirective("ng:hide", function(expression, element){
*
* @description
* The ng:style allows you to set CSS style on an HTML element conditionally.
- *
+ *
* @element ANY
- * @param {expression} expression which evals to an object whes key's are
- * CSS style names and values are coresponding values for those
+ * @param {expression} expression which evals to an object whes key's are
+ * CSS style names and values are coresponding values for those
* CSS keys.
*
- * @exampleDescription
* @example
-
-
-
- Sample Text
- myStyle={{myStyle}}
- *
- * @scenario
- it('should check ng:style', function(){
- expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)');
- element('.doc-example-live :button[value=set]').click();
- expect(element('.doc-example-live span').css('color')).toBe('red');
- element('.doc-example-live :button[value=clear]').click();
- expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)');
- });
+
+
+
+
+
+ Sample Text
+ myStyle={{myStyle}}
+
+
+ it('should check ng:style', function(){
+ expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)');
+ element('.doc-example-live :button[value=set]').click();
+ expect(element('.doc-example-live span').css('color')).toBe('red');
+ element('.doc-example-live :button[value=clear]').click();
+ expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)');
+ });
+
+
*/
angularDirective("ng:style", function(expression, element){
return function(element){
diff --git a/src/filters.js b/src/filters.js
index 7fa7926d..0f6121ec 100644
--- a/src/filters.js
+++ b/src/filters.js
@@ -14,19 +14,23 @@
* When the value is negative, this css class is applied to the binding making it by default red.
*
* @example
-
- {{amount | currency}}
- *
- * @scenario
- it('should init with 1234.56', function(){
- expect(binding('amount | currency')).toBe('$1,234.56');
- });
- it('should update', function(){
- input('amount').enter('-1234');
- expect(binding('amount | currency')).toBe('$-1,234.00');
- expect(element('.doc-example-live .ng-binding').attr('className')).
- toMatch(/ng-format-negative/);
- });
+
+
+
+ {{amount | currency}}
+
+
+ it('should init with 1234.56', function(){
+ expect(binding('amount | currency')).toBe('$1,234.56');
+ });
+ it('should update', function(){
+ input('amount').enter('-1234');
+ expect(binding('amount | currency')).toBe('$-1,234.00');
+ expect(element('.doc-example-live .ng-binding').attr('className')).
+ toMatch(/ng-format-negative/);
+ });
+
+
*/
angularFilter.currency = function(amount){
this.$element.toggleClass('ng-format-negative', amount < 0);
@@ -49,24 +53,28 @@ angularFilter.currency = function(amount){
* @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
*
* @example
- Enter number:
- Default formatting: {{val | number}}
- No fractions: {{val | number:0}}
- Negative number: {{-val | number:4}}
+
+
+ Enter number:
+ Default formatting: {{val | number}}
+ No fractions: {{val | number:0}}
+ Negative number: {{-val | number:4}}
+
+
+ it('should format numbers', function(){
+ expect(binding('val | number')).toBe('1,234.57');
+ expect(binding('val | number:0')).toBe('1,235');
+ expect(binding('-val | number:4')).toBe('-1,234.5679');
+ });
- * @scenario
- it('should format numbers', function(){
- expect(binding('val | number')).toBe('1,234.57');
- expect(binding('val | number:0')).toBe('1,235');
- expect(binding('-val | number:4')).toBe('-1,234.5679');
- });
-
- it('should update', function(){
- input('val').enter('3374.333');
- expect(binding('val | number')).toBe('3,374.33');
- expect(binding('val | number:0')).toBe('3,374');
- expect(binding('-val | number:4')).toBe('-3,374.3330');
- });
+ it('should update', function(){
+ input('val').enter('3374.333');
+ expect(binding('val | number')).toBe('3,374.33');
+ expect(binding('val | number:0')).toBe('3,374');
+ expect(binding('-val | number:4')).toBe('-3,374.3330');
+ });
+
+
*/
angularFilter.number = function(number, fractionSize){
if (isNaN(number) || !isFinite(number)) {
@@ -183,19 +191,22 @@ var NUMBER_STRING = /^\d+$/;
* @returns {string} Formatted string or the input if input is not recognized as date/millis.
*
* @example
- {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}:
- {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
- {{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}:
- {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
- *
- * @scenario
- it('should format date', function(){
- expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).
- toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} \-?\d{4}/);
- expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).
- toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(am|pm)/);
- });
- *
+
+
+ {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}:
+ {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
+ {{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}:
+ {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
+
+
+ it('should format date', function(){
+ expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).
+ toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} \-?\d{4}/);
+ expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).
+ toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(am|pm)/);
+ });
+
+
*/
angularFilter.date = function(date, format) {
if (isString(date)) {
@@ -255,19 +266,23 @@ angularFilter.date = function(date, format) {
* @css ng-monospace Always applied to the encapsulating element.
*
* @example:
-
- {{ obj | json }}
- *
- * @scenario
- it('should jsonify filtered objects', function() {
- expect(binding('obj | json')).toBe('{\n "a":1,\n "b":[]}');
- });
+
+
+
+ {{ obj | json }}
+
+
+ it('should jsonify filtered objects', function() {
+ expect(binding('obj | json')).toBe('{\n "a":1,\n "b":[]}');
+ });
- it('should update', function() {
- input('objTxt').enter('[1, 2, 3]');
- expect(binding('obj | json')).toBe('[1,2,3]');
- });
+ it('should update', function() {
+ input('objTxt').enter('[1, 2, 3]');
+ expect(binding('obj | json')).toBe('[1,2,3]');
+ });
+
+
*
*/
angularFilter.json = function(object) {
@@ -324,63 +339,67 @@ angularFilter.uppercase = uppercase;
* @returns {string} Sanitized or raw html.
*
* @example
- Snippet: