-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add initial implementation #3
Changes from 8 commits
9681a81
9d27a83
476f810
c857f21
e844e6c
cc38b8f
1814d4e
e5be062
824c2f5
99da1be
dfbf7cb
a75dc94
54ea997
d5ee103
0e0fadd
e664deb
5b32e88
ea48a9b
39dad7e
33c9f5e
91bce54
b57de47
7b628b2
9de4f7b
632f79d
8dc65c7
088ced4
5b1b7f3
ddc43d8
3a22f42
670abb9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,14 +50,13 @@ | |
|
||
#### paginator.page | ||
|
||
This is a [getter][mdn-defineproperty] property. | ||
|
||
[mdn-defineproperty]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty | ||
This is a property is read-only. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Github hid it. Grammarize this. |
||
|
||
```javascript | ||
let paginator = new BasePaginator(request); | ||
// True | ||
|
||
paginator.page === 0; | ||
// -> true | ||
``` | ||
|
||
#### paginator.queryHandler | ||
|
@@ -192,10 +191,10 @@ promise.then((mergedResponse) => { | |
```javascript | ||
let error = new PaginatorError('Something went wrong.'); | ||
|
||
// True | ||
error instanceof PaginatorError; | ||
// True | ||
// -> true | ||
error instanceof Error; | ||
// -> true | ||
``` | ||
|
||
## Paginators | ||
|
@@ -226,8 +225,9 @@ new PageNumberPaginator(request[, requestOptions, queryParams]); | |
```javascript | ||
let queryParams = { page: 2 }; | ||
let paginator = new PageNumberPaginator(request, null, queryParams); | ||
// True | ||
|
||
paginator.page === 2; | ||
// -> true | ||
``` | ||
|
||
### LimitOffsetPaginator | ||
|
@@ -241,8 +241,9 @@ new LimitOffsetPaginator(request[, requestOptions, queryParams]); | |
```javascript | ||
let queryParams = { limit: 50, offset: 50 }; | ||
let paginator = new LimitOffsetPaginator(request, null, queryParams); | ||
// True | ||
|
||
paginator.page === 2; | ||
// -> true | ||
``` | ||
|
||
## Query Handlers | ||
|
@@ -275,8 +276,8 @@ _Example:_ | |
let options = { pageQueryParam: 'p' }; | ||
let queryHandler = new PageNumberQueryHandler(options); | ||
let queryParams = queryHandler.makeParams(42); | ||
// True | ||
queryParams.p === 42; | ||
// -> true | ||
``` | ||
|
||
[drf-page-number-config]: http://www.django-rest-framework.org/api-guide/pagination/#configuration | ||
|
@@ -320,10 +321,11 @@ let queryHandler = new LimitOffsetQueryHandler(options); | |
queryHandler.setParams({ l: 50 }); | ||
|
||
let queryParams = queryHandler.makeParams(3); | ||
// True | ||
|
||
queryParams.l === 50; | ||
// True | ||
queryParams.o === 100; | ||
// -> true | ||
queryParams.o === 100 | ||
// -> true; | ||
``` | ||
|
||
## Utility | ||
|
@@ -373,7 +375,7 @@ import querystring from 'querystring'; | |
let request = function(options, queryParams) { | ||
let {user} = options; | ||
let query = querystring.stringify(queryParams); | ||
let url = `https://example.com/users/${user/}?${query}`; | ||
let url = `https://example.com/users/${user}?${query}`; | ||
|
||
return fetch(url) | ||
.then((response) => response.json()); | ||
|
@@ -399,37 +401,37 @@ import {requests} from 'user-image-service'; | |
/** | ||
* Create a paginator for the endpoint using an existing request function | ||
*/ | ||
const userPhotoUrls = new drfp.LimitOffsetPaginator( | ||
requests.fetchPhotoUrls, | ||
const userImageUrls = new drfp.LimitOffsetPaginator( | ||
requests.fetchImageUrls, | ||
{ user: 'abc123' }, | ||
{ limit: 20 } | ||
); | ||
|
||
/** | ||
* Create a request function that retrieves and merges ten pages of results | ||
*/ | ||
const batchFetchPhotoUrls = function(options, queryParams) { | ||
const batchFetchImageUrls = function(options, queryParams) { | ||
const {page} = queryParams; | ||
const startPage = page * 10 - 9; | ||
const endPage = page * 10; | ||
const pageMerger = new drfp.PageMerger(userPhotoUrls); | ||
const pageMerger = new drfp.PageMerger(userImageUrls); | ||
|
||
return pageMerger.merge(startPage, endPage); | ||
}; | ||
|
||
/** | ||
* Create a paginator for the new request function | ||
* Create a paginator for the batch request function | ||
*/ | ||
let batchUserPhotoUrls = drfp.paginate(batchFetchPhotoUrls); | ||
const batchUserImageUrls = drfp.paginate(batchFetchImageUrls); | ||
|
||
const displayNextImages = function() { | ||
return batchUserPhotoUrls.next() | ||
.then(displayPhotos) | ||
return batchUserImageUrls.next() | ||
.then(displayImages) | ||
.catch(displayError); | ||
}; | ||
|
||
/** | ||
* Display the first page of 200 images | ||
* Display the first page of 200 Images | ||
*/ | ||
showNextImages(); | ||
displayNextImages(); | ||
``` |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,10 +7,11 @@ | |
"license": "MIT", | ||
"main": "src/index.js", | ||
"scripts": { | ||
"cover": "rm -rf coverage && babel-node node_modules/.bin/isparta cover --root src/ --report text --report lcov --report html node_modules/.bin/_mocha -- src/test-setup.js $(find src -name '*-spec.js')", | ||
"coveralls": "cat coverage/lcov.info | coveralls", | ||
"jshint": "jshint src", | ||
"test": "karma start karma.unit.conf.js && jshint src", | ||
"unit": "karma start karma.unit.conf.js" | ||
"test": "npm run cover && npm run jshint", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we want linting to break tests. Snitch does that for us, and because linting errors are often stylelistic, they shouldn't affect tests. Do you agree? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remember @thomasw saying we ought to, but didn't find a comment after some searching. It is ran in SBUI though. |
||
"unit": "babel-node node_modules/.bin/_mocha --require src/test-setup.js --recursive src" | ||
}, | ||
"keywords": [ | ||
"django", | ||
|
@@ -28,46 +29,37 @@ | |
"url": "https://github.com/yola/drf-paginator/issues" | ||
}, | ||
"dependencies": { | ||
"babel-preset-es2015": "~6.6.0", | ||
"lodash.assign": "~4.0.6", | ||
"lodash.clonedeep": "~4.3.2", | ||
"lodash.omit": "~4.1.0", | ||
"lodash.reduce": "~4.3.0" | ||
}, | ||
"devDependencies": { | ||
"babel-preset-es2015": "~6.6.0", | ||
"babelify": "~7.2.0", | ||
"app-module-path": "~1.0.6", | ||
"babel-cli": "~6.7.5", | ||
"bluebird": "~3.3.4", | ||
"browserify": "~13.0.0", | ||
"chai": "~3.5.0", | ||
"chai-as-promised": "~5.3.0", | ||
"coveralls": "~2.11.9", | ||
"isparta": "~4.0.0", | ||
"jsgreat": "~0.1.8", | ||
"jshint": "~2.9.1", | ||
"karma": "~0.13.22", | ||
"karma-browserify": "~5.0.3", | ||
"karma-coverage": "~0.5.5", | ||
"karma-mocha": "~0.2.2", | ||
"karma-phantomjs-launcher": "~1.0.0", | ||
"karma-spec-reporter": "0.0.24", | ||
"mocha": "~2.4.5", | ||
"phantomjs-prebuilt": "~2.1.6", | ||
"sinon": "~1.17.3", | ||
"sinon-chai": "~2.8.0", | ||
"watchify": "~3.7.0" | ||
"sinon-chai": "~2.8.0" | ||
}, | ||
"babel": { | ||
"presets": [ | ||
"es2015" | ||
] | ||
}, | ||
"browserify": { | ||
"paths": [ | ||
"." | ||
], | ||
"transform": [ | ||
[ | ||
"babelify", | ||
{ | ||
"presets": [ | ||
"es2015" | ||
] | ||
} | ||
] | ||
"babelify" | ||
] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import chai from 'chai'; | ||
|
||
import actions from 'src/actions'; | ||
|
||
|
||
const {expect} = chai; | ||
|
||
describe('drf-paginator', function() { | ||
const response = { | ||
count: 0, | ||
results: [] | ||
}; | ||
|
||
describe('actions', function() { | ||
it('should export inferResponseLimit', function() { | ||
expect(actions.inferResponseLimit).to.exist; | ||
}); | ||
|
||
it('should export parseResponse', function() { | ||
expect(actions.parseResponse).to.exist; | ||
}); | ||
|
||
describe('inferResponseLimit', function() { | ||
it('returns NULL when it can\'t determine the limit', function() { | ||
const result = actions.inferResponseLimit(response); | ||
|
||
expect(result).to.be.null; | ||
}); | ||
}); | ||
|
||
describe('parseResponse', function() { | ||
it('parses responses', function() { | ||
const result = actions.parseResponse(response); | ||
|
||
const expectedResult = { | ||
count: 0, | ||
limit: null, | ||
pageCount: 1, | ||
results: response.results | ||
}; | ||
|
||
expect(result).to.eql(expectedResult); | ||
}); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
export const inferResponseLimit = function(data) { | ||
const count = data.count; | ||
const resultCount = data.results.length; | ||
export const inferResponseLimit = function(response) { | ||
const count = response.count; | ||
const resultCount = response.results.length; | ||
|
||
if (count > resultCount) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's a scenario where this is true, and why would that arise? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When a query has multiple pages, that expression will always be true for the first page response. |
||
return resultCount; | ||
|
@@ -9,9 +9,9 @@ export const inferResponseLimit = function(data) { | |
return null; | ||
}; | ||
|
||
export const parseResponse = function(data) { | ||
const {count, results} = data; | ||
const limit = inferResponseLimit(data); | ||
export const parseResponse = function(response) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious why this is called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I called it parse since it's only pulling out the properties of the response it cares about, and creating a new object. However, I do see where you're coming from. The function is really only calculating the |
||
const {count, results} = response; | ||
const limit = inferResponseLimit(response); | ||
let pageCount = 1; | ||
|
||
if (count && limit) { | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,18 @@ | ||
import assign from 'lodash.assign'; | ||
import sinon from 'sinon'; | ||
|
||
import limitOffsetResponse from 'src/fixtures/limit-offset-response.json'; | ||
import pageNumberResponse from 'src/fixtures/page-number-response.json'; | ||
|
||
|
||
export const request = function(options, queryParams) { | ||
const uniqueValue = Math.random(); | ||
let fixture; | ||
|
||
if (queryParams.hasOwnProperty('page')) { | ||
fixture = pageNumberResponse; | ||
} else { | ||
fixture = limitOffsetResponse; | ||
} | ||
|
||
const response = assign({}, fixture, { uniqueValue }); | ||
const response = assign({}, pageNumberResponse, { uniqueValue }); | ||
|
||
return Promise.resolve(response); | ||
}; | ||
|
||
export const spy = sinon.spy(request); | ||
|
||
export const getArgs = function() { | ||
const args = spy.args; | ||
return args[args.length - 1]; | ||
}; | ||
|
||
export const getCallCount = function() { | ||
return spy.callCount; | ||
}; | ||
|
||
export const getOptions = function() { | ||
return getArgs()[0]; | ||
}; | ||
|
||
export const getQueryParams = function() { | ||
return getArgs()[1]; | ||
}; | ||
|
||
export const getOffset = function() { | ||
return getQueryParams().offset; | ||
}; | ||
|
||
export const getPage = function() { | ||
return getQueryParams().page; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,13 +51,15 @@ export class BasePaginator { | |
return this._getRequest(page) | ||
.then(cloneDeep); | ||
} | ||
|
||
if (!this._isValidPage(page)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. linebreak |
||
return this._rejectPage(page); | ||
} | ||
|
||
const handleResponse = (response) => { | ||
return this._handleResponse(response, page); | ||
}; | ||
|
||
const request = this._sendRequest(page) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. linebreak |
||
.then(handleResponse); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
import appModulePath from 'app-module-path'; | ||
import bluebird from 'bluebird'; | ||
|
||
|
||
window.Promise = bluebird; | ||
appModulePath.addPath(__dirname + '/..'); | ||
global.Promise = bluebird; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grammarize