├── .bowerrc ├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── README.md ├── bower.json ├── dist ├── angular-filter.js ├── angular-filter.min.js └── angular-filter.zip ├── index.js ├── license.md ├── package.json ├── src ├── _common.js ├── _filter │ ├── boolean │ │ ├── angular.js │ │ ├── conditions.js │ │ └── is-null.js │ ├── collection │ │ ├── after-where.js │ │ ├── after.js │ │ ├── before-where.js │ │ ├── before.js │ │ ├── chunk-by.js │ │ ├── concat.js │ │ ├── contains.js │ │ ├── count-by.js │ │ ├── defaults.js │ │ ├── every.js │ │ ├── filter-by.js │ │ ├── first.js │ │ ├── flatten.js │ │ ├── fuzzy-by.js │ │ ├── fuzzy.js │ │ ├── group-by.js │ │ ├── is-empty.js │ │ ├── join.js │ │ ├── last.js │ │ ├── map.js │ │ ├── omit.js │ │ ├── pick.js │ │ ├── range.js │ │ ├── remove-with.js │ │ ├── remove.js │ │ ├── reverse.js │ │ ├── search-field.js │ │ ├── to-array.js │ │ ├── unique.js │ │ ├── where.js │ │ └── xor.js │ ├── math │ │ ├── abs.js │ │ ├── byte-fmt.js │ │ ├── degrees.js │ │ ├── kb-fmt.js │ │ ├── max.js │ │ ├── min.js │ │ ├── percent.js │ │ ├── radians.js │ │ ├── radix.js │ │ ├── short-fmt.js │ │ └── sum.js │ └── string │ │ ├── ends-with.js │ │ ├── latinize.js │ │ ├── ltrim.js │ │ ├── match.js │ │ ├── phone-us.js │ │ ├── repeat.js │ │ ├── rtrim.js │ │ ├── slugify.js │ │ ├── split.js │ │ ├── starts-with.js │ │ ├── stringular.js │ │ ├── strip-tags.js │ │ ├── test.js │ │ ├── trim.js │ │ ├── truncate.js │ │ ├── ucfirst.js │ │ ├── uri-component-encode.js │ │ ├── uri-encode.js │ │ └── wrap.js ├── _provider │ └── watcher.js └── filters.js └── test ├── .jshintrc ├── karma.conf.js ├── karma.underscore.conf.js └── spec ├── filter ├── boolean │ ├── angular.js │ ├── conditions.js │ └── is-null.js ├── collection │ ├── after-where.js │ ├── after.js │ ├── before.js │ ├── beforeWhere.js │ ├── chunk-by.js │ ├── concat.js │ ├── contains.js │ ├── count-by.js │ ├── defaults.js │ ├── every.js │ ├── filter-by.js │ ├── first.js │ ├── flatten.js │ ├── fuzzy-by.js │ ├── fuzzy.js │ ├── group-by.js │ ├── is-empty.js │ ├── join.js │ ├── last.js │ ├── map.js │ ├── omit.js │ ├── pick.js │ ├── range.js │ ├── remove-with.js │ ├── remove.js │ ├── reverse.js │ ├── search-field.js │ ├── to-array.js │ ├── unique.js │ ├── where.js │ └── xor.js ├── math │ ├── abs.js │ ├── byte-fmt.js │ ├── degrees.js │ ├── kb-fmt.js │ ├── max.js │ ├── min.js │ ├── percent.js │ ├── radians.js │ ├── radix.js │ ├── short-fmt.js │ └── sum.js └── string │ ├── ends-with.js │ ├── latinize.js │ ├── ltrim.js │ ├── match.js │ ├── phone-us.js │ ├── repeat.js │ ├── rtrim.js │ ├── slugify.js │ ├── split.js │ ├── starts-with.js │ ├── stringular.js │ ├── strip-tags.js │ ├── test.js │ ├── trim.js │ ├── truncate.js │ ├── ucfirst.js │ ├── uri-component-encode.js │ ├── uri-encode.js │ └── wrap.js └── provider └── watcher.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .tmp 3 | .sass-cache 4 | bower_components 5 | app 6 | .idea* 7 | .jshintrc 8 | .editorconfig 9 | .gitattributes 10 | .coveralls.yml 11 | test/coverage 12 | *.iml 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '6' 4 | before_script: 5 | - export DISPLAY=:99.0 6 | - sh -e /etc/init.d/xvfb start 7 | - 'npm install -g bower grunt-cli' 8 | - 'bower install --config.interactive=false' 9 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 'use strict'; 3 | 4 | // Project configuration. 5 | grunt.initConfig({ 6 | pkg: grunt.file.readJSON('package.json'), 7 | meta: { 8 | banner: [ 9 | '/**', 10 | ' * <%= pkg.description %>', 11 | ' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>' + 12 | ' * @link <%= pkg.homepage %>', 13 | ' * @author <%= pkg.author %>', 14 | ' * @license MIT License, http://www.opensource.org/licenses/MIT', 15 | ' */' 16 | ].join('\n') 17 | }, 18 | dirs: { 19 | dest: 'dist' 20 | }, 21 | concat: { 22 | options: { 23 | banner: '<%= meta.banner %>' + '\n' + 24 | '(function ( window, angular, undefined ) {' + '\n', 25 | footer: '})( window, window.angular );' 26 | }, 27 | dist: { 28 | src: ['src/**/*.js'], 29 | dest: '<%= dirs.dest %>/<%= pkg.name %>.js' 30 | } 31 | }, 32 | zip: { 33 | '<%= dirs.dest %>/angular-filter.zip': [ 34 | '<%= dirs.dest %>/<%= pkg.name %>.js', 35 | '<%= dirs.dest %>/<%= pkg.name %>.min.js' 36 | ] 37 | }, 38 | bowerInstall: { 39 | install: { 40 | options: { 41 | targetDir: './bower_components' 42 | } 43 | } 44 | }, 45 | uglify: { 46 | options: { 47 | banner: '<%= meta.banner %>' 48 | }, 49 | dist: { 50 | src: ['<%= concat.dist.dest %>'], 51 | dest: '<%= dirs.dest %>/<%= pkg.name %>.min.js' 52 | } 53 | }, 54 | jshint: { 55 | files: ['Gruntfile.js', 'src/**/*.js'], 56 | options: { 57 | jshintrc: true 58 | } 59 | }, 60 | karma: { 61 | options: { 62 | configFile: 'test/karma.conf.js' 63 | }, 64 | build: { 65 | singleRun: true, 66 | autoWatch: false 67 | }, 68 | debug: { 69 | singleRun: false, 70 | autoWatch: true, 71 | browsers: ['Chrome'] 72 | }, 73 | travis: { 74 | singleRun: true, 75 | autoWatch: false, 76 | browsers: ['Firefox'] 77 | }, 78 | travisUnderscore: { 79 | singleRun: true, 80 | autoWatch: false, 81 | browsers: ['Firefox'], 82 | configFile: 'test/karma.underscore.conf.js' 83 | }, 84 | buildUnderscore: { 85 | configFile: 'test/karma.underscore.conf.js', 86 | singleRun: true, 87 | autoWatch: false 88 | }, 89 | dev: { 90 | autoWatch: true 91 | } 92 | }, 93 | changelog: { 94 | options: { 95 | dest: 'CHANGELOG.md' 96 | } 97 | }, 98 | coveralls: { 99 | options: { 100 | force: true, 101 | recursive: true 102 | }, 103 | all: { 104 | src: 'test/coverage/**/lcov.info' 105 | } 106 | } 107 | }); 108 | 109 | // Load the plugin that provides the "jshint" task. 110 | grunt.loadNpmTasks('grunt-contrib-jshint'); 111 | 112 | // Load the plugin that provides the "concat" task. 113 | grunt.loadNpmTasks('grunt-contrib-concat'); 114 | 115 | // Load the plugin that provides the "uglify" task. 116 | grunt.loadNpmTasks('grunt-contrib-uglify'); 117 | 118 | grunt.loadNpmTasks('grunt-bower-task'); 119 | 120 | grunt.renameTask('bower', 'bowerInstall'); 121 | 122 | grunt.loadNpmTasks('grunt-karma'); 123 | 124 | grunt.loadNpmTasks('grunt-conventional-changelog'); 125 | 126 | grunt.loadNpmTasks('grunt-zip'); 127 | 128 | grunt.loadNpmTasks('grunt-coveralls'); 129 | 130 | // Default task. 131 | grunt.registerTask('default', ['build']); 132 | 133 | // Build task. 134 | grunt.registerTask('build', ['bowerInstall', 'karma:build', 'karma:buildUnderscore', 'concat', 'uglify', 'zip', 'coveralls']); 135 | 136 | grunt.registerTask('test', ['karma:build', 'karma:buildUnderscore']); 137 | 138 | grunt.registerTask('test-debug', ['karma:debug']); 139 | 140 | grunt.registerTask('travis', ['karma:travis', 'karma:travisUnderscore']); 141 | 142 | // Provides the "bump" task. 143 | grunt.registerTask('bump', 'Increment version number', function() { 144 | var versionType = grunt.option('type'); 145 | function bumpVersion(version, versionType) { 146 | var type = {patch: 2, minor: 1, major: 0}, 147 | parts = version.split('.'), 148 | idx = type[versionType || 'patch']; 149 | parts[idx] = parseInt(parts[idx], 10) + 1; 150 | while(++idx < parts.length) { parts[idx] = 0; } 151 | return parts.join('.'); 152 | } 153 | var version; 154 | function updateFile(file) { 155 | var json = grunt.file.readJSON(file); 156 | version = json.version = bumpVersion(json.version, versionType || 'patch'); 157 | grunt.file.write(file, JSON.stringify(json, null, ' ')); 158 | } 159 | updateFile('package.json'); 160 | updateFile('bower.json'); 161 | grunt.log.ok('Version bumped to ' + version); 162 | }); 163 | 164 | }; 165 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-filter", 3 | "main": "dist/angular-filter.js", 4 | "description": "Bunch of useful filters for angularJS(with no external dependencies!)", 5 | "version": "0.5.17", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/a8m/angular-filter.git" 10 | }, 11 | "dependencies": { 12 | "angular": ">=1.4.3" 13 | }, 14 | "devDependencies": { 15 | "angular-mocks": "1.4.3" 16 | }, 17 | "ignore": [ 18 | "node_modules", 19 | "bower_components", 20 | "package.json", 21 | "lib", 22 | "test", 23 | "src", 24 | "Gruntfile.js", 25 | ".gitignore", 26 | "README.md", 27 | "travis.yml", 28 | ".bowercc" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /dist/angular-filter.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a8m/angular-filter/0bc1607f2468bf003a8419718f42f310b1445bd9/dist/angular-filter.zip -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('./dist/angular-filter.js'); 2 | module.exports = 'angular.filter'; 3 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2015 Ariel Mashraki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-filter", 3 | "description": "Bunch of useful filters for angularJS(with no external dependencies!)", 4 | "version": "0.5.17", 5 | "filename": "angular-filter.min.js", 6 | "main": "index.js", 7 | "files": [ 8 | "dist/*.js", 9 | "index.js", 10 | "src" 11 | ], 12 | "browser": "index.js", 13 | "homepage": "https://github.com/a8m/angular-filter", 14 | "author": "Ariel Mashraki ", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/a8m/angular-filter.git" 18 | }, 19 | "engines": { 20 | "node": ">=0.10.0" 21 | }, 22 | "keywords": [ 23 | "angular", 24 | "client", 25 | "browser", 26 | "filter", 27 | "lodash", 28 | "underscore", 29 | "collection" 30 | ], 31 | "dependencies": { 32 | "angular": "*" 33 | }, 34 | "devDependencies": { 35 | "coveralls": "^2.11.11", 36 | "grunt": "^0.4.5", 37 | "grunt-bower": "^0.21.2", 38 | "grunt-bower-task": "*", 39 | "grunt-cli": ">= 0.1.7", 40 | "grunt-contrib-concat": "*", 41 | "grunt-contrib-jshint": "*", 42 | "grunt-contrib-uglify": "*", 43 | "grunt-conventional-changelog": "0.0.12", 44 | "grunt-coveralls": "~0.3.0", 45 | "grunt-karma": "^0.12.0", 46 | "grunt-karma-coveralls": "~2.5.1", 47 | "grunt-zip": "*", 48 | "karma": "^0.13.22", 49 | "karma-chrome-launcher": "~0.1.2", 50 | "karma-coverage": "^0.2.7", 51 | "karma-firefox-launcher": "~0.1.3", 52 | "karma-jasmine": "^0.1.6", 53 | "karma-phantomjs-launcher": "1.0.0", 54 | "phantomjs": "^2.1.7", 55 | "phantomjs-prebuilt": "^2.1.13" 56 | }, 57 | "scripts": { 58 | "test": "grunt test --verbose" 59 | }, 60 | "license": "MIT" 61 | } 62 | -------------------------------------------------------------------------------- /src/_common.js: -------------------------------------------------------------------------------- 1 | /*jshint globalstrict:true*/ 2 | 'use strict'; 3 | 4 | var isDefined = angular.isDefined, 5 | isUndefined = angular.isUndefined, 6 | isFunction = angular.isFunction, 7 | isString = angular.isString, 8 | isNumber = angular.isNumber, 9 | isObject = angular.isObject, 10 | isArray = angular.isArray, 11 | forEach = angular.forEach, 12 | extend = angular.extend, 13 | copy = angular.copy, 14 | equals = angular.equals; 15 | 16 | 17 | /** 18 | * @description 19 | * get an object and return array of values 20 | * @param object 21 | * @returns {Array} 22 | */ 23 | function toArray(object) { 24 | return isArray(object) 25 | ? object 26 | : Object.keys(object).map(function(key) { 27 | return object[key]; 28 | }); 29 | } 30 | 31 | /** 32 | * @param value 33 | * @returns {boolean} 34 | */ 35 | function isNull(value) { 36 | return value === null; 37 | } 38 | 39 | /** 40 | * @description 41 | * return if object contains partial object 42 | * @param partial{object} 43 | * @param object{object} 44 | * @returns {boolean} 45 | */ 46 | function objectContains(partial, object) { 47 | var keys = Object.keys(partial); 48 | 49 | return keys.map(function(el) { 50 | return (object[el] !== undefined) && (object[el] == partial[el]); 51 | }).indexOf(false) == -1; 52 | 53 | } 54 | 55 | /** 56 | * @description 57 | * search for approximate pattern in string 58 | * @param word 59 | * @param pattern 60 | * @returns {*} 61 | */ 62 | function hasApproxPattern(word, pattern) { 63 | // cheaper version of indexOf; instead of creating each 64 | // iteration new str. 65 | function indexOf(word, p, c) { 66 | var j = 0; 67 | while ((p + j) <= word.length) { 68 | if (word.charAt(p + j) == c) return j; 69 | j++; 70 | } 71 | return -1; 72 | } 73 | var p = 0; 74 | for (var i = 0; i <= pattern.length; i++) { 75 | var index = indexOf(word, p, pattern.charAt(i)); 76 | if (index == -1) return false; 77 | p += index + 1; 78 | } 79 | return true 80 | } 81 | 82 | /** 83 | * @description 84 | * return the first n element of an array, 85 | * if expression provided, is returns as long the expression return truthy 86 | * @param array 87 | * @param n {number} 88 | * @param expression {$parse} 89 | * @return array or single object 90 | */ 91 | function getFirstMatches(array, n, expression) { 92 | var count = 0; 93 | 94 | return array.filter(function(elm) { 95 | var rest = isDefined(expression) ? (count < n && expression(elm)) : count < n; 96 | count = rest ? count+1 : count; 97 | 98 | return rest; 99 | }); 100 | } 101 | /** 102 | * Polyfill to ECMA6 String.prototype.contains 103 | */ 104 | if (!String.prototype.contains) { 105 | String.prototype.contains = function() { 106 | return String.prototype.indexOf.apply(this, arguments) !== -1; 107 | }; 108 | } 109 | 110 | /** 111 | * @param num {Number} 112 | * @param decimal {Number} 113 | * @returns {Number} 114 | */ 115 | function convertToDecimal(num, decimal){ 116 | return Math.round(num * Math.pow(10,decimal)) / (Math.pow(10, decimal)); 117 | } 118 | 119 | /** 120 | * @description 121 | * Get an object, and return an array composed of it's properties names(nested too). 122 | * @param obj {Object} 123 | * @param stack {Array} 124 | * @param parent {String} 125 | * @returns {Array} 126 | * @example 127 | * parseKeys({ a:1, b: { c:2, d: { e: 3 } } }) ==> ["a", "b.c", "b.d.e"] 128 | */ 129 | function deepKeys(obj, stack, parent) { 130 | stack = stack || []; 131 | var keys = Object.keys(obj); 132 | 133 | keys.forEach(function(el) { 134 | //if it's a nested object 135 | if(isObject(obj[el]) && !isArray(obj[el])) { 136 | //concatenate the new parent if exist 137 | var p = parent ? parent + '.' + el : parent; 138 | deepKeys(obj[el], stack, p || el); 139 | } else { 140 | //create and save the key 141 | var key = parent ? parent + '.' + el : el; 142 | stack.push(key) 143 | } 144 | }); 145 | return stack 146 | } 147 | 148 | /** 149 | * @description 150 | * Test if given object is a Scope instance 151 | * @param obj 152 | * @returns {Boolean} 153 | */ 154 | function isScope(obj) { 155 | return obj && obj.$evalAsync && obj.$watch; 156 | } 157 | -------------------------------------------------------------------------------- /src/_filter/boolean/angular.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name a8m.angular 4 | * @kind function 5 | * 6 | * @description 7 | * reference to angular function 8 | */ 9 | 10 | angular.module('a8m.angular', []) 11 | 12 | .filter('isUndefined', function () { 13 | return function (input) { 14 | return angular.isUndefined(input); 15 | } 16 | }) 17 | .filter('isDefined', function() { 18 | return function (input) { 19 | return angular.isDefined(input); 20 | } 21 | }) 22 | .filter('isFunction', function() { 23 | return function (input) { 24 | return angular.isFunction(input); 25 | } 26 | }) 27 | .filter('isString', function() { 28 | return function (input) { 29 | return angular.isString(input) 30 | } 31 | }) 32 | .filter('isNumber', function() { 33 | return function (input) { 34 | return angular.isNumber(input); 35 | } 36 | }) 37 | .filter('isArray', function() { 38 | return function (input) { 39 | return angular.isArray(input); 40 | } 41 | }) 42 | .filter('isObject', function() { 43 | return function (input) { 44 | return angular.isObject(input); 45 | } 46 | }) 47 | .filter('isEqual', function() { 48 | return function (o1, o2) { 49 | return angular.equals(o1, o2); 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /src/_filter/boolean/conditions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name a8m.conditions 4 | * @kind function 5 | * 6 | * @description 7 | * reference to math conditions 8 | */ 9 | angular.module('a8m.conditions', []) 10 | 11 | .filter({ 12 | isGreaterThan : isGreaterThanFilter, 13 | '>' : isGreaterThanFilter, 14 | 15 | isGreaterThanOrEqualTo : isGreaterThanOrEqualToFilter, 16 | '>=' : isGreaterThanOrEqualToFilter, 17 | 18 | isLessThan : isLessThanFilter, 19 | '<' : isLessThanFilter, 20 | 21 | isLessThanOrEqualTo : isLessThanOrEqualToFilter, 22 | '<=' : isLessThanOrEqualToFilter, 23 | 24 | isEqualTo : isEqualToFilter, 25 | '==' : isEqualToFilter, 26 | 27 | isNotEqualTo : isNotEqualToFilter, 28 | '!=' : isNotEqualToFilter, 29 | 30 | isIdenticalTo : isIdenticalToFilter, 31 | '===' : isIdenticalToFilter, 32 | 33 | isNotIdenticalTo : isNotIdenticalToFilter, 34 | '!==' : isNotIdenticalToFilter 35 | }); 36 | 37 | function isGreaterThanFilter() { 38 | return function (input, check) { 39 | return input > check; 40 | }; 41 | } 42 | 43 | function isGreaterThanOrEqualToFilter() { 44 | return function (input, check) { 45 | return input >= check; 46 | }; 47 | } 48 | 49 | function isLessThanFilter() { 50 | return function (input, check) { 51 | return input < check; 52 | }; 53 | } 54 | 55 | function isLessThanOrEqualToFilter() { 56 | return function (input, check) { 57 | return input <= check; 58 | }; 59 | } 60 | 61 | function isEqualToFilter() { 62 | return function (input, check) { 63 | return input == check; 64 | }; 65 | } 66 | 67 | function isNotEqualToFilter() { 68 | return function (input, check) { 69 | return input != check; 70 | }; 71 | } 72 | 73 | function isIdenticalToFilter() { 74 | return function (input, check) { 75 | return input === check; 76 | }; 77 | } 78 | 79 | function isNotIdenticalToFilter() { 80 | return function (input, check) { 81 | return input !== check; 82 | }; 83 | } -------------------------------------------------------------------------------- /src/_filter/boolean/is-null.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name isNull 4 | * @kind function 5 | * 6 | * @description 7 | * checks if value is null or not 8 | * @return Boolean 9 | */ 10 | angular.module('a8m.is-null', []) 11 | .filter('isNull', function () { 12 | return function(input) { 13 | return isNull(input); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /src/_filter/collection/after-where.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name after-where 4 | * @kind function 5 | * 6 | * @description 7 | * get a collection and properties object, and returns all of the items 8 | * in the collection after the first that found with the given properties. 9 | * 10 | */ 11 | angular.module('a8m.after-where', []) 12 | .filter('afterWhere', function() { 13 | return function (collection, object) { 14 | 15 | collection = isObject(collection) 16 | ? toArray(collection) 17 | : collection; 18 | 19 | if(!isArray(collection) || isUndefined(object)) return collection; 20 | 21 | var index = collection.map( function( elm ) { 22 | return objectContains(object, elm); 23 | }).indexOf( true ); 24 | 25 | return collection.slice((index === -1) ? 0 : index); 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /src/_filter/collection/after.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name after 4 | * @kind function 5 | * 6 | * @description 7 | * get a collection and specified count, and returns all of the items 8 | * in the collection after the specified count. 9 | * 10 | */ 11 | 12 | angular.module('a8m.after', []) 13 | .filter('after', function() { 14 | return function (collection, count) { 15 | collection = isObject(collection) 16 | ? toArray(collection) 17 | : collection; 18 | 19 | return (isArray(collection)) 20 | ? collection.slice(count) 21 | : collection; 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /src/_filter/collection/before-where.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name before-where 4 | * @kind function 5 | * 6 | * @description 7 | * get a collection and properties object, and returns all of the items 8 | * in the collection before the first that found with the given properties. 9 | */ 10 | angular.module('a8m.before-where', []) 11 | .filter('beforeWhere', function() { 12 | return function (collection, object) { 13 | 14 | collection = isObject(collection) 15 | ? toArray(collection) 16 | : collection; 17 | 18 | if(!isArray(collection) || isUndefined(object)) return collection; 19 | 20 | var index = collection.map( function( elm ) { 21 | return objectContains(object, elm); 22 | }).indexOf( true ); 23 | 24 | return collection.slice(0, (index === -1) ? collection.length : ++index); 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /src/_filter/collection/before.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name before 4 | * @kind function 5 | * 6 | * @description 7 | * get a collection and specified count, and returns all of the items 8 | * in the collection before the specified count. 9 | */ 10 | angular.module('a8m.before', []) 11 | .filter('before', function() { 12 | return function (collection, count) { 13 | collection = isObject(collection) 14 | ? toArray(collection) 15 | : collection; 16 | 17 | return (isArray(collection)) 18 | ? collection.slice(0, (!count) ? count : --count) 19 | : collection; 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /src/_filter/collection/chunk-by.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name chunkBy 4 | * @kind function 5 | * 6 | * @description 7 | * Collect data into fixed-length chunks or blocks 8 | */ 9 | 10 | angular.module('a8m.chunk-by', ['a8m.filter-watcher']) 11 | .filter('chunkBy', ['filterWatcher', function (filterWatcher) { 12 | return function (array, n, fillVal) { 13 | 14 | return filterWatcher.isMemoized('chunkBy', arguments) || 15 | filterWatcher.memoize('chunkBy', arguments, this, 16 | _chunkBy(array, n, fillVal)); 17 | /** 18 | * @description 19 | * Get array with size `n` in `val` inside it. 20 | * @param n 21 | * @param val 22 | * @returns {Array} 23 | */ 24 | function fill(n, val) { 25 | var ret = []; 26 | while (n--) ret[n] = val; 27 | return ret; 28 | } 29 | 30 | function _chunkBy(array, n, fillVal) { 31 | if (!isArray(array)) return array; 32 | return array.map(function (el, i, self) { 33 | i = i * n; 34 | el = self.slice(i, i + n); 35 | return !isUndefined(fillVal) && el.length < n 36 | ? el.concat(fill(n - el.length, fillVal)) 37 | : el; 38 | }).slice(0, Math.ceil(array.length / n)); 39 | } 40 | } 41 | }]); 42 | -------------------------------------------------------------------------------- /src/_filter/collection/concat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name concat 4 | * @kind function 5 | * 6 | * @description 7 | * get (array/object, object/array) and return merged collection 8 | */ 9 | angular.module('a8m.concat', []) 10 | .filter('concat', [function () { 11 | return function (collection, joined) { 12 | 13 | if (isUndefined(joined)) return collection; 14 | 15 | if (isArray(collection)) { 16 | return isObject(joined) 17 | ? collection.concat(toArray(joined)) 18 | : collection.concat(joined); 19 | } 20 | 21 | if (isObject(collection)) { 22 | var array = toArray(collection); 23 | return (isObject(joined)) 24 | ? array.concat(toArray(joined)) 25 | : array.concat(joined); 26 | } 27 | return collection; 28 | }; 29 | } 30 | ]); 31 | -------------------------------------------------------------------------------- /src/_filter/collection/contains.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name contains 4 | * @kind function 5 | * 6 | * @description 7 | * Checks if given expression is present in one or more object in the collection 8 | */ 9 | angular.module('a8m.contains', []) 10 | .filter({ 11 | contains: ['$parse', containsFilter], 12 | some: ['$parse', containsFilter] 13 | }); 14 | 15 | function containsFilter($parse) { 16 | return function (collection, expression) { 17 | 18 | collection = isObject(collection) ? toArray(collection) : collection; 19 | 20 | if(!isArray(collection) || isUndefined(expression)) { 21 | return false; 22 | } 23 | 24 | return collection.some(function(elm) { 25 | return ((isString(expression) && isObject(elm)) || isFunction(expression)) 26 | ? $parse(expression)(elm) 27 | : elm === expression; 28 | }); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/_filter/collection/count-by.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name countBy 4 | * @kind function 5 | * 6 | * @description 7 | * Sorts a list into groups and returns a count for the number of objects in each group. 8 | */ 9 | 10 | angular.module('a8m.count-by', []) 11 | 12 | .filter('countBy', [ '$parse', function ( $parse ) { 13 | return function (collection, property) { 14 | 15 | var result = {}, 16 | get = $parse(property), 17 | prop; 18 | 19 | collection = (isObject(collection)) ? toArray(collection) : collection; 20 | 21 | if(!isArray(collection) || isUndefined(property)) { 22 | return collection; 23 | } 24 | 25 | collection.forEach( function( elm ) { 26 | prop = get(elm); 27 | 28 | if(!result[prop]) { 29 | result[prop] = 0; 30 | } 31 | 32 | result[prop]++; 33 | }); 34 | 35 | return result; 36 | } 37 | }]); 38 | -------------------------------------------------------------------------------- /src/_filter/collection/defaults.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name defaults 4 | * @kind function 5 | * 6 | * @description 7 | * defaultsFilter allows to specify a default fallback value for properties that resolve to undefined. 8 | */ 9 | angular.module('a8m.defaults', []) 10 | .filter('defaults', ['$parse', function( $parse ) { 11 | return function(collection, defaults) { 12 | 13 | collection = isObject(collection) ? toArray(collection) : collection; 14 | 15 | if(!isArray(collection) || !isObject(defaults)) { 16 | return collection; 17 | } 18 | 19 | var keys = deepKeys(defaults); 20 | 21 | collection.forEach(function(elm) { 22 | //loop through all the keys 23 | keys.forEach(function(key) { 24 | var getter = $parse(key); 25 | var setter = getter.assign; 26 | //if it's not exist 27 | if(isUndefined(getter(elm))) { 28 | //get from defaults, and set to the returned object 29 | setter(elm, getter(defaults)) 30 | } 31 | }); 32 | }); 33 | 34 | return collection; 35 | } 36 | }]); -------------------------------------------------------------------------------- /src/_filter/collection/every.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name every 4 | * @kind function 5 | * 6 | * @description 7 | * Checks if given expression is present in all members in the collection 8 | * 9 | */ 10 | angular.module('a8m.every', []) 11 | .filter('every', ['$parse', function($parse) { 12 | return function (collection, expression) { 13 | collection = isObject(collection) ? toArray(collection) : collection; 14 | 15 | if(!isArray(collection) || isUndefined(expression)) { 16 | return true; 17 | } 18 | 19 | return collection.every( function(elm) { 20 | return (isObject(elm) || isFunction(expression)) 21 | ? $parse(expression)(elm) 22 | : elm === expression; 23 | }); 24 | } 25 | }]); 26 | -------------------------------------------------------------------------------- /src/_filter/collection/filter-by.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name filterBy 4 | * @kind function 5 | * 6 | * @description 7 | * filter by specific properties, avoid the rest 8 | */ 9 | angular.module('a8m.filter-by', []) 10 | .filter('filterBy', ['$parse', function( $parse ) { 11 | return function(collection, properties, search, strict) { 12 | var comparator; 13 | 14 | search = (isString(search) || isNumber(search)) ? 15 | String(search).toLowerCase() : undefined; 16 | 17 | collection = isObject(collection) ? toArray(collection) : collection; 18 | 19 | if(!isArray(collection) || isUndefined(search)) { 20 | return collection; 21 | } 22 | 23 | return collection.filter(function(elm) { 24 | return properties.some(function(prop) { 25 | 26 | /** 27 | * check if there is concatenate properties 28 | * example: 29 | * object: { first: 'foo', last:'bar' } 30 | * filterBy: ['first + last'] => search by full name(i.e 'foo bar') 31 | */ 32 | if(!~prop.indexOf('+')) { 33 | comparator = $parse(prop)(elm) 34 | } else { 35 | var propList = prop.replace(/\s+/g, '').split('+'); 36 | comparator = propList 37 | .map(function(prop) { return $parse(prop)(elm); }) 38 | .join(' '); 39 | } 40 | 41 | if (!isString(comparator) && !isNumber(comparator)) { 42 | return false; 43 | } 44 | 45 | comparator = String(comparator).toLowerCase(); 46 | 47 | return strict ? comparator === search : comparator.contains(search); 48 | }); 49 | }); 50 | } 51 | }]); 52 | -------------------------------------------------------------------------------- /src/_filter/collection/first.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name first 4 | * @kind function 5 | * 6 | * @description 7 | * Gets the first element or first n elements of an array 8 | * if callback is provided, is returns as long the callback return truthy 9 | */ 10 | angular.module('a8m.first', []) 11 | .filter('first', ['$parse', function( $parse ) { 12 | return function(collection) { 13 | var n 14 | , getter 15 | , args; 16 | 17 | collection = isObject(collection) 18 | ? toArray(collection) 19 | : collection; 20 | 21 | if(!isArray(collection)) { 22 | return collection; 23 | } 24 | 25 | args = Array.prototype.slice.call(arguments, 1); 26 | n = (isNumber(args[0])) ? args[0] : 1; 27 | getter = (!isNumber(args[0])) ? args[0] : (!isNumber(args[1])) ? args[1] : undefined; 28 | 29 | return (args.length) ? getFirstMatches(collection, n,(getter) ? $parse(getter) : getter) : 30 | collection[0]; 31 | } 32 | }]); 33 | -------------------------------------------------------------------------------- /src/_filter/collection/flatten.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name flatten 4 | * @kind function 5 | * 6 | * @description 7 | * Flattens a nested array (the nesting can be to any depth). 8 | * If you pass shallow, the array will only be flattened a single level 9 | */ 10 | angular.module('a8m.flatten', []) 11 | .filter('flatten', function () { 12 | return function(collection, shallow) { 13 | 14 | shallow = shallow || false; 15 | collection = isObject(collection) 16 | ? toArray(collection) 17 | : collection; 18 | 19 | if(!isArray(collection)) { 20 | return collection; 21 | } 22 | 23 | return !shallow 24 | ? flatten(collection, 0) 25 | : [].concat.apply([], collection); 26 | } 27 | }); 28 | 29 | /** 30 | * flatten nested array (the nesting can be to any depth). 31 | * @param array {Array} 32 | * @param i {int} 33 | * @returns {Array} 34 | * @private 35 | */ 36 | function flatten(array, i) { 37 | i = i || 0; 38 | 39 | if(i >= array.length) 40 | return array; 41 | 42 | if(isArray(array[i])) { 43 | return flatten(array.slice(0,i) 44 | .concat(array[i], array.slice(i+1)), i); 45 | } 46 | return flatten(array, i+1); 47 | } 48 | -------------------------------------------------------------------------------- /src/_filter/collection/fuzzy-by.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name fuzzyByKey 4 | * @kind function 5 | * 6 | * @description 7 | * fuzzy string searching by key 8 | */ 9 | angular.module('a8m.fuzzy-by', []) 10 | .filter('fuzzyBy', ['$parse', function ( $parse ) { 11 | return function (collection, property, search, csensitive) { 12 | 13 | var sensitive = csensitive || false, 14 | prop, getter; 15 | 16 | collection = isObject(collection) ? toArray(collection) : collection; 17 | 18 | if(!isArray(collection) || isUndefined(property) 19 | || isUndefined(search)) { 20 | return collection; 21 | } 22 | 23 | getter = $parse(property); 24 | 25 | return collection.filter(function(elm) { 26 | 27 | prop = getter(elm); 28 | if(!isString(prop)) { 29 | return false; 30 | } 31 | 32 | prop = (sensitive) ? prop : prop.toLowerCase(); 33 | search = (sensitive) ? search : search.toLowerCase(); 34 | 35 | return hasApproxPattern(prop, search) !== false 36 | }) 37 | } 38 | 39 | }]); -------------------------------------------------------------------------------- /src/_filter/collection/fuzzy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name fuzzy 4 | * @kind function 5 | * 6 | * @description 7 | * fuzzy string searching for array of strings, objects 8 | */ 9 | angular.module('a8m.fuzzy', []) 10 | .filter('fuzzy', function () { 11 | return function (collection, search, csensitive) { 12 | var sensitive = csensitive || false; 13 | collection = isObject(collection) ? toArray(collection) : collection; 14 | 15 | if(!isArray(collection) || isUndefined(search)) { 16 | return collection; 17 | } 18 | 19 | search = (sensitive) ? search : search.toLowerCase(); 20 | 21 | return collection.filter(function(elm) { 22 | if(isString(elm)) { 23 | elm = (sensitive) ? elm : elm.toLowerCase(); 24 | return hasApproxPattern(elm, search) !== false 25 | } 26 | return (isObject(elm)) ? _hasApproximateKey(elm, search) : false; 27 | }); 28 | 29 | /** 30 | * checks if object has key{string} that match 31 | * to fuzzy search pattern 32 | * @param object 33 | * @param search 34 | * @returns {boolean} 35 | * @private 36 | */ 37 | function _hasApproximateKey(object, search) { 38 | var properties = Object.keys(object), 39 | prop, flag; 40 | return 0 < properties.filter(function (elm) { 41 | prop = object[elm]; 42 | 43 | //avoid iteration if we found some key that equal[performance] 44 | if(flag) return true; 45 | 46 | if (isString(prop)) { 47 | prop = (sensitive) ? prop : prop.toLowerCase(); 48 | return flag = (hasApproxPattern(prop, search) !== false); 49 | } 50 | 51 | return false; 52 | 53 | }).length; 54 | } 55 | } 56 | }); 57 | -------------------------------------------------------------------------------- /src/_filter/collection/group-by.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name groupBy 4 | * @kind function 5 | * 6 | * @description 7 | * Create an object composed of keys generated from the result of running each element of a collection, 8 | * each key is an array of the elements. 9 | */ 10 | 11 | angular.module('a8m.group-by', [ 'a8m.filter-watcher' ]) 12 | .filter('groupBy', [ '$parse', 'filterWatcher', function ( $parse, filterWatcher ) { 13 | return function (collection, property) { 14 | 15 | if(!isObject(collection) || isUndefined(property)) { 16 | return collection; 17 | } 18 | 19 | return filterWatcher.isMemoized('groupBy', arguments) || 20 | filterWatcher.memoize('groupBy', arguments, this, 21 | _groupBy(collection, $parse(property))); 22 | 23 | /** 24 | * groupBy function 25 | * @param collection 26 | * @param getter 27 | * @returns {{}} 28 | */ 29 | function _groupBy(collection, getter) { 30 | var result = {}; 31 | var prop; 32 | 33 | forEach( collection, function( elm ) { 34 | prop = getter(elm); 35 | 36 | if(!result[prop]) { 37 | result[prop] = []; 38 | } 39 | result[prop].push(elm); 40 | }); 41 | return result; 42 | } 43 | } 44 | }]); 45 | -------------------------------------------------------------------------------- /src/_filter/collection/is-empty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name isEmpty 4 | * @kind function 5 | * 6 | * @description 7 | * get collection or string and return if it empty 8 | */ 9 | angular.module('a8m.is-empty', []) 10 | .filter('isEmpty', function () { 11 | return function(collection) { 12 | return isObject(collection) 13 | ? !toArray(collection).length 14 | : !collection.length; 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /src/_filter/collection/join.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name join 4 | * @kind function 5 | * 6 | * @description 7 | * join a collection by a provided delimiter (space by default) 8 | */ 9 | angular.module('a8m.join', []) 10 | .filter('join', function () { 11 | return function (input, delimiter) { 12 | if (isUndefined(input) || !isArray(input)) { 13 | return input; 14 | } 15 | if (isUndefined(delimiter)) delimiter = ' '; 16 | 17 | return input.join(delimiter); 18 | }; 19 | }) 20 | ; 21 | -------------------------------------------------------------------------------- /src/_filter/collection/last.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name last 4 | * @kind function 5 | * 6 | * @description 7 | * Gets the last element or last n elements of an array 8 | * if callback is provided, is returns as long the callback return truthy 9 | */ 10 | angular.module('a8m.last', []) 11 | .filter('last', ['$parse', function( $parse ) { 12 | return function(collection) { 13 | var n 14 | , getter 15 | , args 16 | //cuz reverse change our src collection 17 | //and we don't want side effects 18 | , reversed = copy(collection); 19 | 20 | reversed = isObject(reversed) 21 | ? toArray(reversed) 22 | : reversed; 23 | 24 | if(!isArray(reversed)) { 25 | return reversed; 26 | } 27 | 28 | args = Array.prototype.slice.call(arguments, 1); 29 | n = (isNumber(args[0])) ? args[0] : 1; 30 | getter = (!isNumber(args[0])) ? args[0] : (!isNumber(args[1])) ? args[1] : undefined; 31 | 32 | return (args.length) 33 | //send reversed collection as arguments, and reverse it back as result 34 | ? getFirstMatches(reversed.reverse(), n,(getter) ? $parse(getter) : getter).reverse() 35 | //get the last element 36 | : reversed[reversed.length-1]; 37 | } 38 | }]); 39 | -------------------------------------------------------------------------------- /src/_filter/collection/map.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name map 4 | * @kind function 5 | * 6 | * @description 7 | * Returns a new collection of the results of each expression execution. 8 | */ 9 | angular.module('a8m.map', []) 10 | .filter('map', ['$parse', function($parse) { 11 | return function (collection, expression) { 12 | 13 | collection = isObject(collection) 14 | ? toArray(collection) 15 | : collection; 16 | 17 | if(!isArray(collection) || isUndefined(expression)) { 18 | return collection; 19 | } 20 | 21 | return collection.map(function (elm) { 22 | return $parse(expression)(elm); 23 | }); 24 | } 25 | }]); 26 | -------------------------------------------------------------------------------- /src/_filter/collection/omit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name omit 4 | * @kind function 5 | * 6 | * @description 7 | * filter collection by expression 8 | */ 9 | 10 | angular.module('a8m.omit', []) 11 | 12 | .filter('omit', ['$parse', function($parse) { 13 | return function (collection, expression) { 14 | 15 | collection = isObject(collection) 16 | ? toArray(collection) 17 | : collection; 18 | 19 | if(!isArray(collection) || isUndefined(expression)) { 20 | return collection; 21 | } 22 | 23 | return collection.filter(function (elm) { 24 | return !($parse(expression)(elm)); 25 | }); 26 | } 27 | }]); 28 | -------------------------------------------------------------------------------- /src/_filter/collection/pick.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name pick 4 | * @kind function 5 | * 6 | * @description 7 | * filter collection by expression 8 | */ 9 | 10 | angular.module('a8m.pick', []) 11 | 12 | .filter('pick', ['$parse', function($parse) { 13 | return function (collection, expression) { 14 | 15 | collection = isObject(collection) 16 | ? toArray(collection) 17 | : collection; 18 | 19 | if(!isArray(collection) || isUndefined(expression)) { 20 | return collection; 21 | } 22 | 23 | return collection.filter(function (elm) { 24 | return $parse(expression)(elm); 25 | }); 26 | } 27 | }]); 28 | -------------------------------------------------------------------------------- /src/_filter/collection/range.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name range 4 | * @kind function 5 | * 6 | * @description 7 | * rangeFilter provides some support for a for loop using numbers 8 | */ 9 | angular.module('a8m.range', []) 10 | .filter('range', function () { 11 | return function (input, total, start, increment, cb) { 12 | start = start || 0; 13 | increment = increment || 1; 14 | for (var i = 0; i < parseInt(total); i++) { 15 | var j = start + i * increment; 16 | input.push(isFunction(cb) ? cb(j) : j); 17 | } 18 | return input; 19 | }; 20 | }); -------------------------------------------------------------------------------- /src/_filter/collection/remove-with.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name removeWith 4 | * @kind function 5 | * 6 | * @description 7 | * get collection and properties object, and removed elements 8 | * with this properties 9 | */ 10 | 11 | angular.module('a8m.remove-with', []) 12 | .filter('removeWith', function() { 13 | return function (collection, object) { 14 | 15 | if(isUndefined(object)) { 16 | return collection; 17 | } 18 | collection = isObject(collection) 19 | ? toArray(collection) 20 | : collection; 21 | 22 | return collection.filter(function (elm) { 23 | return !objectContains(object, elm); 24 | }); 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /src/_filter/collection/remove.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @ngdoc filter 4 | * @name remove 5 | * @kind function 6 | * 7 | * @description 8 | * remove specific members from collection 9 | */ 10 | 11 | angular.module('a8m.remove', []) 12 | 13 | .filter('remove', function () { 14 | return function (collection) { 15 | collection = isObject(collection) ? toArray(collection) : collection; 16 | var args = Array.prototype.slice.call(arguments, 1); 17 | 18 | if(!isArray(collection)) { 19 | return collection; 20 | } 21 | 22 | return collection.filter( function( member ) { 23 | return !args.some(function(nest) { 24 | return equals(nest, member); 25 | }) 26 | }); 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /src/_filter/collection/reverse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name reverse 4 | * @kind function 5 | * 6 | * @description 7 | * Reverses a string or collection 8 | */ 9 | angular.module('a8m.reverse', []) 10 | .filter('reverse',[ function () { 11 | return function (input) { 12 | input = isObject(input) ? toArray(input) : input; 13 | 14 | if(isString(input)) { 15 | return input.split('').reverse().join(''); 16 | } 17 | 18 | return isArray(input) 19 | ? input.slice().reverse() 20 | : input; 21 | } 22 | }]); 23 | -------------------------------------------------------------------------------- /src/_filter/collection/search-field.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name searchField 4 | * @kind function 5 | * 6 | * @description 7 | * for each member, join several strings field and add them to 8 | * new field called 'searchField' (use for search filtering) 9 | */ 10 | angular.module('a8m.search-field', []) 11 | .filter('searchField', ['$parse', function ($parse) { 12 | return function (collection) { 13 | 14 | var get, field; 15 | 16 | collection = isObject(collection) ? toArray(collection) : collection; 17 | 18 | var args = Array.prototype.slice.call(arguments, 1); 19 | 20 | if(!isArray(collection) || !args.length) { 21 | return collection; 22 | } 23 | 24 | return collection.map(function(member) { 25 | 26 | field = args.map(function(field) { 27 | get = $parse(field); 28 | return get(member); 29 | }).join(' '); 30 | 31 | return extend(member, { searchField: field }); 32 | }); 33 | } 34 | }]); 35 | -------------------------------------------------------------------------------- /src/_filter/collection/to-array.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name toArray 4 | * @kind function 5 | * 6 | * @description 7 | * Convert objects into stable arrays. 8 | * if addKey set to true,the filter also attaches a new property 9 | * $key to the value containing the original key that was used in 10 | * the object we are iterating over to reference the property 11 | */ 12 | angular.module('a8m.to-array', []) 13 | .filter('toArray', function() { 14 | return function (collection, addKey) { 15 | 16 | if(!isObject(collection)) { 17 | return collection; 18 | } 19 | 20 | return !addKey 21 | ? toArray(collection) 22 | : Object.keys(collection).map(function (key) { 23 | return extend(collection[key], { $key: key }); 24 | }); 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /src/_filter/collection/unique.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name unique/uniq 4 | * @kind function 5 | * 6 | * @description 7 | * get collection and filter duplicate members 8 | * if uniqueFilter get a property(nested to) as argument it's 9 | * filter by this property as unique identifier 10 | */ 11 | 12 | angular.module('a8m.unique', []) 13 | .filter({ 14 | unique: ['$parse', uniqFilter], 15 | uniq: ['$parse', uniqFilter] 16 | }); 17 | 18 | function uniqFilter($parse) { 19 | return function (collection, property) { 20 | 21 | collection = isObject(collection) ? toArray(collection) : collection; 22 | 23 | if (!isArray(collection)) { 24 | return collection; 25 | } 26 | 27 | //store all unique identifiers 28 | var uniqueItems = [], 29 | get = $parse(property); 30 | 31 | return (isUndefined(property)) 32 | //if it's kind of primitive array 33 | ? collection.filter(function (elm, pos, self) { 34 | return self.indexOf(elm) === pos; 35 | }) 36 | //else compare with equals 37 | : collection.filter(function (elm) { 38 | var prop = get(elm); 39 | if(some(uniqueItems, prop)) { 40 | return false; 41 | } 42 | uniqueItems.push(prop); 43 | return true; 44 | }); 45 | 46 | //checked if the unique identifier is already exist 47 | function some(array, member) { 48 | if(isUndefined(member)) { 49 | return false; 50 | } 51 | return array.some(function(el) { 52 | return equals(el, member); 53 | }); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/_filter/collection/where.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name where 4 | * @kind function 5 | * 6 | * @description 7 | * of each element in a collection to the given properties object, 8 | * returning an array of all elements that have equivalent property values. 9 | * 10 | */ 11 | angular.module('a8m.where', []) 12 | .filter('where', function() { 13 | return function (collection, object) { 14 | if(isUndefined(object)) return collection; 15 | collection = isObject(collection) 16 | ? toArray(collection) 17 | : collection; 18 | 19 | return collection.filter(function (elm) { 20 | return objectContains(object, elm); 21 | }); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /src/_filter/collection/xor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name xor 4 | * @kind function 5 | * 6 | * @description 7 | * Exclusive or filter by expression 8 | */ 9 | 10 | angular.module('a8m.xor', []) 11 | 12 | .filter('xor', ['$parse', function($parse) { 13 | return function (col1, col2, expression) { 14 | 15 | expression = expression || false; 16 | 17 | col1 = isObject(col1) ? toArray(col1) : col1; 18 | col2 = isObject(col2) ? toArray(col2) : col2; 19 | 20 | if(!isArray(col1) || !isArray(col2)) return col1; 21 | 22 | return col1.concat(col2) 23 | .filter(function(elm) { 24 | return !(some(elm, col1) && some(elm, col2)); 25 | }); 26 | 27 | function some(el, col) { 28 | var getter = $parse(expression); 29 | return col.some(function(dElm) { 30 | return expression 31 | ? equals(getter(dElm), getter(el)) 32 | : equals(dElm, el); 33 | }); 34 | } 35 | } 36 | }]); 37 | -------------------------------------------------------------------------------- /src/_filter/math/abs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name abs 4 | * @kind function 5 | * 6 | * @description 7 | * Will return the absolute value of a number 8 | */ 9 | angular.module('a8m.math.abs', []) 10 | .filter('abs', function () { 11 | return function (input) { 12 | return Math.abs(input); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /src/_filter/math/byte-fmt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name formatBytes 4 | * @kind function 5 | * 6 | * @description 7 | * Convert bytes into appropriate display 8 | * 1024 bytes => 1 KB 9 | */ 10 | angular.module('a8m.math.byteFmt', []) 11 | .filter('byteFmt', function () { 12 | var compared = [{str: 'B', val: 1024}]; 13 | ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'].forEach(function(el, i) { 14 | compared.push({str: el, val: compared[i].val * 1024 }); 15 | }); 16 | return function (bytes, decimal) { 17 | if(isNumber(decimal) && isFinite(decimal) && decimal%1===0 && decimal >= 0 && 18 | isNumber(bytes) && isFinite(bytes)) { 19 | var i = 0; 20 | while (i < compared.length-1 && bytes >= compared[i].val) i++; 21 | bytes /= i > 0 ? compared[i-1].val : 1; 22 | return convertToDecimal(bytes, decimal) + ' ' + compared[i].str; 23 | } 24 | return 'NaN'; 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /src/_filter/math/degrees.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name degrees 4 | * @kind function 5 | * 6 | * @description 7 | * Convert angle from radians to degrees 8 | */ 9 | angular.module('a8m.math.degrees', []) 10 | .filter('degrees', function () { 11 | return function (radians, decimal) { 12 | // if decimal is not an integer greater than -1, we cannot do. quit with error "NaN" 13 | // if degrees is not a real number, we cannot do also. quit with error "NaN" 14 | if(isNumber(decimal) && isFinite(decimal) && decimal%1===0 && decimal >= 0 && 15 | isNumber(radians) && isFinite(radians)) { 16 | var degrees = (radians * 180) / Math.PI; 17 | return Math.round(degrees * Math.pow(10,decimal)) / (Math.pow(10,decimal)); 18 | } else { 19 | return 'NaN'; 20 | } 21 | } 22 | }); 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/_filter/math/kb-fmt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name formatBytes 4 | * @kind function 5 | * 6 | * @description 7 | * Convert bytes into appropriate display 8 | * 1024 kilobytes => 1 MB 9 | */ 10 | angular.module('a8m.math.kbFmt', []) 11 | .filter('kbFmt', function () { 12 | var compared = [{str: 'KB', val: 1024}]; 13 | ['MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'].forEach(function(el, i) { 14 | compared.push({str: el, val: compared[i].val * 1024 }); 15 | }); 16 | return function (bytes, decimal) { 17 | if(isNumber(decimal) && isFinite(decimal) && decimal%1===0 && decimal >= 0 && 18 | isNumber(bytes) && isFinite(bytes)) { 19 | var i = 0; 20 | while (i < compared.length-1 && bytes >= compared[i].val) i++; 21 | bytes /= i > 0 ? compared[i-1].val : 1; 22 | return convertToDecimal(bytes, decimal) + ' ' + compared[i].str; 23 | } 24 | return 'NaN'; 25 | } 26 | }); -------------------------------------------------------------------------------- /src/_filter/math/max.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name max 4 | * @kind function 5 | * 6 | * @description 7 | * Math.max will get an array and return the max value. if an expression 8 | * is provided, will return max value by expression. 9 | */ 10 | angular.module('a8m.math.max', []) 11 | .filter('max', ['$parse', function ($parse) { 12 | return function (input, expression) { 13 | 14 | if(!isArray(input)) { 15 | return input; 16 | } 17 | return isUndefined(expression) 18 | ? Math.max.apply(Math, input) 19 | : input[indexByMax(input, expression)]; 20 | }; 21 | 22 | /** 23 | * @private 24 | * @param array 25 | * @param exp 26 | * @returns {number|*|Number} 27 | */ 28 | function indexByMax(array, exp) { 29 | var mappedArray = array.map(function(elm){ 30 | return $parse(exp)(elm); 31 | }); 32 | return mappedArray.indexOf(Math.max.apply(Math, mappedArray)); 33 | } 34 | }]); -------------------------------------------------------------------------------- /src/_filter/math/min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name min 4 | * @kind function 5 | * 6 | * @description 7 | * Math.min will get an array and return the min value. if an expression 8 | * is provided, will return min value by expression. 9 | */ 10 | angular.module('a8m.math.min', []) 11 | .filter('min', ['$parse', function ($parse) { 12 | return function (input, expression) { 13 | 14 | if(!isArray(input)) { 15 | return input; 16 | } 17 | return isUndefined(expression) 18 | ? Math.min.apply(Math, input) 19 | : input[indexByMin(input, expression)]; 20 | }; 21 | 22 | /** 23 | * @private 24 | * @param array 25 | * @param exp 26 | * @returns {number|*|Number} 27 | */ 28 | function indexByMin(array, exp) { 29 | var mappedArray = array.map(function(elm){ 30 | return $parse(exp)(elm); 31 | }); 32 | return mappedArray.indexOf(Math.min.apply(Math, mappedArray)); 33 | } 34 | }]); -------------------------------------------------------------------------------- /src/_filter/math/percent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name Percent 4 | * @kind function 5 | * 6 | * @description 7 | * percentage between two numbers 8 | */ 9 | angular.module('a8m.math.percent', []) 10 | .filter('percent', function () { 11 | return function (input, divided, round) { 12 | 13 | var divider = isString(input) ? Number(input) : input; 14 | divided = divided || 100; 15 | round = round || false; 16 | 17 | if (!isNumber(divider) || isNaN(divider)) return input; 18 | 19 | return round 20 | ? Math.round((divider / divided) * 100) 21 | : (divider / divided) * 100; 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /src/_filter/math/radians.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name toRadians 4 | * @kind function 5 | * 6 | * @description 7 | * Convert angle from degrees to radians 8 | */ 9 | angular.module('a8m.math.radians', []) 10 | .filter('radians', function() { 11 | return function (degrees, decimal) { 12 | // if decimal is not an integer greater than -1, we cannot do. quit with error "NaN" 13 | // if degrees is not a real number, we cannot do also. quit with error "NaN" 14 | if(isNumber(decimal) && isFinite(decimal) && decimal%1===0 && decimal >= 0 && 15 | isNumber(degrees) && isFinite(degrees)) { 16 | var radians = (degrees * 3.14159265359) / 180; 17 | return Math.round(radians * Math.pow(10,decimal)) / (Math.pow(10,decimal)); 18 | } 19 | return 'NaN'; 20 | } 21 | }); 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/_filter/math/radix.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name Radix 4 | * @kind function 5 | * 6 | * @description 7 | * converting decimal numbers to different bases(radix) 8 | */ 9 | angular.module('a8m.math.radix', []) 10 | .filter('radix', function () { 11 | return function (input, radix) { 12 | var RANGE = /^[2-9]$|^[1-2]\d$|^3[0-6]$/; 13 | 14 | if(!isNumber(input) || !RANGE.test(radix)) { 15 | return input; 16 | } 17 | 18 | return input.toString(radix).toUpperCase(); 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /src/_filter/math/short-fmt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name formatBytes 4 | * @kind function 5 | * 6 | * @description 7 | * Convert number into abbreviations. 8 | * i.e: K for one thousand, M for Million, B for billion 9 | * e.g: number of users:235,221, decimal:1 => 235.2 K 10 | */ 11 | angular.module('a8m.math.shortFmt', []) 12 | .filter('shortFmt', function () { 13 | return function (number, decimal) { 14 | if(isNumber(decimal) && isFinite(decimal) && decimal%1===0 && decimal >= 0 && 15 | isNumber(number) && isFinite(number)){ 16 | if(number < 1e3) { 17 | return '' + number; // Coerce to string 18 | } else if(number < 1e6) { 19 | return convertToDecimal((number / 1e3), decimal) + ' K'; 20 | } else if(number < 1e9){ 21 | return convertToDecimal((number / 1e6), decimal) + ' M'; 22 | } else { 23 | return convertToDecimal((number / 1e9), decimal) + ' B'; 24 | } 25 | 26 | } 27 | return 'NaN'; 28 | } 29 | }); -------------------------------------------------------------------------------- /src/_filter/math/sum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name sum 4 | * @kind function 5 | * 6 | * @description 7 | * Sum up all values within an array 8 | */ 9 | angular.module('a8m.math.sum', []) 10 | .filter('sum', function () { 11 | return function (input, initial) { 12 | return !isArray(input) 13 | ? input 14 | : input.reduce(function(prev, curr) { 15 | return prev + curr; 16 | }, initial || 0); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /src/_filter/string/ends-with.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name endsWith 4 | * @kind function 5 | * 6 | * @description 7 | * checks whether string ends with the ends parameter. 8 | */ 9 | angular.module('a8m.ends-with', []) 10 | 11 | .filter('endsWith', function () { 12 | return function (input, ends, csensitive) { 13 | 14 | var sensitive = csensitive || false, 15 | position; 16 | 17 | if(!isString(input) || isUndefined(ends)) { 18 | return input; 19 | } 20 | 21 | input = (sensitive) ? input : input.toLowerCase(); 22 | position = input.length - ends.length; 23 | 24 | return input.indexOf((sensitive) ? ends : ends.toLowerCase(), position) !== -1; 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /src/_filter/string/latinize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name latinize 4 | * @kind function 5 | * 6 | * @description 7 | * remove accents/diacritics from a string 8 | */ 9 | angular.module('a8m.latinize', []) 10 | .filter('latinize',[ function () { 11 | var defaultDiacriticsRemovalap = [ 12 | {'base':'A', 'letters':'\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'}, 13 | {'base':'AA','letters':'\uA732'}, 14 | {'base':'AE','letters':'\u00C6\u01FC\u01E2'}, 15 | {'base':'AO','letters':'\uA734'}, 16 | {'base':'AU','letters':'\uA736'}, 17 | {'base':'AV','letters':'\uA738\uA73A'}, 18 | {'base':'AY','letters':'\uA73C'}, 19 | {'base':'B', 'letters':'\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'}, 20 | {'base':'C', 'letters':'\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'}, 21 | {'base':'D', 'letters':'\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779'}, 22 | {'base':'DZ','letters':'\u01F1\u01C4'}, 23 | {'base':'Dz','letters':'\u01F2\u01C5'}, 24 | {'base':'E', 'letters':'\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'}, 25 | {'base':'F', 'letters':'\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'}, 26 | {'base':'G', 'letters':'\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'}, 27 | {'base':'H', 'letters':'\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'}, 28 | {'base':'I', 'letters':'\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'}, 29 | {'base':'J', 'letters':'\u004A\u24BF\uFF2A\u0134\u0248'}, 30 | {'base':'K', 'letters':'\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'}, 31 | {'base':'L', 'letters':'\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'}, 32 | {'base':'LJ','letters':'\u01C7'}, 33 | {'base':'Lj','letters':'\u01C8'}, 34 | {'base':'M', 'letters':'\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'}, 35 | {'base':'N', 'letters':'\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'}, 36 | {'base':'NJ','letters':'\u01CA'}, 37 | {'base':'Nj','letters':'\u01CB'}, 38 | {'base':'O', 'letters':'\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'}, 39 | {'base':'OI','letters':'\u01A2'}, 40 | {'base':'OO','letters':'\uA74E'}, 41 | {'base':'OU','letters':'\u0222'}, 42 | {'base':'OE','letters':'\u008C\u0152'}, 43 | {'base':'oe','letters':'\u009C\u0153'}, 44 | {'base':'P', 'letters':'\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'}, 45 | {'base':'Q', 'letters':'\u0051\u24C6\uFF31\uA756\uA758\u024A'}, 46 | {'base':'R', 'letters':'\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'}, 47 | {'base':'S', 'letters':'\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'}, 48 | {'base':'T', 'letters':'\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'}, 49 | {'base':'TZ','letters':'\uA728'}, 50 | {'base':'U', 'letters':'\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'}, 51 | {'base':'V', 'letters':'\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'}, 52 | {'base':'VY','letters':'\uA760'}, 53 | {'base':'W', 'letters':'\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'}, 54 | {'base':'X', 'letters':'\u0058\u24CD\uFF38\u1E8A\u1E8C'}, 55 | {'base':'Y', 'letters':'\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'}, 56 | {'base':'Z', 'letters':'\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'}, 57 | {'base':'a', 'letters':'\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'}, 58 | {'base':'aa','letters':'\uA733'}, 59 | {'base':'ae','letters':'\u00E6\u01FD\u01E3'}, 60 | {'base':'ao','letters':'\uA735'}, 61 | {'base':'au','letters':'\uA737'}, 62 | {'base':'av','letters':'\uA739\uA73B'}, 63 | {'base':'ay','letters':'\uA73D'}, 64 | {'base':'b', 'letters':'\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'}, 65 | {'base':'c', 'letters':'\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'}, 66 | {'base':'d', 'letters':'\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'}, 67 | {'base':'dz','letters':'\u01F3\u01C6'}, 68 | {'base':'e', 'letters':'\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'}, 69 | {'base':'f', 'letters':'\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'}, 70 | {'base':'g', 'letters':'\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'}, 71 | {'base':'h', 'letters':'\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'}, 72 | {'base':'hv','letters':'\u0195'}, 73 | {'base':'i', 'letters':'\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'}, 74 | {'base':'j', 'letters':'\u006A\u24D9\uFF4A\u0135\u01F0\u0249'}, 75 | {'base':'k', 'letters':'\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'}, 76 | {'base':'l', 'letters':'\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'}, 77 | {'base':'lj','letters':'\u01C9'}, 78 | {'base':'m', 'letters':'\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'}, 79 | {'base':'n', 'letters':'\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'}, 80 | {'base':'nj','letters':'\u01CC'}, 81 | {'base':'o', 'letters':'\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'}, 82 | {'base':'oi','letters':'\u01A3'}, 83 | {'base':'ou','letters':'\u0223'}, 84 | {'base':'oo','letters':'\uA74F'}, 85 | {'base':'p','letters':'\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'}, 86 | {'base':'q','letters':'\u0071\u24E0\uFF51\u024B\uA757\uA759'}, 87 | {'base':'r','letters':'\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'}, 88 | {'base':'s','letters':'\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'}, 89 | {'base':'t','letters':'\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'}, 90 | {'base':'tz','letters':'\uA729'}, 91 | {'base':'u','letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'}, 92 | {'base':'v','letters':'\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'}, 93 | {'base':'vy','letters':'\uA761'}, 94 | {'base':'w','letters':'\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'}, 95 | {'base':'x','letters':'\u0078\u24E7\uFF58\u1E8B\u1E8D'}, 96 | {'base':'y','letters':'\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'}, 97 | {'base':'z','letters':'\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'} 98 | ]; 99 | 100 | var diacriticsMap = {}; 101 | for (var i = 0; i < defaultDiacriticsRemovalap.length; i++) { 102 | var letters = defaultDiacriticsRemovalap[i].letters.split(""); 103 | for (var j = 0; j < letters.length ; j++){ 104 | diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base; 105 | } 106 | } 107 | 108 | // "what?" version ... http://jsperf.com/diacritics/12 109 | function removeDiacritics (str) { 110 | return str.replace(/[^\u0000-\u007E]/g, function(a){ 111 | return diacriticsMap[a] || a; 112 | }); 113 | } 114 | 115 | return function (input) { 116 | 117 | return isString(input) 118 | ? removeDiacritics(input) 119 | : input; 120 | } 121 | }]); 122 | -------------------------------------------------------------------------------- /src/_filter/string/ltrim.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name ltrim 4 | * @kind function 5 | * 6 | * @description 7 | * Left trim. Similar to trimFilter, but only for left side. 8 | */ 9 | angular.module('a8m.ltrim', []) 10 | .filter('ltrim', function () { 11 | return function(input, chars) { 12 | 13 | var trim = chars || '\\s'; 14 | 15 | return isString(input) 16 | ? input.replace(new RegExp('^' + trim + '+'), '') 17 | : input; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /src/_filter/string/match.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name match 4 | * @kind function 5 | * 6 | * @description 7 | * Return the matched pattern in a string. 8 | */ 9 | angular.module('a8m.match', []) 10 | .filter('match', function () { 11 | return function (input, pattern, flag) { 12 | 13 | var reg = new RegExp(pattern, flag); 14 | 15 | return isString(input) 16 | ? input.match(reg) 17 | : null; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /src/_filter/string/phone-us.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name phone-us 4 | * @kind function 5 | * 6 | * @description 7 | * format a string or a number into a us-style 8 | * phone number in the form (***) ***-**** 9 | */ 10 | angular.module('a8m.phoneUS', []) 11 | .filter('phoneUS', function () { 12 | return function(num) { 13 | num += ''; 14 | return '(' + num.slice(0, 3) + ') ' + num.slice(3, 6) + '-' + num.slice(6); 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /src/_filter/string/repeat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name repeat 4 | * @kind function 5 | * 6 | * @description 7 | * Repeats a string n times 8 | */ 9 | angular.module('a8m.repeat', []) 10 | .filter('repeat',[ function () { 11 | return function (input, n, separator) { 12 | 13 | var times = ~~n; 14 | 15 | if(!isString(input)) { 16 | return input; 17 | } 18 | 19 | return !times 20 | ? input 21 | : strRepeat(input, --n, separator || ''); 22 | } 23 | }]); 24 | 25 | /** 26 | * Repeats a string n times with given separator 27 | * @param str string to repeat 28 | * @param n number of times 29 | * @param sep separator 30 | * @returns {*} 31 | */ 32 | function strRepeat(str, n, sep) { 33 | if(!n) { 34 | return str; 35 | } 36 | return str + sep + strRepeat(str, --n, sep); 37 | } -------------------------------------------------------------------------------- /src/_filter/string/rtrim.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name rtrim 4 | * @kind function 5 | * 6 | * @description 7 | * Right trim. Similar to trimFilter, but only for right side. 8 | */ 9 | angular.module('a8m.rtrim', []) 10 | .filter('rtrim', function () { 11 | return function(input, chars) { 12 | 13 | var trim = chars || '\\s'; 14 | 15 | return isString(input) 16 | ? input.replace(new RegExp(trim + '+$'), '') 17 | : input; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /src/_filter/string/slugify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name slugify 4 | * @kind function 5 | * 6 | * @description 7 | * remove spaces from string, replace with "-" or given argument 8 | */ 9 | angular.module('a8m.slugify', []) 10 | .filter('slugify',[ function () { 11 | return function (input, sub) { 12 | 13 | var replace = (isUndefined(sub)) ? '-' : sub; 14 | 15 | return isString(input) 16 | ? input.toLowerCase().replace(/\s+/g, replace) 17 | : input; 18 | } 19 | }]); 20 | -------------------------------------------------------------------------------- /src/_filter/string/split.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name split 4 | * @kind function 5 | * 6 | * @description 7 | * split a string by a provided delimiter (none '' by default) and skip first n-delimiters 8 | */ 9 | angular.module('a8m.split', []) 10 | .filter('split', function () { 11 | function escapeRegExp(str) { 12 | return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 13 | } 14 | 15 | return function (input, delimiter, skip) { 16 | var _regexp, _matches, _splitted, _temp; 17 | 18 | if (isUndefined(input) || !isString(input)) { 19 | return null; 20 | } 21 | if (isUndefined(delimiter)) delimiter = ''; 22 | if (isNaN(skip)) skip = 0; 23 | 24 | _regexp = new RegExp(escapeRegExp(delimiter), 'g'); 25 | _matches = input.match(_regexp); 26 | 27 | if (isNull(_matches) || skip >= _matches.length) { 28 | return [input]; 29 | } 30 | 31 | if (skip === 0) return input.split(delimiter); 32 | 33 | _splitted = input.split(delimiter); 34 | _temp = _splitted.splice(0, skip + 1); 35 | _splitted.unshift(_temp.join(delimiter)); 36 | 37 | return _splitted; 38 | }; 39 | }) 40 | ; 41 | -------------------------------------------------------------------------------- /src/_filter/string/starts-with.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name startWith 4 | * @kind function 5 | * 6 | * @description 7 | * checks whether string starts with the starts parameter. 8 | */ 9 | angular.module('a8m.starts-with', []) 10 | .filter('startsWith', function () { 11 | return function (input, start, csensitive) { 12 | 13 | var sensitive = csensitive || false; 14 | 15 | if(!isString(input) || isUndefined(start)) { 16 | return input; 17 | } 18 | 19 | input = (sensitive) ? input : input.toLowerCase(); 20 | 21 | return !input.indexOf((sensitive) ? start : start.toLowerCase()); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /src/_filter/string/stringular.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name stringular 4 | * @kind function 5 | * 6 | * @description 7 | * get string with {n} and replace match with enumeration values 8 | */ 9 | angular.module('a8m.stringular', []) 10 | .filter('stringular', function () { 11 | return function(input) { 12 | 13 | var args = Array.prototype.slice.call(arguments, 1); 14 | 15 | return input.replace(/{(\d+)}/g, function (match, number) { 16 | return isUndefined(args[number]) ? match : args[number]; 17 | }); 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /src/_filter/string/strip-tags.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name stripTags 4 | * @kind function 5 | * 6 | * @description 7 | * strip html tags from string 8 | */ 9 | angular.module('a8m.strip-tags', []) 10 | .filter('stripTags', function () { 11 | return function(input) { 12 | return isString(input) 13 | ? input.replace(/<\S[^><]*>/g, '') 14 | : input; 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /src/_filter/string/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name test 4 | * @kind function 5 | * 6 | * @description 7 | * test if a string match a pattern. 8 | */ 9 | angular.module('a8m.test', []) 10 | .filter('test', function () { 11 | return function (input, pattern, flag) { 12 | 13 | var reg = new RegExp(pattern, flag); 14 | 15 | return isString(input) 16 | ? reg.test(input) 17 | : input; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /src/_filter/string/trim.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name trim 4 | * @kind function 5 | * 6 | * @description 7 | * Strip whitespace (or other characters) from the beginning and end of a string 8 | */ 9 | angular.module('a8m.trim', []) 10 | .filter('trim', function () { 11 | return function(input, chars) { 12 | 13 | var trim = chars || '\\s'; 14 | 15 | return isString(input) 16 | ? input.replace(new RegExp('^' + trim + '+|' + trim + '+$', 'g'), '') 17 | : input; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /src/_filter/string/truncate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name truncate 4 | * @kind function 5 | * 6 | * @description 7 | * truncates a string given a specified length, providing a custom string to denote an omission. 8 | */ 9 | angular.module('a8m.truncate', []) 10 | .filter('truncate', function () { 11 | return function(input, length, suffix, preserve) { 12 | 13 | length = isUndefined(length) ? input.length : length; 14 | preserve = preserve || false; 15 | suffix = suffix || ''; 16 | 17 | if(!isString(input) || (input.length <= length)) return input; 18 | 19 | return input.substring(0, (preserve) 20 | ? ((input.indexOf(' ', length) === -1) ? input.length : input.indexOf(' ', length)) 21 | : length) + suffix; 22 | }; 23 | }); 24 | -------------------------------------------------------------------------------- /src/_filter/string/ucfirst.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name ucfirst 4 | * @kind function 5 | * 6 | * @description 7 | * ucfirst 8 | */ 9 | angular.module('a8m.ucfirst', []) 10 | .filter({ 11 | ucfirst: ucfirstFilter, 12 | titleize: ucfirstFilter 13 | }); 14 | 15 | function ucfirstFilter() { 16 | return function (input) { 17 | return isString(input) 18 | ? input 19 | .split(' ') 20 | .map(function (ch) { 21 | return ch.charAt(0).toUpperCase() + ch.substring(1); 22 | }) 23 | .join(' ') 24 | : input; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/_filter/string/uri-component-encode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name uriComponentEncode 4 | * @kind function 5 | * 6 | * @description 7 | * get string as parameter and return encoded string 8 | */ 9 | angular.module('a8m.uri-component-encode', []) 10 | .filter('uriComponentEncode',['$window', function ($window) { 11 | return function (input) { 12 | return isString(input) 13 | ? $window.encodeURIComponent(input) 14 | : input; 15 | } 16 | }]); 17 | -------------------------------------------------------------------------------- /src/_filter/string/uri-encode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name uriEncode 4 | * @kind function 5 | * 6 | * @description 7 | * get string as parameter and return encoded string 8 | */ 9 | angular.module('a8m.uri-encode', []) 10 | .filter('uriEncode',['$window', function ($window) { 11 | return function (input) { 12 | return isString(input) 13 | ? $window.encodeURI(input) 14 | : input; 15 | } 16 | }]); 17 | -------------------------------------------------------------------------------- /src/_filter/string/wrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc filter 3 | * @name wrap 4 | * @kind function 5 | * 6 | * @description 7 | * Wrap a string with another string 8 | */ 9 | angular.module('a8m.wrap', []) 10 | .filter('wrap', function () { 11 | return function(input, wrap, ends) { 12 | return isString(input) && isDefined(wrap) 13 | ? [wrap, input, ends || wrap].join('') 14 | : input; 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /src/_provider/watcher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc provider 3 | * @name filterWatcher 4 | * @kind function 5 | * 6 | * @description 7 | * store specific filters result in $$cache, based on scope life time(avoid memory leak). 8 | * on scope.$destroy remove it's cache from $$cache container 9 | */ 10 | 11 | angular.module('a8m.filter-watcher', []) 12 | .provider('filterWatcher', function() { 13 | 14 | this.$get = ['$window', '$rootScope', function($window, $rootScope) { 15 | 16 | /** 17 | * Cache storing 18 | * @type {Object} 19 | */ 20 | var $$cache = {}; 21 | 22 | /** 23 | * Scope listeners container 24 | * scope.$destroy => remove all cache keys 25 | * bind to current scope. 26 | * @type {Object} 27 | */ 28 | var $$listeners = {}; 29 | 30 | /** 31 | * $timeout without triggering the digest cycle 32 | * @type {function} 33 | */ 34 | var $$timeout = $window.setTimeout; 35 | 36 | /** 37 | * @description 38 | * get `HashKey` string based on the given arguments. 39 | * @param fName 40 | * @param args 41 | * @returns {string} 42 | */ 43 | function getHashKey(fName, args) { 44 | function replacerFactory() { 45 | var cache = []; 46 | return function(key, val) { 47 | if(isObject(val) && !isNull(val)) { 48 | if (~cache.indexOf(val)) return '[Circular]'; 49 | cache.push(val) 50 | } 51 | if($window == val) return '$WINDOW'; 52 | if($window.document == val) return '$DOCUMENT'; 53 | if(isScope(val)) return '$SCOPE'; 54 | return val; 55 | } 56 | } 57 | return [fName, JSON.stringify(args, replacerFactory())] 58 | .join('#') 59 | .replace(/"/g,''); 60 | } 61 | 62 | /** 63 | * @description 64 | * fir on $scope.$destroy, 65 | * remove cache based scope from `$$cache`, 66 | * and remove itself from `$$listeners` 67 | * @param event 68 | */ 69 | function removeCache(event) { 70 | var id = event.targetScope.$id; 71 | forEach($$listeners[id], function(key) { 72 | delete $$cache[key]; 73 | }); 74 | delete $$listeners[id]; 75 | } 76 | 77 | /** 78 | * @description 79 | * for angular version that greater than v.1.3.0 80 | * it clear cache when the digest cycle is end. 81 | */ 82 | function cleanStateless() { 83 | $$timeout(function() { 84 | if(!$rootScope.$$phase) 85 | $$cache = {}; 86 | }, 2000); 87 | } 88 | 89 | /** 90 | * @description 91 | * Store hashKeys in $$listeners container 92 | * on scope.$destroy, remove them all(bind an event). 93 | * @param scope 94 | * @param hashKey 95 | * @returns {*} 96 | */ 97 | function addListener(scope, hashKey) { 98 | var id = scope.$id; 99 | if(isUndefined($$listeners[id])) { 100 | scope.$on('$destroy', removeCache); 101 | $$listeners[id] = []; 102 | } 103 | return $$listeners[id].push(hashKey); 104 | } 105 | 106 | /** 107 | * @description 108 | * return the `cacheKey` or undefined. 109 | * @param filterName 110 | * @param args 111 | * @returns {*} 112 | */ 113 | function $$isMemoized(filterName, args) { 114 | var hashKey = getHashKey(filterName, args); 115 | return $$cache[hashKey]; 116 | } 117 | 118 | /** 119 | * @description 120 | * store `result` in `$$cache` container, based on the hashKey. 121 | * add $destroy listener and return result 122 | * @param filterName 123 | * @param args 124 | * @param scope 125 | * @param result 126 | * @returns {*} 127 | */ 128 | function $$memoize(filterName, args, scope, result) { 129 | var hashKey = getHashKey(filterName, args); 130 | //store result in `$$cache` container 131 | $$cache[hashKey] = result; 132 | // for angular versions that less than 1.3 133 | // add to `$destroy` listener, a cleaner callback 134 | if(isScope(scope)) { 135 | addListener(scope, hashKey); 136 | } else { 137 | cleanStateless(); 138 | } 139 | return result; 140 | } 141 | 142 | return { 143 | isMemoized: $$isMemoized, 144 | memoize: $$memoize 145 | } 146 | }]; 147 | }); 148 | 149 | -------------------------------------------------------------------------------- /src/filters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ngdoc module 3 | * @name angular.filters 4 | * @description 5 | * Bunch of useful filters for angularJS 6 | */ 7 | 8 | angular.module('angular.filter', [ 9 | 10 | 'a8m.ucfirst', 11 | 'a8m.uri-encode', 12 | 'a8m.uri-component-encode', 13 | 'a8m.slugify', 14 | 'a8m.latinize', 15 | 'a8m.strip-tags', 16 | 'a8m.stringular', 17 | 'a8m.truncate', 18 | 'a8m.starts-with', 19 | 'a8m.ends-with', 20 | 'a8m.wrap', 21 | 'a8m.trim', 22 | 'a8m.ltrim', 23 | 'a8m.rtrim', 24 | 'a8m.repeat', 25 | 'a8m.test', 26 | 'a8m.match', 27 | 'a8m.split', 28 | 'a8m.phoneUS', 29 | 30 | 'a8m.to-array', 31 | 'a8m.concat', 32 | 'a8m.contains', 33 | 'a8m.unique', 34 | 'a8m.is-empty', 35 | 'a8m.after', 36 | 'a8m.after-where', 37 | 'a8m.before', 38 | 'a8m.before-where', 39 | 'a8m.defaults', 40 | 'a8m.where', 41 | 'a8m.reverse', 42 | 'a8m.remove', 43 | 'a8m.remove-with', 44 | 'a8m.group-by', 45 | 'a8m.count-by', 46 | 'a8m.chunk-by', 47 | 'a8m.search-field', 48 | 'a8m.fuzzy-by', 49 | 'a8m.fuzzy', 50 | 'a8m.omit', 51 | 'a8m.pick', 52 | 'a8m.every', 53 | 'a8m.filter-by', 54 | 'a8m.xor', 55 | 'a8m.map', 56 | 'a8m.first', 57 | 'a8m.last', 58 | 'a8m.flatten', 59 | 'a8m.join', 60 | 'a8m.range', 61 | 62 | 'a8m.math.max', 63 | 'a8m.math.min', 64 | 'a8m.math.abs', 65 | 'a8m.math.percent', 66 | 'a8m.math.radix', 67 | 'a8m.math.sum', 68 | 'a8m.math.degrees', 69 | 'a8m.math.radians', 70 | 'a8m.math.byteFmt', 71 | 'a8m.math.kbFmt', 72 | 'a8m.math.shortFmt', 73 | 74 | 'a8m.angular', 75 | 'a8m.conditions', 76 | 'a8m.is-null', 77 | 78 | 'a8m.filter-watcher' 79 | ]); 80 | -------------------------------------------------------------------------------- /test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "globals": { 22 | "after": false, 23 | "afterEach": false, 24 | "angular": false, 25 | "before": false, 26 | "beforeEach": false, 27 | "browser": false, 28 | "describe": false, 29 | "expect": false, 30 | "inject": false, 31 | "it": false, 32 | "jasmine": false, 33 | "spyOn": false, 34 | "toEqual": false 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /test/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // http://karma-runner.github.io/0.12/config/configuration-file.html 3 | // Generated on 2014-07-06 using 4 | // generator-karma 0.8.3 5 | 6 | module.exports = function(config) { 7 | 'use strict'; 8 | 9 | config.set({ 10 | // enable / disable watching file and executing tests whenever any file changes 11 | autoWatch: true, 12 | 13 | // base path, that will be used to resolve files and exclude 14 | basePath: '../', 15 | 16 | // testing framework to use (jasmine/mocha/qunit/...) 17 | frameworks: ['jasmine'], 18 | 19 | reporters: ['coverage'], 20 | //files to coverage 21 | preprocessors: { 22 | "src/**/*js": 'coverage' 23 | }, 24 | 25 | coverageReporter: { 26 | type: 'lcov', 27 | dir: 'test/coverage/' 28 | }, 29 | 30 | // list of files / patterns to load in the browser 31 | files: [ 32 | 'bower_components/angular/angular.js', 33 | 'bower_components/angular-mocks/angular-mocks.js', 34 | 'src/*.js', 35 | 'src/**/*.js', 36 | 'src/**/**/*.js', 37 | 'test/spec/**/*.js', 38 | 'test/spec/**/**/*.js' 39 | ], 40 | 41 | // list of files / patterns to exclude 42 | exclude: [], 43 | 44 | // web server port 45 | port: 9876, 46 | 47 | 48 | // cli runner port 49 | runnerPort: 9100, 50 | 51 | // Start these browsers, currently available: 52 | // - Chrome 53 | // - ChromeCanary 54 | // - Firefox 55 | // - Opera 56 | // - Safari (only Mac) 57 | // - PhantomJS 58 | // - IE (only Windows) 59 | browsers: [ 60 | 'PhantomJS' 61 | ], 62 | 63 | // Which plugins to enable 64 | plugins: [ 65 | 'karma-phantomjs-launcher', 66 | 'karma-jasmine', 67 | 'karma-coverage' 68 | ], 69 | 70 | // Continuous Integration mode 71 | // if true, it capture browsers, run tests and exit 72 | singleRun: false, 73 | 74 | colors: true, 75 | 76 | // level of logging 77 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 78 | logLevel: config.LOG_INFO, 79 | 80 | // If browser does not capture in given timeout [ms], kill it 81 | captureTimeout: 60000, 82 | 83 | phantomjsLauncher: { 84 | // Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing phantom) 85 | exitOnResourceError: true 86 | } 87 | }); 88 | }; 89 | -------------------------------------------------------------------------------- /test/karma.underscore.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Fri Aug 09 2013 14:14:35 GMT-0500 (CDT) 3 | 4 | module.exports = function(config) { 5 | 'use strict'; 6 | 7 | config.set({ 8 | 9 | // base path, that will be used to resolve files and exclude 10 | basePath: '../', 11 | 12 | frameworks: ["jasmine"], 13 | 14 | // list of files / patterns to load in the browser 15 | files: [ 16 | 'bower_components/angular/angular.js', 17 | 'bower_components/angular-mocks/angular-mocks.js', 18 | 'src/**/*.js', 19 | 'src/**/**/*.js', 20 | 'test/spec/**/*.js', 21 | 'test/spec/**/**/*.js' 22 | ], 23 | 24 | 25 | // list of files to exclude 26 | exclude: [ 27 | 28 | ], 29 | 30 | 31 | // test results reporter to use 32 | // possible values: 'dots', 'progress', 'junit' 33 | reporters: ['progress'], 34 | 35 | 36 | // web server port 37 | port: 9877, 38 | 39 | 40 | // cli runner port 41 | runnerPort: 9101, 42 | 43 | 44 | // enable / disable colors in the output (reporters and logs) 45 | colors: true, 46 | 47 | 48 | // level of logging 49 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 50 | logLevel: config.LOG_INFO, 51 | 52 | 53 | // enable / disable watching file and executing tests whenever any file changes 54 | autoWatch: true, 55 | 56 | 57 | // Start these browsers, currently available: 58 | // - Chrome 59 | // - ChromeCanary 60 | // - Firefox 61 | // - Opera 62 | // - Safari (only Mac) 63 | // - PhantomJS 64 | // - IE (only Windows) 65 | browsers: ['PhantomJS'], 66 | 67 | 68 | // If browser does not capture in given timeout [ms], kill it 69 | captureTimeout: 60000, 70 | 71 | 72 | // Continuous Integration mode 73 | // if true, it capture browsers, run tests and exit 74 | singleRun: false 75 | 76 | }); 77 | }; 78 | -------------------------------------------------------------------------------- /test/spec/filter/boolean/angular.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('angularFilter', function () { 4 | 5 | var isDefined, 6 | isUndefined, 7 | isFunction, 8 | isString, 9 | isNumber, 10 | isObject, 11 | isArray, 12 | isEqual; 13 | 14 | beforeEach(module('a8m.angular')); 15 | 16 | beforeEach(inject(function ($filter) { 17 | isDefined = $filter('isDefined'); 18 | isUndefined = $filter('isUndefined'); 19 | isFunction = $filter('isFunction'); 20 | isString = $filter('isString'); 21 | isNumber = $filter('isNumber'); 22 | isObject = $filter('isObject'); 23 | isArray = $filter('isArray'); 24 | isEqual = $filter('isEqual'); 25 | })); 26 | 27 | it('should called angular.isDefined method with the given input', function() { 28 | 29 | spyOn(angular, 'isDefined'); 30 | isDefined(undefined); 31 | expect(angular.isDefined).toHaveBeenCalledWith(undefined) 32 | 33 | }); 34 | 35 | it('should called angular.isUndefined method with the given input', function() { 36 | 37 | spyOn(angular, 'isUndefined'); 38 | isUndefined(undefined); 39 | expect(angular.isUndefined).toHaveBeenCalledWith(undefined) 40 | 41 | }); 42 | 43 | it('should called angular.isFunction method with the given input', function() { 44 | 45 | var func = function() {}; 46 | spyOn(angular, 'isFunction'); 47 | isFunction(func); 48 | expect(angular.isFunction).toHaveBeenCalledWith(func) 49 | 50 | }); 51 | 52 | it('should called angular.isString method with the given input', function() { 53 | 54 | spyOn(angular, 'isString'); 55 | isString('string'); 56 | expect(angular.isString).toHaveBeenCalledWith('string') 57 | 58 | }); 59 | 60 | it('should called angular.isNumber method with the given input', function() { 61 | 62 | spyOn(angular, 'isNumber'); 63 | isNumber(777); 64 | expect(angular.isNumber).toHaveBeenCalledWith(777) 65 | 66 | }); 67 | 68 | it('should called angular.isArray method with the given input', function() { 69 | 70 | spyOn(angular, 'isArray'); 71 | isArray([]); 72 | expect(angular.isArray).toHaveBeenCalledWith([]) 73 | 74 | }); 75 | 76 | it('should called angular.isObject method with the given input', function() { 77 | 78 | spyOn(angular, 'isObject'); 79 | isObject({}); 80 | expect(angular.isObject).toHaveBeenCalledWith({}) 81 | 82 | }); 83 | 84 | it('should called angular.equals method with the given input', function() { 85 | 86 | var o1 = {}, o2 = {}; 87 | spyOn(angular, 'equals'); 88 | isEqual(o1, o2); 89 | expect(angular.equals).toHaveBeenCalledWith(o1, o2) 90 | 91 | }); 92 | 93 | 94 | }); 95 | -------------------------------------------------------------------------------- /test/spec/filter/boolean/conditions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('conditionsFilter', function () { 4 | 5 | var isGreaterThan, 6 | isGreaterThanOrEqualTo, 7 | isLessThan, 8 | isLessThanOrEqualTo, 9 | isEqualTo, 10 | isNotEqualTo, 11 | isIdenticalTo, 12 | isNotIdenticalTo; 13 | 14 | beforeEach(module('a8m.conditions')); 15 | 16 | beforeEach(inject(function ($filter) { 17 | isGreaterThan = $filter('isGreaterThan'); 18 | isGreaterThanOrEqualTo = $filter('isGreaterThanOrEqualTo'); 19 | isLessThan = $filter('isLessThan'); 20 | isLessThanOrEqualTo = $filter('isLessThanOrEqualTo'); 21 | isEqualTo = $filter('isEqualTo'); 22 | isNotEqualTo = $filter('isNotEqualTo'); 23 | isIdenticalTo = $filter('isIdenticalTo'); 24 | isNotIdenticalTo = $filter('isNotIdenticalTo'); 25 | })); 26 | 27 | it('should check expected conditions', function() { 28 | expect(isGreaterThan(1, 2)).toBe(false); 29 | expect(isGreaterThanOrEqualTo(1, 1)).toBe(true); 30 | 31 | expect(isLessThan(1, 2)).toBe(true); 32 | expect(isLessThanOrEqualTo(3, 2)).toBe(false); 33 | 34 | expect(isEqualTo(3, '3')).toBe(true); 35 | expect(isNotEqualTo(3, '3')).toBe(false); 36 | 37 | expect(isIdenticalTo(3, 3)).toBe(true); 38 | expect(isNotIdenticalTo(3, 3)).toBe(false); 39 | }); 40 | 41 | it('should be aliases for each condition filter', inject( 42 | function($filter){ 43 | var filters = { 44 | isGreaterThan: '>', 45 | isGreaterThanOrEqualTo: '>=', 46 | isLessThan: '<', 47 | isLessThanOrEqualTo: '<=', 48 | isEqualTo: '==', 49 | isNotEqualTo: '!=', 50 | isIdenticalTo: '===', 51 | isNotIdenticalTo: '!==' 52 | }; 53 | //expectations 54 | angular.forEach(filters, function(val, key) { 55 | expect($filter(val).toString()).toEqual($filter(key).toString()); 56 | }); 57 | })); 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /test/spec/filter/boolean/is-null.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('isNullFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.is-null')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('isNull'); 11 | })); 12 | 13 | it('should returns true if the value is null, else false.', function() { 14 | 15 | expect(filter(null)).toBeTruthy(); 16 | 17 | expect(filter({})).toBeFalsy(); 18 | expect(filter([])).toBeFalsy(); 19 | expect(filter(1)).toBeFalsy(); 20 | expect(filter(!1)).toBeFalsy(); 21 | expect(filter('string')).toBeFalsy(); 22 | expect(filter(undefined)).toBeFalsy(); 23 | 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /test/spec/filter/collection/after-where.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('afterWhereFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.after-where')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('afterWhere'); 10 | })); 11 | 12 | it('should get array as a collection and properties object, and returns all of the items,' + 13 | 'in the collection after the first that found with the given properties including it.', function() { 14 | 15 | var array = [{ a: 1 }, { a: 2 }, { a: 3 }], 16 | orders = [ 17 | { id: 1, customer: { name: 'foo' }, date: 'Tue Jul 15 2014' }, 18 | { id: 2, customer: { name: 'foo' }, date: 'Tue Jul 16 2014' }, 19 | { id: 3, customer: { name: 'foo' }, date: 'Tue Jul 17 2014' }, 20 | { id: 4, customer: { name: 'foo' }, date: 'Tue Jul 18 2014' }, 21 | { id: 5, customer: { name: 'foo' }, date: 'Tue Jul 19 2014' } 22 | ]; 23 | 24 | expect(filter(array, { a: 2 })).toEqual([{ a: 2 }, { a: 3 }]); 25 | //get all orders after July include 26 | expect(filter(orders, { date: 'Tue Jul 17 2014' })).toEqual([ orders[2], orders[3], orders[4] ]); 27 | 28 | //if identifier not exist, return it as-is 29 | expect(filter(orders, { date: 'Tue Jul 10 2014' })).toEqual(orders); 30 | }); 31 | 32 | it('should get object as a collection and properties object, and returns all of the items,' + 33 | 'in the collection after the first that found with the given properties including it.', function() { 34 | 35 | var object = { 36 | 0: { a: 1 }, 37 | 1: { a: 2 }, 38 | 2: { a: 3 }, 39 | 3: { a: 4 } 40 | },orders = { 41 | 0: { id: 1, customer: { name: 'foo' }, date: 'Tue Jul 15 2014' }, 42 | 1: { id: 2, customer: { name: 'foo' }, date: 'Tue Jul 16 2014' }, 43 | 2: { id: 3, customer: { name: 'foo' }, date: 'Tue Jul 17 2014' }, 44 | 3: { id: 4, customer: { name: 'foo' }, date: 'Tue Jul 18 2014' }, 45 | 4: { id: 5, customer: { name: 'foo' }, date: 'Tue Jul 19 2014' } 46 | }; 47 | 48 | expect(filter(object, { a: 3 } )).toEqual([{ a: 3 }, { a: 4 }]); 49 | 50 | expect(filter(orders, { date: 'Tue Jul 18 2014' } )).toEqual([orders[3], orders[4]]); 51 | 52 | }); 53 | 54 | it('should get a !collection and return it as-is', function() { 55 | 56 | expect(filter(!1)).toBeFalsy(); 57 | expect(filter(1)).toEqual(1); 58 | expect(filter('string')).toEqual('string'); 59 | 60 | }); 61 | 62 | it('should return the collection as-is, if not get a properties object', function() { 63 | 64 | expect(filter([{}, {}])).toEqual([{}, {}]); 65 | expect(filter([])).toEqual([]); 66 | 67 | }); 68 | 69 | }); 70 | -------------------------------------------------------------------------------- /test/spec/filter/collection/after.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('afterFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.after')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('after'); 10 | })); 11 | 12 | it('should get array as a collection and specified count, and returns all of the items' + 13 | 'in the collection after the specified count.', function() { 14 | 15 | var array = [{ a: 1 }, { a: 2 }]; 16 | 17 | expect(filter(array, 1)).toEqual([{ a:2 }]); 18 | 19 | expect(filter([1,2,3,4], 1)).toEqual([2,3,4]); 20 | expect(filter([1,2,3,4], 5)).toEqual([]); 21 | 22 | }); 23 | 24 | it('should get object as a collection and specified count, and returns all of the items' + 25 | 'in the collection after the specified count.', function() { 26 | 27 | var object = { 28 | 0: { a: 1 }, 29 | 1: { a: 2 }, 30 | 2: { a: 3 }, 31 | 3: { a: 4 } 32 | }; 33 | 34 | expect(filter(object, 3)).toEqual([{ a: 4 }]); 35 | expect(filter(object, 2)).toEqual([{ a: 3 }, { a: 4 }]); 36 | 37 | expect(filter(object, 10)).toEqual([]); 38 | 39 | }); 40 | 41 | it('should get a !collection and return it as-is', function() { 42 | 43 | expect(filter(!1)).toBeFalsy(); 44 | expect(filter(1)).toEqual(1); 45 | expect(filter('string')).toEqual('string'); 46 | 47 | }); 48 | 49 | }); 50 | -------------------------------------------------------------------------------- /test/spec/filter/collection/before.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('beforeFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.before')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('before'); 10 | })); 11 | 12 | it('should get array as a collection and specified count, and returns all of the items' + 13 | 'in the collection before the specified count.', function() { 14 | 15 | var array = [{ a: 1 }, { a: 2 }]; 16 | 17 | expect(filter(array, 2)).toEqual([{ a: 1 }]); 18 | 19 | expect(filter([1,2,3,4], 4)).toEqual([1,2,3]); 20 | expect(filter([1,2,3,4], 5)).toEqual([1,2,3,4]); 21 | 22 | }); 23 | 24 | it('should get object as a collection and specified count, and returns all of the items' + 25 | 'in the collection before the specified count.', function() { 26 | 27 | var object = { 28 | 0: { a: 1 }, 29 | 1: { a: 2 }, 30 | 2: { a: 3 }, 31 | 3: { a: 4 } 32 | }; 33 | 34 | expect(filter(object, 3)).toEqual([{ a: 1 }, { a: 2 }]); 35 | expect(filter(object, 1)).toEqual([]); 36 | 37 | expect(filter(object, 10)).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }]); 38 | 39 | }); 40 | 41 | it('should get a !collection and return it as-is', function() { 42 | 43 | expect(filter(!1)).toBeFalsy(); 44 | expect(filter(1)).toEqual(1); 45 | expect(filter('string')).toEqual('string'); 46 | 47 | }); 48 | 49 | }); 50 | -------------------------------------------------------------------------------- /test/spec/filter/collection/beforeWhere.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('beforeWhereFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.before-where')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('beforeWhere'); 10 | })); 11 | 12 | it('should get array as a collection and properties object, and returns all of the items,' + 13 | 'in the collection before the first that found with the given properties including it.', function() { 14 | 15 | var array = [{ a: 1 }, { a: 2 }, { a: 3 }], 16 | orders = [ 17 | { id: 1, customer: { name: 'foo' }, date: 'Tue Jul 15 2014' }, 18 | { id: 2, customer: { name: 'foo' }, date: 'Tue Jul 16 2014' }, 19 | { id: 3, customer: { name: 'foo' }, date: 'Tue Jul 17 2014' }, 20 | { id: 4, customer: { name: 'foo' }, date: 'Tue Jul 18 2014' }, 21 | { id: 5, customer: { name: 'foo' }, date: 'Tue Jul 19 2014' } 22 | ]; 23 | 24 | expect(filter(array, { a: 2 })).toEqual([{ a: 1 }, { a: 2 }]); 25 | //get all orders after July include 26 | expect(filter(orders, { date: 'Tue Jul 17 2014' })).toEqual([ orders[0], orders[1], orders[2] ]); 27 | 28 | //if identifier not exist, return it as-is 29 | expect(filter(orders, { date: 'Tue Jul 10 2014' })).toEqual(orders); 30 | }); 31 | 32 | it('should get object as a collection and properties object, and returns all of the items,' + 33 | 'in the collection before the first that found with the given properties including it.', function() { 34 | 35 | var object = { 36 | 0: { a: 1 }, 37 | 1: { a: 2 }, 38 | 2: { a: 3 }, 39 | 3: { a: 4 } 40 | },orders = { 41 | 0: { id: 1, customer: { name: 'foo' }, date: 'Tue Jul 15 2014' }, 42 | 1: { id: 2, customer: { name: 'foo' }, date: 'Tue Jul 16 2014' }, 43 | 2: { id: 3, customer: { name: 'foo' }, date: 'Tue Jul 17 2014' }, 44 | 3: { id: 4, customer: { name: 'foo' }, date: 'Tue Jul 18 2014' }, 45 | 4: { id: 5, customer: { name: 'foo' }, date: 'Tue Jul 19 2014' } 46 | }; 47 | 48 | expect(filter(object, { a: 3 } )).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }]); 49 | 50 | expect(filter(orders, { date: 'Tue Jul 15 2014' } )).toEqual([orders[0]]); 51 | 52 | }); 53 | 54 | it('should get a !collection and return it as-is', function() { 55 | 56 | expect(filter(!1)).toBeFalsy(); 57 | expect(filter(1)).toEqual(1); 58 | expect(filter('string')).toEqual('string'); 59 | 60 | }); 61 | 62 | it('should return the collection as-is, if not get a properties object', function() { 63 | 64 | expect(filter([{}, {}])).toEqual([{}, {}]); 65 | expect(filter([])).toEqual([]); 66 | 67 | }); 68 | 69 | }); 70 | -------------------------------------------------------------------------------- /test/spec/filter/collection/chunk-by.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('chunkByFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.chunk-by')); 7 | beforeEach(inject(function($filter) { 8 | filter = $filter('chunkBy'); 9 | })); 10 | 11 | it('should collect data into fixed-length chunks or blocks', function() { 12 | expect(filter([1, 2, 3, 4], 2)).toEqual([[1, 2], [3, 4]]); 13 | }); 14 | it('should collect data into fixed-length chunks or blocks', function() { 15 | expect(filter([1, 2, 3, 4], 3)).toEqual([[1, 2, 3], [4]]); 16 | }); 17 | it('should collect data into fixed-length chunks or blocks', function() { 18 | expect(filter(['a', 'b', 'c', 'd'], 4)).toEqual([['a', 'b', 'c', 'd']]); 19 | }); 20 | 21 | it('should get an fill-value and complete blocks that less than `n`', function() { 22 | expect(filter([1, 2, 3, 4, 5], 2, 0)).toEqual([[1, 2], [3, 4], [5, 0]]); 23 | }); 24 | it('should get an fill-value and complete blocks that less than `n`', function() { 25 | expect(filter([1, 2, 3, 4], 3, 1)).toEqual([[1, 2, 3], [4, 1, 1]]); 26 | }); 27 | 28 | it('should get a !collection and return it as-is', function() { 29 | expect(filter(!1)).toBeFalsy(); 30 | expect(filter(1)).toEqual(1); 31 | }); 32 | it('should get a !collection and return it as-is', function() { 33 | expect(filter('string')).toEqual('string'); 34 | }); 35 | it('should get a !collection and return it as-is', function() { 36 | expect(filter(undefined)).toEqual(undefined); 37 | }); 38 | 39 | describe('inside the DOM', function() { 40 | it('should not throw and not trigger the infinite digest exception', 41 | inject(function($rootScope, $compile) { 42 | var scope = $rootScope.$new(); 43 | scope.list = [ 44 | { name: 'foo', team: 'a' }, 45 | { name: 'lol', team: 'b' }, 46 | { name: 'bar', team: 'b' }, 47 | { name: 'baz', team: 'a' }, 48 | { name: 'bag', team: 'a' } 49 | ]; 50 | scope.search = ''; 51 | var elm = angular.element( 52 | '' 57 | ); 58 | var temp = $compile(elm)(scope); 59 | expect(function() { scope.$digest() }).not.toThrow(); 60 | expect(angular.element(temp.children()[0]).children().length).toEqual(3); 61 | expect(angular.element(temp.children()[1]).children().length).toEqual(2); 62 | })); 63 | }); 64 | }); 65 | -------------------------------------------------------------------------------- /test/spec/filter/collection/concat.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('concatFilter', function() { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.concat')); 8 | 9 | beforeEach(inject(function($filter) { 10 | filter = $filter('concat'); 11 | })); 12 | 13 | it('should get 2 arrays as parameters and return merged one', function() { 14 | 15 | expect(filter([1,2,3], [4,5,6])).toEqual([1,2,3,4,5,6]); 16 | expect(filter([], [4,5,6])).toEqual([4,5,6]); 17 | expect(filter([true, false], [])).toEqual([true, false]); 18 | 19 | expect(filter([{a: 1}], [{a: 2}])).toEqual([{a: 1}, {a: 2}]); 20 | }); 21 | 22 | it('should get a wrong ot none parameters, and not touch it', function () { 23 | 24 | expect(filter('string', [])).toEqual('string'); 25 | expect(filter('string')).toEqual('string'); 26 | 27 | expect(filter([], undefined)).toEqual([]); 28 | expect(filter(undefined, [])).toEqual(undefined); 29 | 30 | }); 31 | 32 | it('should get a mixed parameters and return merged collection', function() { 33 | 34 | var array = [{a: 1}], 35 | object = { 36 | 0: {a: 2}, 37 | 1: {a: 3} 38 | }; 39 | 40 | expect(filter(array, object)).toEqual([{a: 1}, {a: 2}, {a: 3}]); 41 | expect(filter(object, array)).toEqual([{a: 2}, {a: 3}, {a: 1}]); 42 | 43 | expect(filter(object, object)).toEqual([{a: 2}, {a: 3}, {a: 2}, {a: 3}]); 44 | expect(filter(array, array)).toEqual([{a: 1}, {a: 1}]); 45 | 46 | }); 47 | 48 | }); 49 | -------------------------------------------------------------------------------- /test/spec/filter/collection/contains.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('containsFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.contains')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('contains'); 10 | })); 11 | 12 | it('should find elements which are objects', function() { 13 | var needle = {}; 14 | var haystack = [needle]; 15 | 16 | expect(filter(haystack, needle)).toBeTruthy(); 17 | }); 18 | 19 | it('should get collection of primitives and use strict comparison(===)', function() { 20 | expect(filter(['foo', 'bar'], 'bar')).toBeTruthy(); 21 | expect(filter([1,2,3,4], 4)).toBeTruthy(); 22 | 23 | expect(filter(['foo', 'bar'], 'baz')).toBeFalsy(); 24 | expect(filter([1,2,3,4], -1)).toBeFalsy(); 25 | }); 26 | 27 | it('should get array as collection and return if given expression is ' + 28 | 'present in one or more object in the collection', function() { 29 | var array = [ 30 | { id: 1, name: 'foo' }, 31 | { id: 2, name: 'baz' }, 32 | { id: 1, name: 'ariel' }, 33 | { id: 1, name: 'bar' } 34 | ]; 35 | 36 | expect(filter(array, 'id === 2')).toBeTruthy(); 37 | expect(filter(array, 'id >= 1 && name === \'foo\'')).toBeTruthy(); 38 | expect(filter(array)).toBeFalsy(); 39 | 40 | expect(filter(array, 'id > 77')).toBeFalsy(); 41 | expect(filter(array, 'name.indexOf(\'u\') !== -1')).toBeFalsy(); 42 | }); 43 | 44 | it('should get object as collection and return if given expression is ' + 45 | 'present in one or more object in the collection', function() { 46 | var object = { 47 | 0: { id: 1, name: 'foo' }, 48 | 1: { id: 2, name: 'baz' }, 49 | 2: { id: 1, name: 'ariel' }, 50 | 3: { id: 1, name: 'bar' } 51 | }; 52 | 53 | expect(filter(object, 'id === 2')).toBeTruthy(); 54 | expect(filter(object, 'id >= 1 && name === "foo"')).toBeTruthy(); 55 | expect(filter(object)).toBeFalsy(); 56 | 57 | expect(filter(object, 'id > 77')).toBeFalsy(); 58 | expect(filter(object, 'name.indexOf(\'u\') !== -1')).toBeFalsy(); 59 | }); 60 | 61 | it('should get function as expression', function() { 62 | var array = [1, 2, 3, 4, 5]; 63 | 64 | function mod2(elm) { 65 | return !(elm % 2); 66 | } 67 | 68 | expect(filter(array, mod2)).toBeTruthy(); 69 | }); 70 | 71 | it('should get !collection and return always true', function() { 72 | expect(filter('lorem ipsum')).toBeFalsy(); 73 | expect(filter(1, null)).toBeFalsy(); 74 | expect(filter(!1)).toBeFalsy(); 75 | }); 76 | 77 | }); 78 | -------------------------------------------------------------------------------- /test/spec/filter/collection/count-by.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('countByFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.count-by')); 7 | beforeEach(inject(function ($filter) { 8 | filter = $filter('countBy'); 9 | })); 10 | 11 | it('should returns a count for the number of objects in each group.', function() { 12 | 13 | var players = [ 14 | {name: 'Gene', team: 'alpha'}, 15 | {name: 'George', team: 'beta'}, 16 | {name: 'Steve', team: 'gamma'}, 17 | {name: 'Paula', team: 'beta'}, 18 | {name: 'Scruath', team: 'gamma'} 19 | ]; 20 | 21 | expect(filter(players, 'team')).toEqual( { 22 | alpha: 1, 23 | beta: 2, 24 | gamma: 2 25 | }); 26 | 27 | }); 28 | 29 | it('should support nested properties to', function() { 30 | 31 | var orders = [ 32 | { id:10, customer: { name: 'foo', id: 1 } }, 33 | { id:11, customer: { name: 'bar', id: 2 } }, 34 | { id:12, customer: { name: 'foo', id: 1 } }, 35 | { id:13, customer: { name: 'bar', id: 2 } }, 36 | { id:14, customer: { name: 'bar', id: 3 } }, 37 | 2, null, true 38 | ]; 39 | 40 | expect(filter(orders, 'customer.name')).toEqual( { 41 | foo: 2, 42 | bar: 3, 43 | undefined: 3 44 | }); 45 | 46 | }); 47 | 48 | 49 | it('should get object as collection, property(nested to) as identifier and ' + 50 | 'returns the composed aggregate object.', function() { 51 | 52 | var dataObject = { 53 | 0: { id: 1, data: {} }, 54 | 1: { id: 1, data: {} }, 55 | 2: { id: 2, data: {} }, 56 | 3: { id: 2, data: {} } 57 | }; 58 | 59 | expect(filter(dataObject, 'id')).toEqual({ 60 | 1: 2, 61 | 2: 2 62 | }); 63 | 64 | }); 65 | 66 | it('should get !collection and return it as-is ', function() { 67 | 68 | expect(filter('string')).toEqual('string'); 69 | expect(filter(1)).toEqual(1); 70 | expect(filter(!1)).toBeFalsy(); 71 | expect(filter(null)).toBeNull(); 72 | 73 | }); 74 | 75 | }); 76 | -------------------------------------------------------------------------------- /test/spec/filter/collection/defaults.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('defaultsFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.defaults')); 7 | beforeEach(inject(function ($filter) { 8 | filter = $filter('defaults'); 9 | })); 10 | 11 | it('should return the collection as-is, if default object not provided', function() { 12 | expect(filter([{}])).toEqual([{}]); 13 | expect(filter([])).toEqual([]); 14 | }); 15 | 16 | it('should change the source object', function() { 17 | var array = [{ a: 1 }]; 18 | var defaults = { b: 2 }; 19 | var copy = angular.copy(array); 20 | 21 | expect(filter(array, defaults)).toEqual([{ a:1, b: 2 }]); 22 | expect(array).not.toEqual(copy); 23 | }); 24 | 25 | //test the simple usage 26 | describe('should use fallback value', function() { 27 | var expectOrders = [ 28 | { id:1, destination: { zip: 21908 }, name: 'Ariel M.' }, 29 | { id:2, destination: { zip: 'Pickup' }, name: 'John F.' }, 30 | { id:3, destination: { zip: 45841 }, name: 'Not available'}, 31 | { id:4, destination: { zip: 78612 }, name: 'Danno L.' } 32 | ]; 33 | var defaults = { name: 'Not available', destination: { zip: 'Pickup' } }; 34 | 35 | it('should work with array', function() { 36 | var orders = [ 37 | { id:1, destination: { zip: 21908 }, name: 'Ariel M.' }, 38 | { id:2, name: 'John F.' }, 39 | { id:3, destination: { zip: 45841 } }, 40 | { id:4, destination: { zip: 78612 }, name: 'Danno L.' } 41 | ]; 42 | var copyOrders = angular.copy(orders); 43 | 44 | expect(filter(copyOrders, defaults)).toEqual(expectOrders); 45 | expect(filter(copyOrders, defaults)).not.toEqual(orders); 46 | }); 47 | 48 | it('should work with object', function() { 49 | var orders = { 50 | 0: { id:1, destination: { zip: 21908 }, name: 'Ariel M.' }, 51 | 1: { id:2, name: 'John F.' }, 52 | 2: { id:3, destination: { zip: 45841 } }, 53 | 3: { id:4, destination: { zip: 78612 }, name: 'Danno L.' } 54 | }; 55 | var copyOrders = angular.copy(orders); 56 | 57 | expect(filter(copyOrders, defaults)).toEqual(expectOrders); 58 | expect(filter(copyOrders, defaults)).not.toEqual(orders); 59 | }); 60 | 61 | }); 62 | 63 | it('should work fine with complex objects', function() { 64 | var array = [ 65 | { a: 'string', 66 | b: { c: 1 }, 67 | d: { e: { f: new Function() } }, 68 | g: [], 69 | h: undefined, 70 | i: { j: { k: { l: 'm' } } }, 71 | o: new RegExp } 72 | ]; 73 | var copy = angular.copy(array); 74 | var defaults = { z: 'z', z1: { z2: 'z2' } , h: 1 }; 75 | angular.extend(array[0], defaults); 76 | expect(filter(copy, defaults)).toEqual(array); 77 | }); 78 | 79 | it('should get !collection and return it as-is ', function() { 80 | expect(filter('string')).toEqual('string'); 81 | expect(filter(1)).toEqual(1); 82 | expect(filter(!1)).toBeFalsy(); 83 | expect(filter(null)).toBeNull(); 84 | }); 85 | 86 | }); 87 | -------------------------------------------------------------------------------- /test/spec/filter/collection/every.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('everyFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.every')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('every'); 10 | })); 11 | 12 | it('should get collection of primitives and use strict comparison(===)', function() { 13 | 14 | expect(filter(['bar', 'bar'], 'bar')).toBeTruthy(); 15 | expect(filter([4,4,4,4], 4)).toBeTruthy(); 16 | 17 | expect(filter(['foo', 'bar'], 'bar')).toBeFalsy(); 18 | expect(filter([1,4,4,4], 4)).toBeFalsy(); 19 | 20 | }); 21 | 22 | it('should get array as collection and return if given expression is ' + 23 | 'present all members in the collection', function() { 24 | 25 | var array = [ 26 | { id: 1, name: 'faa' }, 27 | { id: 1, name: 'baz' }, 28 | { id: 1, name: 'ariel' }, 29 | { id: 1, name: 'bar' } 30 | ]; 31 | 32 | expect(filter(array, 'id === 1')).toBeTruthy(); 33 | expect(filter(array, 'id >= 1 && name.indexOf(\'a\') !== -1')).toBeTruthy(); 34 | expect(filter(array)).toBeTruthy(); 35 | 36 | expect(filter(array, 'id > 77')).toBeFalsy(); 37 | expect(filter(array, 'name.indexOf(\'b\') !== -1')).toBeFalsy(); 38 | 39 | }); 40 | 41 | it('should get object as collection and return if given expression is ' + 42 | 'present all members in the collection', function() { 43 | 44 | var object = { 45 | 0: { id: 2, name: 'faa' }, 46 | 1: { id: 2, name: 'baz' }, 47 | 2: { id: 2, name: 'ariel' }, 48 | 3: { id: 2, name: 'bar' } 49 | }; 50 | 51 | 52 | expect(filter(object, 'id === 2')).toBeTruthy(); 53 | expect(filter(object, 'id >= 1 && name.indexOf(\'a\') !== -1')).toBeTruthy(); 54 | expect(filter(object)).toBeTruthy(); 55 | 56 | expect(filter(object, 'id > 77')).toBeFalsy(); 57 | expect(filter(object, 'name.indexOf(\'b\') !== -1')).toBeFalsy(); 58 | 59 | }); 60 | 61 | it('should get function as expression', function() { 62 | 63 | var array = [0, 2, 4, 6, 8]; 64 | 65 | function mod2(elm) { 66 | return !(elm % 2); 67 | } 68 | 69 | expect(filter(array, mod2)).toBeTruthy(); 70 | 71 | }); 72 | 73 | it('should get !collection and return always true', function() { 74 | 75 | expect(filter('lorem ipsum')).toBeTruthy(); 76 | expect(filter(1, null)).toBeTruthy(); 77 | expect(filter(!1)).toBeTruthy(); 78 | 79 | }); 80 | 81 | }); 82 | -------------------------------------------------------------------------------- /test/spec/filter/collection/filter-by.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('filterByFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.filter-by')); 7 | beforeEach(inject(function($filter) { 8 | filter = $filter('filterBy'); 9 | })); 10 | 11 | it('should filter by specific properties and avoid the rest', function() { 12 | var users = [ 13 | { id: 1, user: { first_name: 'foo', last_name: 'bar', mobile: 4444 } }, 14 | { id: 2, user: { first_name: 'bar', last_name: 'foo', mobile: 3333 } }, 15 | { id: 3, user: { first_name: 'foo', last_name: 'baz', mobile: 2222 } }, 16 | { id: 4, user: { first_name: 'baz', last_name: 'foo', mobile: 1111 } } 17 | ]; 18 | 19 | expect(filter(users, ['user.first_name', 'user.last_name'], 'foo')).toEqual(users); 20 | expect(filter(users, ['user.first_name'], 'foo')).toEqual([users[0], users[2]]); 21 | expect(filter(users, ['user.last_name'], 'bar')).toEqual([users[0]]); 22 | 23 | expect(filter(users, ['id', 'user.mobile'], '1')).toEqual([users[0], users[3]]); 24 | expect(filter(users, ['id'], '1')).toEqual([users[0]]); 25 | expect(filter(users, ['id', 'user.mobile'], '11')).toEqual([users[3]]); 26 | }); 27 | 28 | it('should support to get object as collection', function() { 29 | var users = { 30 | 0: { id: 1, user: { first_name: 'foo', last_name: 'bar', mobile: 4444 } }, 31 | 1: { id: 2, user: { first_name: 'bar', last_name: 'foo', mobile: 3333 } }, 32 | 2: { id: 3, user: { first_name: 'foo', last_name: 'baz', mobile: 2222 } }, 33 | 3: { id: 4, user: { first_name: 'baz', last_name: 'foo', mobile: 1111 } } 34 | }; 35 | 36 | expect(filter(users, ['user.first_name', 'user.last_name'], 'foo')).toEqual(users); 37 | expect(filter(users, ['user.first_name'], 'oo')).toEqual([users[0], users[2]]); 38 | expect(filter(users, ['user.last_name'], 'bar')).toEqual([users[0]]); 39 | }); 40 | 41 | it('should parse concatenate properties, and search them by one field', function() { 42 | var users = [ 43 | { id: 1, user: { first_name: 'foo', last_name: 'bar', mobile: 4444 } }, 44 | { id: 2, user: { first_name: 'bar', last_name: 'foo', mobile: 3333 } }, 45 | { id: 3, user: { first_name: 'foo', last_name: 'baz', mobile: 2222 } }, 46 | { id: 4, user: { first_name: 'baz', last_name: 'foo', mobile: 1111 } } 47 | ]; 48 | 49 | expect(filter(users, ['user.first_name + user.last_name'], 'foo bar')).toEqual([users[0]]); 50 | expect(filter(users, ['user.first_name+user.last_name'], 'foo bar')).toEqual([users[0]]); 51 | expect(filter(users, ['user.first_name + user.mobile'], 'foo 4444')).toEqual([users[0]]); 52 | 53 | expect(filter(users, ['user.first_name + user.undefined'], 'foo')).toEqual([users[0], users[2]]); 54 | 55 | expect(filter(users, ['user.first_name + user.last_name'], 'a')).toEqual(users); 56 | expect(filter(users, ['user.first_name + user.last_name'], 'ba')).toEqual(users); 57 | expect(filter(users, ['user.first_name + user.last_name'], 'foo')).toEqual(users); 58 | }); 59 | 60 | it('should take care on extreme conditions', function() { 61 | var users = [ 62 | { id: 1, user: { first_name: 'foo', last_name: 'bar', mobile: 4444 } }, 63 | { id: 2, user: { first_name: 'bar', last_name: 'foo', mobile: 3333 } }, 64 | { id: 3, user: { first_name: 'foo', last_name: 'baz', mobile: 2222 } }, 65 | { id: 4, user: { first_name: 'baz', last_name: 'foo', mobile: 1111 } } 66 | ]; 67 | 68 | expect(filter(users, ['id'], 1)).toEqual([users[0]]); 69 | expect(filter(users, ['id'])).toEqual(users); 70 | expect(filter(users, ['id', 'phone'], 4)).toEqual([users[3]]); 71 | expect(filter(users, ['id', 'phone'], null)).toEqual(users); 72 | expect(filter(users, null, null)).toEqual(users); 73 | expect(filter(users, [], [])).toEqual(users); 74 | }); 75 | 76 | it('should get a !collection and return it as-is', function() { 77 | expect(filter(!1)).toBeFalsy(); 78 | expect(filter(1)).toEqual(1); 79 | expect(filter('string')).toEqual('string'); 80 | expect(filter(undefined)).toEqual(undefined); 81 | }); 82 | 83 | it('should not coerce non-string/number properties', function() { 84 | var users = [ 85 | { id: [1, 2], user: { first_name: 'foo', last_name: 'bar', mobile: 4444 } } 86 | ]; 87 | 88 | expect(filter(users, ['id'], 1)).toEqual([]); 89 | }); 90 | 91 | describe('strict mode', function() { 92 | var users = [ 93 | { id: 1, user: { first_name: 'foo', last_name: 'bar', mobile: 4444 } } 94 | ]; 95 | 96 | it('should only return exact matches', function() { 97 | expect(filter(users, ['user.first_name'], 'fo', true)).toEqual([]); 98 | expect(filter(users, ['user.first_name'], 'foo', true)).toEqual(users); 99 | }); 100 | 101 | it('should handle multiple properties', function() { 102 | expect(filter(users, ['user.first_name', 'user.last_name'], 'ba', true)).toEqual([]); 103 | expect(filter(users, ['user.first_name', 'user.last_name'], 'bar', true)).toEqual(users); 104 | }); 105 | 106 | it('should handle concatenation', function() { 107 | expect(filter(users, ['user.first_name + user.last_name'], 'foo ba', true)).toEqual([]); 108 | expect(filter(users, ['user.first_name + user.last_name'], 'foo bar', true)).toEqual(users); 109 | }); 110 | }); 111 | }); 112 | -------------------------------------------------------------------------------- /test/spec/filter/collection/first.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('firstFilter', function() { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.first')); 8 | 9 | beforeEach(inject(function($filter) { 10 | filter = $filter('first'); 11 | })); 12 | 13 | it('should return the first member in a collection', function() { 14 | expect(filter([1,2,3,4,5])).toEqual(1); 15 | expect(filter(['a', 'b', 'c', 'd'])).toEqual('a'); 16 | expect(filter([undefined, null, null])).toEqual(undefined); 17 | expect(filter({0: 'foo', 1: 'bar'})).toEqual('foo'); 18 | }); 19 | 20 | it('should return first n elements of a collection', function() { 21 | expect(filter([1,2,3,4,5], 3)).toEqual([1,2,3]); 22 | expect(filter([undefined, null, null], 1)).toEqual([undefined]); 23 | expect(filter({0: 'foo', 1: 'bar'}, 2)).toEqual(['foo', 'bar']); 24 | }); 25 | 26 | it('should return the first element that match the expression', function() { 27 | var users = [ 28 | { id: 1, name: { first: 'foo', last: 'bar' } }, 29 | { id: 2, name: { first: 'baz', last: 'bar' } }, 30 | { id: 3, name: { first: 'bar', last: 'bar' } }, 31 | { id: 4, name: { first: 'lol', last: 'bar' } } 32 | ]; 33 | 34 | expect(filter(users, 'name.first === name.last')).toEqual([ users[2] ]); 35 | expect(filter(users, '!(id % 2)')).toEqual([ users[1] ]); 36 | expect(filter(users, 'name.first === \'lol\' && name.last === \'bar\'')).toEqual([ users[3] ]); 37 | expect(filter(users, 'id > 5')).toEqual([]); 38 | }); 39 | 40 | it('should return the first n element that match the expression', function() { 41 | var users = [ 42 | { id: 1, name: { first: 'foo', last: 'bar' } }, 43 | { id: 2, name: { first: 'baz', last: 'bar' } }, 44 | { id: 3, name: { first: 'bar', last: 'bar' } }, 45 | { id: 4, name: { first: 'lol', last: 'bar' } } 46 | ]; 47 | 48 | expect(filter(users, 2, 'name.first === name.last')).toEqual([ users[2] ]); 49 | expect(filter(users, 2, '!(id % 2)')).toEqual([ users[1], users[3] ]); 50 | expect(filter(users, 'id > 5')).toEqual([]); 51 | 52 | function mod2(elm) { 53 | return !(elm%2); 54 | } 55 | 56 | expect(filter([1, 2, 3, 4], 2, mod2)).toEqual([2, 4]); 57 | expect(filter([1, 2, 3, 4, 6], 2, mod2)).toEqual([2, 4]); 58 | expect(filter([1, 2], 2, mod2)).toEqual([2]); 59 | }); 60 | 61 | it('should get !collection and return it as-is', function() { 62 | expect(filter('string')).toEqual('string'); 63 | expect(filter(1010)).toEqual(1010); 64 | expect(filter(!0)).toBeTruthy(); 65 | }); 66 | 67 | }); 68 | -------------------------------------------------------------------------------- /test/spec/filter/collection/flatten.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('flattenFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.flatten')); 7 | 8 | beforeEach(inject(function($filter) { 9 | filter = $filter('flatten'); 10 | })); 11 | 12 | it('should get a multiple nested array and return it flatten', function() { 13 | expect(filter([[[[[0]]]]])).toEqual([0]); 14 | 15 | expect(filter([[], 'A', 'B', ['C', 'D'], ['E', ['F'], []]])) 16 | .toEqual(['A', 'B', 'C', 'D', 'E', 'F']); 17 | 18 | expect(filter([[[[null]]], [[null]], [null]])) 19 | .toEqual([null, null, null]); 20 | 21 | expect(filter([[], 1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, [12, [[[[[13], [[[[14, 15]]]]]]]]]]]]])) 22 | .toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); 23 | }); 24 | 25 | it('should have ability to get object as a collection', function() { 26 | expect(filter({ 0: 1, 1: 2, 2: [3, 4], 3: [5, [6, 7, [8]]] })) 27 | .toEqual([1, 2, 3, 4, 5, 6, 7, 8]); 28 | expect(filter({})) 29 | .toEqual([]); 30 | }); 31 | 32 | it('should flattened a single level, if shallow set to true', function() { 33 | expect(filter(['out', ['out', ['in']], ['out', 'out', ['in', 'in']], ['out', 'out']], true)) 34 | .toEqual(['out', 'out', ['in'], 'out', 'out', ['in', 'in'], 'out', 'out']); 35 | expect(filter([[], 1, [1, [0, [0, [0]]], 1, [0]], 1, [1, [0]]], true)) 36 | .toEqual([1, 1, [0, [0, [0]]], 1, [0], 1, 1, [0]]); 37 | }); 38 | 39 | it('should get !collection, and return it as-is', function() { 40 | expect(filter('string')).toEqual('string'); 41 | expect(filter(1, true)).toEqual(1); 42 | expect(filter(~~undefined)).toEqual(0); 43 | expect(filter(null)).toEqual(null); 44 | }); 45 | 46 | }); 47 | -------------------------------------------------------------------------------- /test/spec/filter/collection/fuzzy-by.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('fuzzyByFilter', function() { 4 | var filter, 5 | collection = [ 6 | { title: 'The DaVinci Code' }, 7 | { title: 'The Great Gatsby' }, 8 | { title: 'Angels & Demons' }, 9 | { title: 'The Lost Symbol' }, 10 | { title: 'Old Man\'s War' } 11 | ]; 12 | 13 | beforeEach(module('a8m.fuzzy-by')); 14 | 15 | beforeEach(inject(function ($filter) { 16 | filter = $filter('fuzzyBy'); 17 | })); 18 | 19 | it('should get array as collection, property, search, and filter by fuzzy searching', function() { 20 | 21 | expect(filter(collection, 'title', 'tha')).toEqual([collection[0], collection[1]]); 22 | expect(filter(collection, 'title', 'thesy')).toEqual([collection[1], collection[3]]); 23 | expect(filter(collection, 'title', 'omwar')).toEqual([collection[4]]); 24 | 25 | 26 | }); 27 | 28 | it('should be case sensitive if set to true', function() { 29 | 30 | expect(filter(collection, 'title', 'tha', true)).toEqual([]); 31 | expect(filter(collection, 'title', 'thesy', true)).toEqual([]); 32 | expect(filter(collection, 'title', 'omwar', true)).toEqual([]); 33 | 34 | expect(filter(collection, 'title', 'TDC', true)).toEqual([collection[0]]); 35 | expect(filter(collection, 'title', 'ThLSy', true)).toEqual([collection[3]]); 36 | expect(filter(collection, 'title', 'OldWar', true)).toEqual([collection[4]]); 37 | 38 | }); 39 | 40 | it('should support nested properties', function() { 41 | 42 | collection = [ 43 | { details: { title: 'The DaVinci Code' } }, 44 | { details: { title: 'The Great Gatsby' } }, 45 | { details: { title: 'Angels & Demons' } }, 46 | { details: { title: 'The Lost Symbol' } }, 47 | { details: { title: 'Old Man\'s War' } } 48 | ]; 49 | 50 | expect(filter(collection, 'details.title', 'tha')).toEqual([collection[0], collection[1]]); 51 | expect(filter(collection, 'details.title', 'thesy')).toEqual([collection[1], collection[3]]); 52 | expect(filter(collection, 'details.title', 'omwar')).toEqual([collection[4]]); 53 | 54 | }); 55 | 56 | it('should not get a property and return the collection as-is', function() { 57 | 58 | var array = [{ name: 'foo' }]; 59 | 60 | expect(filter(array)).toEqual(array); 61 | 62 | }); 63 | 64 | it('should get a !collection and return it as-is', function() { 65 | 66 | expect(filter(!1)).toBeFalsy(); 67 | expect(filter(1)).toEqual(1); 68 | expect(filter('string')).toEqual('string'); 69 | 70 | }); 71 | 72 | }); 73 | -------------------------------------------------------------------------------- /test/spec/filter/collection/fuzzy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('fuzzyFilter', function() { 4 | var filter, 5 | collection = [ 6 | { title: 'The DaVinci Code', author: 'F. Scott Fitzgerald' }, 7 | { title: 'The Great Gatsby', author: 'Dan Browns' }, 8 | { title: 'Angels & Demons', author: 'Dan Louis' }, 9 | { title: 'The Lost Symbol', author: 'David Maine' }, 10 | { title: 'Old Man\'s War', author: 'Rob Grant' } 11 | ]; 12 | 13 | beforeEach(module('a8m.fuzzy')); 14 | 15 | beforeEach(inject(function ($filter) { 16 | filter = $filter('fuzzy'); 17 | })); 18 | 19 | it('should get array as collection, search, and filter by fuzzy searching', function() { 20 | 21 | //search by title 22 | expect(filter(collection, 'tha')).toEqual([collection[0], collection[1]]); 23 | expect(filter(collection, 'thesy')).toEqual([collection[1], collection[3]]); 24 | expect(filter(collection, 'omwar')).toEqual([collection[4]]); 25 | 26 | //search by author 27 | expect(filter(collection, 'sfd')).toEqual([collection[0]]); 28 | expect(filter(collection, 'danos')).toEqual([collection[1], collection[2]]); 29 | expect(filter(collection, 'rgnt')).toEqual([collection[4]]); 30 | 31 | }); 32 | 33 | it('should be case sensitive if set to true', function() { 34 | 35 | expect(filter(collection, 'tha', true)).toEqual([]); 36 | expect(filter(collection, 'thesy', true)).toEqual([]); 37 | expect(filter(collection, 'omwar', true)).toEqual([]); 38 | 39 | expect(filter(collection,'TDC', true)).toEqual([collection[0]]); 40 | expect(filter(collection,'ThLSy', true)).toEqual([collection[3]]); 41 | expect(filter(collection,'OldWar', true)).toEqual([collection[4]]); 42 | 43 | }); 44 | 45 | it('should get array of strings, search, and filter by fuzzy searching', function() { 46 | 47 | var array = ['Dan Brown', 'Dan Louis', 'David Maine', 'Rob Grant', 'F. Scott Fitzgerald']; 48 | 49 | expect(filter(array)).toEqual(array); 50 | expect(filter(array, 'da')).toEqual([ 'Dan Brown', 'Dan Louis', 'David Maine' ]); 51 | expect(filter(array, 'oa')).toEqual([ 'Rob Grant', 'F. Scott Fitzgerald' ]); 52 | expect(filter(array, 'S', true)).toEqual([ 'F. Scott Fitzgerald' ]); 53 | 54 | }); 55 | 56 | it('should not get a search and return the collection as-is', function() { 57 | 58 | var array = [{ name: 'foo' }]; 59 | 60 | expect(filter(array)).toEqual(array); 61 | 62 | }); 63 | 64 | it('should get a !collection and return it as-is', function() { 65 | 66 | expect(filter(!1)).toBeFalsy(); 67 | expect(filter(1)).toEqual(1); 68 | expect(filter('string')).toEqual('string'); 69 | 70 | }); 71 | 72 | }); 73 | -------------------------------------------------------------------------------- /test/spec/filter/collection/group-by.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('groupByFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.group-by')); 7 | beforeEach(inject(function ($filter) { 8 | filter = $filter('groupBy'); 9 | })); 10 | 11 | it('should get array as collection, property(nested to) as identifier and ' + 12 | 'returns the composed aggregate object.', function() { 13 | 14 | var players = [ 15 | {name: 'Gene', team: 'alpha'}, 16 | {name: 'George', team: 'beta'}, 17 | {name: 'Steve', team: 'gamma'}, 18 | {name: 'Paula', team: 'beta'}, 19 | {name: 'Scruath', team: 'gamma'} 20 | ]; 21 | 22 | expect(filter(players, 'team')).toEqual( { 23 | alpha: [players[0]], 24 | beta: [players[1], players[3]], 25 | gamma: [players[2], players[4]] 26 | }); 27 | }); 28 | 29 | it('should support nested properties to', function() { 30 | var orders = [ 31 | { id:10, customer: { name: 'foo', id: 1 } }, 32 | { id:11, customer: { name: 'bar', id: 2 } }, 33 | { id:12, customer: { name: 'foo', id: 1 } }, 34 | { id:13, customer: { name: 'bar', id: 2 } }, 35 | { id:14, customer: { name: 'bar', id: 3 } }, 36 | 2, null, true 37 | ]; 38 | 39 | expect(filter(orders, 'customer.name')).toEqual( { 40 | foo: [orders[0], orders[2]], 41 | bar: [orders[1], orders[3], orders[4]], 42 | undefined: [2, null, true] 43 | }); 44 | }); 45 | 46 | 47 | it('should get object as collection, property(nested to) as identifier and ' + 48 | 'returns the composed aggregate object.', function() { 49 | var dataObject = { 50 | 0: { id: 1, data: {} }, 51 | 1: { id: 1, data: {} }, 52 | 2: { id: 2, data: {} }, 53 | 3: { id: 2, data: {} } 54 | }; 55 | 56 | expect(filter(dataObject, 'id')).toEqual({ 57 | 1: [dataObject[0], dataObject[1]], 58 | 2: [dataObject[2], dataObject[3]] 59 | }); 60 | }); 61 | 62 | it('should get !collection and return it as-is ', function() { 63 | expect(filter('string')).toEqual('string'); 64 | expect(filter(1)).toEqual(1); 65 | expect(filter(!1)).toBeFalsy(); 66 | expect(filter(null)).toBeNull(); 67 | }); 68 | 69 | describe('inside the DOM', function() { 70 | it('should not throw and not trigger the infinite digest exception', 71 | inject(function($rootScope, $compile) { 72 | var scope = $rootScope.$new(); 73 | scope.players = [ 74 | { name: 'foo', team: 'a' }, 75 | { name: 'lol', team: 'b' }, 76 | { name: 'bar', team: 'b' }, 77 | { name: 'baz', team: 'a' } 78 | ]; 79 | scope.search = ''; 80 | var elm = angular.element( 81 | '' 87 | ); 88 | var temp = $compile(elm)(scope); 89 | expect(function() { scope.$digest() }).not.toThrow(); 90 | expect(temp.children().length).toEqual(2); 91 | })); 92 | }); 93 | }); 94 | -------------------------------------------------------------------------------- /test/spec/filter/collection/is-empty.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('isEmptyFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.is-empty')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('isEmpty'); 10 | })); 11 | 12 | it('should get collection or string, and return true if it empty', function() { 13 | 14 | expect(filter([])).toBeTruthy(); 15 | expect(filter({})).toBeTruthy(); 16 | expect(filter('')).toBeTruthy(); 17 | 18 | expect(filter([1,2])).toBeFalsy(); 19 | expect(filter({foo: 'bar'})).toBeFalsy(); 20 | expect(filter('lorem ipsum')).toBeFalsy(); 21 | 22 | }); 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /test/spec/filter/collection/join.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('isJoinFilter', function () { 4 | var joinFilter; 5 | 6 | beforeEach(module('a8m.join')); 7 | 8 | beforeEach(inject(function (_joinFilter_) { 9 | joinFilter = _joinFilter_; 10 | })); 11 | 12 | describe('given a collection', function () { 13 | var arr; 14 | 15 | describe('which is empty', function () { 16 | beforeEach(function () { 17 | arr = []; 18 | }); 19 | 20 | it('should return an empty string', function () { 21 | expect(joinFilter(arr)).toEqual(''); 22 | }); 23 | 24 | }); 25 | 26 | describe('of strings', function () { 27 | beforeEach(function () { 28 | arr = ['hello', 'world']; 29 | }); 30 | 31 | describe('with no delimiter', function () { 32 | it('should join elements with a space', function () { 33 | expect(joinFilter(arr)).toEqual('hello world'); 34 | }); 35 | }); 36 | 37 | describe('with a custom delimiter', function () { 38 | var delim; 39 | 40 | describe('which is not a string', function () { 41 | it('should join elements with a toString representation of the delimiter', function () { 42 | delim = true; 43 | expect(joinFilter(arr, delim)).toEqual('hellotrueworld'); 44 | 45 | delim = 10; 46 | expect(joinFilter(arr, delim)).toEqual('hello10world'); 47 | 48 | delim = {toString: function () { return ' - ' }} 49 | expect(joinFilter(arr, delim)).toEqual('hello - world'); 50 | }); 51 | }); 52 | 53 | it('should join elements with the given delimiter', function () { 54 | delim = ', ' 55 | expect(joinFilter(arr, delim)).toEqual('hello, world'); 56 | }); 57 | }); 58 | }); 59 | 60 | }); 61 | 62 | describe('given something that is not a collection', function () { 63 | var str, obj, bool, num; 64 | beforeEach(function () { 65 | str = 'string'; 66 | obj = {'a': 'b'}; 67 | bool = true; 68 | num = 5; 69 | }); 70 | 71 | it('should return the input as is', function () { 72 | expect(joinFilter(str)).toEqual(str); 73 | expect(joinFilter(obj)).toEqual(obj); 74 | expect(joinFilter(bool)).toEqual(bool); 75 | expect(joinFilter(num)).toEqual(num); 76 | }); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /test/spec/filter/collection/last.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('lastFilter', function() { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.last')); 8 | 9 | beforeEach(inject(function($filter) { 10 | filter = $filter('last'); 11 | })); 12 | 13 | it('should return the last member in a collection', function() { 14 | expect(filter([1,2,3,4,5])).toEqual(5); 15 | expect(filter(['a', 'b', 'c', 'd'])).toEqual('d'); 16 | expect(filter([undefined, null, null])).toEqual(null); 17 | expect(filter({0: 'foo', 1: 'bar'})).toEqual('bar'); 18 | }); 19 | 20 | it('should return last n elements of a collection', function() { 21 | expect(filter([1, 2, 3, 4, 5], 3)).toEqual([3, 4, 5]); 22 | expect(filter([undefined, null, null], 2)).toEqual([null, null]); 23 | expect(filter({0: 'foo', 1: 'bar'}, 2)).toEqual(['foo', 'bar']); 24 | }); 25 | 26 | it('should return the last element that match the expression', function() { 27 | var users = [ 28 | { id: 1, name: { first: 'foo', last: 'bar' } }, 29 | { id: 2, name: { first: 'baz', last: 'bar' } }, 30 | { id: 3, name: { first: 'bar', last: 'bar' } }, 31 | { id: 4, name: { first: 'lol', last: 'bar' } } 32 | ]; 33 | 34 | expect(filter(users, 'name.first === name.last')).toEqual([ users[2] ]); 35 | expect(filter(users, '!(id % 2)')).toEqual([ users[3] ]); 36 | expect(filter(users, 'name.first !== \'lol\' && name.last === \'bar\'')).toEqual([ users[2] ]); 37 | expect(filter(users, 'id > 5')).toEqual([]); 38 | }); 39 | 40 | it('should return the last n element that match the expression', function() { 41 | var users = [ 42 | { id: 1, name: { first: 'foo', last: 'bar' } }, 43 | { id: 2, name: { first: 'baz', last: 'bar' } }, 44 | { id: 3, name: { first: 'bar', last: 'bar' } }, 45 | { id: 4, name: { first: 'lol', last: 'bar' } } 46 | ]; 47 | 48 | expect(filter(users, 2, 'name.first !== name.last')).toEqual([users[1], users[3]]); 49 | expect(filter(users, 2, '(id % 2)')).toEqual([users[0], users[2]]); 50 | expect(filter(users, 'id > 5')).toEqual([]); 51 | 52 | function mod2(elm) { 53 | return !(elm%2); 54 | } 55 | 56 | expect(filter([1, 2, 3, 4, 5, 6], 2, mod2)).toEqual([4, 6]); 57 | expect(filter([1, 2, 3, 4, 6, 11], 2, mod2)).toEqual([4, 6]); 58 | expect(filter([2,1], 2, mod2)).toEqual([2]); 59 | }); 60 | 61 | it('should get !collection and return it as-is', function() { 62 | expect(filter('string')).toEqual('string'); 63 | expect(filter(1010)).toEqual(1010); 64 | expect(filter(!0)).toBeTruthy(); 65 | }); 66 | 67 | }); 68 | -------------------------------------------------------------------------------- /test/spec/filter/collection/map.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('mapFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.map')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('map'); 10 | })); 11 | 12 | it('should returns a new collection of the results of each expression execution', function() { 13 | 14 | var array = [ 15 | { id: 1, name: 'foo' }, 16 | { id: 2, name: 'baz' }, 17 | { id: 1, name: 'ariel' }, 18 | { id: 1, name: 'bar' } 19 | ]; 20 | 21 | expect(filter(array, 'name')).toEqual(['foo', 'baz', 'ariel', 'bar']); 22 | expect(filter(array, 'id === 1 && name === "foo"')).toEqual([true, false, false, false]); 23 | expect(filter(array)).toEqual(array); 24 | 25 | }); 26 | 27 | it('should get object as a collection and filter by expression', function() { 28 | 29 | var object = { 30 | 0: { id: 1, name: 'foo' }, 31 | 1: { id: 2, name: 'baz' }, 32 | 2: { id: 1, name: 'ariel' }, 33 | 3: { id: 1, name: 'bar' } 34 | }; 35 | 36 | expect(filter(object, 'name')).toEqual(['foo', 'baz', 'ariel', 'bar']); 37 | expect(filter(object, 'id === 1 && name === "foo"')).toEqual([true, false, false, false]); 38 | expect(filter(object)).toEqual([object[0], object[1], object[2], object[3]]); 39 | 40 | }); 41 | 42 | it('should get function ad expression', function() { 43 | 44 | var array = [1, 2, 3, 4, 5]; 45 | 46 | function divide(elm) { 47 | return (elm/2); 48 | } 49 | 50 | expect(filter(array, divide)).toEqual([0.5, 1, 1.5, 2, 2.5]); 51 | 52 | }); 53 | 54 | it('should get !collection and return it as-is', function() { 55 | 56 | expect(filter('lorem ipsum')).toEqual('lorem ipsum'); 57 | expect(filter(1, null)).toEqual(1); 58 | expect(filter(!1)).toBeFalsy(); 59 | 60 | }); 61 | 62 | }); 63 | -------------------------------------------------------------------------------- /test/spec/filter/collection/omit.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('omitFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.omit')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('omit'); 10 | })); 11 | 12 | it('should get array as a collection and filter by expression', function() { 13 | 14 | var array = [ 15 | { id: 1, name: 'foo' }, 16 | { id: 2, name: 'baz' }, 17 | { id: 1, name: 'ariel' }, 18 | { id: 1, name: 'bar' } 19 | ]; 20 | 21 | expect(filter(array, 'id === 1')).toEqual([array[1]]); 22 | expect(filter(array, 'id === 1 && name === "foo"')).toEqual([array[1], array[2], array[3]]); 23 | expect(filter(array)).toEqual(array); 24 | 25 | }); 26 | 27 | it('should get object as a collection and filter by expression', function() { 28 | 29 | var object = { 30 | 0: { id: 1, name: 'foo' }, 31 | 1: { id: 2, name: 'baz' }, 32 | 2: { id: 1, name: 'ariel' }, 33 | 3: { id: 1, name: 'bar' } 34 | }; 35 | 36 | expect(filter(object, 'id === 1')).toEqual([object[1]]); 37 | expect(filter(object, 'id === 1 && name === "foo"')).toEqual([object[1], object[2], object[3]]); 38 | expect(filter(object, 'name === german')).toEqual([object[0], object[1], object[2], object[3]]); 39 | 40 | }); 41 | 42 | it('should get function ad expression', function() { 43 | 44 | var array = [1, 2, 3, 4, 5]; 45 | 46 | function mod2(elm) { 47 | return !(elm % 2); 48 | } 49 | 50 | expect(filter(array, mod2)).toEqual([1, 3, 5]); 51 | 52 | }); 53 | 54 | it('should get !collection and return it as-is', function() { 55 | 56 | expect(filter('lorem ipsum')).toEqual('lorem ipsum'); 57 | expect(filter(1, null)).toEqual(1); 58 | expect(filter(!1)).toBeFalsy(); 59 | 60 | }); 61 | 62 | }); 63 | -------------------------------------------------------------------------------- /test/spec/filter/collection/pick.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('pickFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.pick')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('pick'); 10 | })); 11 | 12 | it('should get array as a collection and filter by expression', function() { 13 | 14 | var array = [ 15 | { id: 1, name: 'foo' }, 16 | { id: 2, name: 'baz' }, 17 | { id: 1, name: 'ariel' }, 18 | { id: 1, name: 'bar' } 19 | ]; 20 | 21 | expect(filter(array, 'id === 2')).toEqual([array[1]]); 22 | expect(filter(array, 'id === 1 && name === "foo"')).toEqual([array[0]]); 23 | expect(filter(array)).toEqual(array); 24 | 25 | }); 26 | 27 | it('should get object as a collection and filter by expression', function() { 28 | 29 | var object = { 30 | 0: { id: 1, name: 'foo' }, 31 | 1: { id: 2, name: 'baz' }, 32 | 2: { id: 1, name: 'ariel' }, 33 | 3: { id: 1, name: 'bar' } 34 | }; 35 | 36 | expect(filter(object, 'id === 1')).toEqual([object[0], object[2], object[3]]); 37 | expect(filter(object, 'id === 1 && name === "foo"')).toEqual([object[0]]); 38 | expect(filter(object, 'name === german')).toEqual([]); 39 | 40 | }); 41 | 42 | it('should get function ad expression', function() { 43 | 44 | var array = [1, 2, 3, 4, 5]; 45 | 46 | function mod2(elm) { 47 | return !(elm % 2); 48 | } 49 | 50 | expect(filter(array, mod2)).toEqual([2, 4]); 51 | 52 | }); 53 | 54 | it('should get !collection and return it as-is', function() { 55 | 56 | expect(filter('lorem ipsum')).toEqual('lorem ipsum'); 57 | expect(filter(1, null)).toEqual(1); 58 | expect(filter(!1)).toBeFalsy(); 59 | 60 | }); 61 | 62 | }); 63 | -------------------------------------------------------------------------------- /test/spec/filter/collection/range.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('rangeFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.range')); 7 | beforeEach(inject(function ($filter) { 8 | filter = $filter('range'); 9 | })); 10 | 11 | it('should return an array of 10 items', function() { 12 | expect(filter([], 10)).toEqual([0,1,2,3,4,5,6,7,8,9]); 13 | expect(filter([], 10).length).toEqual(10); 14 | }); 15 | 16 | it('should return 10 items starting at 10 incrementing by 1', function() { 17 | expect(filter([], 10, 10)).toEqual([10,11,12,13,14,15,16,17,18,19]); 18 | expect(filter([], 10).length).toEqual(10); 19 | }); 20 | 21 | it('should return 10 items starting at 10 incrementing by 10 ', function() { 22 | expect(filter([], 10, 10, 10)).toEqual([10,20,30,40,50,60,70,80,90,100]); 23 | expect(filter([], 10).length).toEqual(10); 24 | }); 25 | 26 | it('should return 10 items starting at 10 incrementing by 10 and multiplied by 2.', function() { 27 | expect(filter([], 10, 10, 10, function(n) { return 2 * n; })) 28 | .toEqual([20,40,60,80,100,120,140,160,180,200]); 29 | expect(filter([], 10).length).toEqual(10); 30 | }); 31 | 32 | }); -------------------------------------------------------------------------------- /test/spec/filter/collection/remove-with.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('removeWithFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.remove-with')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('removeWith'); 10 | })); 11 | 12 | it('should get array and properties object and return' + 13 | 'array filtered by equivalent property values.', function() { 14 | 15 | var array = [ 16 | { id: 1, name: 'ariel' }, 17 | { id: 2, name: 'baz' }, 18 | { id: 1, name: 'ariel' }, 19 | { id: 1, name: 'bar' } 20 | ]; 21 | 22 | expect(filter(array, { id: 1 })).toEqual([{ id: 2, name: 'baz' }]); 23 | expect(filter(array, { id: 1, name: 'ariel' })).toEqual([{ id: 2, name: 'baz' }, { id: 1, name: 'bar' }]); 24 | 25 | expect(filter(array, {})).toEqual([]); 26 | 27 | }); 28 | 29 | it('should get object and properties object and return' + 30 | 'array of all elements that have equivalent property values.', function() { 31 | 32 | var object = { 33 | 0: { id: 1, name: 'ariel' }, 34 | 1: { id: 2, name: 'baz' }, 35 | 2: { id: 1, name: 'ariel' }, 36 | 3: { id: 1, name: 'bar' } 37 | }; 38 | 39 | expect(filter(object, { id: 1 })).toEqual([ object[1] ]); 40 | expect(filter(object, { id: 1 , name: 'ariel' })).not.toContain(object[0]); 41 | 42 | expect(filter(object, {}).length).toEqual(0); 43 | 44 | }); 45 | 46 | it('should not get properties object and return the collection as is', function() { 47 | 48 | expect(filter([{ a: 1 }])).toEqual([{ a:1 }]); 49 | expect(filter([{ a: 1 }, { b: 2 }])).toEqual([{ a:1 }, { b: 2 }]); 50 | 51 | }); 52 | 53 | it('should get !collection and return it as-is', function() { 54 | expect(filter(999)).toEqual(999); 55 | expect(filter(!1)).toBeFalsy(); 56 | expect(null).toEqual(null); 57 | }); 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /test/spec/filter/collection/remove.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('removeFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.remove')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('remove'); 10 | })); 11 | 12 | it('should get array as a collection and members as an arguments' + 13 | 'and remove them from collection', function() { 14 | 15 | var array = [ 16 | { id: 1, name: 'ariel' }, 17 | { id: 2, name: 'baz' }, 18 | { id: 1, name: 'ariel' }, 19 | { id: 1, name: 'bar' } 20 | ]; 21 | 22 | expect(filter(array, { id: 1 , name: 'ariel' })).toEqual([{ id: 2, name: 'baz' }, { id: 1, name: 'bar' }]); 23 | expect(filter(array, { id: 1, name: 'ariel' }, { id: 1, name: 'bar' })).toEqual([{ id: 2, name: 'baz' }]); 24 | 25 | expect(filter([1,2,3, null], null, 2, 1)).toEqual([3]); 26 | 27 | expect(filter(array, {})).toEqual(array); 28 | 29 | }); 30 | 31 | it('should get object as a collection and members as an arguments' + 32 | 'and remove them from collection.', function() { 33 | 34 | var object = { 35 | 0: { id: 1, name: 'ariel' }, 36 | 1: { id: 2, name: 'baz' }, 37 | 2: { id: 1, name: 'ariel' }, 38 | 3: { id: 1, name: 'bar' } 39 | }; 40 | 41 | expect(filter(object, { id: 1, name: 'ariel' })).toEqual([{ id: 2, name: 'baz' }, { id: 1, name: 'bar' }]); 42 | expect(filter(object, { id: 1 , name: 'ariel' })).not.toContain(object[0]); 43 | 44 | expect(filter(object, {}).length).toEqual(4); 45 | 46 | }); 47 | 48 | it('should not arguments and return the collection as is', function() { 49 | 50 | expect(filter([{ a: 1 }])).toEqual([{ a:1 }]); 51 | expect(filter([{ a: 1 }, { b: 2 }])).toEqual([{ a:1 }, { b: 2 }]); 52 | 53 | }); 54 | 55 | it('should get !collection and return it as-is', function() { 56 | 57 | expect(filter('lorem ipsum')).toEqual('lorem ipsum'); 58 | expect(filter(1, null)).toEqual(1); 59 | 60 | }); 61 | 62 | }); 63 | -------------------------------------------------------------------------------- /test/spec/filter/collection/reverse.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('reverseFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.reverse')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('reverse'); 10 | })); 11 | 12 | it('should get array as collection and return it revered', function() { 13 | 14 | var array = [1,2,3,4]; 15 | 16 | expect(filter(array)).toEqual(array.reverse()); 17 | expect(filter([1])).toEqual([1]); 18 | expect(filter(['foo', 'bar'])).toEqual(['bar', 'foo']); 19 | 20 | }); 21 | 22 | it('should get object as collection and return it revered array', function() { 23 | 24 | var object = { 25 | 0: { id: 1 }, 26 | 1: { id: 2 }, 27 | 2: { id: 3 } 28 | }; 29 | 30 | expect(filter(object)).toEqual([{ id: 3 }, { id: 2 }, { id: 1 }]); 31 | 32 | }); 33 | 34 | it('should get string as a parameter and return it reversed', function() { 35 | 36 | expect(filter('foobar')).toEqual('raboof'); 37 | expect(filter('Lorem Ipsum')).toEqual('muspI meroL'); 38 | expect(filter('FOO, BAR, BAZ')).toEqual('ZAB ,RAB ,OOF'); 39 | 40 | }); 41 | 42 | it('should get !string and !collection and return it as-is', function() { 43 | 44 | expect(filter(999)).toEqual(999); 45 | expect(filter(!1)).toBeFalsy(); 46 | expect(null).toEqual(null); 47 | 48 | }); 49 | 50 | }); 51 | -------------------------------------------------------------------------------- /test/spec/filter/collection/search-field.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('searchFieldFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.search-field')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('searchField'); 10 | })); 11 | 12 | it('should get array as a collection, and several keys for searchFiled and' + 13 | 'return new array with the new "searchField" property', function() { 14 | 15 | var input = [ 16 | { first_name: 'Sharon', last_name: 'Melendez' }, 17 | { first_name: 'Edmundo', last_name: 'Hepler' }, 18 | { first_name: 'Marsha', last_name: 'Letourneau' } 19 | ]; 20 | 21 | var output = [ 22 | { first_name: 'Sharon', last_name: 'Melendez', searchField: 'Sharon Melendez' }, 23 | { first_name: 'Edmundo', last_name: 'Hepler', searchField: 'Edmundo Hepler' }, 24 | { first_name: 'Marsha', last_name: 'Letourneau', searchField: 'Marsha Letourneau' } 25 | ]; 26 | 27 | expect(filter(input, 'first_name', 'last_name')).toEqual(output); 28 | 29 | expect(filter([{a: 'a', b: 'b'}], 'a', 'b')).toEqual([{a: 'a', b: 'b', searchField: 'a b'}]); 30 | 31 | }); 32 | 33 | it('should support nested properties to', function() { 34 | 35 | var input = [ 36 | { user: { first_name: 'Sharon', last_name: 'Melendez' } }, 37 | { user: { first_name: 'Edmundo', last_name: 'Hepler' } }, 38 | { user: { first_name: 'Marsha', last_name: 'Letourneau' } } 39 | ]; 40 | 41 | var output = [ 42 | { user: { first_name: 'Sharon', last_name: 'Melendez' }, searchField: 'Sharon Melendez' }, 43 | { user: { first_name: 'Edmundo', last_name: 'Hepler' }, searchField: 'Edmundo Hepler' }, 44 | { user: { first_name: 'Marsha', last_name: 'Letourneau' }, searchField: 'Marsha Letourneau' } 45 | ]; 46 | 47 | var inputObject = { user: { details: { name: { first: 'Ariel', last: 'Mashraki' } } } }, 48 | outputObject = { user: { details: { name: { first: 'Ariel', last: 'Mashraki' } } }, searchField: 'Ariel Mashraki' }; 49 | 50 | expect(filter(input, 'user.first_name', 'user.last_name')).toEqual(output); 51 | 52 | expect(filter([inputObject], 'user.details.name.first', 'user.details.name.last')).toEqual([outputObject]); 53 | 54 | }); 55 | 56 | it('should change the original/source collection', function() { 57 | 58 | var mutable = [{a: 'a', b: 'b'}]; 59 | filter(mutable, 'a', 'b'); 60 | 61 | expect(mutable).toEqual([{a: 'a', b: 'b', searchField: 'a b'}]); 62 | 63 | }); 64 | 65 | it('should get !collection and return it as-is', function() { 66 | 67 | expect(filter('string', 'foo')).toEqual('string'); 68 | expect(filter(1)).toEqual(1); 69 | expect(filter(!1)).toBeFalsy(); 70 | expect(filter(null)).toBeNull(); 71 | 72 | }); 73 | 74 | }); 75 | -------------------------------------------------------------------------------- /test/spec/filter/collection/to-array.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('toArray', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.to-array')); 7 | 8 | beforeEach(inject(function($filter) { 9 | filter = $filter('toArray'); 10 | })); 11 | 12 | it('should convert an object to an array of values', function() { 13 | var object = { 14 | 0: { f: 'foo' }, 15 | 1: { b: 'bar' }, 16 | 2: { b: 'baz' } 17 | }; 18 | 19 | expect(filter(object)).toEqual([object[0], object[1], object[2]]); 20 | 21 | expect(filter({ 0: 0, 1: 1, 2: 2 })).toEqual([0, 1, 2]); 22 | }); 23 | 24 | it('should add $key property if addKey param is true', function() { 25 | var object = { 26 | 0: { f: 'foo' }, 27 | 1: { b: 'bar' }, 28 | 2: { b: 'baz' } 29 | }; 30 | 31 | expect(filter(object, true)).toEqual([ 32 | { $key: '0', f: 'foo' }, 33 | { $key: '1', b: 'bar' }, 34 | { $key: '2', b: 'baz' } 35 | ]); 36 | }); 37 | 38 | it('should get !object and return it as-is', function() { 39 | expect(filter(1)).toEqual(1); 40 | expect(filter(!0)).toBeTruthy(); 41 | expect(filter('string')).toEqual('string'); 42 | expect(filter(undefined)).toEqual(undefined); 43 | }); 44 | 45 | }); 46 | -------------------------------------------------------------------------------- /test/spec/filter/collection/unique.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('uniqFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.unique')); 7 | beforeEach(inject(function ($filter) { 8 | filter = $filter('unique'); 9 | })); 10 | 11 | 12 | it('should get a collection of primitives and return filtered collection', function() { 13 | //Boolean 14 | expect(filter([true, true, false, false, true])).toEqual([true, false]); 15 | //numbers 16 | expect(filter([1, 1, 2, 3, 4, 5, 5, 5, 5])).toEqual([1, 2, 3, 4, 5]); 17 | //strings 18 | expect(filter(["Ariel", "Ariel", "Ariel"])).toEqual(["Ariel"]); 19 | }); 20 | 21 | it('should get array as collection, property(nested to) as identifier and filter', function() { 22 | 23 | var orders = [ 24 | { id:10, customer: { name: 'foo', id: 1 } }, 25 | { id:11, customer: { name: 'bar', id: 2 } }, 26 | { id:12, customer: { name: 'foo', id: 1 } }, 27 | { id:13, customer: { name: 'bar', id: 2 } }, 28 | { id:14, customer: { name: 'baz', id: 3 } }, 29 | ]; 30 | 31 | var filteredOrders = [ 32 | { id:10, customer: { name: 'foo', id: 1 } }, 33 | { id:11, customer: { name: 'bar', id: 2 } }, 34 | { id:14, customer: { name: 'baz', id: 3 } }, 35 | ]; 36 | 37 | expect(filter(orders, 'customer.id')).toEqual(filteredOrders); 38 | expect(filter(orders, 'customer.id').length).toEqual(filteredOrders.length); 39 | 40 | expect(filter(orders, 'customer.name')).toEqual(filteredOrders); 41 | expect(filter(orders, 'customer.name').length).toEqual(filteredOrders.length); 42 | 43 | expect(filter(orders, 'id')).toEqual(orders); 44 | expect(filter(orders, 'id').length).toEqual(orders.length); 45 | 46 | }); 47 | 48 | it('should filtered by property and not touch members without this property', function() { 49 | 50 | var array = [ 51 | { id: 1, person: { name: 'Ariel' , age: 25 } }, 52 | { id: 2, person: { name: 'Joe' , age: 25 } }, 53 | { id: 3, person: { name: 'Bob' , age: 42 } }, 54 | { id: 4, person: { name: 'Marie' , age: 42 } }, 55 | {}, [], 1,2, 'foo', true, null 56 | ]; 57 | 58 | var filteredArray = [ 59 | { id: 1, person: { name: 'Ariel' , age: 25 } }, 60 | { id: 3, person: { name: 'Bob' , age: 42 } }, 61 | {}, [], 1,2, 'foo', true, null 62 | ]; 63 | 64 | //filter by person.age 65 | expect(filter(array, 'person.age')).toEqual(filteredArray); 66 | 67 | //should not touch members without this property 68 | expect(filter(array, 'id')).toEqual(array); 69 | 70 | }); 71 | 72 | it('should get object as collection and return filtered collection', function() { 73 | 74 | var dataObject = { 75 | 0: { id: 1, data: {} }, 76 | 1: { id: 1, data: {} }, 77 | 2: { id: 2, data: {} }, 78 | 3: { id: 2, data: {} } 79 | }; 80 | var dataArray = [ 81 | { id: 1, data: {} }, 82 | { id: 2, data: {}} 83 | ]; 84 | 85 | expect(filter(dataObject, 'id')).toEqual(dataArray); 86 | 87 | }); 88 | 89 | it('should support advance nested properties', function() { 90 | var orders = [ 91 | { order: { person: { credit: { information: { num: 99999 } } } } }, 92 | { order: { person: { credit: { information: { num: 99999 } } } } }, 93 | { order: { person: { credit: { information: { num: 99999 } } } } } 94 | ]; 95 | expect(filter(orders, 'order.person.credit.information.num')).toEqual([orders[0]]); 96 | }); 97 | 98 | it('should get a !collection and return as-is', function() { 99 | expect(filter(undefined)).toEqual(undefined); 100 | expect(filter('foo')).toEqual('foo'); 101 | expect(filter(1)).toEqual(1); 102 | expect(filter(!1)).toBeFalsy(); 103 | }); 104 | 105 | }); 106 | -------------------------------------------------------------------------------- /test/spec/filter/collection/where.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('whereFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.where')); 7 | 8 | beforeEach(inject(function ($filter) { 9 | filter = $filter('where'); 10 | })); 11 | 12 | it('should get array and properties object and return' + 13 | 'array of all elements that have equivalent property values.', function() { 14 | 15 | var array = [ 16 | { id: 0, name: 'ariel' }, 17 | { id: 1, name: 'baz' }, 18 | { id: 0, name: 'ariel' }, 19 | { id: 0, name: 'bar' } 20 | ]; 21 | 22 | expect(filter(array, { id: 0, name: 'ariel' })).toEqual([array[0], array[2]]); 23 | expect(filter(array, { id: 0 })).not.toContain(array[1]); 24 | 25 | expect(filter(array, {})).toEqual(array); 26 | 27 | }); 28 | 29 | it('should get object and properties object and return' + 30 | 'array of all elements that have equivalent property values.', function() { 31 | 32 | var object = { 33 | 0: { id: 1, name: 'ariel' }, 34 | 1: { id: 2, name: 'baz' }, 35 | 2: { id: 1, name: 'ariel' }, 36 | 3: { id: 1, name: 'bar' } 37 | }; 38 | 39 | expect(filter(object, { id: 1, name: 'ariel' })).toEqual([object[0], object[2]]); 40 | expect(filter(object, { id: 1 })).not.toContain(object[1]); 41 | 42 | expect(filter(object, {}).length).toEqual(4); 43 | 44 | }); 45 | 46 | it('should not get properties object and return the collection as is', function() { 47 | 48 | expect(filter([{ a: 1 }])).toEqual([{ a:1 }]); 49 | expect(filter([{ a: 1 }, { b: 2 }])).toEqual([{ a:1 }, { b: 2 }]); 50 | 51 | }); 52 | 53 | it('should get !collection and return it as-is', function() { 54 | expect(filter(999)).toEqual(999); 55 | expect(filter(!1)).toBeFalsy(); 56 | expect(null).toEqual(null); 57 | }); 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /test/spec/filter/collection/xor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('xorFilter', function() { 4 | var filter; 5 | 6 | beforeEach(module('a8m.xor')); 7 | 8 | beforeEach(inject(function($filter) { 9 | filter = $filter('xor'); 10 | })); 11 | 12 | it('should get 2 array collection and return exclusive or between them', function() { 13 | expect(filter([1,2], [1])).toEqual([2]); 14 | expect(filter([1, 2, 3], [5, 2, 1, 4])).toEqual([3, 5, 4]); 15 | 16 | expect(filter([1, 2, 3], [4, 5])).toEqual([1, 2, 3, 4, 5]); 17 | expect(filter([1, 2, 3], [2, 3, 4])).toEqual([1, 4]); 18 | }); 19 | 20 | it('should get objects as collection', function() { 21 | expect(filter({ 0: 1, 1: 2 }, { 0: 3 })).toEqual([1, 2, 3]); 22 | expect(filter({ 0: 1, 1: 2 }, { 0: 1 })).toEqual([2]); 23 | }); 24 | 25 | it('should get an objects collection and filters by value', function() { 26 | 27 | var array = [ 28 | { id: 1, name: 'foo' }, 29 | { id: 2, name: 'bar' }, 30 | { id: 3, name: 'baz' } 31 | ]; 32 | 33 | expect(filter(array, array)).toEqual([]); // A (xor) A 34 | expect(filter(array, [ { id: 1, name:'foo' } ])).toEqual([array[1], array[2]]); 35 | 36 | expect(filter(array, [ { id: 1 } ])).toEqual( 37 | array.concat([{ id: 1 }]) 38 | ); 39 | }); 40 | 41 | it('should filter by specific property', function() { 42 | var users = [ 43 | { id: 0, details: { first_name: 'foo', last_name: 'bar' } }, 44 | { id: 1, details: { first_name: 'foo', last_name: 'baz' } }, 45 | { id: 2, details: { first_name: 'foo', last_name: 'bag' } } 46 | ]; 47 | 48 | expect(filter(users, [{ details: { first_name: 'foo' } }], 'details.first_name')) 49 | .toEqual([]); 50 | expect(filter(users, [{ id: 0 }, { id: 1 }], 'id')).toEqual([users[2]]); 51 | 52 | expect(filter(users, [{ id: 3, details: { first_name: 'foo', last_name: 'bag' }}], 'id')) 53 | .toEqual( 54 | users.concat([{ id: 3, details: { first_name: 'foo', last_name: 'bag' }}] 55 | )); 56 | }); 57 | 58 | it('should filter by expression', function() { 59 | expect(filter([ { id: 2 }, { id: 3 }], [ { id: 4 } ], 'id % 2')).toEqual([{ id: 3 }]); 60 | }); 61 | 62 | 63 | it('should get !collection and return it as-is', function() { 64 | expect(filter(999)).toEqual(999); 65 | expect(filter(!1)).toBeFalsy(); 66 | expect(null).toEqual(null); 67 | }); 68 | 69 | }); 70 | -------------------------------------------------------------------------------- /test/spec/filter/math/abs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('absFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.abs')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('abs'); 11 | })); 12 | 13 | it('should return absolute values of any numbers inputted', function() { 14 | expect(filter(-123.45)).toEqual(123.45); 15 | expect(filter(123.45)).toEqual(123.45); 16 | expect(filter('-123.45')).toEqual(123.45); 17 | expect(filter('123.45')).toEqual(123.45); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/spec/filter/math/byte-fmt.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('byteFmtFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.byteFmt')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('byteFmt'); 11 | })); 12 | 13 | it('should return the correct display from number of bytes', function() { 14 | expect(filter(0,2)).toEqual("0 B"); 15 | expect(filter(5,2)).toEqual("5 B"); 16 | expect(filter(1024,0)).toEqual("1 KB"); 17 | expect(filter(1998,2)).toEqual("1.95 KB"); 18 | expect(filter(1049901,5)).toEqual("1.00126 MB"); 19 | expect(filter(909234901,1)).toEqual("867.1 MB"); 20 | expect(filter(1339234901,5)).toEqual("1.24726 GB"); 21 | expect(filter(23423234234,2)).toEqual("21.81 GB"); 22 | expect(filter(23985391855616,2)).toEqual("21.81 TB"); 23 | expect(filter(95340189555097611,1)).toEqual("84.7 PB"); 24 | expect(filter(2249548013871562752,3)).toEqual("1.951 EB"); 25 | expect(filter(5180591620717411303425,2)).toEqual("4.39 ZB"); 26 | expect(filter(5123980591620717411303425,2)).toEqual("4.24 YB"); 27 | }); 28 | 29 | it('should return NaN if bytes is not a number', function(){ 30 | expect(filter("0",2)).toEqual("NaN"); 31 | expect(filter([0],2)).toEqual("NaN"); 32 | expect(filter({number:0},0)).toEqual("NaN"); 33 | }); 34 | 35 | it('should return NaN if decimal point is less than zero or not a number', function(){ 36 | expect(filter(0.45,-1)).toEqual("NaN"); 37 | expect(filter(-0.25,-101)).toEqual("NaN"); 38 | expect(filter(0.45,1.3)).toEqual("NaN"); 39 | expect(filter(0.45,"0")).toEqual("NaN"); 40 | expect(filter(0.45,[3])).toEqual("NaN"); 41 | expect(filter(0.45,{num : 4})).toEqual("NaN"); 42 | }); 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /test/spec/filter/math/degrees.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('degreesFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.degrees')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('degrees'); 11 | })); 12 | 13 | it('should return the correct degrees from radians', function() { 14 | expect(filter(1.5,2)).toEqual(85.94); 15 | expect(filter(0,0)).toEqual(0); 16 | expect(filter(0.3235,0)).toEqual(19); 17 | expect(filter(0.8222235,5)).toEqual(47.10994); 18 | expect(filter(-0.8222235,5)).toEqual(-47.10994); 19 | expect(filter(45,2)).toEqual(2578.31); 20 | 21 | }); 22 | 23 | it('should return NaN if radians is not a number', function(){ 24 | expect(filter('0',2)).toEqual('NaN'); 25 | expect(filter([0],2)).toEqual('NaN'); 26 | expect(filter({number:0},0)).toEqual('NaN'); 27 | }); 28 | 29 | it('should return NaN if decimal point is less than zero or not a number', function(){ 30 | expect(filter(0.45,-1)).toEqual('NaN'); 31 | expect(filter(-0.25,-101)).toEqual('NaN'); 32 | expect(filter(0.45,1.3)).toEqual('NaN'); 33 | expect(filter(0.45,'0')).toEqual('NaN'); 34 | expect(filter(0.45,[3])).toEqual('NaN'); 35 | expect(filter(0.45,{num : 4})).toEqual('NaN'); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/spec/filter/math/kb-fmt.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('kbFmtFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.kbFmt')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('kbFmt'); 11 | })); 12 | 13 | it('should return the correct display from number of kilobytes', function() { 14 | expect(filter(0,2)).toEqual("0 KB"); 15 | expect(filter(5,2)).toEqual("5 KB"); 16 | expect(filter(1024,0)).toEqual("1 MB"); 17 | expect(filter(1998,2)).toEqual("1.95 MB"); 18 | expect(filter(1049901,5)).toEqual("1.00126 GB"); 19 | expect(filter(909234901,1)).toEqual("867.1 GB"); 20 | expect(filter(1339234901,5)).toEqual("1.24726 TB"); 21 | expect(filter(23423234234,2)).toEqual("21.81 TB"); 22 | expect(filter(23985391855616,2)).toEqual("21.81 PB"); 23 | expect(filter(95340189555097611,1)).toEqual("84.7 EB"); 24 | expect(filter(2249548013871562752,3)).toEqual("1.951 ZB"); 25 | expect(filter(5180591620717411303425,2)).toEqual("4.39 YB"); 26 | expect(filter(5123980591620717411303425,2)).toEqual("4340.18 YB"); 27 | }); 28 | 29 | it('should return NaN if kilobytes is not a number', function(){ 30 | expect(filter("0",2)).toEqual("NaN"); 31 | expect(filter([0],2)).toEqual("NaN"); 32 | expect(filter({number:0},0)).toEqual("NaN"); 33 | }); 34 | 35 | it('should return NaN if decimal point is less than zero or not a number', function(){ 36 | expect(filter(0.45,-1)).toEqual("NaN"); 37 | expect(filter(-0.25,-101)).toEqual("NaN"); 38 | expect(filter(0.45,1.3)).toEqual("NaN"); 39 | expect(filter(0.45,"0")).toEqual("NaN"); 40 | expect(filter(0.45,[3])).toEqual("NaN"); 41 | expect(filter(0.45,{num : 4})).toEqual("NaN"); 42 | }); 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /test/spec/filter/math/max.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('maxFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.max')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('max'); 11 | })); 12 | 13 | it('should get an array of numbers and return the biggest one', function() { 14 | expect(filter([1,2,3,4,5])).toEqual(5); 15 | expect(filter([2,2,2,2,2])).toEqual(2); 16 | expect(filter([1])).toEqual(1); 17 | }); 18 | 19 | it('should get an array and expression and return an object', function() { 20 | var users = [ 21 | { user: { score: 988790 } }, 22 | { user: { score: 123414 } }, 23 | { user: { rank : 988999 } }, 24 | { user: { score: 987621 } } 25 | ]; 26 | expect(filter(users, 'user.score || user.rank')).toEqual(users[2]); 27 | expect(filter(users, 'user.score || 0')).toEqual(users[0]); 28 | }); 29 | 30 | it('should get an !array and return it as-is', function() { 31 | expect(filter('string')).toEqual('string'); 32 | expect(filter({})).toEqual({}); 33 | expect(filter(!0)).toBeTruthy(); 34 | }); 35 | 36 | }); 37 | -------------------------------------------------------------------------------- /test/spec/filter/math/min.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('minFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.min')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('min'); 11 | })); 12 | 13 | it('should get an array of numbers and return the lowest one', function() { 14 | expect(filter([1,2,3,4,5])).toEqual(1); 15 | expect(filter([2,0,2,2,2])).toEqual(0); 16 | expect(filter([1])).toEqual(1); 17 | }); 18 | 19 | it('should get an array and expression and return an object', function() { 20 | var users = [ 21 | { user: { score: 988790 } }, 22 | { user: { score: 123414 } }, 23 | { user: { rank : 100000 } }, 24 | { user: { score: 987621 } } 25 | ]; 26 | expect(filter(users, 'user.score || user.rank')).toEqual(users[2]); 27 | expect(filter(users, 'user.score || 1e9')).toEqual(users[1]); 28 | }); 29 | 30 | 31 | it('should get an !array and return it as-is', function() { 32 | expect(filter('string')).toEqual('string'); 33 | expect(filter({})).toEqual({}); 34 | expect(filter(!0)).toBeTruthy(); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /test/spec/filter/math/percent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('percentFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.percent')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('percent'); 11 | })); 12 | 13 | it('should return percentage between two numbers', function() { 14 | 15 | expect(filter(10, 100)).toEqual(10); 16 | expect(filter(1, 100)).toEqual(1); 17 | expect(filter(23, 500)).toEqual(4.6); 18 | 19 | }); 20 | 21 | it('should get string as a number', function() { 22 | 23 | expect(filter('20', 400)).toEqual(5); 24 | expect(filter('100', 100)).toEqual(100); 25 | 26 | }); 27 | 28 | it('should return a round number if set to true', function() { 29 | 30 | expect(filter('20.2', 400, true)).toEqual(5); 31 | expect(filter('100.3', 100, true)).toEqual(100); 32 | expect(filter(23.4, 100, true)).toEqual(23); 33 | 34 | }); 35 | 36 | it('should set divided to 100, if not defined', function() { 37 | 38 | expect(filter(32)).toEqual(32); 39 | expect(filter(200)).toEqual(200); 40 | 41 | }); 42 | 43 | it('should get a !number and return it as-is', function() { 44 | 45 | expect(filter('string')).toEqual('string'); 46 | expect(filter({})).toEqual({}); 47 | expect(filter(!0)).toBeTruthy(); 48 | expect(filter([])).toEqual([]); 49 | 50 | }); 51 | 52 | }); 53 | -------------------------------------------------------------------------------- /test/spec/filter/math/radians.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('radiansFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.radians')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('radians'); 11 | })); 12 | 13 | it('should return the correct radians from degrees', function() { 14 | expect(filter(180,2)).toEqual(3.14); 15 | expect(filter(180,0)).toEqual(3); 16 | expect(filter(50,2)).toEqual(0.87); 17 | expect(filter(130,2)).toEqual(2.27); 18 | expect(filter(-30,4)).toEqual(-0.5236); 19 | expect(filter(1030,5)).toEqual(17.97689); 20 | }); 21 | 22 | it('should return NaN if degrees is not a number', function(){ 23 | expect(filter("0",2)).toEqual("NaN"); 24 | expect(filter([0],2)).toEqual("NaN"); 25 | expect(filter({number:0},0)).toEqual("NaN"); 26 | }); 27 | 28 | it('should return NaN if decimal point is less than zero or not a number', function(){ 29 | expect(filter(45,-1)).toEqual("NaN"); 30 | expect(filter(-25,-101)).toEqual("NaN"); 31 | expect(filter(45,1.3)).toEqual("NaN"); 32 | expect(filter(45,"0")).toEqual("NaN"); 33 | expect(filter(45,[3])).toEqual("NaN"); 34 | expect(filter(45,{num : 4})).toEqual("NaN"); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /test/spec/filter/math/radix.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('radixFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.radix')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('radix'); 11 | })); 12 | 13 | it('should converting decimal numbers to different bases(radix)', function() { 14 | expect(filter(8, 2)).toEqual('1000'); 15 | expect(filter(15, 16)).toEqual('F'); 16 | expect(filter(32586, 16)).toEqual('7F4A'); 17 | expect(filter(32, 8)).toEqual('40'); 18 | }); 19 | 20 | it('should not be able to convert base less than 2 , and bigger than 36', function() { 21 | expect(filter(998, 37)).toEqual(998); 22 | expect(filter(15, 1)).toEqual(15); 23 | }); 24 | 25 | it('should get a !number and return it as-is', function() { 26 | 27 | expect(filter('string')).toEqual('string'); 28 | expect(filter({})).toEqual({}); 29 | expect(filter(!0)).toBeTruthy(); 30 | 31 | }); 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /test/spec/filter/math/short-fmt.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('shortFmtFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.shortFmt')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('shortFmt'); 11 | })); 12 | 13 | it('should return the correct display from the number', function() { 14 | expect(filter(0,2)).toEqual('0'); 15 | expect(filter(5,2)).toEqual('5'); 16 | expect(filter(1024,0)).toEqual("1 K"); 17 | expect(filter(1993,2)).toEqual("1.99 K"); 18 | expect(filter(1049901,5)).toEqual("1.0499 M"); 19 | expect(filter(1909234901,2)).toEqual("1.91 B"); 20 | 21 | }); 22 | 23 | it('should return NaN if bytes is not a number', function(){ 24 | expect(filter("0",2)).toEqual("NaN"); 25 | expect(filter([0],2)).toEqual("NaN"); 26 | expect(filter({number:0},0)).toEqual("NaN"); 27 | }); 28 | 29 | it('should return NaN if decimal point is less than zero or not a number', function(){ 30 | expect(filter(0.45,-1)).toEqual("NaN"); 31 | expect(filter(-0.25,-101)).toEqual("NaN"); 32 | expect(filter(0.45,1.3)).toEqual("NaN"); 33 | expect(filter(0.45,"0")).toEqual("NaN"); 34 | expect(filter(0.45,[3])).toEqual("NaN"); 35 | expect(filter(0.45,{num : 4})).toEqual("NaN"); 36 | }); 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /test/spec/filter/math/sum.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('sumFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.math.sum')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('sum'); 11 | })); 12 | 13 | it('should return the sum of all members in array', function() { 14 | expect(filter([1,2,3,4,5,6])).toEqual(21); 15 | expect(filter([0,0,0,0,0,1])).toEqual(1); 16 | }); 17 | 18 | it('should be able to get an initial value', function() { 19 | expect(filter([2,3,5], 10)).toEqual(20); 20 | expect(filter([2,3,5], -10)).toEqual(0); 21 | }); 22 | 23 | it('should return a string if the members type != number', function() { 24 | expect(typeof filter([{}, 'string', 'foo'])).toEqual('string') 25 | }); 26 | 27 | it('should return the input as-is if is not an array', function() { 28 | expect(filter('string')).toEqual('string'); 29 | expect(filter(1)).toEqual(1); 30 | expect(filter(!1)).toBeFalsy(); 31 | }) 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /test/spec/filter/string/ends-with.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('endsWithFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.ends-with')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('endsWith'); 11 | })); 12 | 13 | it('should return whether string ends with the ends parameter', function() { 14 | 15 | expect(filter('string', 'g')).toBeTruthy(); 16 | expect(filter('string', 'ing')).toBeTruthy(); 17 | expect(filter('foo bar', 'BAR')).toBeTruthy(); 18 | 19 | expect(filter('.JPG', '.jpg')).toBeTruthy(); 20 | expect(filter('string', 'str')).toBeFalsy(); 21 | expect(filter('string', 'fing')).toBeFalsy(); 22 | expect(filter('foo bar', 'baz')).toBeFalsy(); 23 | 24 | }); 25 | 26 | it('should be case sensitive', function() { 27 | 28 | expect(filter('.JPG', '.jpg', true)).toBeFalsy(); 29 | expect(filter('string', 'ING', true)).toBeFalsy(); 30 | expect(filter('string', 'ING', false)).toBeTruthy(); 31 | expect(filter('foo bar', 'Foo B', true)).toBeFalsy(); 32 | 33 | }); 34 | 35 | it('should get a !string and not touch it', function() { 36 | expect(filter({})).toEqual({}); 37 | expect(filter([])).toEqual([]); 38 | expect(filter(1)).toEqual(1); 39 | expect(filter(!1)).toBeFalsy(); 40 | }); 41 | 42 | }); 43 | -------------------------------------------------------------------------------- /test/spec/filter/string/latinize.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('latinizeFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.latinize')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('latinize'); 11 | })); 12 | 13 | it('should get a string and replace accents/diacritics with the ASCII equivalent', function() { 14 | expect(filter('a ç')).toEqual('a c'); 15 | expect(filter('föo bàr baz')).toEqual('foo bar baz'); 16 | expect(filter('Lòrém Ìpsûm dölôr sít Àmet')).toEqual('Lorem Ipsum dolor sit Amet'); 17 | }); 18 | 19 | it('should get a !string and not touch it', function() { 20 | expect(filter({})).toEqual({}); 21 | expect(filter([])).toEqual([]); 22 | expect(filter(1)).toEqual(1); 23 | expect(filter(!1)).toBeFalsy(); 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /test/spec/filter/string/ltrim.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('ltrimFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.ltrim')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('ltrim'); 11 | })); 12 | 13 | it('should strip whitespace from the beginning of a string', function() { 14 | 15 | expect(filter(' a')).toEqual('a'); 16 | expect(filter(' foo bar ')).toEqual('foo bar '); 17 | expect(filter(' ')).toEqual(''); 18 | 19 | }); 20 | 21 | it('should strip specific chars from the beginning of a string', function() { 22 | 23 | expect(filter('__a__', '__')).toEqual('a__'); 24 | expect(filter('//foo bar//', '//')).toEqual('foo bar//'); 25 | expect(filter('barfoobar', 'bar')).toEqual('foobar'); 26 | 27 | expect(filter('barfoobar', 'foo')).toEqual('barfoobar'); 28 | 29 | }); 30 | 31 | it('should get a !string and not touch it', function() { 32 | expect(filter({})).toEqual({}); 33 | expect(filter([])).toEqual([]); 34 | expect(filter(1)).toEqual(1); 35 | expect(filter(!1)).toBeFalsy(); 36 | }); 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /test/spec/filter/string/match.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('matchFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.match')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('match'); 11 | })); 12 | 13 | it('should test a string with given pattern', function() { 14 | 15 | expect(filter('15/12/2003', '\\d+', 'g')).toEqual(['15', '12', '2003']); 16 | expect(angular.equals(filter('foobarbaz', '[a-z]{3}'), ['foo'])).toBeTruthy(); 17 | expect(filter('foobarbaz', '[a-z]{3}', 'g')).toEqual(['foo', 'bar', 'baz']); 18 | 19 | }); 20 | 21 | it('should get a !string and return null', function() { 22 | expect(filter({})).toEqual(null); 23 | expect(filter([])).toEqual(null); 24 | expect(filter(1)).toEqual(null); 25 | expect(filter(!1)).toBeFalsy(null); 26 | }); 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /test/spec/filter/string/phone-us.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('phoneUSFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.phoneUS')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('phoneUS'); 11 | })); 12 | 13 | it('should format a number as a US-style phone number', function () { 14 | expect(filter(1234567890)).toEqual('(123) 456-7890'); 15 | }); 16 | 17 | it('should format a string as a US-style phone number', function () { 18 | expect(filter('1234567890')).toEqual('(123) 456-7890'); 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /test/spec/filter/string/repeat.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('repeatFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.repeat')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('repeat'); 11 | })); 12 | 13 | it('should repeat a string n times', function() { 14 | 15 | expect(filter('a')).toEqual('a'); 16 | expect(filter('a', 3)).toEqual('aaa'); 17 | expect(filter('a ', 3)).toEqual('a a a '); 18 | 19 | expect(filter('foo', 3)).toEqual('foofoofoo'); 20 | 21 | }); 22 | 23 | it('should add a separator if given', function() { 24 | 25 | expect(filter('foo', undefined, 'bar')).toEqual('foo'); 26 | expect(filter('a', 3, '^')).toEqual('a^a^a'); 27 | expect(filter('^', 2, '_')).toEqual('^_^'); 28 | expect(filter('foo', 2, 'bar')).toEqual('foobarfoo'); 29 | 30 | }); 31 | 32 | it('should get a !string and not touch it', function() { 33 | expect(filter({})).toEqual({}); 34 | expect(filter([])).toEqual([]); 35 | expect(filter(1)).toEqual(1); 36 | expect(filter(!1)).toBeFalsy(); 37 | }); 38 | 39 | }); 40 | -------------------------------------------------------------------------------- /test/spec/filter/string/rtrim.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('rtrimFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.rtrim')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('rtrim'); 11 | })); 12 | 13 | it('should strip whitespace from the beginning of a string', function() { 14 | 15 | expect(filter('a ')).toEqual('a'); 16 | expect(filter(' foo bar ')).toEqual(' foo bar'); 17 | expect(filter(' ')).toEqual(''); 18 | 19 | }); 20 | 21 | it('should strip specific chars from the beginning of a string', function() { 22 | 23 | expect(filter('__a__', '__')).toEqual('__a'); 24 | expect(filter('//foo bar//', '//')).toEqual('//foo bar'); 25 | expect(filter('barfoobar', 'bar')).toEqual('barfoo'); 26 | 27 | expect(filter('barfoobar', 'foo')).toEqual('barfoobar'); 28 | 29 | }); 30 | 31 | it('should get a !string and not touch it', function() { 32 | expect(filter({})).toEqual({}); 33 | expect(filter([])).toEqual([]); 34 | expect(filter(1)).toEqual(1); 35 | expect(filter(!1)).toBeFalsy(); 36 | }); 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /test/spec/filter/string/slugify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('slugifyFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.slugify')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('slugify'); 11 | })); 12 | 13 | it('should get a string with no replacer and replace spaces with dash(-)', function() { 14 | expect(filter('a a')).toEqual('a-a'); 15 | expect(filter('foo bar baz')).toEqual('foo-bar-baz'); 16 | expect(filter('Lorem ipsum dolor sit amet')).toEqual('lorem-ipsum-dolor-sit-amet'); 17 | }); 18 | 19 | it('should get a string with replacer and replace spaces with it', function() { 20 | expect(filter('a a', 1)).toEqual('a1a'); 21 | expect(filter('foo bar baz', '!')).toEqual('foo!bar!baz'); 22 | expect(filter('lorem ipsum dolor sit amet', ' ')).toEqual('lorem ipsum dolor sit amet'); 23 | expect(filter('Lorem ipsum dolor sit amet', '-')).toEqual('lorem-ipsum-dolor-sit-amet'); 24 | expect(filter('Lorem ipsum dolor sit amet', '')).toEqual('loremipsumdolorsitamet'); 25 | }); 26 | 27 | it('should get a !string and not touch it', function() { 28 | expect(filter({})).toEqual({}); 29 | expect(filter([])).toEqual([]); 30 | expect(filter(1)).toEqual(1); 31 | expect(filter(!1)).toBeFalsy(); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /test/spec/filter/string/split.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('splitFilter', function () { 4 | 5 | var filter, sentence = "Today is a beautiful and sunny day!"; 6 | 7 | beforeEach(module('a8m.split')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('split'); 11 | })); 12 | 13 | it('should test a string with given pattern', function() { 14 | 15 | expect(filter(sentence, ' ', 3)).toEqual(['Today is a beautiful', 'and', 'sunny', 'day!']); 16 | expect(angular.equals(filter(sentence, '.'), [sentence])).toBeTruthy(); 17 | expect(filter(sentence, ' ')).toEqual(['Today', 'is', 'a', 'beautiful', 'and', 'sunny', 'day!']); 18 | 19 | }); 20 | 21 | it('should get a !string and return null', function() { 22 | expect(filter({})).toEqual(null); 23 | expect(filter([])).toEqual(null); 24 | expect(filter(1)).toEqual(null); 25 | expect(filter(!1)).toBeFalsy(null); 26 | }); 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /test/spec/filter/string/starts-with.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('startsWithFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.starts-with')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('startsWith'); 11 | })); 12 | 13 | it('should return whether string starts with the starts parameter', function() { 14 | 15 | expect(filter('string', 's')).toBeTruthy(); 16 | expect(filter('string', 'str')).toBeTruthy(); 17 | expect(filter('foo bar', 'Foo B')).toBeTruthy(); 18 | 19 | expect(filter('string', 'tring')).toBeFalsy(); 20 | expect(filter('string', 'ig')).toBeFalsy(); 21 | expect(filter('foo bar', 'bar')).toBeFalsy(); 22 | 23 | }); 24 | 25 | it('should be case sensitive', function() { 26 | 27 | expect(filter('string', 'STR', true)).toBeFalsy(); 28 | expect(filter('string', 'STR', false)).toBeTruthy(); 29 | expect(filter('foo bar', 'Foo B', true)).toBeFalsy(); 30 | 31 | }); 32 | 33 | it('should get a !string and not touch it', function() { 34 | expect(filter({})).toEqual({}); 35 | expect(filter([])).toEqual([]); 36 | expect(filter(1)).toEqual(1); 37 | expect(filter(!1)).toBeFalsy(); 38 | }); 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /test/spec/filter/string/stringular.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('stringularFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.stringular')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('stringular'); 11 | })); 12 | 13 | it('should return the text as it was if only one argument is passed', function () { 14 | expect(filter('lorem ipsum dolor sit amet')).toEqual('lorem ipsum dolor sit amet'); 15 | }); 16 | 17 | it('should replace {n} with arguments passed after the text argument', function () { 18 | expect(filter('lorem {0} dolor sit amet', 'ipsum')).toEqual('lorem ipsum dolor sit amet'); 19 | expect(filter('lorem {0} dolor {1} amet', 'ipsum', 'sit')).toEqual('lorem ipsum dolor sit amet'); 20 | expect(filter('{3} {0} dolor {1} amet', 'ipsum', 'sit', null, 'lorem')).toEqual('lorem ipsum dolor sit amet'); 21 | }); 22 | 23 | it('should keep {n} if no matching argument was found', function () { 24 | expect(filter('lorem {0} dolor sit amet')).toEqual('lorem {0} dolor sit amet'); 25 | expect(filter('lorem {0} dolor {1} amet', 'ipsum')).toEqual('lorem ipsum dolor {1} amet'); 26 | }); 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /test/spec/filter/string/strip-tags.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('stripTagsFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.strip-tags')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('stripTags'); 11 | })); 12 | 13 | it('should get a string with tags and splash it', function() { 14 | expect(filter('

lorem ipsum

')).toEqual('lorem ipsum'); 15 | expect(filter('
foo bar
')).toEqual('foo bar'); 16 | expect(filter('awesome title')).toEqual('awesome title'); 17 | }); 18 | 19 | it('should get a !string and not touch it', function() { 20 | expect(filter({})).toEqual({}); 21 | expect(filter([])).toEqual([]); 22 | expect(filter(1)).toEqual(1); 23 | expect(filter(!1)).toBeFalsy(); 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /test/spec/filter/string/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('testFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.test')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('test'); 11 | })); 12 | 13 | it('should test a string with given pattern', function() { 14 | 15 | expect(filter('15/12/2003', '^[0-9]{2}[/]{1}[0-9]{2}[/]{1}[0-9]{4}$', 'i')).toEqual(true); 16 | expect(filter('foobarbaz', '^[a-z]{3,}$')).toEqual(true); 17 | expect(filter('FOOBARBAZ', '^[a-z]{3,}$', 'i')).toEqual(true); 18 | expect(filter('FOOBARBAZ', '^[a-z]{3,}$')).toEqual(false); 19 | expect(filter('foobarbaz', '\\W')).toEqual(false); 20 | expect(filter('foobarbaz', '\\w')).toEqual(true); 21 | expect(filter('1a/bb/2003', '^[0-9]{2}[/]{1}[0-9]{2}[/]{1}[0-9]{4}$', 'i')).toEqual(false); 22 | 23 | }); 24 | 25 | it('should get a !string and not touch it', function() { 26 | expect(filter({})).toEqual({}); 27 | expect(filter([])).toEqual([]); 28 | expect(filter(1)).toEqual(1); 29 | expect(filter(!1)).toBeFalsy(); 30 | }); 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /test/spec/filter/string/trim.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('trimFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.trim')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('trim'); 11 | })); 12 | 13 | it('should strip whitespace from the beginning and end of a string', function() { 14 | 15 | expect(filter(' a ')).toEqual('a'); 16 | expect(filter(' foo bar ')).toEqual('foo bar'); 17 | expect(filter(' ')).toEqual(''); 18 | 19 | }); 20 | 21 | it('should strip specific chars from the beginning and end of a string', function() { 22 | 23 | expect(filter('__a__', '__')).toEqual('a'); 24 | expect(filter('//foo bar//', '//')).toEqual('foo bar'); 25 | expect(filter('barfoobar', 'bar')).toEqual('foo'); 26 | 27 | expect(filter('barfoobar', 'foo')).toEqual('barfoobar'); 28 | 29 | }); 30 | 31 | it('should get a !string and not touch it', function() { 32 | expect(filter({})).toEqual({}); 33 | expect(filter([])).toEqual([]); 34 | expect(filter(1)).toEqual(1); 35 | expect(filter(!1)).toBeFalsy(); 36 | }); 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /test/spec/filter/string/truncate.js: -------------------------------------------------------------------------------- 1 | describe('truncateFilter', function () { 2 | var filter; 3 | 4 | beforeEach(module('a8m.truncate')); 5 | 6 | beforeEach(inject(function($filter) { 7 | filter = $filter('truncate'); 8 | })); 9 | 10 | it('should cut a string if it is longer than the provided length', function () { 11 | 12 | expect(filter('lorem ipsum dolor sit amet', 5, '', false)).toEqual('lorem'); 13 | expect(filter('lorem ipsum dolor sit amet', 11, '', false)).toEqual('lorem ipsum'); 14 | expect(filter('lorem ipsum dolor sit amet', 50, '', false)).toEqual('lorem ipsum dolor sit amet'); 15 | 16 | expect(filter('abcdef', 3, '', false)).toEqual('abc'); 17 | expect(filter('abcd ef', 6, '', false)).toEqual('abcd e'); 18 | 19 | }); 20 | 21 | it('should not cut words in the middle if preserve is true', function () { 22 | 23 | expect(filter('lorem ipsum dolor sit amet', 7, '', true)).toEqual('lorem ipsum'); 24 | expect(filter('lorem ipsum dolor sit amet', 13, '', true)).toEqual('lorem ipsum dolor'); 25 | expect(filter('lorem ipsum dolor sit amet', 50, '', true)).toEqual('lorem ipsum dolor sit amet'); 26 | 27 | expect(filter('abcdef', 3, '', true)).toEqual('abcdef'); 28 | expect(filter('abcd ef', 6, '', true)).toEqual('abcd ef'); 29 | 30 | }); 31 | 32 | it('should append the provided prefix if a string has been cut', function () { 33 | 34 | expect(filter('lorem ipsum dolor sit amet', 7, '...', true)).toEqual('lorem ipsum...'); 35 | expect(filter('lorem ipsum dolor sit amet', 13, '...', true)).toEqual('lorem ipsum dolor...'); 36 | expect(filter('lorem ipsum dolor sit amet', 50, '...', true)).toEqual('lorem ipsum dolor sit amet'); 37 | 38 | }); 39 | 40 | it('should get !string and return it as-is', function() { 41 | 42 | expect(filter([])).toEqual([]); 43 | expect(filter({})).toEqual({}); 44 | expect(filter(1)).toEqual(1); 45 | expect(filter(!1)).toBeFalsy(); 46 | 47 | }); 48 | 49 | }); -------------------------------------------------------------------------------- /test/spec/filter/string/ucfirst.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('ucfirstFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.ucfirst')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('ucfirst'); 11 | })); 12 | 13 | it('should get a string and return it uppercase each first letter', function() { 14 | expect(filter('a')).toEqual('A'); 15 | expect(filter('foo bar baz')).toEqual('Foo Bar Baz'); 16 | expect(filter('lorem ipsum is simply dummy.... industry.')).toEqual('Lorem Ipsum Is Simply Dummy.... Industry.'); 17 | }); 18 | 19 | it('should get a !string and not touch it', function() { 20 | expect(filter({})).toEqual({}); 21 | expect(filter([])).toEqual([]); 22 | expect(filter(1)).toEqual(1); 23 | expect(filter(!1)).toBeFalsy(); 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /test/spec/filter/string/uri-component-encode.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('uriComponentEncodeFilter', function() { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.uri-component-encode', function($provide) { 8 | $provide.value('$window', { 9 | encodeURIComponent: function(){} 10 | }); 11 | })); 12 | 13 | beforeEach(inject(function($filter) { 14 | filter = $filter('uriComponentEncode'); 15 | })); 16 | 17 | it('it should get string as parameter and called encodeURIComponent', inject(function($window) { 18 | 19 | var string = 'foo bar baz'; 20 | 21 | spyOn($window, 'encodeURIComponent'); 22 | 23 | filter(string); 24 | 25 | expect($window.encodeURIComponent).toHaveBeenCalledWith(string) 26 | })); 27 | 28 | it('should get !string as parameter and return it as is', inject(function($window) { 29 | 30 | spyOn($window, 'encodeURIComponent'); 31 | 32 | expect(filter([])).toEqual([]); 33 | expect(filter({})).toEqual({}); 34 | expect(filter(777)).toEqual(777); 35 | expect($window.encodeURIComponent).not.toHaveBeenCalled(); 36 | })); 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /test/spec/filter/string/uri-encode.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('uriEncodeFilter', function() { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.uri-encode', function($provide) { 8 | $provide.value('$window', { 9 | encodeURI: function(){} 10 | }); 11 | })); 12 | 13 | beforeEach(inject(function($filter) { 14 | filter = $filter('uriEncode'); 15 | })); 16 | 17 | it('it should get string as parameter and called encodeURI', inject(function($window) { 18 | 19 | var string = 'foo bar baz'; 20 | 21 | spyOn($window, 'encodeURI'); 22 | 23 | filter(string); 24 | 25 | expect($window.encodeURI).toHaveBeenCalledWith(string) 26 | })); 27 | 28 | it('should get !string as parameter and return it as is', inject(function($window) { 29 | 30 | spyOn($window, 'encodeURI'); 31 | 32 | expect(filter([])).toEqual([]); 33 | expect(filter({})).toEqual({}); 34 | expect(filter(777)).toEqual(777); 35 | expect($window.encodeURI).not.toHaveBeenCalled(); 36 | })); 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /test/spec/filter/string/wrap.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('wrapFilter', function () { 4 | 5 | var filter; 6 | 7 | beforeEach(module('a8m.wrap')); 8 | 9 | beforeEach(inject(function ($filter) { 10 | filter = $filter('wrap'); 11 | })); 12 | 13 | it('should wrap a string with given wrapper', function() { 14 | 15 | expect(filter('a', 'b')).toEqual('bab'); 16 | expect(filter('a', 1)).toEqual('1a1'); 17 | expect(filter('a', '.')).toEqual('.a.'); 18 | 19 | }); 20 | 21 | it('should wrap a string with starts and ends wrapper', function() { 22 | 23 | expect(filter('b', 'a', 'c')).toEqual('abc'); 24 | expect(filter('a', 1, 2)).toEqual('1a2'); 25 | expect(filter('a', '/', '.')).toEqual('/a.'); 26 | 27 | }); 28 | 29 | 30 | it('should get a !string and not touch it', function() { 31 | expect(filter({})).toEqual({}); 32 | expect(filter([])).toEqual([]); 33 | expect(filter(1)).toEqual(1); 34 | expect(filter(!1)).toBeFalsy(); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /test/spec/provider/watcher.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('filterWatcherProvider', function() { 4 | //helpers 5 | var stub = { fn: function(x) { return x; } }; 6 | 7 | beforeEach(module('a8m.filter-watcher')); 8 | 9 | it('should have 2 main functions `isMemoized` and `memoize`', inject(function(filterWatcher) { 10 | expect(filterWatcher.isMemoized).toEqual(jasmine.any(Function)); 11 | expect(filterWatcher.memoize).toEqual(jasmine.any(Function)); 12 | })); 13 | 14 | it('should call the function if it\'s not cached', 15 | inject(function(filterWatcher) { 16 | var spy = spyOn(stub, 'fn'); 17 | (function memoizedOnly(n) { 18 | return filterWatcher.isMemoized('fName',n) || stub.fn(n); 19 | })(); 20 | expect(spy).toHaveBeenCalled(); 21 | expect(spy.callCount).toEqual(1); 22 | })); 23 | 24 | it('should not crash in circular structure situations', 25 | inject(function(filterWatcher, $document, $window, $rootScope) { 26 | var o1 = { a: 1, b: 2 }; 27 | var o2 = { a: 1, b: 2 }; 28 | o1.own = o1; 29 | o1.window = $window; 30 | o1.document = $document; 31 | o1.scope = $rootScope; 32 | o1.trait = o2; 33 | o2.own = o2; 34 | (function memoizedOnly(n) { 35 | return filterWatcher.isMemoized('fName',n) || stub.fn(n); 36 | })(o1); 37 | })); 38 | 39 | it('should get the result from cache if it\'s memoized', 40 | inject(function(filterWatcher, $rootScope) { 41 | var scope = $rootScope.$new(); 42 | var spy = spyOn(stub, 'fn').andCallThrough(); 43 | function memoize(n) { 44 | return filterWatcher.isMemoized('fName', n) || 45 | filterWatcher.memoize('fName', n, scope, stub.fn(n)); 46 | } 47 | [1,1,1,1,4,4,4,4,4].forEach(function(el) { 48 | memoize(el); 49 | }); 50 | expect(spy).toHaveBeenCalled(); 51 | expect(spy.callCount).toEqual(2); 52 | })); 53 | 54 | it('should clear cache from scope listeners on `$destroy`', 55 | inject(function(filterWatcher, $rootScope) { 56 | var scope; 57 | var spy = spyOn(stub, 'fn').andCallThrough(); 58 | function memoize(n) { 59 | return filterWatcher.isMemoized('fName', n) || 60 | filterWatcher.memoize('fName', n, scope = $rootScope.$new(), stub.fn(n)); 61 | } 62 | [1,1,1,1,1,1,1,1,1,1].forEach(function(el) { 63 | memoize(el); 64 | scope.$destroy(); 65 | }); 66 | expect(spy.callCount).toEqual(10); 67 | })); 68 | 69 | it('should clear cache manually', function() { 70 | window.setTimeout = function(cb) { cb(); }; 71 | inject(function(filterWatcher) { 72 | var src = [1,2] 73 | , result = [3,4]; 74 | filterWatcher.memoize('fName', src, null, result); 75 | expect(filterWatcher.isMemoized('fName', src)).toBeFalsy(); 76 | }); 77 | }); 78 | }); --------------------------------------------------------------------------------