mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
chore(ngdocs): provide test code for lunr search in docs
This commit is contained in:
parent
46dfb92afd
commit
f6be59c1b9
4 changed files with 200 additions and 88 deletions
72
docs/component-spec/NavigationCtrlSpec.js
Normal file
72
docs/component-spec/NavigationCtrlSpec.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
describe("DocsNavigationCtrl", function() {
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
var ctrl, $scope;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('docsPages', []);
|
||||
$provide.factory('docsSearch', function() {
|
||||
return function(q) {
|
||||
return ['one','two','three'];
|
||||
};
|
||||
});
|
||||
});
|
||||
inject(function($controller, $rootScope, $location, docsSearch) {
|
||||
$scope = $rootScope.$new();
|
||||
ctrl = $controller('DocsNavigationCtrl', {
|
||||
$scope : $scope,
|
||||
$location : $location,
|
||||
docsSearch : docsSearch
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should search and return data from docsSearch", function() {
|
||||
$scope.search('1234')
|
||||
expect($scope.results.join(',')).toBe('one,two,three');
|
||||
expect($scope.hasResults).toBe(true);
|
||||
});
|
||||
|
||||
it("should avoid searching if the search term is too short", function() {
|
||||
$scope.search('1')
|
||||
expect($scope.results.length).toBe(0);
|
||||
expect($scope.hasResults).toBe(false);
|
||||
});
|
||||
|
||||
it("should set the columns classname based on the total grouped results", function() {
|
||||
$scope.search('1234');
|
||||
expect($scope.colClassName).toBe('cols-3');
|
||||
|
||||
$scope.search('1');
|
||||
expect($scope.colClassName).toBe(null);
|
||||
});
|
||||
|
||||
it("should hide and clear the results when called", function() {
|
||||
$scope.hasResults = true;
|
||||
$scope.results = ['one'];
|
||||
$scope.colClassName = '...';
|
||||
$scope.hideResults();
|
||||
expect($scope.hasResults).toBe(false);
|
||||
expect($scope.results.length).toBe(0);
|
||||
expect($scope.colClassName).toBe(null);
|
||||
});
|
||||
|
||||
it("should hide, clear and change the path of the page when submitted", inject(function($location) {
|
||||
$scope.hasResults = true;
|
||||
$scope.results = {
|
||||
api : [
|
||||
{url : '/home'}
|
||||
],
|
||||
tutorial : [
|
||||
{url : '/tutorial'}
|
||||
]
|
||||
};
|
||||
$scope.submit();
|
||||
expect($location.path()).toBe('/home');
|
||||
expect($scope.results.length).toBe(0);
|
||||
expect($scope.hasResults).toBe(false);
|
||||
}));
|
||||
|
||||
});
|
||||
59
docs/component-spec/docsSearchSpec.js
Normal file
59
docs/component-spec/docsSearchSpec.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
describe("docsSearch", function() {
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
var interceptedLunrResults;
|
||||
beforeEach(function() {
|
||||
interceptedLunrResults = [];
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
var results = [];
|
||||
results[0] = { section: 'tutorial', shortName: 'item one', keywords: 'item, one, 1' };
|
||||
results[1] = { section: 'tutorial', shortName: 'item man', keywords: 'item, man' };
|
||||
results[2] = { section: 'api', shortName: 'item other', keywords: 'item, other' };
|
||||
results[3] = { section: 'cookbook', shortName: 'item cookbook', keywords: 'item, other' };
|
||||
results[4] = { section: 'api', shortName: 'ngRepeat', keywords: 'item, other' };
|
||||
|
||||
$provide.value('NG_PAGES', results);
|
||||
$provide.factory('lunrSearch', function() {
|
||||
return function() {
|
||||
return {
|
||||
store : function(value) {
|
||||
interceptedLunrResults.push(value);
|
||||
},
|
||||
search : function(q) {
|
||||
var data = [];
|
||||
angular.forEach(results, function(res, i) {
|
||||
data.push({ ref : i });
|
||||
});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should lookup and organize values properly", inject(function(docsSearch) {
|
||||
var items = docsSearch('item');
|
||||
expect(items['api'].length).toBe(2);
|
||||
}));
|
||||
|
||||
it("should place cookbook items in the tutorial", inject(function(docsSearch) {
|
||||
var items = docsSearch('item');
|
||||
expect(items['tutorial'].length).toBe(3);
|
||||
}));
|
||||
|
||||
it("should return all results without a search", inject(function(docsSearch) {
|
||||
var items = docsSearch();
|
||||
expect(items['tutorial'].length).toBe(3);
|
||||
expect(items['api'].length).toBe(2);
|
||||
}));
|
||||
|
||||
it("should store values with and without a ng prefix", inject(function(docsSearch) {
|
||||
expect(interceptedLunrResults[4].title).toBe('ngRepeat repeat');
|
||||
}));
|
||||
|
||||
});
|
||||
|
|
@ -461,6 +461,7 @@ pre ol li {
|
|||
box-shadow:-6px 0 5px #555;
|
||||
display:block;
|
||||
border-radius:10px;
|
||||
}
|
||||
|
||||
.docs-version-jump {
|
||||
width:180px;
|
||||
|
|
|
|||
|
|
@ -62,29 +62,31 @@ docsApp.controller.DocsVersionsCtrl = ['$scope', '$window', 'NG_VERSIONS', funct
|
|||
};
|
||||
}];
|
||||
|
||||
docsApp.controller.DocsNavigationCtrl = ['$scope', 'fullTextSearch', '$location', function($scope, fullTextSearch, $location) {
|
||||
fullTextSearch.init();
|
||||
docsApp.controller.DocsNavigationCtrl = ['$scope', '$location', 'docsSearch', function($scope, $location, docsSearch) {
|
||||
function clearResults() {
|
||||
$scope.results = [];
|
||||
$scope.colClassName = null;
|
||||
$scope.hasResults = false;
|
||||
}
|
||||
|
||||
$scope.search = function(q) {
|
||||
fullTextSearch.search(q, function(results) {
|
||||
if(q && q.length >= 4) {
|
||||
$scope.results = results;
|
||||
var totalSections = 0;
|
||||
for(var i in results) {
|
||||
++totalSections;
|
||||
}
|
||||
if(totalSections > 0) {
|
||||
$scope.colClassName = 'cols-' + totalSections;
|
||||
$scope.hasResults = true;
|
||||
}
|
||||
else {
|
||||
$scope.hasResults = false;
|
||||
}
|
||||
var MIN_SEARCH_LENGTH = 4;
|
||||
if(q.length >= MIN_SEARCH_LENGTH) {
|
||||
var results = docsSearch(q);
|
||||
var totalSections = 0;
|
||||
for(var i in results) {
|
||||
++totalSections;
|
||||
}
|
||||
else {
|
||||
$scope.hasResults = false;
|
||||
if(totalSections > 0) {
|
||||
$scope.colClassName = 'cols-' + totalSections;
|
||||
$scope.hasResults = true;
|
||||
}
|
||||
if(!$scope.$$phase) $scope.$apply();
|
||||
});
|
||||
$scope.results = results;
|
||||
}
|
||||
else {
|
||||
clearResults();
|
||||
}
|
||||
if(!$scope.$$phase) $scope.$apply();
|
||||
};
|
||||
$scope.submit = function() {
|
||||
var result;
|
||||
|
|
@ -100,82 +102,60 @@ docsApp.controller.DocsNavigationCtrl = ['$scope', 'fullTextSearch', '$location'
|
|||
}
|
||||
};
|
||||
$scope.hideResults = function() {
|
||||
$scope.hasResults = false;
|
||||
clearResults();
|
||||
$scope.q = '';
|
||||
};
|
||||
}];
|
||||
|
||||
docsApp.serviceFactory.fullTextSearch = ['$q', '$rootScope', 'NG_PAGES', function($q, $rootScope, NG_PAGES) {
|
||||
return {
|
||||
dbName : 'docs',
|
||||
indexName : 'docsindex',
|
||||
docsApp.serviceFactory.lunrSearch = function() {
|
||||
return function(properties) {
|
||||
var engine = lunr(properties);
|
||||
return {
|
||||
store : function(values) {
|
||||
engine.add(values);
|
||||
},
|
||||
search : function(q) {
|
||||
return engine.search(q);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
init : function(onReady) {
|
||||
this.init = function() {};
|
||||
docsApp.serviceFactory.docsSearch = ['$rootScope','lunrSearch', 'NG_PAGES',
|
||||
function($rootScope, lunrSearch, NG_PAGES) {
|
||||
|
||||
var self = this;
|
||||
this.deferReady = $q.defer();
|
||||
this.readyPromise = this.deferReady.promise;
|
||||
var index = lunrSearch(function() {
|
||||
this.ref('id');
|
||||
this.field('title', {boost: 50});
|
||||
this.field('description', { boost : 20 });
|
||||
});
|
||||
|
||||
this.engine = lunr(function () {
|
||||
this.ref('id');
|
||||
this.field('title', {boost: 50});
|
||||
this.field('description', { boost : 20 });
|
||||
});
|
||||
this.prepare();
|
||||
this.onReady();
|
||||
},
|
||||
onReady : function() {
|
||||
this.ready = true;
|
||||
var self = this;
|
||||
self.deferReady.resolve();
|
||||
if(!$rootScope.$$phase) {
|
||||
$rootScope.$apply();
|
||||
}
|
||||
},
|
||||
whenReady : function(fn) {
|
||||
if(this.ready) {
|
||||
fn();
|
||||
}
|
||||
else {
|
||||
this.init();
|
||||
this.readyPromise.then(fn);
|
||||
}
|
||||
},
|
||||
prepare : function(injector, callback) {
|
||||
for(var i=0;i<NG_PAGES.length;i++) {
|
||||
var page = NG_PAGES[i];
|
||||
var title = page.shortName;
|
||||
if(title.charAt(0) == 'n' && title.charAt(1) == 'g') {
|
||||
title = title + ' ' + title.substr(2);
|
||||
}
|
||||
this.engine.add({
|
||||
id: i,
|
||||
title: title,
|
||||
description: page.keywords
|
||||
});
|
||||
}
|
||||
},
|
||||
search : function(q, onReady) {
|
||||
var self = this;
|
||||
this.whenReady(function() {
|
||||
var data = [];
|
||||
var results = self.engine.search(q);
|
||||
var groups = {};
|
||||
angular.forEach(results, function(result) {
|
||||
var item = NG_PAGES[result.ref];
|
||||
var section = item.section;
|
||||
if(section == 'cookbook') {
|
||||
section = 'tutorial';
|
||||
}
|
||||
groups[section] = groups[section] || [];
|
||||
if(groups[section].length < 15) {
|
||||
groups[section].push(item);
|
||||
}
|
||||
});
|
||||
onReady(groups);
|
||||
});
|
||||
angular.forEach(NG_PAGES, function(page, i) {
|
||||
var title = page.shortName;
|
||||
if(title.charAt(0) == 'n' && title.charAt(1) == 'g') {
|
||||
title = title + ' ' + title.charAt(2).toLowerCase() + title.substr(3);
|
||||
}
|
||||
index.store({
|
||||
id: i,
|
||||
title: title,
|
||||
description: page.keywords
|
||||
});
|
||||
});
|
||||
|
||||
return function(q) {
|
||||
var results = {};
|
||||
angular.forEach(index.search(q), function(result) {
|
||||
var item = NG_PAGES[result.ref];
|
||||
var section = item.section;
|
||||
if(section == 'cookbook') {
|
||||
section = 'tutorial';
|
||||
}
|
||||
results[section] = results[section] || [];
|
||||
if(results[section].length < 15) {
|
||||
results[section].push(item);
|
||||
}
|
||||
});
|
||||
return results;
|
||||
};
|
||||
}];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue