From 9c5a0a3ea3360d8cef859e0a61d80cf67f198336 Mon Sep 17 00:00:00 2001 From: Juzer Ali Date: Sat, 17 Nov 2012 20:05:29 +0530 Subject: [PATCH 01/37] Test added for group query --- test/group-query-test.js | 67 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/test/group-query-test.js b/test/group-query-test.js index ac210833..4221a720 100644 --- a/test/group-query-test.js +++ b/test/group-query-test.js @@ -1 +1,66 @@ -//TODO support http://wiki.apache.org/solr/FieldCollapsing?highlight=%28field%29%7C%28collapsing%29 \ No newline at end of file +/** + * Modules dependencies + */ + +var mocha = require('mocha'), + assert = require('chai').assert, + libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', + solr = require( libPath + '/solr'), + sassert = require('./sassert'); + +// Test suite +var client = solr.createClient(); + + +describe('Client#createQuery',function(){ + + describe('.groupBy(field), callback)',function(){ + it('should create a group by query',function(done){ + var query = client.createQuery() + .q('test') + .groupBy('title_t') + .debugQuery(); + client.search(query, function(err, data){ + sassert.ok(err, data); + assert(data.responseHeader.params.group); + assert.equal('title_t', data.responseHeader.params['group.field']); + done(); + }); + }); + }); + + describe('#group(options), callback)',function(){ + it('should create a group query',function(done){ + var options = { + "on": true + , "field": "title_t" + , "func": "test" + , "rows": 11 + , "start": 1 + , "limit": 15 + , "offset": 8 + , "sort": "score desc" + , "format": "simple" + , "main": true + , "ngroups": true + , "truncate": true + , "facet": true + , "cache": 50 + }; + + var query = client.createQuery() + .group(options); + + client.search(query, function(err, data){ + console.log(JSON.stringify(data.responseHeader.params)+'\n'); + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + {'group.format':'simple','group.ngroups':'true','group.limit':'15','group.truncate':'true', + 'group.field':'title_t','group.main':'true',group:'true','group.sort':'score desc', + 'group.cache.percent':'50','group.offset':'8',wt:'json', 'group.func': 'test', rows: '11', + 'start': '1', 'group.facet': 'true'}); + done(); + }); + }); + }); +}); From 50dd3b7bac2faae305fef18c69126b10d16c7721 Mon Sep 17 00:00:00 2001 From: Juzer Ali Date: Sun, 18 Nov 2012 20:51:48 +0530 Subject: [PATCH 02/37] Test added for MoreLikeThis query --- test/mlt-query-test.js | 58 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/test/mlt-query-test.js b/test/mlt-query-test.js index 355984fb..5fb79cee 100644 --- a/test/mlt-query-test.js +++ b/test/mlt-query-test.js @@ -1 +1,57 @@ -//TODO support http://wiki.apache.org/solr/MoreLikeThis \ No newline at end of file +/** + * Modules dependencies + */ + +var mocha = require('mocha'), + assert = require('chai').assert, + libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', + solr = require( libPath + '/solr'), + sassert = require('./sassert'); + +// Test suite +var client = solr.createClient(); + + +describe('Client#createQuery',function(){ + describe('#mlt(options), callback)',function(){ + it('should create a MoreLikeThis query',function(done){ + var options = { + "on": true + , "fl": ['content', 'title'] + , "count": 15 + , "mintf": 0 + , "mindf": 0 + , "minwl": 0 + , "maxwl": 1500 + , "maxqt": 1500 + , "maxntp": 1500 + , "boost": true + , "qf": 1 + }; + + var query = client.createQuery() + .mlt(options) + .q({'title_t': 'test'}) + .debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { 'mlt.minwl': '0', + 'mlt.fl': 'content,title', + 'mlt.boost': 'true', + 'mlt.mintf': '0', + 'mlt.qf': '1', + mlt: 'true', + 'mlt.maxwl': '1500', + 'mlt.maxntp': '1500', + 'mlt.maxqt': '1500', + wt: 'json', + 'mlt.mindf': '0', + 'mlt.count': '15' + }); + done(); + }); + }); + }); +}); From 8cb446c23a3a57b116df84b8de7bfc2308a9d88a Mon Sep 17 00:00:00 2001 From: Juzer Ali Date: Sun, 18 Nov 2012 21:57:49 +0530 Subject: [PATCH 03/37] Test added for facet-query --- test/facet-query-test.js | 103 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 6 deletions(-) diff --git a/test/facet-query-test.js b/test/facet-query-test.js index 1af25e8a..b61d8661 100644 --- a/test/facet-query-test.js +++ b/test/facet-query-test.js @@ -17,12 +17,45 @@ var mocha = require('mocha'), var client = solr.createClient(); describe('Client#createQuery()',function(){ - describe('.facet({field : "category_t"}).q({title_t : "test"})',function(){ - it('should create a facet on the field "category_t"',function(done){ + describe('.facet(options)',function(){ + it('should create a facet for multiple date/range fields',function(done){ + var date = new Date().getTime(); + var facetOptions = { + "on": true + , "query": "query" + , "field": "field" + , "prefix": "prefix" + , "sort": "field desc" + , "limit": 100 + , "offset": 5 + , "mincount": 10 + , "missing": true + , "method": "fc" + , "date": [{ + "field": "date_field" + , "start": date + , "end": date + , "gap": "+1DAY" + , "hardened": true + , "other": "all" + , "include": "all" + }] + , "range": [{ + "field": "range_field" + , "start": 0.0 + , "end": "1000" + , "gap": "+1DAY" + , "hardened": true + , "other": "all" + , "include": "all" + }] + , "pivot": { + "fields": ["cat", "popularity"] + , "mincount": 10 + } + } var query = client.createQuery() - .facet({ - field : 'category_t' - }) + .facet(facetOptions) .q({ title_t : 'test'}) .debugQuery(); client.search(query,function(err,data){ @@ -33,7 +66,65 @@ describe('Client#createQuery()',function(){ wt: 'json', debugQuery: 'true', q: 'title_t:test', - 'facet.field': 'category_t' + 'facet.field': 'field' + /* Other response params here */ + } + ); + assert.equal(data.debug.QParser,'LuceneQParser'); + done(); + }); + }); + + it('should create a facet for single date/range fields',function(done){ + var date = new Date().getTime(); + var facetOptions = { + "on": true + , "query": "query" + , "field": "field" + , "prefix": "prefix" + , "sort": "field desc" + , "limit": 100 + , "offset": 5 + , "mincount": 10 + , "missing": true + , "method": "fc" + , "date": { + "field": "date_field" + , "start": date + , "end": date + , "gap": "+1DAY" + , "hardened": true + , "other": "all" + , "include": "all" + } + , "range": { + "field": "range_field" + , "start": 0.0 + , "end": "1000" + , "gap": "+1DAY" + , "hardened": true + , "other": "all" + , "include": "all" + } + , "pivot": { + "fields": "cat" + , "mincount": 10 + } + } + var query = client.createQuery() + .facet(facetOptions) + .q({ title_t : 'test'}) + .debugQuery(); + client.search(query,function(err,data){ + sassert.ok(err,data); + assert.deepEqual(data.responseHeader.params, + { + facet: 'true', + wt: 'json', + debugQuery: 'true', + q: 'title_t:test', + 'facet.field': 'field' + /* Other response params here */ } ); assert.equal(data.debug.QParser,'LuceneQParser'); From 5e1edd4d314b4fb6a2ac89e53d233d8c303075fa Mon Sep 17 00:00:00 2001 From: Vlad Date: Tue, 13 May 2014 14:32:05 +0300 Subject: [PATCH 04/37] NEW: Add 'get' method to make arbitrary requests --- lib/solr.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/solr.js b/lib/solr.js index ec52c0e2..76a1df8b 100644 --- a/lib/solr.js +++ b/lib/solr.js @@ -410,7 +410,7 @@ Client.prototype.search = function(query,callback){ /** * Search documents matching the `query` - * + * * Spellcheck is also enabled. * * @param {Query|String} query @@ -436,6 +436,33 @@ Client.prototype.spell = function(query,callback){ return self; } +/** + * Make an arbitraty get request to Solr + * + * @param {Path|String} Path + * @param {Query|String} query + * @param {Function} callback(err,obj) - a function executed when the Solr server responds or an error occurs + * @param {Error} callback().err + * @param {Object} callback().obj - JSON response sent by the Solr server deserialized + * + * @return {Client} + * @api public + */ + +Client.prototype.get = function(path,query,callback){ + var self = this; + // Allow to be more flexible allow query to be a string and not only a Query object + var parameters = query.build ? query.build() : query; + this.options.fullPath = [this.options.path,this.options.core,path + '?' + parameters + '&wt=json'] + .filter(function(element){ + if(element) return true; + return false; + }) + .join('/'); ; + queryRequest(this.options,callback); + return self; +} + /** * Create an instance of `Query` * From ac53d760470cf1b49a1f580ba921fa76e0123685 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Wed, 16 Jul 2014 08:48:02 +0200 Subject: [PATCH 05/37] making the solr connection params configurable during test as per suggestion in issue #85 --- package.json | 61 ++++++++++++++++++------------------ test/add-test.js | 10 +++--- test/commit-test.js | 6 ++-- test/config.json | 8 +++++ test/core-query-test.js | 2 +- test/createAddStream-test.js | 7 +++-- test/createClient-test.js | 2 +- test/delete-test.js | 12 ++++--- test/deleteAll-test.js | 6 ++-- test/deleteById-test.js | 12 ++++--- test/deleteByQuery-test.js | 12 ++++--- test/deleteByRange-test.js | 12 ++++--- test/dismax-query-test.js | 6 ++-- test/facet-query-test.js | 6 ++-- test/group-query-test.js | 2 +- test/mlt-query-test.js | 2 +- test/optimize-test.js | 6 ++-- test/ping-test.js | 6 ++-- test/prepareCommit-test.js | 8 +++-- test/rollback-test.js | 6 ++-- test/sassert.js | 2 +- test/search-test.js | 6 ++-- test/softCommit-test.js | 8 +++-- test/utils-test.js | 2 +- 24 files changed, 125 insertions(+), 85 deletions(-) create mode 100644 test/config.json diff --git a/package.json b/package.json index 492f13f0..72ec367a 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,32 @@ { - "author": { - "name": "Remy Loubradou", - "email": "remy.loubradou@gmail.com", - "url": "https://twitter.com/#!/lbdremy" - }, - "name": "solr-client", - "main": "./main", - "description": " A Solr client library for indexing, adding, deleting, committing, optimizing and searching documents within an Apache Solr installation (version>=3.2)", - "version": "0.2.3", - "repository": { - "type": "git", - "url": "https://github.com/lbdremy/solr-node-client" - }, - "engines": { - "node": ">= 0.4.7" - }, - "dependencies": { - "JSONStream" : "~0.3.1", - "duplexer" : "~0.0.2", - "request" : "~2.11.0" - }, - "devDependencies": { - "nock": "0.12.x", - "mocha" : "~1.6.0 ", - "chai" : "~1.3.0 " - }, - "scripts": { - "test": "./node_modules/mocha/bin/mocha -R spec test/*-test.js" - } -} \ No newline at end of file + "author": { + "name": "Remy Loubradou", + "email": "remy.loubradou@gmail.com", + "url": "https://twitter.com/#!/lbdremy" + }, + "name": "solr-client", + "main": "./main", + "description": " A Solr client library for indexing, adding, deleting, committing, optimizing and searching documents within an Apache Solr installation (version>=3.2)", + "version": "0.2.3", + "repository": { + "type": "git", + "url": "https://github.com/lbdremy/solr-node-client" + }, + "engines": { + "node": ">= 0.4.7" + }, + "dependencies": { + "JSONStream": "~0.3.1", + "duplexer": "~0.0.2", + "request": "~2.11.0", + "figc": "0.0.3" + }, + "devDependencies": { + "nock": "0.12.x", + "mocha": "~1.6.0 ", + "chai": "~1.3.0 " + }, + "scripts": { + "test": "./node_modules/mocha/bin/mocha -R spec test/*-test.js" + } +} diff --git a/test/add-test.js b/test/add-test.js index c8cbee38..51e8ba21 100644 --- a/test/add-test.js +++ b/test/add-test.js @@ -9,7 +9,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#add({ id : 1, title_t : "title"},callback)',function(){ @@ -58,7 +60,7 @@ describe('Client',function(){ softCommit : true }; var request = client.add(docs,options,function(err,data){ - assert.equal(request.path,'/solr/update/json?softCommit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?softCommit=true&wt=json'); sassert.ok(err,data); done(); }); @@ -80,7 +82,7 @@ describe('Client',function(){ commit : true }; var request = client.add(docs,options,function(err,data){ - assert.equal(request.path,'/solr/update/json?commit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?commit=true&wt=json'); sassert.ok(err,data); done(); }); @@ -102,7 +104,7 @@ describe('Client',function(){ commitWithin : 10000 }; var request = client.add(docs,options,function(err,data){ - assert.equal(request.path,'/solr/update/json?commitWithin=10000&wt=json'); + assert.equal(request.path, basePath + '/update/json?commitWithin=10000&wt=json'); sassert.ok(err,data); done(); }); diff --git a/test/commit-test.js b/test/commit-test.js index a344cf0f..2bfbd4de 100644 --- a/test/commit-test.js +++ b/test/commit-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#commit(callback)',function(){ @@ -45,4 +47,4 @@ describe('Client',function(){ }); }); }); -}); \ No newline at end of file +}); diff --git a/test/config.json b/test/config.json new file mode 100644 index 00000000..fc9a0944 --- /dev/null +++ b/test/config.json @@ -0,0 +1,8 @@ +{ + "client": { + "host": "127.0.0.1", + "port": 8983, + "path": "/solr", + "core": "test-node-client" + } +} diff --git a/test/core-query-test.js b/test/core-query-test.js index 0278d73a..2bf6fcf9 100644 --- a/test/core-query-test.js +++ b/test/core-query-test.js @@ -1 +1 @@ -//TODO support http://wiki.apache.org/solr/CommonQueryParameters \ No newline at end of file +//TODO support http://wiki.apache.org/solr/CommonQueryParameters diff --git a/test/createAddStream-test.js b/test/createAddStream-test.js index 83f97291..42ae58e9 100644 --- a/test/createAddStream-test.js +++ b/test/createAddStream-test.js @@ -11,7 +11,9 @@ var mocha = require('mocha'), Stream = require('stream'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#createAddStream()',function(){ @@ -21,7 +23,6 @@ describe('Client',function(){ }); describe('#write() to the `Stream` returned',function(){ it('should add documents',function(done){ - var client = solr.createClient(); var addStream = client.createAddStream(); var data = ''; addStream @@ -44,4 +45,4 @@ describe('Client',function(){ }) }); }); -}); \ No newline at end of file +}); diff --git a/test/createClient-test.js b/test/createClient-test.js index 0cd0e7e7..f47ef6f8 100644 --- a/test/createClient-test.js +++ b/test/createClient-test.js @@ -43,4 +43,4 @@ describe('solr',function(){ assert.equal(client.options.path,'/solr4'); }); }) -}); \ No newline at end of file +}); diff --git a/test/delete-test.js b/test/delete-test.js index 77382c9f..1f1a8f06 100644 --- a/test/delete-test.js +++ b/test/delete-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#delete("title_t","test",callback)',function(){ @@ -24,7 +26,7 @@ describe('Client',function(){ describe('#delete("title_t","test",{ commit : true},callback)',function(){ it('should delete all documents where the field "title_t" is "test" and hard commit all changes',function(done){ var request = client.delete('title_t','test',{commit : true},function(err,data){ - assert.equal(request.path,'/solr/update/json?commit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?commit=true&wt=json'); sassert.ok(err,data); done(); }); @@ -33,7 +35,7 @@ describe('Client',function(){ describe('#delete("title_t","test",{ softCommit : true},callback)',function(){ it('should delete all documents where the field "title_t" is "test" and soft commit all changes',function(done){ var request = client.delete('title_t','test',{softCommit : true},function(err,data){ - assert.equal(request.path,'/solr/update/json?softCommit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?softCommit=true&wt=json'); sassert.ok(err,data); done(); }); @@ -42,7 +44,7 @@ describe('Client',function(){ describe('#delete("title_t","test",{ commitWithin : 10000},callback)',function(){ it('should delete all documents where the field "title_t" is "test" and commit within 10s all changes',function(done){ var request = client.delete('title_t','test',{commitWithin : 10000},function(err,data){ - assert.equal(request.path,'/solr/update/json?commitWithin=10000&wt=json'); + assert.equal(request.path, basePath + '/update/json?commitWithin=10000&wt=json'); sassert.ok(err,data); done(); }); @@ -56,4 +58,4 @@ describe('Client',function(){ }); }); }); -}); \ No newline at end of file +}); diff --git a/test/deleteAll-test.js b/test/deleteAll-test.js index 5628e15f..27d6af8d 100644 --- a/test/deleteAll-test.js +++ b/test/deleteAll-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#deleteAll(callback)',function(){ @@ -21,4 +23,4 @@ describe('Client',function(){ }); }); }); -}); \ No newline at end of file +}); diff --git a/test/deleteById-test.js b/test/deleteById-test.js index 897b13ee..90741249 100644 --- a/test/deleteById-test.js +++ b/test/deleteById-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#deleteByID(1,callback)',function(){ @@ -24,7 +26,7 @@ describe('Client',function(){ describe('#deleteByID(1,{softCommit : true },callback)',function(){ it('should delete the document with the id 1 and the soft commit option enabled',function(done){ var request = client.deleteByID(1,{softCommit : true},function(err,data){ - assert.equal(request.path,'/solr/update/json?softCommit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?softCommit=true&wt=json'); sassert.ok(err,data); done(); }); @@ -33,7 +35,7 @@ describe('Client',function(){ describe('#deleteByID(1,{commitWithin : 10000},callback)',function(){ it('should delete the document with the id 1 and commit changes within 10s',function(done){ var request = client.deleteByID(1,{commitWithin : 10000},function(err,data){ - assert.equal(request.path,'/solr/update/json?commitWithin=10000&wt=json'); + assert.equal(request.path, basePath + '/update/json?commitWithin=10000&wt=json'); sassert.ok(err,data); done(); }); @@ -42,10 +44,10 @@ describe('Client',function(){ describe('#deleteByID(1,{commit : true},callback)',function(){ it('should delete the document with the id 1 and hard commit changes',function(done){ var request = client.deleteByID(1,{commit : true},function(err,data){ - assert.equal(request.path,'/solr/update/json?commit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?commit=true&wt=json'); sassert.ok(err,data); done(); }); }); }); -}); \ No newline at end of file +}); diff --git a/test/deleteByQuery-test.js b/test/deleteByQuery-test.js index 33707886..79e26a7f 100644 --- a/test/deleteByQuery-test.js +++ b/test/deleteByQuery-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#deleteByQuery("title_t:*",callback)',function(){ @@ -24,7 +26,7 @@ describe('Client',function(){ describe('#deleteByQuery("title_t:*",{softCommit : true },callback)',function(){ it('should delete all documents having the field title_t with the soft commit option enabled',function(done){ var request = client.deleteByQuery('title_t:*',{softCommit : true},function(err,data){ - assert.equal(request.path,'/solr/update/json?softCommit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?softCommit=true&wt=json'); sassert.ok(err,data); done(); }); @@ -33,7 +35,7 @@ describe('Client',function(){ describe('#deleteByQuery("title_t:*",{commitWithin : 10000},callback)',function(){ it('should delete all documents having the field title_t and commit changes within 10s',function(done){ var request = client.deleteByQuery('title_t:*',{commitWithin : 10000},function(err,data){ - assert.equal(request.path,'/solr/update/json?commitWithin=10000&wt=json'); + assert.equal(request.path, basePath + '/update/json?commitWithin=10000&wt=json'); sassert.ok(err,data); done(); }); @@ -42,10 +44,10 @@ describe('Client',function(){ describe('#deleteByQuery("title_t:*",{commit : true},callback)',function(){ it('should delete all documents having the field title_t and hard commit changes',function(done){ var request = client.deleteByQuery('title_t:*',{commit : true},function(err,data){ - assert.equal(request.path,'/solr/update/json?commit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?commit=true&wt=json'); sassert.ok(err,data); done(); }); }); }); -}); \ No newline at end of file +}); diff --git a/test/deleteByRange-test.js b/test/deleteByRange-test.js index e2e705e2..a80cfc3f 100644 --- a/test/deleteByRange-test.js +++ b/test/deleteByRange-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#deleteByRange(field,start,stop,callback)',function(){ @@ -32,7 +34,7 @@ describe('Client',function(){ var stop = new Date(); stop.setDate(stop.getDate() - 1); var request = client.deleteByRange(field,start,stop,{softCommit : true},function(err,data){ - assert.equal(request.path,'/solr/update/json?softCommit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?softCommit=true&wt=json'); sassert.ok(err,data); done(); }); @@ -45,7 +47,7 @@ describe('Client',function(){ var stop = new Date(); stop.setDate(stop.getDate() - 1); var request = client.deleteByRange(field,start,stop,{commitWithin : 10000},function(err,data){ - assert.equal(request.path,'/solr/update/json?commitWithin=10000&wt=json'); + assert.equal(request.path, basePath + '/update/json?commitWithin=10000&wt=json'); sassert.ok(err,data); done(); }); @@ -58,10 +60,10 @@ describe('Client',function(){ var stop = new Date(); stop.setDate(stop.getDate() - 1); var request = client.deleteByRange(field,start,stop,{commit : true},function(err,data){ - assert.equal(request.path,'/solr/update/json?commit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?commit=true&wt=json'); sassert.ok(err,data); done(); }); }); }); -}); \ No newline at end of file +}); diff --git a/test/dismax-query-test.js b/test/dismax-query-test.js index 41cecafd..0c285aaf 100644 --- a/test/dismax-query-test.js +++ b/test/dismax-query-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client#createQuery()',function(){ describe('.dismax().q("test")',function(){ @@ -27,4 +29,4 @@ describe('Client#createQuery()',function(){ }); }); }); -}); \ No newline at end of file +}); diff --git a/test/facet-query-test.js b/test/facet-query-test.js index 1af25e8a..39cc8fac 100644 --- a/test/facet-query-test.js +++ b/test/facet-query-test.js @@ -14,7 +14,9 @@ var mocha = require('mocha'), // and http://wiki.apache.org/solr/HierarchicalFaceting // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client#createQuery()',function(){ describe('.facet({field : "category_t"}).q({title_t : "test"})',function(){ @@ -41,4 +43,4 @@ describe('Client#createQuery()',function(){ }); }); }); -}); \ No newline at end of file +}); diff --git a/test/group-query-test.js b/test/group-query-test.js index ac210833..106131a8 100644 --- a/test/group-query-test.js +++ b/test/group-query-test.js @@ -1 +1 @@ -//TODO support http://wiki.apache.org/solr/FieldCollapsing?highlight=%28field%29%7C%28collapsing%29 \ No newline at end of file +//TODO support http://wiki.apache.org/solr/FieldCollapsing?highlight=%28field%29%7C%28collapsing%29 diff --git a/test/mlt-query-test.js b/test/mlt-query-test.js index 355984fb..9a06a0ed 100644 --- a/test/mlt-query-test.js +++ b/test/mlt-query-test.js @@ -1 +1 @@ -//TODO support http://wiki.apache.org/solr/MoreLikeThis \ No newline at end of file +//TODO support http://wiki.apache.org/solr/MoreLikeThis diff --git a/test/optimize-test.js b/test/optimize-test.js index 7d854e5b..598797d8 100644 --- a/test/optimize-test.js +++ b/test/optimize-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#optimize(callback)',function(){ @@ -53,4 +55,4 @@ describe('Client',function(){ }); }); }); -}); \ No newline at end of file +}); diff --git a/test/ping-test.js b/test/ping-test.js index 983f08cf..7bd55808 100644 --- a/test/ping-test.js +++ b/test/ping-test.js @@ -9,7 +9,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#ping(callback)',function(){ @@ -20,4 +22,4 @@ describe('Client',function(){ }) }); }) -}); \ No newline at end of file +}); diff --git a/test/prepareCommit-test.js b/test/prepareCommit-test.js index ab083c7a..03ba08c0 100644 --- a/test/prepareCommit-test.js +++ b/test/prepareCommit-test.js @@ -10,14 +10,16 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#prepareCommit(callback)',function(){ it('should prepare the commit',function(done){ var request = client.prepareCommit(function(err,data){ sassert.ok(err,data); - assert.equal(request.path,'/solr/update/json?prepareCommit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?prepareCommit=true&wt=json'); done(); }); }); @@ -25,4 +27,4 @@ describe('Client',function(){ }); // Support -// http://wiki.apache.org/solr/UpdateXmlMessages?highlight=%28softCommit%29#A.22prepareCommit.22 \ No newline at end of file +// http://wiki.apache.org/solr/UpdateXmlMessages?highlight=%28softCommit%29#A.22prepareCommit.22 diff --git a/test/rollback-test.js b/test/rollback-test.js index ebc9630b..0ab4d203 100644 --- a/test/rollback-test.js +++ b/test/rollback-test.js @@ -9,7 +9,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#rollback(callback)',function(){ @@ -20,4 +22,4 @@ describe('Client',function(){ }) }); }) -}); \ No newline at end of file +}); diff --git a/test/sassert.js b/test/sassert.js index a76b7b0d..40a8f28f 100644 --- a/test/sassert.js +++ b/test/sassert.js @@ -16,4 +16,4 @@ exports.ok = function(err,data){ exports.nok = function(err,data){ assert.instanceOf(err,SolrError); -} \ No newline at end of file +} diff --git a/test/search-test.js b/test/search-test.js index b87035d1..f95bbf31 100644 --- a/test/search-test.js +++ b/test/search-test.js @@ -10,7 +10,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#search("q=*:*")',function(){ @@ -35,4 +37,4 @@ describe('Client',function(){ }); }); }); -}); \ No newline at end of file +}); diff --git a/test/softCommit-test.js b/test/softCommit-test.js index c29f8a92..33046f57 100644 --- a/test/softCommit-test.js +++ b/test/softCommit-test.js @@ -10,14 +10,16 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var client = solr.createClient(); +var config = require('./config.json') || { client: {path: '/solr'}}; +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/') ; describe('Client',function(){ describe('#softCommit(callback)',function(){ it('should do a soft commit',function(done){ var request = client.softCommit(function(err,data){ sassert.ok(err,data); - assert.equal(request.path,'/solr/update/json?softCommit=true&wt=json'); + assert.equal(request.path, basePath + '/update/json?softCommit=true&wt=json'); done(); }); }); @@ -25,4 +27,4 @@ describe('Client',function(){ }); // Support -// http://wiki.apache.org/solr/UpdateXmlMessages?highlight=%28softCommit%29#A.22prepareCommit.22 \ No newline at end of file +// http://wiki.apache.org/solr/UpdateXmlMessages?highlight=%28softCommit%29#A.22prepareCommit.22 diff --git a/test/utils-test.js b/test/utils-test.js index 48bf7d56..f3dcfd87 100644 --- a/test/utils-test.js +++ b/test/utils-test.js @@ -30,4 +30,4 @@ describe('format',function(){ assert.equal(dateArrayISOify[0],date.toISOString()); }); }); -}); \ No newline at end of file +}); From f904146756b1e84eab1f2fb09aea4b7ff0a73708 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Thu, 17 Jul 2014 08:37:09 +0200 Subject: [PATCH 06/37] introducing the figc configurability and describing how to use it. Closes #85 --- README.md | 11 +++++++++-- test/add-test.js | 5 +++-- test/commit-test.js | 5 +++-- test/config.json | 2 +- test/createAddStream-test.js | 5 +++-- test/delete-test.js | 5 +++-- test/deleteAll-test.js | 5 +++-- test/deleteById-test.js | 5 +++-- test/deleteByQuery-test.js | 5 +++-- test/deleteByRange-test.js | 5 +++-- test/dismax-query-test.js | 5 +++-- test/facet-query-test.js | 5 +++-- test/optimize-test.js | 5 +++-- test/ping-test.js | 5 +++-- test/prepareCommit-test.js | 5 +++-- test/rollback-test.js | 5 +++-- test/search-test.js | 5 +++-- test/softCommit-test.js | 5 +++-- 18 files changed, 58 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 746cf851..1ca501f3 100644 --- a/README.md +++ b/README.md @@ -54,10 +54,17 @@ client.add({ id : 12, title_t : 'Hello' },function(err,obj){ ##Test -```js +``` npm test ``` - +### v0.3.x +Tests are executed against a running SOLR instance, so you might want to: +- install the schema.xml and solrconfig.xml expected by the tests. You find these in test/materials +- make sure your solr instance is running +- specifiy non-default connection params to your server in test/config.json You can inject these also on the command line through: +``` +mocha test/*-test.js --client.core=test-node-client --client.port=8080 +``` ## Test coverage Before to be able to run the command below, you will need to install jscoverage available here https://github.com/visionmedia/node-jscoverage. diff --git a/test/add-test.js b/test/add-test.js index 51e8ba21..896594ae 100644 --- a/test/add-test.js +++ b/test/add-test.js @@ -3,15 +3,16 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#add({ id : 1, title_t : "title"},callback)',function(){ diff --git a/test/commit-test.js b/test/commit-test.js index 2bfbd4de..2f937515 100644 --- a/test/commit-test.js +++ b/test/commit-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#commit(callback)',function(){ diff --git a/test/config.json b/test/config.json index fc9a0944..ef09d803 100644 --- a/test/config.json +++ b/test/config.json @@ -3,6 +3,6 @@ "host": "127.0.0.1", "port": 8983, "path": "/solr", - "core": "test-node-client" + "core": null } } diff --git a/test/createAddStream-test.js b/test/createAddStream-test.js index 42ae58e9..d94ae1a9 100644 --- a/test/createAddStream-test.js +++ b/test/createAddStream-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -11,9 +12,9 @@ var mocha = require('mocha'), Stream = require('stream'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#createAddStream()',function(){ diff --git a/test/delete-test.js b/test/delete-test.js index 1f1a8f06..f7035e31 100644 --- a/test/delete-test.js +++ b/test/delete-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#delete("title_t","test",callback)',function(){ diff --git a/test/deleteAll-test.js b/test/deleteAll-test.js index 27d6af8d..110c9cb7 100644 --- a/test/deleteAll-test.js +++ b/test/deleteAll-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#deleteAll(callback)',function(){ diff --git a/test/deleteById-test.js b/test/deleteById-test.js index 90741249..12bd2f28 100644 --- a/test/deleteById-test.js +++ b/test/deleteById-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#deleteByID(1,callback)',function(){ diff --git a/test/deleteByQuery-test.js b/test/deleteByQuery-test.js index 79e26a7f..b295d747 100644 --- a/test/deleteByQuery-test.js +++ b/test/deleteByQuery-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#deleteByQuery("title_t:*",callback)',function(){ diff --git a/test/deleteByRange-test.js b/test/deleteByRange-test.js index a80cfc3f..167eb5ab 100644 --- a/test/deleteByRange-test.js +++ b/test/deleteByRange-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#deleteByRange(field,start,stop,callback)',function(){ diff --git a/test/dismax-query-test.js b/test/dismax-query-test.js index 0c285aaf..522326d3 100644 --- a/test/dismax-query-test.js +++ b/test/dismax-query-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client#createQuery()',function(){ describe('.dismax().q("test")',function(){ diff --git a/test/facet-query-test.js b/test/facet-query-test.js index 39cc8fac..5fb73d93 100644 --- a/test/facet-query-test.js +++ b/test/facet-query-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -14,9 +15,9 @@ var mocha = require('mocha'), // and http://wiki.apache.org/solr/HierarchicalFaceting // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client#createQuery()',function(){ describe('.facet({field : "category_t"}).q({title_t : "test"})',function(){ diff --git a/test/optimize-test.js b/test/optimize-test.js index 598797d8..b4cc2302 100644 --- a/test/optimize-test.js +++ b/test/optimize-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#optimize(callback)',function(){ diff --git a/test/ping-test.js b/test/ping-test.js index 7bd55808..9a46699d 100644 --- a/test/ping-test.js +++ b/test/ping-test.js @@ -3,15 +3,16 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#ping(callback)',function(){ diff --git a/test/prepareCommit-test.js b/test/prepareCommit-test.js index 03ba08c0..e321d4da 100644 --- a/test/prepareCommit-test.js +++ b/test/prepareCommit-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#prepareCommit(callback)',function(){ diff --git a/test/rollback-test.js b/test/rollback-test.js index 0ab4d203..9952e9f9 100644 --- a/test/rollback-test.js +++ b/test/rollback-test.js @@ -3,15 +3,16 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#rollback(callback)',function(){ diff --git a/test/search-test.js b/test/search-test.js index f95bbf31..58ab8575 100644 --- a/test/search-test.js +++ b/test/search-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#search("q=*:*")',function(){ diff --git a/test/softCommit-test.js b/test/softCommit-test.js index 33046f57..f4c9e635 100644 --- a/test/softCommit-test.js +++ b/test/softCommit-test.js @@ -3,6 +3,7 @@ */ var mocha = require('mocha'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), @@ -10,9 +11,9 @@ var mocha = require('mocha'), sassert = require('./sassert'); // Test suite -var config = require('./config.json') || { client: {path: '/solr'}}; +var config = figc(__dirname + '/config.json'); var client = solr.createClient(config.client); -var basePath = [config.client.path, config.client.core].join('/') ; +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); describe('Client',function(){ describe('#softCommit(callback)',function(){ From 723ef87c28c1b8512038b8f9b6ef338186242bb6 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Thu, 17 Jul 2014 09:26:02 +0200 Subject: [PATCH 07/37] tabs/spaces - follow current code style --- test/add-test.js | 2 +- test/commit-test.js | 2 +- test/createAddStream-test.js | 2 +- test/delete-test.js | 2 +- test/deleteAll-test.js | 2 +- test/deleteById-test.js | 2 +- test/deleteByQuery-test.js | 2 +- test/deleteByRange-test.js | 2 +- test/dismax-query-test.js | 2 +- test/facet-query-test.js | 2 +- test/optimize-test.js | 2 +- test/ping-test.js | 2 +- test/prepareCommit-test.js | 2 +- test/rollback-test.js | 2 +- test/search-test.js | 2 +- test/softCommit-test.js | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/add-test.js b/test/add-test.js index 896594ae..c41c3fca 100644 --- a/test/add-test.js +++ b/test/add-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/commit-test.js b/test/commit-test.js index 2f937515..98c783e7 100644 --- a/test/commit-test.js +++ b/test/commit-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/createAddStream-test.js b/test/createAddStream-test.js index d94ae1a9..771add5a 100644 --- a/test/createAddStream-test.js +++ b/test/createAddStream-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/delete-test.js b/test/delete-test.js index f7035e31..50129a2e 100644 --- a/test/delete-test.js +++ b/test/delete-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/deleteAll-test.js b/test/deleteAll-test.js index 110c9cb7..9f82eb80 100644 --- a/test/deleteAll-test.js +++ b/test/deleteAll-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/deleteById-test.js b/test/deleteById-test.js index 12bd2f28..b9fa6924 100644 --- a/test/deleteById-test.js +++ b/test/deleteById-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/deleteByQuery-test.js b/test/deleteByQuery-test.js index b295d747..04672d24 100644 --- a/test/deleteByQuery-test.js +++ b/test/deleteByQuery-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/deleteByRange-test.js b/test/deleteByRange-test.js index 167eb5ab..e00cf590 100644 --- a/test/deleteByRange-test.js +++ b/test/deleteByRange-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/dismax-query-test.js b/test/dismax-query-test.js index 522326d3..378a12cf 100644 --- a/test/dismax-query-test.js +++ b/test/dismax-query-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/facet-query-test.js b/test/facet-query-test.js index 5fb73d93..85687c2e 100644 --- a/test/facet-query-test.js +++ b/test/facet-query-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/optimize-test.js b/test/optimize-test.js index b4cc2302..fb7f8589 100644 --- a/test/optimize-test.js +++ b/test/optimize-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/ping-test.js b/test/ping-test.js index 9a46699d..800647a5 100644 --- a/test/ping-test.js +++ b/test/ping-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/prepareCommit-test.js b/test/prepareCommit-test.js index e321d4da..459553f4 100644 --- a/test/prepareCommit-test.js +++ b/test/prepareCommit-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/rollback-test.js b/test/rollback-test.js index 9952e9f9..fb772b00 100644 --- a/test/rollback-test.js +++ b/test/rollback-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/search-test.js b/test/search-test.js index 58ab8575..7cb9260b 100644 --- a/test/search-test.js +++ b/test/search-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), diff --git a/test/softCommit-test.js b/test/softCommit-test.js index f4c9e635..96132050 100644 --- a/test/softCommit-test.js +++ b/test/softCommit-test.js @@ -3,7 +3,7 @@ */ var mocha = require('mocha'), - figc = require('figc'), + figc = require('figc'), assert = require('chai').assert, libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', solr = require( libPath + '/solr'), From 2a4f74cbca1647834081ca981a9970b66257a82a Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Thu, 17 Jul 2014 13:01:34 +0200 Subject: [PATCH 08/37] figc is only a dev-dependency --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 1fad84d3..b1ed3d27 100644 --- a/package.json +++ b/package.json @@ -18,15 +18,15 @@ "dependencies": { "JSONStream": "~0.7.1", "duplexer": "~0.1.1", - "request": "~2.33.0", - "figc": "0.0.3" + "request": "~2.33.0" }, "devDependencies": { "chai": "^1.9.1", "csv-stream": "^0.1.3", - "mocha": "^1.20.1" + "mocha": "^1.20.1", + "figc": "0.0.3" }, - "scripts": { + "scripts": "test": "./node_modules/mocha/bin/mocha -R spec test/*-test.js", "test-cov" : "jscoverage lib lib-cov && ./node_modules/mocha/bin/mocha -R html-cov test/*-test.js > coverage.html && rm -r lib-cov" } From a991d0d7e554d44b4d953c4d087bf13afc37fc38 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Thu, 17 Jul 2014 21:45:35 +0200 Subject: [PATCH 09/37] silly typeglitch - and urgent remind to self never to try and edit this kind of file through the github web interface ever again ;) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b1ed3d27..8fdb03aa 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "mocha": "^1.20.1", "figc": "0.0.3" }, - "scripts": + "scripts": { "test": "./node_modules/mocha/bin/mocha -R spec test/*-test.js", "test-cov" : "jscoverage lib lib-cov && ./node_modules/mocha/bin/mocha -R html-cov test/*-test.js > coverage.html && rm -r lib-cov" } From a2f764a9e7e08d8fdcbc48f4348a420c1183b530 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Fri, 18 Jul 2014 10:19:06 +0200 Subject: [PATCH 10/37] making the facet-test pass --> by picking a facet field (author) that exists in the schema and adding the extra returned data to compare --- test/facet-query-test.js | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/test/facet-query-test.js b/test/facet-query-test.js index fa32c0b6..3d1fffd9 100644 --- a/test/facet-query-test.js +++ b/test/facet-query-test.js @@ -26,7 +26,7 @@ describe('Client#createQuery()',function(){ var facetOptions = { "on": true , "query": "query" - , "field": "field" + , "field": "author" , "prefix": "prefix" , "sort": "field desc" , "limit": 100 @@ -62,6 +62,7 @@ describe('Client#createQuery()',function(){ .q({ title_t : 'test'}) .debugQuery(); client.search(query,function(err,data){ + console.log("\n\n--> client response\n err=%s\n data=%j\n", err, data); sassert.ok(err,data); assert.deepEqual(data.responseHeader.params, { @@ -69,8 +70,15 @@ describe('Client#createQuery()',function(){ wt: 'json', debugQuery: 'true', q: 'title_t:test', - 'facet.field': 'field' - /* Other response params here */ + "facet.field": 'author', + "facet.limit": "100", + "facet.method": "fc", + "facet.mincount": "10", + "facet.missing": "true", + "facet.offset": "5", + "facet.prefix": "prefix", + "facet.query": "query", + "facet.sort": "field\\ desc" } ); assert.equal(data.debug.QParser,'LuceneQParser'); @@ -83,7 +91,7 @@ describe('Client#createQuery()',function(){ var facetOptions = { "on": true , "query": "query" - , "field": "field" + , "field": "author" , "prefix": "prefix" , "sort": "field desc" , "limit": 100 @@ -126,8 +134,15 @@ describe('Client#createQuery()',function(){ wt: 'json', debugQuery: 'true', q: 'title_t:test', - 'facet.field': 'field' - /* Other response params here */ + "facet.field": 'author', + "facet.limit": "100", + "facet.method": "fc", + "facet.mincount": "10", + "facet.missing": "true", + "facet.offset": "5", + "facet.prefix": "prefix", + "facet.query": "query", + "facet.sort": "field\\ desc" } ); assert.equal(data.debug.QParser,'LuceneQParser'); From 7274bcfe310fdcc712e9c7a9e4ea6aeb07f1c614 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Fri, 18 Jul 2014 10:33:29 +0200 Subject: [PATCH 11/37] making the mlt test work --> by just adding the fields to the expected return --- test/mlt-query-test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/mlt-query-test.js b/test/mlt-query-test.js index de9789d8..0f02358c 100644 --- a/test/mlt-query-test.js +++ b/test/mlt-query-test.js @@ -52,7 +52,9 @@ describe('Client#createQuery',function(){ 'mlt.maxqt': '1500', wt: 'json', 'mlt.mindf': '0', - 'mlt.count': '15' + 'mlt.count': '15', + "debugQuery": "true", + q: "title_t:test" }); done(); }); From b926043b70f420063755fda390ebd36ba5f31f22 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Fri, 18 Jul 2014 10:56:06 +0200 Subject: [PATCH 12/37] remove logging statement --- test/facet-query-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/facet-query-test.js b/test/facet-query-test.js index 3d1fffd9..d5037db9 100644 --- a/test/facet-query-test.js +++ b/test/facet-query-test.js @@ -62,7 +62,6 @@ describe('Client#createQuery()',function(){ .q({ title_t : 'test'}) .debugQuery(); client.search(query,function(err,data){ - console.log("\n\n--> client response\n err=%s\n data=%j\n", err, data); sassert.ok(err,data); assert.deepEqual(data.responseHeader.params, { From 34bb8e45fa51fd3ecc4308d99bb8d8560121ab3c Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Fri, 18 Jul 2014 12:43:44 +0200 Subject: [PATCH 13/37] making the group test work --> by changing our expectations about the outcome --- test/group-query-test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/group-query-test.js b/test/group-query-test.js index be2a8975..6a2820d4 100644 --- a/test/group-query-test.js +++ b/test/group-query-test.js @@ -60,8 +60,7 @@ describe('Client#createQuery',function(){ assert.deepEqual(data.responseHeader.params, {'group.format':'simple','group.ngroups':'true','group.limit':'15','group.truncate':'true', 'group.field':'title_t','group.main':'true',group:'true','group.sort':'score desc', - 'group.cache.percent':'50','group.offset':'8',wt:'json', 'group.func': 'test', rows: '11', - 'start': '1', 'group.facet': 'true'}); + 'group.cache.percent':'50','group.offset':'8',wt:'json'}); done(); }); }); From 31f71e6d1c0d12b1ff61e8cc65cbf6e76eb89e51 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Fri, 18 Jul 2014 18:18:35 +0200 Subject: [PATCH 14/37] better no logging, and surely not before the sassert.ok --- test/group-query-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/group-query-test.js b/test/group-query-test.js index 6a2820d4..bb8413fa 100644 --- a/test/group-query-test.js +++ b/test/group-query-test.js @@ -55,7 +55,6 @@ describe('Client#createQuery',function(){ .group(options); client.search(query, function(err, data){ - console.log(JSON.stringify(data.responseHeader.params)+'\n'); sassert.ok(err, data); assert.deepEqual(data.responseHeader.params, {'group.format':'simple','group.ngroups':'true','group.limit':'15','group.truncate':'true', From bd088665e1f29427cf2a031ddd8ee7c9ad97e747 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Sat, 19 Jul 2014 15:29:34 +0200 Subject: [PATCH 15/37] Add support for deep-paging through cursorMarks as suggested in #89 --- lib/query.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/query.js b/lib/query.js index 2226bc9b..497ffa47 100644 --- a/lib/query.js +++ b/lib/query.js @@ -140,6 +140,23 @@ Query.prototype.rows = function(rows){ return self; } +/** + * Request to use cursorMarks for deep-paging as explained in http://heliosearch.org/solr/paging-and-deep-paging/ + * Note that usage of a cursor requires a sort containing a uniqueKey field tie breaker + * + * @param {String} mark - The mark to use, defaults to "*" to request a new cursor in the first request + * + * @return {Query} + * @api public + */ +Query.prototype.cursorMark = function(mark){ + var self = this; + mark = mark || "*"; + var parameter = 'cursorMark=' + mark ; + this.parameters.push(parameter); + return self; +} + /** * Sort a result in descending or ascending order based on one or more fields. * From 7bb0bc57692b54c4bbca59567e03e55aaf17e055 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Sat, 19 Jul 2014 16:27:51 +0200 Subject: [PATCH 16/37] adding tests for common features in order to fulfill the suggestions in #39 --- test/core-query-test.js | 187 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 186 insertions(+), 1 deletion(-) diff --git a/test/core-query-test.js b/test/core-query-test.js index 2bf6fcf9..9b63495d 100644 --- a/test/core-query-test.js +++ b/test/core-query-test.js @@ -1 +1,186 @@ -//TODO support http://wiki.apache.org/solr/CommonQueryParameters +// Testing support http://wiki.apache.org/solr/CommonQueryParameters +/** + * Modules dependencies + */ + +var mocha = require('mocha'), + figc = require('figc'), + assert = require('chai').assert, + libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', + solr = require( libPath + '/solr'), + sassert = require('./sassert'); + +// Test suite +var config = figc(__dirname + '/config.json'); +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); + +describe('Client#createQuery',function(){ + + describe('query() with various query options',function(){ + it('basic query with multiple fields',function(done){ + + var query = client.createQuery() + .q({"title": "name", "author" : "me"}).debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "title:name AND author:me" + , wt: 'json'}); + done(); + }); + }); + + it('query sorted',function(done){ + + var query = client.createQuery() + .q("*:*").sort({ "author":"asc", "category":"desc"}).debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", sort: "author asc,category desc" + , wt: 'json'}); + done(); + }); + }); + + it('query with paging',function(done){ + + var query = client.createQuery() + .q("*:*").start(21).rows(20).debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", start: "21", rows: "20" + , wt: 'json'}); + done(); + }); + }); + + it('query paged with cursorMark',function(done){ + + var query = client.createQuery() + .q("*:*").start(0).sort({"id": "asc"}).cursorMark().debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", start: "0", sort: "id asc", cursorMark: "*" + , wt: 'json'}); + done(); + }); + }); + + it('custom parameter setting - allows for any Filterquery(fq)',function(done){ + + var query = client.createQuery() + .q("*:*").set("fq=sqrt(id)").debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", fq: "sqrt(id)" + , wt: 'json'}); + done(); + }); + }); + + it('listing fields with fl',function(done){ + + var query = client.createQuery() + .q("*:*").fl(['id','title*', 'score']).debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", fl: "id,title*,score" + , wt: 'json'}); + done(); + }); + }); + + it('query with deftype',function(done){ + + var query = client.createQuery() + .q("*:*").defType("lucene").debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", defType: "lucene" + , wt: 'json'}); + done(); + }); + }); + + it('query with time-allowed',function(done){ + + var query = client.createQuery() + .q("*:*").timeout(1000).debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", timeAllowed: "1000" + , wt: 'json'}); + done(); + }); + }); + + it('q.op - Default query-operator',function(done){ + + var query = client.createQuery() + .q("author:ali remy marc").qop("OR").debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "author:ali remy marc", "q.op": "OR" + , wt: 'json'}); + done(); + }); + }); + + it('query with range-filter',function(done){ + + var query = client.createQuery() + .q("*:*").rangeFilter({field: 'id', start: 100, end: 200}).debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", fq:"id:[100 TO 200]" + , wt: 'json'}); + done(); + }); + }); + + it('query with match-filter',function(done){ + + var query = client.createQuery() + .q("*:*").matchFilter('id', "19700506.173.85").debugQuery(); + + client.search(query, function(err, data){ + sassert.ok(err, data); + assert.deepEqual(data.responseHeader.params, + { debugQuery: "true" + , q: "*:*", fq:"id:19700506.173.85" + , wt: 'json'}); + done(); + }); + }); + }); +}); From cd24531d746a5f62eb8ea8f0efb39be2ef875117 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Sun, 20 Jul 2014 08:32:20 +0200 Subject: [PATCH 17/37] Introducing real-time-get support as suggested in #88 First stab at it, including the test suggested in https://wiki.apache.org/solr/RealTimeGet --- lib/solr.js | 32 ++++++++++++++++++++ test/rt-get-test.js | 73 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 test/rt-get-test.js diff --git a/lib/solr.js b/lib/solr.js index f6ab9b27..f54b1aa0 100644 --- a/lib/solr.js +++ b/lib/solr.js @@ -75,6 +75,7 @@ function Client(options){ this.UPDATE_HANDLER = 'update'; this.SELECT_HANDLER = 'select'; this.ADMIN_PING_HANDLER = 'admin/ping'; + this.GET_HANDLER = 'get'; } /** @@ -129,6 +130,37 @@ Client.prototype.add = function(docs,options,callback){ return this.update(docs,options,callback); } +/** +/** + * Get a document by id or a list of documents using the Real-time-get feature in SOLR4 (https://wiki.apache.org/solr/RealTimeGet) + * + * @param {String|Array} ids - id or list of ids that identify the documents to get + * @param {Object} [options] - + * @param {Function} callback(err,obj) - a function executed when the Solr server responds or an error occurs + * @param {Error} callback().err + * @param {Object} callback().obj - JSON response sent by the Solr server deserialized + * + * @return {http.ClientRequest} + * @api public + */ + +Client.prototype.get = function(ids, options, callback){ + if(typeof(options) === 'function'){ + callback = options; + options = {}; + } + ids = Array.isArray(ids) ? ids : [ids]; + options.ids=ids.join(','); + + var qs = querystring.stringify(options); + this.options.fullPath = [this.options.path,this.options.core, this.GET_HANDLER + '?' + qs ] + .filter(function(element){ + return element; + }) + .join('/'); + return queryRequest(this.options,callback); +} + /** * Add the remote resource located at the given path `options.path` into the Solr database. * diff --git a/test/rt-get-test.js b/test/rt-get-test.js new file mode 100644 index 00000000..93f659a3 --- /dev/null +++ b/test/rt-get-test.js @@ -0,0 +1,73 @@ +// Testing support for Real-Time GET -- https://wiki.apache.org/solr/RealTimeGet +/** + * Modules dependencies + */ + +var mocha = require('mocha'), + figc = require('figc'), + assert = require('chai').assert, + libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', + solr = require( libPath + '/solr'), + sassert = require('./sassert'); + +// Test suite +var config = figc(__dirname + '/config.json'); +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); + +describe('Client',function(){ + describe('Real-time-get functionality',function(){ + var id = "RandomId-" + Math.floor(Math.random() * 1000000); + var title = "the title for " + id; + var doc = { id : id, title_t : title }; + + it('should add one document with a long period before committing',function(done){ + var options = { + commitWithin : 10000000 //extremely long, giving us plenty of time to test + }; + client.add(doc, options, function(err,data){ + sassert.ok(err,data); + done(); + }); + }); + + it('should not find that document in the index yet' ,function(done){ + var query = client.createQuery(); + query.matchFilter('id', id); + client.search(query,function(err,data){ + sassert.ok(err,data); + assert.equal(data.response.numFound, 0, "Added document should not be index and thus not found."); + done(); + }); + }); + + it('should be able to get that specific document',function(done){ + // note that by default the /get handler will have omitHeader=true configured on the server! + client.get(id,{omitHeader: false}, function(err,data){ + sassert.ok(err,data); + assert.equal(data.response.numFound, 1, "Added document should be retrieved in real-time get."); + var retrieved = data.response.docs[0]; + console.log("\nretrieved ==> %j\n", retrieved); + assert.equal(retrieved.id, id, "Didn't retrieve the expected document."); + assert.equal(retrieved.title_t, title, "Didn't retrieve the expected document."); + done(); + }); + }); + + it('should be able to delete it',function(done){ + client.deleteByID(id,function(err,data){ + sassert.ok(err,data); + done(); + }); + }); + + it('should no longer be able to get that specific document',function(done){ + client.get(id,{omitHeader: false}, function(err,data){ + sassert.ok(err,data); + assert.equal(data.response.numFound, 0, "Deleted document should no longer be retrievable in real-time get."); + done(); + }); + }); + + }); +}); From ce7e3b7d7832533c1fe77bf6b729e722fe0df626 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Sun, 20 Jul 2014 12:02:30 +0200 Subject: [PATCH 18/37] remove the debug statement to make for silent testing --- test/rt-get-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/rt-get-test.js b/test/rt-get-test.js index 93f659a3..f9b98b5d 100644 --- a/test/rt-get-test.js +++ b/test/rt-get-test.js @@ -47,7 +47,6 @@ describe('Client',function(){ sassert.ok(err,data); assert.equal(data.response.numFound, 1, "Added document should be retrieved in real-time get."); var retrieved = data.response.docs[0]; - console.log("\nretrieved ==> %j\n", retrieved); assert.equal(retrieved.id, id, "Didn't retrieve the expected document."); assert.equal(retrieved.title_t, title, "Didn't retrieve the expected document."); done(); From fbc322d963feac6d2c403980c33361467e5a6f71 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Sun, 20 Jul 2014 14:04:20 +0200 Subject: [PATCH 19/37] Alternative implementation for the #83 suggestion. Making it not-conflicting with the #88 implementation by renaming get --> handleGet() Adding the handlePost to complete the use-case behind this Not returning self but rather the request since that seems the standard pattern in v0.3.x --- lib/solr.js | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/solr.js b/lib/solr.js index 8b58f15f..6398a52d 100644 --- a/lib/solr.js +++ b/lib/solr.js @@ -539,7 +539,7 @@ Client.prototype.spell = function(query,callback){ /** * Make an arbitraty get request to Solr * - * @param {Path|String} Path + * @param {Path|String} handlerPath * @param {Query|String} query * @param {Function} callback(err,obj) - a function executed when the Solr server responds or an error occurs * @param {Error} callback().err @@ -549,18 +549,45 @@ Client.prototype.spell = function(query,callback){ * @api public */ -Client.prototype.get = function(path,query,callback){ +Client.prototype.handleGet = function(handlerPath,query,callback){ var self = this; - // Allow to be more flexible allow query to be a string and not only a Query object var parameters = query.build ? query.build() : query; - this.options.fullPath = [this.options.path,this.options.core,path + '?' + parameters + '&wt=json'] + this.options.fullPath = [this.options.path,this.options.core,handlerPath + '?' + parameters + '&wt=json'] .filter(function(element){ if(element) return true; return false; }) .join('/'); ; - queryRequest(this.options,callback); - return self; + return queryRequest(this.options,callback); +} + +/** + * Make an arbitraty post request to Solr + * + * @param {Path|String} handlerPath + * @param {Query|String} query + * @param {Function} callback(err,obj) - a function executed when the Solr server responds or an error occurs + * @param {Error} callback().err + * @param {Object} callback().obj - JSON response sent by the Solr server deserialized + * + * @return {Client} + * @api public + */ + +Client.prototype.handlePost = function(handlerPath,data,options,callback){ + var self = this; + if(typeof(options) === 'function'){ + callback = options; + options = {}; + } + this.options.json = JSON.stringify(data); + this.options.fullPath = [this.options.path,this.options.core,handlerPath + '?' + parameters + '&wt=json'] + .filter(function(element){ + if(element) return true; + return false; + }) + .join('/'); ; + return updateRequest(this.options,callback); } /** From 4946e469b368164a015ba14a3a1c6f3ab2fa502e Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Sun, 20 Jul 2014 15:14:20 +0200 Subject: [PATCH 20/37] adding tests for generic handleGet and handlePost --- lib/solr.js | 3 ++- test/handlePath-test.js | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/handlePath-test.js diff --git a/lib/solr.js b/lib/solr.js index 6398a52d..f23be8b9 100644 --- a/lib/solr.js +++ b/lib/solr.js @@ -581,7 +581,8 @@ Client.prototype.handlePost = function(handlerPath,data,options,callback){ options = {}; } this.options.json = JSON.stringify(data); - this.options.fullPath = [this.options.path,this.options.core,handlerPath + '?' + parameters + '&wt=json'] + + this.options.fullPath = [this.options.path,this.options.core,handlerPath + '?' + querystring.stringify(options) +'&wt=json'] .filter(function(element){ if(element) return true; return false; diff --git a/test/handlePath-test.js b/test/handlePath-test.js new file mode 100644 index 00000000..73b91320 --- /dev/null +++ b/test/handlePath-test.js @@ -0,0 +1,47 @@ +// Testing support for arbitrary handler-paths configured on solr +/** + * Modules dependencies + */ + +var mocha = require('mocha'), + figc = require('figc'), + assert = require('chai').assert, + libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', + solr = require( libPath + '/solr'), + sassert = require('./sassert'); + +// Test suite +var config = figc(__dirname + '/config.json'); +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); + +describe('Client',function(){ + describe('Arbitrary HandlePath Support',function(){ + it('should add documents over the arbitrary handlePost',function(done){ + var docs = [ + { + id : 4, + title_t : 'title4' + }, + { + id : 5, + title_t : 'title5' + } + ]; + var request = client.handlePost(client.UPDATE_JSON_HANDLER,docs,function(err,data){ + assert.equal(request.path, basePath + '/update/json?&wt=json'); + sassert.ok(err,data); + done(); + }); + }); + + it('should find documents over the generic handleGet',function(done){ + var request = client.handleGet(client.SELECT_HANDLER,'q=*:*',function(err,data){ + assert.equal(request.path, basePath + '/select?q=*:*&wt=json'); + sassert.ok(err,data); + assert.deepEqual({ q : '*:*' , wt: 'json' },data.responseHeader.params); + done(); + }); + }); + }); +}); From 94e6d42313ab4c13db25255012c8c7f9b5200ef5 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Mon, 21 Jul 2014 12:32:52 +0200 Subject: [PATCH 21/37] add test to not leave lingering docs --- test/handlePath-test.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/test/handlePath-test.js b/test/handlePath-test.js index 73b91320..1eaee3fe 100644 --- a/test/handlePath-test.js +++ b/test/handlePath-test.js @@ -17,14 +17,15 @@ var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/, describe('Client',function(){ describe('Arbitrary HandlePath Support',function(){ + var idpfx = Math.floor(Math.random() * 1000000); it('should add documents over the arbitrary handlePost',function(done){ var docs = [ { - id : 4, + id : idpfx + "-1", title_t : 'title4' }, { - id : 5, + id : idpfx + "-2", title_t : 'title5' } ]; @@ -43,5 +44,15 @@ describe('Client',function(){ done(); }); }); + + it('should delete all documents over the generic handlePost',function(done){ + var cmd = { "delete": {"query": "*:*"}}; + var request = client.handlePost(client.UPDATE_HANDLER,cmd,function(err,data){ + assert.equal(request.path, basePath + '/update?&wt=json'); + sassert.ok(err,data); + done(); + }); + }); + }); }); From a29205c7cc8593d84c8bb1578c4d6252f85163b2 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Mon, 21 Jul 2014 18:36:59 +0200 Subject: [PATCH 22/37] let's name this version correctly --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4e27817e..345dc2c4 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "name": "solr-client", "main": "./main", "description": " A Solr client library for indexing, adding, deleting, committing, optimizing and searching documents within an Apache Solr installation (version>=3.2)", - "version": "0.2.9", + "version": "0.3.0", "repository": { "type": "git", "url": "https://github.com/lbdremy/solr-node-client" From 1ad313fb20bba8c3871a6fd444bfaf466630cca4 Mon Sep 17 00:00:00 2001 From: Marc Portier Date: Tue, 5 Aug 2014 09:12:01 +0200 Subject: [PATCH 23/37] first stab at uploading files into the extractor-index, including tests and test-files to use --- lib/solr.js | 111 +++++++++++++++++++++++++++++++- package.json | 3 +- test/extract-test.js | 37 +++++++++++ test/materials/extract/doc.docx | Bin 0 -> 3920 bytes test/materials/extract/doc.html | 5 ++ test/materials/extract/doc.ods | Bin 0 -> 17132 bytes test/materials/extract/doc.odt | Bin 0 -> 11564 bytes test/materials/extract/doc.pdf | Bin 0 -> 12456 bytes test/materials/extract/doc.txt | 1 + test/materials/extract/doc.xlsx | Bin 0 -> 4671 bytes 10 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 test/extract-test.js create mode 100644 test/materials/extract/doc.docx create mode 100644 test/materials/extract/doc.html create mode 100644 test/materials/extract/doc.ods create mode 100644 test/materials/extract/doc.odt create mode 100644 test/materials/extract/doc.pdf create mode 100644 test/materials/extract/doc.txt create mode 100644 test/materials/extract/doc.xlsx diff --git a/lib/solr.js b/lib/solr.js index 64ccb4c3..5423d744 100644 --- a/lib/solr.js +++ b/lib/solr.js @@ -17,7 +17,8 @@ var http = require('http'), SolrError = require('./error/solr-error'), JSONStream = require('JSONStream'), duplexer = require('duplexer'), - request = require('request'); + request = require('request'), + FormData = require('form-data'); /** * Expose `createClient()`. @@ -78,6 +79,7 @@ function Client(options){ this.ADMIN_PING_HANDLER = 'admin/ping'; this.GET_HANDLER = 'get'; this.SPELL_HANDLER = 'spell'; + this.EXTRACT_HANDLER = 'update/extract'; } /** @@ -132,6 +134,41 @@ Client.prototype.add = function(docs,options,callback){ return this.update(docs,options,callback); } +/** + * Add a File's contents to the Solr index through the built-in extraction feature. + * Solr will use the Apache Tika library to extract the contents from the uploads. + * See http://wiki.apache.org/solr/ExtractingRequestHandler. + * + * @param {String} path - path and filename of the file to add to the Solr index + * @param {Object} [fields] - literal fields to add to the index-entry e.g. fields['id'] + * @param {Object} [options] - additional (optional) options to add e.g. options['fmap.content'] + * @param {Function} callback(err,obj) - a function executed when the Solr server responds or an error occurs + * @param {Error} callback().err + * @param {Object} callback().obj - JSON response sent by the Solr server deserialized + * + * @return {http.ClientRequest} + * @api public + */ + +Client.prototype.addFileContents = function(path,fields,options,callback){ + if(typeof(options) === 'function'){ + callback = options; + options = {}; + } + Object.keys(fields).forEach(function(key) { + options['literal.'+key] = fields[key]; + }); + + this.options.file = path; + this.options.fullPath = [this.options.path,this.options.core, this.EXTRACT_HANDLER + '?' + querystring.stringify(options) +'&wt=json'] + .filter(function(element){ + return element; + }) + .join('/'); + + return extractRequest(this.options,callback); +} + /** * Get a document by id or a list of documents by ids using the Real-time-get feature * in SOLR4 (https://wiki.apache.org/solr/RealTimeGet) @@ -656,6 +693,78 @@ var updateRequest = function(params,callback){ return request; } +/** + * HTTP POST request with multipart/form-data for file upload to the Solr ExttractionHandler. + * + * @param {Object} params + * @param {String} params.host - IP address or host address of the Solr server + * @param {Number|String} params.port - port of the Solr server + * @param {String} params.core - name of the Solr core requested + * @param {String} params.authorization - value of the authorization header + * @param {String} params.fullPath - full path of the request + * @param {String} params.file - path to the file to upload + * @param {Function} callback(err,obj) - a function executed when the Solr server responds or an error occurs + * @param {Error} callback().err + * @param {Object} callback().obj - JSON response sent by the Solr server deserialized + * + * @return {http.ClientRequest} + * @api private + */ + +var extractRequest = function(params,callback){ + var form = new FormData(); + + form.append('my_file', fs.createReadStream(params.file)); + var headers = form.getHeaders(); + + if(params.authorization){ + headers['authorization'] = params.authorization; + } + var options = { + host : params.host, + port : params.port, + method : 'POST', + headers : headers, + path : params.fullPath + }; + + if(params.agent !== undefined){ + options.agent = params.agent; + } + + var callbackResponse = function(res){ + var buffer = ''; + var err = null; + res.on('data',function(chunk){ + buffer += chunk; + }); + + res.on('end',function(){ + if(res.statusCode !== 200){ + err = new SolrError(res.statusCode,buffer); + if (callback) callback(err,null); + }else{ + try{ + var data = JSON.parse(buffer); + }catch(error){ + err = error; + }finally{ + if (callback) callback(err,data); + } + } + }); + } + + var request = http.request(options,callbackResponse); + form.pipe(request); + + request.on('error',function(err){ + if (callback) callback(err,null); + }); + + return request; +} + /** * HTTP GET request. Send a query command to the Solr server (query) * diff --git a/package.json b/package.json index 345dc2c4..e0d58555 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dependencies": { "JSONStream": "~0.7.1", "duplexer": "~0.1.1", + "form-data": "~0.1.4", "request": "~2.33.0" }, "devDependencies": { @@ -28,6 +29,6 @@ }, "scripts": { "test": "./node_modules/mocha/bin/mocha -R spec test/*-test.js", - "test-cov" : "jscoverage lib lib-cov && ./node_modules/mocha/bin/mocha -R html-cov test/*-test.js > coverage.html && rm -r lib-cov" + "test-cov": "jscoverage lib lib-cov && ./node_modules/mocha/bin/mocha -R html-cov test/*-test.js > coverage.html && rm -r lib-cov" } } diff --git a/test/extract-test.js b/test/extract-test.js new file mode 100644 index 00000000..48be0866 --- /dev/null +++ b/test/extract-test.js @@ -0,0 +1,37 @@ +// Testing support for Extracting -- http://wiki.apache.org/solr/ExtractingRequestHandler +/** + * Modules dependencies + */ + +var mocha = require('mocha'), + figc = require('figc'), + assert = require('chai').assert, + libPath = process.env['SOLR_CLIENT_COV'] ? '../lib-cov' : '../lib', + solr = require( libPath + '/solr'), + sassert = require('./sassert') + fs = require('fs'); + +// Test suite +var config = figc(__dirname + '/config.json'); +var client = solr.createClient(config.client); +var basePath = [config.client.path, config.client.core].join('/').replace(/\/$/,""); + +var contentPath = __dirname + '/materials/extract'; + +describe('Client',function(){ + describe('Extract functionality loading various files',function(){ + var options = {}; + var files = fs.readdirSync(contentPath); + + files.forEach(function(file, i) { + it('should load & extract this test-document',function(done){ + var fields = {}; + fields.id = "TEST-EXTRACT-" + file + client.addFileContents(contentPath + '/' + file, fields, options, function(err,data){ + sassert.ok(err,data); + done(); + }); + }); + }); + }); +}); diff --git a/test/materials/extract/doc.docx b/test/materials/extract/doc.docx new file mode 100644 index 0000000000000000000000000000000000000000..8e979fa784122be5f840808171b6118c402e63c3 GIT binary patch literal 3920 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 Kw`QM_^6P*55kt`c literal 0 HcmV?d00001 diff --git a/test/materials/extract/doc.html b/test/materials/extract/doc.html new file mode 100644 index 00000000..2641845f --- /dev/null +++ b/test/materials/extract/doc.html @@ -0,0 +1,5 @@ + + +

