Skip to content

Commit

Permalink
Remove controller function as it was not used as controller function …
Browse files Browse the repository at this point in the history
…and move the functions under link function. Remove setTimeout and use for better testability. Remove ng-keyup and use element.on
  • Loading branch information
ghiden committed Feb 15, 2014
1 parent b104c42 commit e5fde2d
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
node_modules
bower_components
components
.*.swp
.DS_Store
5 changes: 4 additions & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"describe": false,
"expect": false,
"it": false,
"inject": false,
"jasmine": false,
"JSHINT": false,
"mostRecentAjaxRequest": false,
Expand All @@ -38,6 +39,8 @@
"spyOn": false,
"spyOnEvent": false,
"waitsFor": false,
"xdescribe": false
"xdescribe": false,
"$": false,
"dump": false
}
}
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = function (grunt) {
karma: {
options: {
configFile: 'test/karma.conf.js',
browsers: ['Firefox', 'PhantomJS']
browsers: ['PhantomJS']
},
unit: {
singleRun: true
Expand Down
20 changes: 11 additions & 9 deletions angucomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

angular.module('angucomplete', [] )
.directive('angucomplete', function ($parse, $http, $sce) {
.directive('angucomplete', function ($parse, $http, $sce, $timeout) {
return {
restrict: 'EA',
scope: {
Expand All @@ -24,15 +24,17 @@ angular.module('angucomplete', [] )
"minLengthUser": "@minlength",
"matchClass": "@matchclass"
},
template: '<div class="angucomplete-holder"><input id="{{id}}_value" ng-model="searchStr" type="text" placeholder="{{placeholder}}" class="{{inputClass}}" ng-keyup="keyPressed($event)"/><div id="{{id}}_dropdown" class="angucomplete-dropdown" ng-if="showDropdown"><div class="angucomplete-searching" ng-show="searching">Searching...</div><div class="angucomplete-searching" ng-show="!searching && (!results || results.length == 0)">No results found</div><div class="angucomplete-row" ng-repeat="result in results" ng-click="selectResult(result)" ng-mouseover="hoverRow()" ng-class="{\'angucomplete-selected-row\': $index == currentIndex}"><div ng-if="imageField" class="angucomplete-image-holder"><img ng-if="result.image && result.image != \'\'" ng-src="{{result.image}}" class="angucomplete-image"/><div ng-if="!result.image && result.image != \'\'" class="angucomplete-image-default"></div></div><div class="angucomplete-title" ng-if="matchClass" ng-bind-html="result.title"></div><div class="angucomplete-title" ng-if="!matchClass">{{ result.title }}</div><div ng-if="result.description && result.description != \'\'" class="angucomplete-description">{{result.description}}</div></div></div></div>',
controller: function ( $scope ) {
template: '<div class="angucomplete-holder"><input id="{{id}}_value" ng-model="searchStr" type="text" placeholder="{{placeholder}}" class="{{inputClass}}"/><div id="{{id}}_dropdown" class="angucomplete-dropdown" ng-if="showDropdown"><div class="angucomplete-searching" ng-show="searching">Searching...</div><div class="angucomplete-searching" ng-show="!searching && (!results || results.length == 0)">No results found</div><div class="angucomplete-row" ng-repeat="result in results" ng-click="selectResult(result)" ng-mouseover="hoverRow()" ng-class="{\'angucomplete-selected-row\': $index == currentIndex}"><div ng-if="imageField" class="angucomplete-image-holder"><img ng-if="result.image && result.image != \'\'" ng-src="{{result.image}}" class="angucomplete-image"/><div ng-if="!result.image && result.image != \'\'" class="angucomplete-image-default"></div></div><div class="angucomplete-title" ng-if="matchClass" ng-bind-html="result.title"></div><div class="angucomplete-title" ng-if="!matchClass">{{ result.title }}</div><div ng-if="result.description && result.description != \'\'" class="angucomplete-description">{{result.description}}</div></div></div></div>',

link: function($scope, elem, attrs) {
$scope.lastSearchTerm = null;
$scope.currentIndex = null;
$scope.justChanged = false;
$scope.searchTimer = null;
$scope.searching = false;
$scope.pause = 500;
$scope.minLength = 3;
$scope.searchStr = null;

if ($scope.minLengthUser && $scope.minLengthUser != "") {
$scope.minLength = $scope.minLengthUser;
Expand Down Expand Up @@ -166,12 +168,12 @@ angular.module('angucomplete', [] )
$scope.results = [];

if ($scope.searchTimer) {
clearTimeout($scope.searchTimer);
$timeout.cancel($scope.searchTimer);
}

$scope.searching = true;

$scope.searchTimer = setTimeout(function() {
$scope.searchTimer = $timeout(function() {
$scope.searchTimerComplete($scope.searchStr);
}, $scope.pause);
}
Expand All @@ -190,11 +192,12 @@ angular.module('angucomplete', [] )
$scope.results = [];
//$scope.$apply();
}
},

link: function($scope, elem, attrs, ctrl) {
var inputField = elem.find('input');

elem.bind("keyup", function (event) {
inputField.on('keyup', $scope.keyPressed);

elem.on("keyup", function (event) {
if(event.which === 40) {
if (($scope.currentIndex + 1) < $scope.results.length) {
$scope.currentIndex ++;
Expand Down Expand Up @@ -235,7 +238,6 @@ angular.module('angucomplete', [] )
}
});


}
};
});
Expand Down
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"angular": ">=1.2.0"
},
"devDependencies": {
"angular-mocks": ">=1.2.0"
"angular-mocks": ">=1.2.0",
"jquery": "~2.1.0"
}
}
82 changes: 80 additions & 2 deletions test/angucompleteSpec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,88 @@
'use strict';

describe('angucomplete', function() {
var $compile, $scope, $timeout;

beforeEach(module('angucomplete'));

it('should pass this simple test', function() {
expect(true).toBe(true);
beforeEach(inject(function(_$compile_, $rootScope, _$timeout_) {
$compile = _$compile_;
$scope = $rootScope.$new();
$timeout = _$timeout_;
}));

describe('Render', function() {

it('should render input element with given id plus _value', function() {
var element = angular.element('<div angucomplete id="ex1" selectedobject="selectedCountry" titlefield="name"></div>');
$scope.selectedCountry = null;
$compile(element)($scope);
$scope.$digest();
expect(element.find('#ex1_value').length).toBe(1);
});

it('should render planceholder string', function() {
var element = angular.element('<div angucomplete id="ex1" placeholder="Search countries" selectedobject="selectedCountry" localdata="countries" searchfields="name" titlefield="name"/>');
$scope.selectedCountry = null;
$compile(element)($scope);
$scope.$digest();
expect(element.find('#ex1_value').attr('placeholder')).toEqual('Search countries');
});

});

describe('Local data', function() {

it('should show search results after 3 letter is entered', function() {
var element = angular.element('<div angucomplete id="ex1" placeholder="Search countries" selectedobject="selectedCountry" localdata="countries" searchfields="name" titlefield="name"/>');
$scope.selectedCountry = undefined;
$scope.countries = [
{name: 'Afghanistan', code: 'AF'},
{name: 'Aland Islands', code: 'AX'},
{name: 'Albania', code: 'AL'}
];
$compile(element)($scope);
$scope.$digest();
var inputField = element.find('#ex1_value');
var e = $.Event('keyup');
e.which = 97; // letter: a

inputField.val('a');
inputField.trigger('input');
inputField.trigger(e);
expect(element.find('#ex1_dropdown').length).toBe(0);

inputField.val('aa');
inputField.trigger('input');
inputField.trigger(e);
expect(element.find('#ex1_dropdown').length).toBe(0);

inputField.val('aaa');
inputField.trigger('input');
inputField.trigger(e);
$timeout.flush();
expect(element.find('#ex1_dropdown').length).toBe(1);
});

it('should show search results after 1 letter is entered with minlength being set to 1', function() {
var element = angular.element('<div angucomplete id="ex1" placeholder="Search countries" selectedobject="selectedCountry" localdata="countries" searchfields="name" titlefield="name" minlength="1"/>');
$scope.selectedCountry = undefined;
$scope.countries = [
{name: 'Afghanistan', code: 'AF'},
{name: 'Aland Islands', code: 'AX'},
{name: 'Albania', code: 'AL'}
];
$compile(element)($scope);
$scope.$digest();
var inputField = element.find('#ex1_value');
var e = $.Event('keyup');
e.which = 97; // letter: a
inputField.val('a');
inputField.trigger('input');
inputField.trigger(e);
$timeout.flush();
expect(element.find('#ex1_dropdown').length).toBe(1);
});
});

});
20 changes: 4 additions & 16 deletions test/karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
// Karma configuration
// Generated on Tue Sep 17 2013 06:59:46 GMT-0400 (EDT)

module.exports = function(config) {
config.set({

// base path, that will be used to resolve files and exclude
basePath: '..',


// frameworks to use
frameworks: ['jasmine'],


// list of files / patterns to load in the browser
files: [
// Dependencies
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'components/sizzle/dist/sizzle.js',
'components/jquery/dist/jquery.js',
'components/angular/angular.js',
'components/angular-mocks/angular-mocks.js',

// Source Code
'angucomplete.js',
Expand All @@ -25,31 +23,24 @@ module.exports = function(config) {
'test/*Spec.js'
],


// list of files to exclude
exclude: [

],


// test results reporter to use
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
reporters: ['progress'],


// web server port
port: 9876,


// enable / disable colors in the output (reporters and logs)
colors: true,


// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,


// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,

Expand All @@ -63,15 +54,12 @@ module.exports = function(config) {
// - IE (only Windows)
browsers: ['Chrome'],


// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,


// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false


});
};

0 comments on commit e5fde2d

Please sign in to comment.