-
Notifications
You must be signed in to change notification settings - Fork 21
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
Fix repeated value #184
Fix repeated value #184
Conversation
The largest size was being repeated in certain conditions, since the value stored in `prev` was exact (possibly fractional) while the number saved in the list of resolutions is rounded to an even number, but the value stored in `prev` was the one being compared to `maxWidth`. In this fix we remove the code which pushes `maxWidth` to the list *after* the loop finishes and compare the last value in the list to `maxWidth` rather than the running exact fractional width value. These together eliminate the areas where the bug can subtly appear. It is then necessary to refactor the loop, by initializing the list to already contain the `minWidth` and then exiting early if `maxWidth` is equal (which has the side benefit that the cache won't be polluted with trivial cases) and then in the loop body push the *new* rather than previous value to the list, after rounding and clamping.
76eac04
to
cd43727
Compare
Thanks for the PR @tremby! Overall I think this is a good fix and should be merged. But it also made me wonder how often something like |
The 0.0999 isn't really the point; the point is that a bug exists and is possible to hit and this is a fix for it. It doesn't make the code any more complicated. I'd strongly argue that it's more readable too. The bug was hiding in two subtle spots, and in my opinion I've eliminated those. (I discussed it in the commit message.) The bug could also rear its head if there are simply a lot of steps -- this module is multiplying repeatedly by a floating-point number after all. |
Agreed there, but I was more so trying to understand if you had discovered this out of an actual use case. To be clear, I'm not saying this PR should be changed but I am thinking out loud about if having more guardrails could help prevent potential issues for users. |
I discovered that "class" of bug when punching in what in my opinion are
some very realistic values for min and max width to show the before/after
example for my other PR. In the new code, right away I found that the
response had a repeated value. That made me scrutinize the code to fix it,
and also made me wonder whether the bug existed in the old code. The bug
didn't exist for the exact same set of inputs on the old code but I very
quickly did find a failing case. Not a realistic one, to be fair, but I
think proof of *a* failing case is enough for a fix, in lieu of proof that
it can't possibly happen in any real-world realistic use case.
That second breaking case is what I added to the tests here in this PR, and
then I added the failing case I originally found as part of the other PR,
and added it to the same test.
I think it's very possible this could happen in real life, especially given
how small the default tolerance is, and therefore how many times it gets
multiplied. If you want me to, I'll write some code to brute-force find a
realistic breaking case, but I don't know why you'd require that!
|
Nope, definitely don't want that! 🙂 |
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.
Hey @tremby 👋 thanks for opening this PR!
src/imgix-core-js.js
Outdated
while (prev < maxWidth) { | ||
resolutions.push(ensureEven(prev)); | ||
prev *= 1 + (INCREMENT_PERCENTAGE * 2); | ||
var exact = minWidth; |
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.
Nit: I think the naming here could be more exact
(ha!). Okay puns/jokes aside, I think the old variable prev
wasn't as descriptive as it could've been, but now since the logic's changed a bit I think exact
could be nextWidth
?
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.
nextWidth
isn't really what it means, though. This variable is the non-rounded non-evened running value; the exact width currently under consideration. It's used both in the context of what to round for the "next"/"current" width to add to the array and then in the next loop as the "previous" one's more-exact value for scaling up for the next candidate. IMO exact
is closer than anything mentioning "next" or "previous". Would exactWidth
be better?
For my own money, this variable is used for so few lines of code (3, all very close together) that it doesn't need a particularly descriptive name -- one needs to read only a little code to understand its purpose. I think "exact" is very descriptive as it says it's not rounded. Maybe nonRounded
to make that extra extra clear?
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.
Or TBH go the other direction and call it w
or something! To show it's something temporary, just for the purpose of this small code loop.
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.
I agree with @tremby here, I'm in favour of something that shows its temporary nature. What about tempWidth
?
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.
I've renamed it to that.
test/test-buildSrcSet.js
Outdated
@@ -953,6 +953,20 @@ describe('SrcSet Builder:', function describeSuite() { | |||
}, Error); | |||
}); | |||
}); | |||
|
|||
describe('with widthTolerance, minWidth, and maxWidth set to promote an edge case', function describeSuite() { |
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.
Looks good 👍 , I have one last nit. This was a good catch on your end; I want to try to highlight the root cause here.
Using this test on main
, widthTolerance: 0.0999
fails. However, widthTolerance: 0.09
and widthTolerance: 0.099
both produce:
https://testing.imgix.net/image.jpg?w=1000 1000w,
https://testing.imgix.net/image.jpg?w=1180 1180w,
https://testing.imgix.net/image.jpg?w=1200 1200w,
and
https://testing.imgix.net/image.jpg?w=1000 1000w,
https://testing.imgix.net/image.jpg?w=1198 1198w,
https://testing.imgix.net/image.jpg?w=1200 1200w
respectively.
So maybe the description should be:
describe('when widthTolerance is between 0.09 and 0.10 (exclusive)', ...)
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.
But 0.0999 isn't some magic number, nor are 0.09 and 0.10. There will be more failing cases at other values of widthTolerance
, or for 0.09
or 0.10
for other values of minWidth
and maxWidth
. The test isn't really about those specific numbers; it's about coaxing out an edge case which reveals a bug.
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.
This may just be a difference in how we like to describe tests. I like to describe the bug I'm trying to highlight, if possible (I could try harder here; maybe "when widthTolerance, minWidth and maxWidth are such that a value fractionally below maxWidth is reached"), whereas perhaps you like to describe particular error-prone circumstances.
I'll change the name of it to what you suggested if you confirm.
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.
This is a hard test case to find a good name for. Overall I'm in agreement with @tremby here. I don't think we should hard-code a value in the test case name, because it doesn't capture the purpose of the test. I think we could improve a bit (as already mentioned) what an "edge case" is, e.g. something like "with widthTolerance, minWidth and maxWidth values that have caused duplicate values in the past"
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.
I've changed some names accordingly.
If/when this is deemed ready, let me squash the tweaks into the respective original commits before merging, please. |
Hey @tremby thank you for updating this so quickly 🙌 From my side it's all good, and from our internal discussions, it seems like we are overall happy with this PR. I'd wait on squashing/rebasing this until @ericdeansanchez replies in here, since he's the one currently overseeing imgix-core-js. He's on holiday today but hopefully should get back to you soon! |
I went ahead and squashed/merged this 👍 @tremby just wanted to say thanks again for this fix! We really appreciate it. |
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-03) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([e4e8d92](e4e8d92)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
🎉 This PR is included in version 0.3.0-beta.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-03) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-05) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-05) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * re-add semantic-release with retagged 2.3.2 release ([6ad6531](6ad6531)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-05) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-05) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update changelog format, trigger semantic ([4aa7127](4aa7127)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-05) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * update semantic release ([f55ff4a](f55ff4a)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-05) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * update semantic release ([ddfe8c7](ddfe8c7)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-06) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * update semantic release ([bf2dcad](bf2dcad)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
# [0.3.0-beta.1](v0.2.3...v0.3.0-beta.1) (2021-02-06) ### Bug Fixes * percent encode plus signs in path components ([#223](#223)) ([a5d756e](a5d756e)) * remove ensureEven requirement ([#206](#206)) ([1007f86](1007f86)) * update minor or patch prior to release ([65c6f3e](65c6f3e)) * **buildSrcSet:** ensure largest size can't be repeated ([#184](#184)) ([71a092a](71a092a)) * **buildURL:** ensure operation is idempotent ([8c6c6f9](8c6c6f9)) * add missing variable declarations ([#121](#121)) ([851a607](851a607)) * deprecate domain sharding ([#39](#39)) ([1b90df3](1b90df3)) * ensure URL-legal, path-illegal characters are encoded ([#61](#61)) ([b89dba1](b89dba1)) * include dpr parameter when generating fixed-width srcset ([#59](#59)) ([189d4f7](189d4f7)) * remove deprecated domain sharding functionality ([#42](#42)) ([66d5cd9](66d5cd9)) * remove deprecated settings.host ([#45](#45)) ([41ef41f](41ef41f)) * throw error when certain srcset modifiers are passed zero ([#114](#114)) ([2630f96](2630f96)) ### Features * add babel core for mocha ([1266c1a](1266c1a)) * add minimal babelrc ([3809a93](3809a93)) * add rollup config ([f62e8db](f62e8db)) * add semantic-release ([ebed795](ebed795)) * add settings.domain argument ([#44](#44)) ([af40091](af40091)) * add src, README to files list ([9d3bb9e](9d3bb9e)) * add srcset generation ([#53](#53)) ([81f38e7](81f38e7)) * add srcset option parameter to buildSrcSet() method signature ([#118](#118)) ([1e5507a](1e5507a)) * add support for defining a custom srcset width array ([#110](#110)) ([84974a5](84974a5)) * add support for defining a custom srcset width tolerance ([#109](#109)) ([504af70](504af70)) * add support for defining a min and max srcset width ([#108](#108)) ([fe5f5ba](fe5f5ba)) * add typescript declaration file for ImgixClient ([#64](#64)) ([a065ad9](a065ad9)) * add validation tests ([91cc39c](91cc39c)) * append variable qualities to dpr srcsets ([#111](#111)) ([b52148d](b52148d)) * create a DPR srcset when a fixed height is specified ([#215](#215)) ([628e6c7](628e6c7)), closes [#177](#177) * drop bower.json ([#222](#222)) ([2def739](2def739)) * enforce 0.01 lower bound for widthTolerance ([#211](#211)) ([8079e75](8079e75)) * generalize test-suite transpilation ([cf49986](cf49986)) * pull constants into separate file ([bb4b36d](bb4b36d)) * pull validation into separate module ([a113fea](a113fea)) * reintro renovate ([d9afcdb](d9afcdb)) * remove old interface ([7a5c1e0](7a5c1e0)) * remove renovate (for now) ([1be0281](1be0281)) * require @babel/register ([c488e43](c488e43)) * rewrite ix-core-js as esm ([7e98689](7e98689)) * run mocha with babel/register ([d5c519c](d5c519c)) * run release on beta branch ([857c864](857c864)) * test on node version 14 ([1d8d4a5](1d8d4a5)) * update @babel/preset-env ([879e235](879e235)) * update buildSrcSet test suite ([5e5d5da](5e5d5da)) * update buildURL test suite ([585bb19](585bb19)) * update client test suite ([e238dc4](e238dc4)) * update package.json ([c8491e0](c8491e0)) * update semantic release ([bf2dcad](bf2dcad)) * use --experimental-modules ([4c9735d](4c9735d)) * use const in validators ([be3ee98](be3ee98)) * use const where possible/appropriate ([4c2a31d](4c2a31d)) * use crypto-js ([a41ef47](a41ef47)) * use explicit extensions for main, module, and browser ([#225](#225)) ([3aa5bab](3aa5bab)) * use mjs file extensions with type module ([#209](#209)) ([72830c4](72830c4)) * use object spread operator ([6142e75](6142e75)) ### Performance Improvements * **srcset:** memoize generated srcset width-pairs ([#115](#115)) ([073d63d](073d63d))
Description
Two commits. One adds a failing test case for a bug where in certain conditions the largest value in the srcset list is repeated. The other commit fixes the bug. Full details are in the commit messages.
Checklist: Bug Fix
chore(readme): fixed typo
. See the end of this file for more information.Steps to Test
See the new test for an example failing case.
buildSrcSet('image.jpg', {}, {widthTolerance: 0.0999, minWidth: 1000, maxWidth: 1200})
was outputting [1000, 1200, 1200].