-
Notifications
You must be signed in to change notification settings - Fork 51
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 a random sample utility #553
Conversation
I think you'll need to replace So for example, the const random = jest.spyOn(global.Math, "random");
...
random.mockReturnValue(0); This would likely be replaced with something like: const {
axios,
getApp,
utils: { cache, sample },
} = require("../utils/test");
...
sample.mockReturnValue({ ...the object that should be returned from the list of options }); Alternatively, you could remove Either way you decide to go, this is a nice addition! |
Ok thanks! I removed from |
Ok so I realize it's this line: Line 17 in 8539c12
So now anything that does a require like this: const { sample } = require('./utils'); will get a function that just returns const sample = require('./utils/sample'); and avoid it getting mocked out like that? |
I think we can mark the CodeQL failure as a false positive. There's nothing security-sensitive about how we're using randomness here. |
Thanks! I think all the code is ready for final review now, got specs passing. |
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.
@@ -5,6 +5,7 @@ const { | |||
helpMessage, | |||
stats: { incrementStats }, | |||
} = require("../utils"); | |||
const sample = require("../utils/sample"); |
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.
To your question in the PR, this seems fine! I don't think it's my ideal case, but it's better than fighting with the tests forever. Maybe someday we can come back and find a way to make the tests work properly, but this is totally within the realm of "good enough," which is all anything needs to be. 😂
@@ -38,7 +39,7 @@ module.exports = (app) => { | |||
} | |||
}); | |||
|
|||
const joke = jokes[Math.floor(Math.random() * jokes.length)]; | |||
const joke = sample(jokes); |
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.
omg I love this so much more.
* @param {Number} [randomValue] random value that can be injected for more deterministic behavior | ||
* @return {T=} an item from the array (or undefined if empty array) | ||
*/ | ||
function sample(arr, randomValue = Math.random()) { |
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 had to double-check when default arguments are evaluated. I think in Python they're evaluated at definition time, in which case every invocation of sample
would get the same value. But you're correct, in Javascript they're evaluated at call time. 🎉
it("selects an item from an array based on randomValue and clamps it to the array bounds", () => { | ||
expect(sample(arr, 0)).toEqual("a"); | ||
expect(sample(arr, 0.999)).toEqual("e"); | ||
expect(sample(arr, -1)).toEqual("a"); | ||
expect(sample(arr, 100)).toEqual("e"); | ||
}); |
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.
🤩
fdd69ce
to
03ebe8c
Compare
I happened to look at #551 and saw that we were copy-pasting a pattern used many times that is
arr[Math.floor(Math.random() * arr.length])
and I figured, what a great opportunity to Not Repeat ourselves.Hubot had a
msg.random
helper so I modeled this after that. Open to renaming it as wellIf we like this, I am happy to update the wiki to suggest it! Or add a lint if we want too.
I'm also looking for help with the test suite, some of the cases seem to be returning
undefined
in ways that I don't expect and my attempts to print-debug were not successfulChecklist:
The OAuth wikipage has been updated if Charlie needs any new OAuth events or scopes
The Environment Variableswiki page has been updated if new environment variables were introduced
or existing ones changed
If appropriate, the NIST 800-218 documentation has been updated