I'm starting to use JSVerify for property based testing.
Given a function (just an example) that accepts a string as parameter, I use JSVerify to pass in a large number of arbitrary strings and see if the function behaves as intended for all of them. It turns out that there are some strings that make the test fail: so far I've found that if the string contains \0000, \0001 or \n, the test fails.
I want to correct my code so that this cases are handled accordingly, but in order to prevent regression, I want to make sure that each one of this cases is included in every test run. I also want to avoid hardcoding the number generator's seed (rngState) since that would prevent the discovery of additional corner cases in the future.
To clarify: suppose that I'm testing my function foo():
jsc.assert(jsc.forall("string", (str) => {
const result = foo(str)
return (/* some expression that evaluates whether the result is correct */)
}))
This test is feeding 100 random strings into foo() every time a run the test suite. Initially it's passing. After some runs it suddenly fails because, precisely this time, the random string generator has generated a string containing the character \0000, which my function doesn't handle as expected. From now on, I would like that my test uses this string as input every time, plus the usual 100 random inputs.
Is there a built-in way to do this using JSVerify? Or should I just treat these inputs as separate test cases?
This is how i'm addressing the problem you mentioned. Instead of testing specific values, my code can specify as many "bad" seeds as needed, in addition to running a random one with each test invocation.
Notes:
1) I am using Mocha
2) I am using async code, so I return a promise
3) the JSON.stringify allows me to easily see the seed given the above
You can still use this method without 1,2,3 above with some refactoring:
const _ = require('lodash');
var jsc = require('jsverify');
// mocha's describe
describe("StackOverflow", function () {
it('example1', function(done) {
let t = jsc.forall('array nat', function (in1) {
let asComplex = foo(in1);
let backAgain = bar(asComplex);
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(_.isEqual(backAgain,in1));
},500); // setTimeout
}); // promise
}); // forall
let props = {size:0xffffffff, tests: 1000};
jsc.check(t, props).then( r => r === true ? done() : done(new Error(JSON.stringify(r))));
props.tests = 3;
jsc.check(t, props).then( r => r === true ? done() : done(new Error(JSON.stringify(r))));
props.rngState = "8e1da6702e395bc84f";
jsc.check(t, props).then( r => r === true ? done() : done(new Error(JSON.stringify(r))));
// add more seeds here
}); // it
}); // describe
Related
I have a email validation fuction where i need to trim string value twice.
(val) => (val.trim() && emailReg.test(val.trim()))
Or
(val) => {
const value = val.trim();
return value &&emailReg.test(value)
}
which is more faster and meet coding standards.
It really depends on personal preference, so either one is fine (as long as they both work).
However, the most performant option is the second option.
This is because you are only trimming the string once, which will save a few milliseconds when returning the value.
const emailReg = undefined; // Email RegEx
const emailTest = (val) => {
const value = val.trim(); // Only trimming once
return value && emailReg.test(value) // Passing both of the variables
}
Edit: However, it may take a few milliseconds when making a new memory reference for the variable.
Again, choose whichever you like (mainly depends on personal preference).
I am relatively new to coding, and I have been doing some practice problems for javascript for the sake of practice. There is this one problem that I am stuck on about implementing the bind function. Essentially, I need to implement a function called bundleArgs with two parameters: a function fn to get args bundled with and args1, args2 to argsn - any numbers of args that will automatically get filled in when the output function is used. bundleArgs is essentially supposed to return a version of the original fn that can take any number of arguments, but when used, will use the args1, args2 to argsn as the first parameters to fn, filling in the new arguments afterwards. I attempted doing this with the bind function, since it basically makes your arguments pre-filled, however I am supposed to implement this WITHOUT using bind, and that is essentially where I am stuck. Example of the output: // example, you have a function that surrounds text with other text
function surroundText(surrounding, text) {
return [surrounding, text, surrounding].join(" ")
}
// but you know you're going to use it for one thing only
const makeCool = bundleArgs(surroundText, "~x~X~x~")
// save yourself some time
console.log(makeCool("i guess")) // ~x~X~x~ i guess ~x~X~x~
// again w/ leftovers
function repeatLetter(letter, times) {
Array(times).fill(letter).join('');
}
// fix 1 of 2 arguments to 'r'
rrrrrollWithIt = bundleArgs(repeatLetter, 'r');
// resulting function has only one arg now
rrrrrollWithIt(10) // rrrrrrrrrr
I'm having trouble understanding this piece of Javascript code:
var _ref3 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () {
if (actualArgs.length === 0) {
const sandbox = yield getValidSandbox(curDir);
// It's just a status command. Print the command that would be
// used to setup the environment along with status of
// the build processes, staleness, package validity etc.
let envForThisPackageScripts = PackageEnvironment.calculateEnvironment(sandbox, sandbox.packageInfo, { useLooseEnvironment: true });
console.log(PackageEnvironment.printEnvironment(envForThisPackageScripts));
} else {
let builtInCommandName = actualArgs[0];
let builtInCommand = builtInCommands[builtInCommandName];
if (builtInCommand) {
builtInCommand(curDir, ...process.argv.slice(3));
} else {
console.error(`unknown command: ${builtInCommandName}`);
}
}
});
What exactly is _ref3 ? a function ? a tuple ? I'm confused
I would not like to read your code for you but i think, with a little help you could understand this code your self. I guess you need help with the various new syntax being used in the code above. I'll try to note down those so that you can understand all of this code yourself.
(0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function*{})
This line basically is similar to
(0,x)(function*{})
where x is a function which takes a generator function as an argument.
Whenever you have a line of the form (x,y) it will always return the last value. So in the case of(x,y) it will return y. If its (0,x) it will return x. Thus in code which you posted, the first line will return (_asyncToGenerator2 || _load_asyncToGenerator()).default.
You could now translate the code to
((_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* {})
This means that above code will return a function which takes a generator as argument
If you need more information on generator you could go here
The generator function has attributes like yield. They are pretty useful especially to handle asynchronous operations. It streamlines your code and makes it easy to read. To get more information what yield means, you could go here and here
You could also see some lines like these in the code.
builtInCommand(curDir, ...process.argv.slice(3));
This is basically spread operators being used. Spread operators basically allow an expression to be expanded in places where multiple arguments are expected. You could go here
to know more about spread operators.
Hope you will be able to read the above code yourself after you understand the concepts.
In Javascript what is the best way to handle scenarios when you have a set of arrays to perform tasks on sets of data and sometimes you do not want to include all of the arrays but instead a combination.
My arrays are labeled in this small snippet L,C,H,V,B,A,S and to put things into perspective the code is around 2500 lines like this. (I have removed code notes from this post)
if(C[0].length>0){
L=L[1].concat(+(MIN.apply(this,L[0])).toFixed(7));
C=C[1].concat(C[0][0]);
H=H[1].concat(+(MAX.apply(this,H[0])).toFixed(7));
V=V[1].concat((V[0].reduce(function(a,b){return a+b}))/(V[0].length));
B=B[1].concat((MAX.apply(this,B[0])-MIN.apply(this,B[0]))/2);
A=A[1].concat((MAX.apply(this,A[0])-MIN.apply(this,A[0]))/2);
D=D[1].concat((D[0].reduce(function(a,b){return a+b}))/(D[0].length));
S=S[1].concat((S[0].reduce(function(a,b){return a+b}))/(S[0].length));
}
It would seem counter-productive in this case to litter the code with tones of bool conditions asking on each loop or code section if an array was included in the task and even more silly to ask inside each loop iteration with say an inline condition as these would also slow down the processing and also make the code look like a maze or rabbit hole.
Is there a logical method / library to ignore instruction or skip if an option was set to false
All I have come up with so far is kind of pointless inline thing
var op=[0,1,1,0,0,0,0,0]; //options
var L=[],C=[],H=[],V=[],B=[],A=[],D=[],S=[];
op[0]&&[L[0]=1];
op[1]&&[C[0]=1,console.log('test, do more than one thing')];
op[2]&&[H[0]=1];
op[3]&&[V[0]=1];
op[4]&&[B[0]=1];
op[5]&&[A[0]=1];
op[6]&&[A[0]=1];
It works in that it sets only C[0] and H[0] to 1 as the options require, but it fails as it needs to ask seven questions per iteration of a loop as it may be done inside a loop. Rather than make seven versions of the the loop or code section, and rather than asking questions inside each loop is there another style / method?
I have also noticed that if I create an array then at some point make it equal to NaN rather than undefined or null the console does not complain
var L=[],C=[],H=[],V=[],B=[],A=[],D=[],S=[];
L=NaN;
L[0]=1;
//1
console.log(L); //NaN
L=undefined;
L[0]=1
//TypeError: Cannot set property '0' of undefined
L=null
L[0]=1
//TypeError: Cannot set property '0' of null
Am I getting warmer? I would assume that if I performed some math on L[0] when isNaN(L)===true that the math is being done but not stored so the line isn't being ignored really..
If I understand what you want I would do something like this.
var op = [...],
opchoice = {
//these can return nothing, no operation, or a new value.
'true': function(val){ /*operation do if true*/ },
'false': function(val){ /*operation do if false*/ },
//add more operations here.
//keys must be strings, or transformed into strings with operation method.
operation: function(val){
//make the boolean a string key.
return this[''+(val == 'something')](val);
}
};
var endop = [];//need this to prevent infinite recursion(loop).
var val;
while(val = op.shift()){
//a queue operation.
endop.push(opchoice.operation(val));
}
I'm sure this is not exactly what you want, but it's close to fulfilling the want of not having a ton of conditions every where.
Your other option is on every line do this.
A = isNaN(A) ? A.concat(...) : A;
Personally I prefer the other method.
It looks like you repeat many of the operations. These operations should be functions so at least you do not redefine the same function over and over again (it is also an optimization to do so).
function get_min(x)
{
return +(MIN.apply(this, a[0])).toFixed(7);
}
function get_max(x)
{
return +(MAX.apply(this, a[0])).toFixed(7);
}
function get_average(x)
{
return (x[0].reduce(function(a, b) {return a + b})) / (x[0].length);
}
function get_mean(x)
{
return (MAX.apply(this, x[0]) - MIN.apply(this, x[0])) / 2;
}
if(C[0].length > 0)
{
L = L[1].concat(get_min(L));
C = C[1].concat(C[0][0]);
H = H[1].concat(get_max(H));
V = V[1].concat(get_average(V));
B = B[1].concat(get_mean(B));
A = A[1].concat(get_mean(A);
D = D[1].concat(get_average(D));
S = S[1].concat(get_average(S));
}
You could also define an object with prototype functions, but it is not clear whether it would be useful (outside of putting those functions in a namespace).
In regard to the idea/concept of having a test, what you've found is probably the best way in JavaScript.
op[0] && S = S[1].concat(get_average(S));
And if you want to apply multiple operators when op[0] is true, use parenthesis and commas:
op[3] && (V = V[1].concat(get_average(V)),
B = B[1].concat(get_mean(B)),
A = A[1].concat(get_mean(A));
op[0] && (D = D[1].concat(get_average(D)),
S = S[1].concat(get_average(S)));
However, this is not any clearer, to a programmer, than an if() block as shown in your question. (Actually, many programmers may have to read it 2 or 3 times before getting it.)
Yet, there is another solution which is to use another function layer. In that last example, you would do something like this:
function VBA()
{
V = V[1].concat(get_average(V));
B = B[1].concat(get_mean(B));
A = A[1].concat(get_mean(A));
}
function DS()
{
D = D[1].concat(get_average(D));
S = S[1].concat(get_average(S));
}
op = [DS,null,null,VBA,null,null,...];
for(key in op)
{
// optional: if(op[key].hasOwnProperty(key)) ... -- verify that we defined that key
if(op[key])
{
op[key](); // call function
}
}
So in other words you have an array of functions and can use a for() loop to go through the various items and if defined, call the function.
All of that will very much depend on the number of combinations you have. You mentioned 2,500 lines of code, but the number of permutations may be such that writing it one way or the other will possibly not reduce the total number of lines, but it will make it easier to maintain because many lines are moved to much smaller code snippet making the overall program easier to understand.
P.S. To make it easier to read and debug later, I strongly suggest you put more spaces everywhere, as shown above. If you want to save space, use a compressor (minimizer), Google or Yahoo! both have one that do a really good job. No need to write your code pre-compressed.
I have a requirement that the user can provide arbitrary statements which can be stored in a function and called later to get a return value. A simple example of this is that userInput might be
var x = 10;
x;
I would store this via
var callback = function() {
return eval(userInput);
}
and then running callback() returns 10 as expected.
However, I also need to support the case with an explicit return statement, ie userInput might be
var x = 10;
return x;
In this case the eval method above will fail with SyntaxError: return not in function. Instead I could store callback as
var callback = new Function(userInput);
My issue is that I would like to combine these two approaches according the rule 'get explicit return value otherwise get the result of the last executed statement'. In particular this can't be done with analysis of the code at callback creation time as the user could potentially do something odd like
if(envVar < 10)
return a;
b * 0.5;
which combines both.
Any thoughts on how to structure the creation of the callback function to accommodate these possible inputs? Unfortunately it is not possible to enforce one style or the other on the user.
UPDATE to answer some of the comments below.
One solution suggested is to search for a return token and choose between new Function and eval. This doesn't work for my last example, see http://jsfiddle.net/ZGb6z/2/ - out4 should be "no" but ends up being undefined as the last executed statement is not returned.
Another suggestion is to modify the user input to add an explicit return on the last line if one is not found. Unfortunately it's not possible to know which statement will be executed last. Consider
var x = 10;
switch(x) {
case 10:
100;
break;
default:
200;
break;
}
When called it should return 100, but it would take some serious analysis to determine where to put returns for arbitrary code.
Just use a try catch, manipulating the input will be very painful for you, and try catch can't really make your code any more obtuse at this point.
var failback = function () {
try {
return eval(userInput);
} catch (e) {
return Function(userInput);
}
};
What I would really suggest is investing in a parser, kind of like how Angular does it. That kind of thing would prevent your users from doing whatever the hell they want, introducing attack vectors, yadda, yadda, yadda.
Either manage your expectations or manage your user's expectations. eval and new Function() are not suitable for your requirements if you require mixed usage of explicit and non-explicit return statements in the same user-input. You will continue to find issues following either of these routes.
Simply searching for the word return is not sufficient either... var returning = true; or var a = 'return'; or /* return true */ true; will all throw false positives.
Managing your expectations: To do such a thing you require a form of lexer and parser, at which point you can do away with eval entirely and execute your own safe functions based on the parsed input. This is the best approach when execution of user input has to occur anyway as you can ensure that nothing gets executed you do not wish to permit. If you want to cover these sort of edge cases and permit strange user input then you must be prepared to increase the size and development time of your application. I have built a few applications executing user generated code and have always come to the conclusion this is the correct route to go down.
Managing your user's expectations: Provide a guide, tell them not to mix explicit returns with non-explicit returns, these are strange coding practices anyway. Better yet explicitly tell them to include or omit the return statement. There is no shame in asking your users to follow them, especially if it allows you to improve their experience elsewhere.
There I was thinking I'd only see problems like this at the code golf stack exchange :)
My solution is here: http://jsfiddle.net/hKq87/1
It essentially replaces the 'return' statement with an exception that has a special string prefixed to it. If we see that string, we know we are actually returning a value, and return it rather than re-raising the exception.
The reason I chose to throw an exception rather than replace the return statement with a function call was because it is hard to know where the JS code evaluated for the return really ends. It could be split across multiple lines, contain several special characters and may not even have the optional semi-colon at the end. So I concatenate a string to whatever the value being returned is and throw it, as the throw keyword doesn't require it's argument to be wrapped in parentheses.
In addition, throwing exceptions provides me a convenient way to immediately terminate execution of the code block, without halting other JS execution.
Here is the callback method:
var callback = function(userInput) {
var returned = undefined;
userInput = userInput.replace(/(^|[\(\\)[\]{};,\s])return(\s*[^\s;])?/gi, function(m, b, e){
return b + " throw '__RETURNED_VALUE'" +
(e !== undefined ? "+" + e : "");
});
try {
returned = eval(userInput);
} catch (e) {
if (e.indexOf("__RETURNED_VALUE") == 0) {
returned = e.substring("__RETURNED_VALUE".length) || undefined;
}
else {
throw e;
}
}
return returned;
}
The regex above accounts for variables that may end with the string "return", that we would not want to replace as it is not a return statement. It also allows for return statements within braces, without trailing semi-colons or at the very beginning/end.
One issue with the current method is that you can not use the (rare) comma operator in a return statement, or expect numerical values to be returned correctly. The last test case in the jsfiddle demonstrates this. An example from here:
//original
return 5 * 2 + 3, 22;
//modified
throw '__RETURNED_VALUE='+ 5 * 2 + 3, 22;
//apply * operator
throw '__RETURNED_VALUE='+ 10 + 3, 22;
//apply + operators
throw '__RETURNED_VALUE=103', 22;
//apply , operator
throw 22;
This problem can be avoided by completely eliminating the prefix '__RETURNED_VALUE=' and just replacing 'return' with 'throw'. However, this means that the code provided must run without throwing exceptions, which I thought to be a harder constraint than just crafting return statements to be simple (avoiding comma operators, non-parenthesized arithmetic, etc.). In addition, if a user ever creates a return statement that we can't handle with the current code, we conveniently throw an exception for it so it easily comes to our attention.
jsFiddle Demo
Lets assume your user can be a little smarter than the average bear. We are going to ask them to specifically provide an initial value and then a callback with an expression for that value.
The main benefit of doing this is that you avoid eval, and actually have a nice implementation that is re-usable as opposed to being subject to later refactoring.
This way also provides a separation of where the input comes from and where the examination comes from. Although the provided example only shows integer input, really it could be another call with absolutely no knowledge of the value aside that it needs to conform to the callback logic.
function expression(x,callback){
return callback(x);
}
out1.innerHTML = expression(8,function(x){
return x;
});
out2.innerHTML = expression(10,function(x){
return x;
});
out3.innerHTML = expression(10,function(x){
if(x === 10) return "yes"; "no";
});
out4.innerHTML = expression(8,function(x){
return x === 10 ? "yes" : "no";
});