This is just a html-file to be uploaded into the Solr index during test.

+ + diff --git a/test/materials/extract/doc.ods b/test/materials/extract/doc.ods new file mode 100644 index 0000000000000000000000000000000000000000..de45f904195e4dc4ddb2881862d0739f12145a2c GIT binary patch literal 17132 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 literal 0 HcmV?d00001 diff --git a/test/materials/extract/doc.odt b/test/materials/extract/doc.odt new file mode 100644 index 0000000000000000000000000000000000000000..cd4db3b7589481e97f1d181fc63e926a6cef433f GIT binary patch literal 11564 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 VycE>ym)lUEKY(Zc$)$WL{RgOdM-u=5 literal 0 HcmV?d00001 diff --git a/test/materials/extract/doc.pdf b/test/materials/extract/doc.pdf new file mode 100644 index 0000000000000000000000000000000000000000..69683fbe3e49c46a730900d5a4d22bded0c187a7 GIT binary patch literal 12456 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

T)Ik!+gF09

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 literal 0 HcmV?d00001 diff --git a/test/materials/extract/doc.txt b/test/materials/extract/doc.txt new file mode 100644 index 00000000..e65e623e --- /dev/null +++ b/test/materials/extract/doc.txt @@ -0,0 +1 @@ +This is just a text-file to be uploaded into the Solr index during test. diff --git a/test/materials/extract/doc.xlsx b/test/materials/extract/doc.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1db314ee5fa15e45a3015a13e24c4ce5b1ab34c9 GIT binary patch literal 4671 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 Date: Tue, 5 Aug 2014 09:34:14 +0200 Subject: [PATCH 24/37] These jar files to include have dropped the apache- prefix in their name (some version between 3.3 and 4.9) So making that optional to include! --- test/materials/solrconfig.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/materials/solrconfig.xml b/test/materials/solrconfig.xml index ea25197d..4a9ec468 100644 --- a/test/materials/solrconfig.xml +++ b/test/materials/solrconfig.xml @@ -70,16 +70,16 @@ with their external dependencies. --> - + - + - + - +