├── .gitignore ├── example ├── logo.png ├── oogle.gif ├── screenshots │ ├── 2014-03-29_1816.png │ ├── 2014-03-29_1817.png │ ├── 2014-03-29_1823.png │ └── 2014-03-29_1830.png ├── index.html ├── app.js └── styles.css ├── test ├── lib │ ├── jasmine │ │ ├── jasmine_favicon.png │ │ ├── jasmine.css │ │ ├── console.js │ │ ├── boot.js │ │ ├── jasmine-html.js │ │ └── jasmine.js │ └── helper.js ├── scripts │ ├── test.sh │ ├── test.bat │ ├── e2e-test.bat │ ├── e2e-test.sh │ ├── watchr.rb │ ├── test-all.sh │ ├── update-angular.sh │ ├── npm-debug.log │ └── web-server.js ├── SpecRunner.html ├── config │ └── karma.conf.js └── unit │ └── directive.spec.js ├── readme.md ├── liveSearch.min.js ├── liveSearch.js └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /example/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/angular-livesearch/master/example/logo.png -------------------------------------------------------------------------------- /example/oogle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/angular-livesearch/master/example/oogle.gif -------------------------------------------------------------------------------- /test/lib/jasmine/jasmine_favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/angular-livesearch/master/test/lib/jasmine/jasmine_favicon.png -------------------------------------------------------------------------------- /example/screenshots/2014-03-29_1816.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/angular-livesearch/master/example/screenshots/2014-03-29_1816.png -------------------------------------------------------------------------------- /example/screenshots/2014-03-29_1817.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/angular-livesearch/master/example/screenshots/2014-03-29_1817.png -------------------------------------------------------------------------------- /example/screenshots/2014-03-29_1823.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/angular-livesearch/master/example/screenshots/2014-03-29_1823.png -------------------------------------------------------------------------------- /example/screenshots/2014-03-29_1830.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/18F/angular-livesearch/master/example/screenshots/2014-03-29_1830.png -------------------------------------------------------------------------------- /test/scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASE_DIR=`dirname $0` 4 | 5 | echo "" 6 | echo "Starting Karma Server (http://karma-runner.github.io)" 7 | echo "-------------------------------------------------------------------" 8 | 9 | $BASE_DIR/../node_modules/karma/bin/karma start $BASE_DIR/../config/karma.conf.js $* 10 | -------------------------------------------------------------------------------- /test/scripts/test.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | REM Windows script for running unit tests 4 | REM You have to run server and capture some browser first 5 | REM 6 | REM Requirements: 7 | REM - NodeJS (http://nodejs.org/) 8 | REM - Karma (npm install -g karma) 9 | 10 | set BASE_DIR=%~dp0 11 | karma start "%BASE_DIR%\..\config\karma.conf.js" %* 12 | -------------------------------------------------------------------------------- /test/scripts/e2e-test.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | REM Windows script for running e2e tests 4 | REM You have to run server first 5 | REM 6 | REM Requirements: 7 | REM - NodeJS (http://nodejs.org/) 8 | REM - Protractor (npm install -g protractor) 9 | 10 | set BASE_DIR=%~dp0 11 | webdriver-manager update 12 | protractor "%BASE_DIR%\..\config\protractor-conf.js" %* 13 | -------------------------------------------------------------------------------- /test/lib/helper.js: -------------------------------------------------------------------------------- 1 | Element.prototype.remove = function() { 2 | this.parentElement.removeChild(this); 3 | }; 4 | 5 | NodeList.prototype.remove = HTMLCollection.prototype.remove = function() { 6 | for(var i = 0, len = this.length; i < len; i++) { 7 | if(this[i] && this[i].parentElement) { 8 | this[i].parentElement.removeChild(this[i]); 9 | } 10 | } 11 | }; -------------------------------------------------------------------------------- /test/scripts/e2e-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASE_DIR=`dirname $0` 4 | 5 | echo "" 6 | echo "Updating WebDriver" 7 | echo $BASE_DIR 8 | echo "-------------------------------------------------------------------" 9 | 10 | $BASE_DIR/../node_modules/protractor/bin/webdriver-manager update 11 | 12 | 13 | echo "" 14 | echo "Starting Protractor tests" 15 | echo $BASE_DIR 16 | echo "-------------------------------------------------------------------" 17 | 18 | $BASE_DIR/../node_modules/protractor/bin/protractor $BASE_DIR/../config/protractor-conf.js $* 19 | -------------------------------------------------------------------------------- /test/scripts/watchr.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env watchr 2 | 3 | # config file for watchr http://github.com/mynyml/watchr 4 | # install: gem install watchr 5 | # run: watch watchr.rb 6 | # note: make sure that you have jstd server running (server.sh) and a browser captured 7 | 8 | log_file = File.expand_path(File.dirname(__FILE__) + '/../logs/jstd.log') 9 | 10 | `cd ..` 11 | `touch #{log_file}` 12 | 13 | puts "String watchr... log file: #{log_file}" 14 | 15 | watch( '(app/js|test/unit)' ) do 16 | `echo "\n\ntest run started @ \`date\`" > #{log_file}` 17 | `scripts/test.sh &> #{log_file}` 18 | end 19 | 20 | -------------------------------------------------------------------------------- /test/scripts/test-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | function cleanUp() { 6 | kill $WEBSERVER_PID 7 | } 8 | 9 | trap cleanUp EXIT 10 | 11 | # Define reasonable set of browsers in case we are running manually from commandline 12 | if [[ -z "$BROWSERS" ]] 13 | then 14 | BROWSERS="Chrome" 15 | fi 16 | 17 | if [[ -z "$BROWSERS_E2E" ]] 18 | then 19 | BROWSERS_E2E="Chrome" 20 | fi 21 | 22 | ROOT_DIR=`dirname $0`/.. 23 | 24 | cd $ROOT_DIR 25 | npm install 26 | 27 | ./scripts/web-server.js > /dev/null & 28 | WEBSERVER_PID=$! 29 | 30 | 31 | ./node_modules/karma/bin/karma start config/karma.conf.js --single-run --browsers $BROWSERS --reporters=dots --no-colors --no-color 32 | ./node_modules/karma/bin/karma start config/karma-e2e.conf.js --browsers $BROWSERS_E2E --reporters=dots --no-colors --no-color 33 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 10 |
11 | 16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/scripts/update-angular.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | NG_BUILD_DIR=$1 3 | if [[ ! -e "$NG_BUILD_DIR/angular.js" ]]; then 4 | echo "Usage: update-angular " 5 | exit 1 6 | fi 7 | 8 | SCRIPT_DIR=$(dirname $0) 9 | ROOT_DIR=$SCRIPT_DIR/../ 10 | VERSION=$(cat $NG_BUILD_DIR/version.txt) 11 | 12 | cd $ROOT_DIR 13 | 14 | rm -fr app/lib/angular 15 | mkdir app/lib/angular 16 | cp -r $NG_BUILD_DIR/* app/lib/angular 17 | rm -fr app/lib/angular/docs 18 | rm app/lib/angular/*.zip 19 | mv app/lib/angular/angular-mocks.js test/lib/angular 20 | cp app/lib/angular/version.txt test/lib/angular 21 | 22 | # Update the inlined angular-loader in app/index-async.html 23 | sed '/@@NG_LOADER@@/{ 24 | s/@@NG_LOADER@@//g 25 | r app/lib/angular/angular-loader.min.js 26 | }' app/index-async.html.template > app/index-async.html 27 | 28 | git add $ROOT_DIR/app 29 | git add $ROOT_DIR/test 30 | git commit -m "update(angular): bump to $VERSION" 31 | -------------------------------------------------------------------------------- /example/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module("MyApp", ["LiveSearch"]); 2 | app.controller("MyController", function($scope, $http, $q, $window) { 3 | 4 | $scope.mySearch = ""; 5 | 6 | $scope.mySearchCallback = function(params) { 7 | 8 | var defer = $q.defer(); 9 | 10 | $http.jsonp("http://gd.geobytes.com/AutoCompleteCity?callback=JSON_CALLBACK&q=" + params.query) 11 | .then(function(response) { 12 | if(!response.data) { 13 | defer.resolve([]); 14 | } 15 | var cities = response.data.map(function(city) { 16 | var parts = city.split(","); 17 | return { 18 | fullName: city, 19 | city: parts[0], 20 | state: parts[1], 21 | country: parts[2] 22 | }; 23 | }); 24 | defer.resolve(cities); 25 | }) 26 | .catch(function(e) { 27 | $window.alert(e.message); 28 | defer.reject(e); 29 | }); 30 | 31 | return defer.promise; 32 | }; 33 | }); -------------------------------------------------------------------------------- /test/SpecRunner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Jasmine Spec Runner v2.0.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | angular-live-search 2 | =========== 3 | 4 | ##Usage 5 | 6 | ### Markup 7 | 8 | ```html 9 |
10 | 15 |
16 | ``` 17 | 18 | ### Controller 19 | 20 | ```js 21 | //define app module with dependency 22 | var app = angular.module("MyApp", ["LiveSearch"]); 23 | app.controller("MyController", function($scope, $http, $q, $window) { 24 | $scope.search1 = ""; 25 | //your search callback 26 | $scope.mySearchCallback = function () { 27 | var defer = $q.defer(); 28 | defer.resolve([ 29 | { city: "nailuva", state: "ce", country: "fiji"}, 30 | { city: "suva", state: "ce", country: "fiji"} 31 | ]); 32 | return defer.promise; 33 | }; 34 | }); 35 | ``` 36 | 37 | ### Example 38 | [Demo on Plunker](http://plnkr.co/edit/ad3Sq9) 39 | 40 | ![Working...](/example/oogle.gif) 41 | -------------------------------------------------------------------------------- /example/styles.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | font-family: sans-serif; 4 | font-size: 12pt; 5 | } 6 | 7 | .container { 8 | position: relative; 9 | margin: 10%; 10 | display: block; 11 | text-align: center; 12 | } 13 | 14 | input 15 | { 16 | width: 50%; 17 | top: 25%; 18 | height: 30px; 19 | } 20 | 21 | #live-search { 22 | position: absolute; 23 | top: 30%; 24 | left: 25%; 25 | right: 25%; 26 | text-align: center; 27 | vertical-align: middle; 28 | } 29 | 30 | /*Live Search styles start*/ 31 | ul.searchresultspopup { 32 | border: #a4bed4 1px solid; 33 | margin-top: 0px; 34 | padding: 0px; 35 | z-index: 99999!important; 36 | position: fixed; 37 | background-color: white; 38 | /*max-height:200px;*/ 39 | border-collapse: separate; 40 | overflow-y: hidden; 41 | } 42 | 43 | ul.searchresultspopup > li { 44 | cursor: pointer; 45 | padding-left: 1px; 46 | text-align: left; 47 | list-style: none; 48 | line-height: 20px; 49 | list-style-image: none; 50 | list-style-position: outside; 51 | list-style-type: none; 52 | text-transform: lowercase; 53 | } 54 | 55 | ul.searchresultspopup li.selected, ul.searchresultspopup li:hover { 56 | background-color: #ededed; 57 | } 58 | 59 | ul.searchresultspopup b { 60 | color: blue; 61 | } 62 | 63 | ul.searchresultspopup strong { 64 | color: green; 65 | } 66 | /*Live Search styles end*/ -------------------------------------------------------------------------------- /test/config/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Wed Mar 12 2014 14:17:25 GMT-0400 (Eastern Daylight Time) 3 | 4 | // base path, that will be used to resolve files and exclude 5 | basePath = "../../"; 6 | 7 | // list of files / patterns to load in the browser 8 | files = [ 9 | JASMINE, 10 | JASMINE_ADAPTER, 11 | "test/lib/angular/angular.js", 12 | "test/lib/angular/angular-mocks.js", 13 | "test/lib/jasmine/jasmine.js", 14 | "test/lib/helper.js", 15 | "liveSearch.js", 16 | "test/unit/*.spec.js" 17 | ]; 18 | 19 | // list of files to exclude 20 | exclude = [ 21 | ]; 22 | 23 | // test results reporter to use 24 | // possible values: "dots", "progress", "junit" 25 | reporters = ["progress"]; 26 | 27 | // web server port 28 | port = 9876; 29 | 30 | // cli runner port 31 | runnerPort = 9100; 32 | 33 | // enable / disable colors in the output (reporters and logs) 34 | colors = true; 35 | 36 | // level of logging 37 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 38 | logLevel = LOG_INFO; 39 | 40 | // enable / disable watching file and executing tests whenever any file changes 41 | autoWatch = true; 42 | 43 | 44 | // Start these browsers, currently available: 45 | // - Chrome 46 | // - ChromeCanary 47 | // - Firefox 48 | // - Opera 49 | // - Safari (only Mac) 50 | // - PhantomJS 51 | // - IE (only Windows) 52 | browsers = ["Chrome"]; 53 | 54 | 55 | // If browser does not capture in given timeout [ms], kill it 56 | captureTimeout = 60000; 57 | 58 | 59 | // Continuous Integration mode 60 | // if true, it capture browsers, run tests and exit 61 | singleRun = false; -------------------------------------------------------------------------------- /liveSearch.min.js: -------------------------------------------------------------------------------- 1 | "use strict";angular.module("LiveSearch",["ng"]).directive("liveSearch",["$compile","$timeout",function(e,t){return{restrict:"E",replace:!0,scope:{liveSearchCallback:"=",liveSearchSelect:"=?",liveSearchItemTemplate:"@",liveSearchWaitTimeout:"=?",liveSearchMaxResultSize:"=?"},template:"",link:function(l,i,n){var c;l.results=[],l.visible=!1,l.selectedIndex=-1,l.select=function(e){l.selectedIndex=e,l.visible=!1},l.isSelected=function(e){return l.selectedIndex===e},l.$watch("selectedIndex",function(e){var t=l.results[e];t&&i.val(n.liveSearchSelect?t[n.liveSearchSelect]:t),"undefined"!==i.controller("ngModel")&&i.controller("ngModel").$setViewValue(i.val())}),l.$watch("visible",function(e){if(0!=e){l.width=i[0].clientWidth;var t=s(i[0]);l.top=t.y+i[0].clientHeight+1,l.left=t.x}}),i[0].onkeydown=function(e){40==e.keyCode?l.selectedIndex+1===l.results.length?l.selectedIndex=0:l.selectedIndex++:38==e.keyCode&&(0==l.selectedIndex?l.selectedIndex=l.results.length-1:-1==l.selectedIndex?l.selectedIndex=0:l.selectedIndex--),13==e.keyCode&&(l.visible=!1),l.$apply()},i[0].onkeyup=function(e){if(13==e.keyCode||37==e.keyCode||38==e.keyCode||39==e.keyCode||40==e.keyCode)return!1;var n=i;t.cancel(c);var s=n.val().split(","),r=s[s.length-1].trim();return r.length<3||r.length>9?(l.visible=!1,void l.$apply()):void(c=t(function(){var e=[],t=l.liveSearchCallback.call(null,{query:r});t.then(function(t){t&&(e=t.slice(0,(l.liveSearchMaxResultSize||20)-1)),l.visible=!0}),t.finally(function(){l.selectedIndex=-1,l.results=e.filter(function(t,l){return e.indexOf(t)==l})})},l.liveSearchWaitTimeout||100))};var s=function(e){for(var t=0,l=0;e;)t+=e.offsetLeft-e.scrollLeft+e.clientLeft,l+=e.offsetTop-e.scrollTop+e.clientTop,e=e.offsetParent;return{x:t,y:l}},r=i.attr("live-search-item-template")||"{{result}}",d="",o=e(d)(l);document.body.appendChild(o[0])}}}]); 2 | -------------------------------------------------------------------------------- /test/lib/jasmine/jasmine.css: -------------------------------------------------------------------------------- 1 | body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } 2 | 3 | .html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } 4 | .html-reporter a { text-decoration: none; } 5 | .html-reporter a:hover { text-decoration: underline; } 6 | .html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; } 7 | .html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; } 8 | .html-reporter .banner .version { margin-left: 14px; } 9 | .html-reporter #jasmine_content { position: fixed; right: 100%; } 10 | .html-reporter .version { color: #aaaaaa; } 11 | .html-reporter .banner { margin-top: 14px; } 12 | .html-reporter .duration { color: #aaaaaa; float: right; } 13 | .html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; } 14 | .html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; } 15 | .html-reporter .symbol-summary li.passed { font-size: 14px; } 16 | .html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; } 17 | .html-reporter .symbol-summary li.failed { line-height: 9px; } 18 | .html-reporter .symbol-summary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; } 19 | .html-reporter .symbol-summary li.disabled { font-size: 14px; } 20 | .html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; } 21 | .html-reporter .symbol-summary li.pending { line-height: 17px; } 22 | .html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; } 23 | .html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } 24 | .html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } 25 | .html-reporter .bar.failed { background-color: #b03911; } 26 | .html-reporter .bar.passed { background-color: #a6b779; } 27 | .html-reporter .bar.skipped { background-color: #bababa; } 28 | .html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; } 29 | .html-reporter .bar.menu a { color: #333333; } 30 | .html-reporter .bar a { color: white; } 31 | .html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; } 32 | .html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; } 33 | .html-reporter .running-alert { background-color: #666666; } 34 | .html-reporter .results { margin-top: 14px; } 35 | .html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } 36 | .html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } 37 | .html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } 38 | .html-reporter.showDetails .summary { display: none; } 39 | .html-reporter.showDetails #details { display: block; } 40 | .html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } 41 | .html-reporter .summary { margin-top: 14px; } 42 | .html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; } 43 | .html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; } 44 | .html-reporter .summary li.passed a { color: #5e7d00; } 45 | .html-reporter .summary li.failed a { color: #b03911; } 46 | .html-reporter .summary li.pending a { color: #ba9d37; } 47 | .html-reporter .description + .suite { margin-top: 0; } 48 | .html-reporter .suite { margin-top: 14px; } 49 | .html-reporter .suite a { color: #333333; } 50 | .html-reporter .failures .spec-detail { margin-bottom: 28px; } 51 | .html-reporter .failures .spec-detail .description { background-color: #b03911; } 52 | .html-reporter .failures .spec-detail .description a { color: white; } 53 | .html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; } 54 | .html-reporter .result-message span.result { display: block; } 55 | .html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; } 56 | -------------------------------------------------------------------------------- /test/lib/jasmine/console.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2008-2013 Pivotal Labs 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | function getJasmineRequireObj() { 24 | if (typeof module !== "undefined" && module.exports) { 25 | return exports; 26 | } else { 27 | window.jasmineRequire = window.jasmineRequire || {}; 28 | return window.jasmineRequire; 29 | } 30 | } 31 | 32 | getJasmineRequireObj().console = function(jRequire, j$) { 33 | j$.ConsoleReporter = jRequire.ConsoleReporter(); 34 | }; 35 | 36 | getJasmineRequireObj().ConsoleReporter = function() { 37 | 38 | var noopTimer = { 39 | start: function(){}, 40 | elapsed: function(){ return 0; } 41 | }; 42 | 43 | function ConsoleReporter(options) { 44 | var print = options.print, 45 | showColors = options.showColors || false, 46 | onComplete = options.onComplete || function() {}, 47 | timer = options.timer || noopTimer, 48 | specCount, 49 | failureCount, 50 | failedSpecs = [], 51 | pendingCount, 52 | ansi = { 53 | green: '\x1B[32m', 54 | red: '\x1B[31m', 55 | yellow: '\x1B[33m', 56 | none: '\x1B[0m' 57 | }; 58 | 59 | this.jasmineStarted = function() { 60 | specCount = 0; 61 | failureCount = 0; 62 | pendingCount = 0; 63 | print("Started"); 64 | printNewline(); 65 | timer.start(); 66 | }; 67 | 68 | this.jasmineDone = function() { 69 | printNewline(); 70 | for (var i = 0; i < failedSpecs.length; i++) { 71 | specFailureDetails(failedSpecs[i]); 72 | } 73 | 74 | printNewline(); 75 | var specCounts = specCount + " " + plural("spec", specCount) + ", " + 76 | failureCount + " " + plural("failure", failureCount); 77 | 78 | if (pendingCount) { 79 | specCounts += ", " + pendingCount + " pending " + plural("spec", pendingCount); 80 | } 81 | 82 | print(specCounts); 83 | 84 | printNewline(); 85 | var seconds = timer.elapsed() / 1000; 86 | print("Finished in " + seconds + " " + plural("second", seconds)); 87 | 88 | printNewline(); 89 | 90 | onComplete(failureCount === 0); 91 | }; 92 | 93 | this.specDone = function(result) { 94 | specCount++; 95 | 96 | if (result.status == "pending") { 97 | pendingCount++; 98 | print(colored("yellow", "*")); 99 | return; 100 | } 101 | 102 | if (result.status == "passed") { 103 | print(colored("green", '.')); 104 | return; 105 | } 106 | 107 | if (result.status == "failed") { 108 | failureCount++; 109 | failedSpecs.push(result); 110 | print(colored("red", 'F')); 111 | } 112 | }; 113 | 114 | return this; 115 | 116 | function printNewline() { 117 | print("\n"); 118 | } 119 | 120 | function colored(color, str) { 121 | return showColors ? (ansi[color] + str + ansi.none) : str; 122 | } 123 | 124 | function plural(str, count) { 125 | return count == 1 ? str : str + "s"; 126 | } 127 | 128 | function repeat(thing, times) { 129 | var arr = []; 130 | for (var i = 0; i < times; i++) { 131 | arr.push(thing); 132 | } 133 | return arr; 134 | } 135 | 136 | function indent(str, spaces) { 137 | var lines = (str || '').split("\n"); 138 | var newArr = []; 139 | for (var i = 0; i < lines.length; i++) { 140 | newArr.push(repeat(" ", spaces).join("") + lines[i]); 141 | } 142 | return newArr.join("\n"); 143 | } 144 | 145 | function specFailureDetails(result) { 146 | printNewline(); 147 | print(result.fullName); 148 | 149 | for (var i = 0; i < result.failedExpectations.length; i++) { 150 | var failedExpectation = result.failedExpectations[i]; 151 | printNewline(); 152 | print(indent(failedExpectation.stack, 2)); 153 | } 154 | 155 | printNewline(); 156 | } 157 | } 158 | 159 | return ConsoleReporter; 160 | }; 161 | -------------------------------------------------------------------------------- /test/scripts/npm-debug.log: -------------------------------------------------------------------------------- 1 | 0 info it worked if it ends with ok 2 | 1 verbose cli [ 'C:\\Program Files\\nodejs\\\\node.exe', 3 | 1 verbose cli 'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js', 4 | 1 verbose cli 'install', 5 | 1 verbose cli '–g', 6 | 1 verbose cli 'karma@0.8.7' ] 7 | 2 info using npm@1.3.11 8 | 3 info using node@v0.10.19 9 | 4 verbose node symlink C:\Program Files\nodejs\\node.exe 10 | 5 verbose readDependencies using package.json deps 11 | 6 verbose cache add [ '–g', null ] 12 | 7 verbose cache add name=undefined spec="–g" args=["–g",null] 13 | 8 verbose parsed url { protocol: null, 14 | 8 verbose parsed url slashes: null, 15 | 8 verbose parsed url auth: null, 16 | 8 verbose parsed url host: null, 17 | 8 verbose parsed url port: null, 18 | 8 verbose parsed url hostname: null, 19 | 8 verbose parsed url hash: null, 20 | 8 verbose parsed url search: null, 21 | 8 verbose parsed url query: null, 22 | 8 verbose parsed url pathname: '–g', 23 | 8 verbose parsed url path: '–g', 24 | 8 verbose parsed url href: '–g' } 25 | 9 verbose cache add [ 'karma@0.8.7', null ] 26 | 10 verbose cache add name=undefined spec="karma@0.8.7" args=["karma@0.8.7",null] 27 | 11 verbose parsed url { protocol: null, 28 | 11 verbose parsed url slashes: null, 29 | 11 verbose parsed url auth: null, 30 | 11 verbose parsed url host: null, 31 | 11 verbose parsed url port: null, 32 | 11 verbose parsed url hostname: null, 33 | 11 verbose parsed url hash: null, 34 | 11 verbose parsed url search: null, 35 | 11 verbose parsed url query: null, 36 | 11 verbose parsed url pathname: 'karma@0.8.7', 37 | 11 verbose parsed url path: 'karma@0.8.7', 38 | 11 verbose parsed url href: 'karma@0.8.7' } 39 | 12 verbose cache add name="karma" spec="0.8.7" args=["karma","0.8.7"] 40 | 13 verbose parsed url { protocol: null, 41 | 13 verbose parsed url slashes: null, 42 | 13 verbose parsed url auth: null, 43 | 13 verbose parsed url host: null, 44 | 13 verbose parsed url port: null, 45 | 13 verbose parsed url hostname: null, 46 | 13 verbose parsed url hash: null, 47 | 13 verbose parsed url search: null, 48 | 13 verbose parsed url query: null, 49 | 13 verbose parsed url pathname: '0.8.7', 50 | 13 verbose parsed url path: '0.8.7', 51 | 13 verbose parsed url href: '0.8.7' } 52 | 14 verbose addNamed [ 'karma', '0.8.7' ] 53 | 15 verbose addNamed [ '0.8.7', '0.8.7' ] 54 | 16 silly lockFile 51e00793-g –g 55 | 17 verbose lock –g C:\Users\mauri\AppData\Roaming\npm-cache\51e00793-g.lock 56 | 18 silly lockFile 8c5aa126-karma-0-8-7 karma@0.8.7 57 | 19 verbose lock karma@0.8.7 C:\Users\mauri\AppData\Roaming\npm-cache\8c5aa126-karma-0-8-7.lock 58 | 20 silly lockFile 51e00793-g –g 59 | 21 silly lockFile 51e00793-g –g 60 | 22 verbose addNamed [ '–g', '' ] 61 | 23 verbose addNamed [ null, '*' ] 62 | 24 silly lockFile 72e0e7f9-g –g@ 63 | 25 verbose lock –g@ C:\Users\mauri\AppData\Roaming\npm-cache\72e0e7f9-g.lock 64 | 26 verbose registry.get karma/0.8.7 not expired, no request 65 | 27 silly addNameRange { name: '–g', range: '*', hasData: false } 66 | 28 verbose url raw –g 67 | 29 verbose url resolving [ 'https://registry.npmjs.org/', './%E2%80%93g' ] 68 | 30 verbose url resolved https://registry.npmjs.org/%E2%80%93g 69 | 31 info trying registry request attempt 1 at 00:17:04 70 | 32 http GET https://registry.npmjs.org/%E2%80%93g 71 | 33 silly lockFile 8c5aa126-karma-0-8-7 karma@0.8.7 72 | 34 silly lockFile 8c5aa126-karma-0-8-7 karma@0.8.7 73 | 35 http 404 https://registry.npmjs.org/%E2%80%93g 74 | 36 silly registry.get cb [ 404, 75 | 36 silly registry.get { date: 'Fri, 21 Mar 2014 04:17:07 GMT', 76 | 36 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B)', 77 | 36 silly registry.get 'content-type': 'application/json', 78 | 36 silly registry.get via: '1.1 varnish', 79 | 36 silly registry.get 'cache-control': 'max-age=0', 80 | 36 silly registry.get 'content-length': '52', 81 | 36 silly registry.get 'accept-ranges': 'bytes', 82 | 36 silly registry.get age: '0', 83 | 36 silly registry.get 'x-served-by': 'cache-v41-ASH, cache-jfk1021-JFK', 84 | 36 silly registry.get 'x-cache': 'MISS, MISS', 85 | 36 silly registry.get 'x-cache-hits': '0, 0', 86 | 36 silly registry.get 'x-timer': 'S1395375427.180256844,VS0,VS-507,VE-425,VE89', 87 | 36 silly registry.get 'keep-alive': 'timeout=10, max=50', 88 | 36 silly registry.get connection: 'Keep-Alive' } ] 89 | 37 silly lockFile 72e0e7f9-g –g@ 90 | 38 silly lockFile 72e0e7f9-g –g@ 91 | 39 error 404 '%E2%80%93g' is not in the npm registry. 92 | 39 error 404 You should bug the author to publish it 93 | 39 error 404 94 | 39 error 404 Note that you can also install from a 95 | 39 error 404 tarball, folder, or http url, or git url. 96 | 40 error System Windows_NT 6.1.7601 97 | 41 error command "C:\\Program Files\\nodejs\\\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install" "–g" "karma@0.8.7" 98 | 42 error cwd D:\Git\justeat\src\tests\scripts 99 | 43 error node -v v0.10.19 100 | 44 error npm -v 1.3.11 101 | 45 error code E404 102 | 46 verbose exit [ 1, true ] 103 | -------------------------------------------------------------------------------- /test/unit/directive.spec.js: -------------------------------------------------------------------------------- 1 | describe('liveSearch directive', function() { 2 | var scope, liveSearch, _window, q, element, timeout; 3 | 4 | beforeEach(module('LiveSearch')); 5 | 6 | beforeEach(inject(function($rootScope, $compile, $q, $timeout) { 7 | scope = $rootScope; 8 | q = $q; 9 | timeout = $timeout; 10 | 11 | scope.mySearchCallback = function () { 12 | var defer = $q.defer(); 13 | defer.resolve([ 14 | { city: "nailuva", state: "ce", country: "fiji"}, 15 | { city: "suva", state: "ce", country: "fiji"} 16 | ]); 17 | return defer.promise; 18 | }; 19 | 20 | scope.search1 = ""; 21 | 22 | element = angular.element( 23 | ''); 29 | $compile(element)(scope); 30 | scope.$digest(); 31 | })); 32 | 33 | //cleanup DOM after 34 | afterEach(function() { 35 | document.getElementsByClassName("searchresultspopup").remove(); 36 | }); 37 | 38 | it('should replace live-search tag by input text', function() { 39 | var input = element.find("input"); 40 | expect(input.length).toBe(1); 41 | expect(input.attr("type")).toBeDefined(); 42 | expect(input.attr("type")).toBe("text"); 43 | }); 44 | 45 | it('should bind value to ngModel if present', function() { 46 | scope.$apply(function() { 47 | scope.search1 = "something" 48 | }); 49 | 50 | var input = element.find("input"); 51 | expect(scope.search1).toBe(input.val()); 52 | }); 53 | 54 | 55 | it('should add key handlers to the input element', function() { 56 | var input = element.find("input")[0]; 57 | 58 | expect(input.onkeydown).toBeDefined(); 59 | expect(input.onkeyup).toBeDefined(); 60 | }); 61 | 62 | it('should add invisble