This is how I am doing my unit test in groovy.
public void testSomeMethod() {
doSomething(1,2,3,4); //this is first test
doSomething(11,22,33,44); //this is second test
}
private void doSomething(a, b, c, d) {
assertEquals(a, actual)
}
Basically I am calling doSomething 2 times with different values under same test.
It might not be a good way to test But I just want to try it out.
So, the problem is, if the first test fails second does't get executed.
Is there a way I can force it to print fail message and move on to next one?
It is a good time for you to use spock, where you can do data driven testing and the second test will not be gated by the first one. You can get more flexibility like the one you have asked for and more.
Eventually, the test would look something like:
void "test something"(){
when:
def result = doSomething(a, b, c, d)
then:
result == expectedResult
where:
a | b | c | d || expectedResult
1 | 2 | 3 | 4 || 100
11 | 22 | 33 | 44 || 1000
}
private doSomething(a, b, c, d){...}
You can find more details in spock framework documents and/or also have a look at these questions.
BTW, above test example can be over simplified to make it groovier. ;)
void "test something"(){
expect:
result == doSomething(a, b, c, d)
where:
a | b | c | d || result
1 | 2 | 3 | 4 || 100
11 | 22 | 33 | 44 || 1000
}
Although I agree with the advice given to use Spock(great framework) you can also use JUnit parameterized tests if you don't want to include additional dependencies.
Related
I run cargo clippy to get some feedback on my code and clippy told me that I can somehow collapse a if let.
Here is the exact "warning":
warning: this `if let` can be collapsed into the outer `if let`
--> src\main.rs:107:21
|
107 | / if let Move::Normal { piece, from, to } = turn {
108 | | if i8::abs(from.1 - to.1) == 2 && piece.getColor() != *color && to.0 == x {
109 | | let offsetX = x - to.0;
110 | |
... |
116 | | }
117 | | }
| |_____________________^
I thought I could maybe just append the inner if using && but then i get a warning ( `let` expressions in this position are experimental, I am using rust version 1.57.0, not nightly).
Any idea what clippy wants me to do?
Edit:
the outer if let is itself again inside another if let:
if let Some(turn) = board.getLastMove() {
And it seems you can indeed combine them like so:
if let Some(Move::Normal { piece, from, to }) = board.getLastMove() {
In my opinion the clippy lint should include the line above as it is otherwise, at least for me, somewhat confusing
Edit 2:
Turns out I just cant read, below the warning listed above was some more information telling me exactly what to do.
= note: `#[warn(clippy::collapsible_match)]` on by default
help: the outer pattern can be modified to include the inner pattern
--> src\main.rs:126:29
|
126 | if let Some(turn) = board.getLastMove() {
| ^^^^ replace this binding
127 | if let Move::Normal { piece, from, to } = turn {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ with this pattern
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match
I'm learning Antlr. At this point, I'm writing a little stack-based language as part of my learning process -- think PostScript or Forth. An RPN language. For instance:
10 20 mul
This would push 10 and 20 on the stack and then perform a multiply, which pops two values, multiplies them, and pushes 200. I'm using the visitor pattern. And I find myself writing some code that's kind of insane. There has to be a better way.
Here's a section of my WaveParser.g4 file:
any_operator:
value_operator |
stack_operator |
logic_operator |
math_operator |
flow_control_operator;
value_operator:
BIND | DEF
;
stack_operator:
DUP |
EXCH |
POP |
COPY |
ROLL |
INDEX |
CLEAR |
COUNT
;
BIND is just the bind keyword, etc. So my visitor has this method:
antlrcpp::Any WaveVisitor::visitAny_operator(Parser::Any_operatorContext *ctx);
And now here's where I'm getting to the very ugly code I'm writing, which leads to the question.
Value::Operator op = Value::Operator::NO_OP;
WaveParser::Value_operatorContext * valueOp = ctx->value_operator();
WaveParser::Stack_operatorContext * stackOp = ctx->stack_operator();
WaveParser::Logic_operatorContext * logicOp = ctx->logic_operator();
WaveParser::Math_operatorContext * mathOp = ctx->math_operator();
WaveParser::Flow_control_operatorContext * flowOp = ctx->flow_control_operator();
if (valueOp) {
if (valueOp->BIND()) {
op = Value::Operator::BIND;
}
else if (valueOp->DEF()) {
op = Value::Operator::DEF;
}
}
else if (stackOp) {
if (stackOp->DUP()) {
op = Value::Operator::DUP;
}
...
}
...
I'm supporting approximately 50 operators, and it's insane that I'm going to have this series of if statements to figure out which operator this is. There must be a better way to do this. I couldn't find a field on the context that mapped to something I could use in a hashmap table.
I don't know if I should make every one of my operators have a separate rule, and use the corresponding method in my visitor, or if what else I'm missing.
Is there a better way?
With ANTLR, it's usually very helpful to label components of your rules, as well as the high level alternatives.
If part of a parser rule can only be one thing with a single type, usually the default accessors are just fine. But if you have several alternatives that are essentially alternatives for the "same thing", or perhaps you have the same sub-rule reference in a parser rule more than one time and want to differentiate them, it's pretty handy to give them names. (Once you start doing this and see the impact to the Context classes, it'll become pretty obvious where they provide value.)
Also, when rules have multiple top-level alternatives, it's very handy to give each of them a label. This will cause ANTLR to generate a separate Context class for each alternative, instead of dumping everything from every alternative into a single class.
(making some stuff up just to get a valid compile)
grammar WaveParser
;
any_operator
: value_operator # val_op
| stack_operator # stack_op
| logic_operator # logic_op
| math_operator # math_op
| flow_control_operator # flow_op
;
value_operator: op = ( BIND | DEF);
stack_operator
: op = (
DUP
| EXCH
| POP
| COPY
| ROLL
| INDEX
| CLEAR
| COUNT
)
;
logic_operator: op = (AND | OR);
math_operator: op = (ADD | SUB);
flow_control_operator: op = (FLOW1 | FLOW2);
AND: 'and';
OR: 'or';
ADD: '+';
SUB: '-';
FLOW1: '>>';
FLOW2: '<<';
BIND: 'bind';
DEF: 'def';
DUP: 'dup';
EXCH: 'exch';
POP: 'pop';
COPY: 'copy';
ROLL: 'roll';
INDEX: 'index';
CLEAR: 'clear';
COUNT: 'count';
Assignment:
Translate the following natural language expressions to C++ expressions. Assume that all the variables are non-negative numbers or boolean (of value true or false).
Natural Language:
Either a and b are both false or c is true, but not both.
My solution:
(a==0 && b==0)xor(c==1)
Professors solution:
(!a && !b) != c
Questions:
I think I slightly understand the first bracket, by saying "not-a" and "not-b" I think that a and b must then be wrong, provided a b are assumed to be non-zero in the beginning. Right?
But what about the part that says "unequal to c"?
I don't understand the Professors solution, can anyone break it down for me?
Thank you for the help!
I'll assume that a, b and c are bool.
Let's draw some truth tables:
| a | !a | a==1 | a==0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 0 |
As you can see, a and a==1 are equivalent, and !a and a==0 are also equivalent, so we can rewrite (a==0 && b==0)xor(c==1) as (!a && !b) xor c.
Now some more truth tables:
| a | b | a xor b | a != b |
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 0 |
So a!=b is equivalent to a xor b, so we can rewrite (!a && !b) xor c to (!a && !b)!=c. As you see, your solutions are fully equivalent, just written with different 'signs'.
UPD: Forgot to mention. There are reasons why professor's solution looks exactly in that way.
The professor's solution is more idiomatic. While your solution is technically correct, it's not an idiomatic C++ code.
First little issue is usage of types. Your solution relies on conversion between int and bool when you compare boolean value to a number or use xor, which is a 'bit-wise exclusive or' operator acting on ints too. In a modern C++ it is much more appreciated to use values of correct types and not to rely on such conversions as they're sometimes not so clear and hard to reason about. For bool such values are true and false instead of 1 and 0 respectively. Also != is more appropriate than xor because while technically bools are stored as numbers, but sematically you haven't any numbers, just logical values.
Second issue is about idiomacy too. It lies here: a == 0. It is not considered a good practice to compare boolean expressions to boolean constants. As you already know, a == true is fully equivalent to just a, and a == false is just !a or not a (I prefer the latter). To understand the reason why that comparing isn't good just compare two code snippets and decide, which is clearer:
if (str.empty() == false) { ... }
vs
if (not str.empty()) { ... }
Think booleans, not bits
In summary, your professor's solution is better (but still wrong, strictly speaking, see further down) because it uses boolean operators instead of bitwise operators and treating booleans as integers. The expression c==1 to represent "c is true" is incorrect because if c may be a number (according to the stated assignment) then any non-zero value of c is to be regarded as representing true.
See this question on why it's better not to compare booleans with 0 or 1, even when it's safe to do so.
One very good reason not to use xor is that this is the bit-wise exclusive or operation. It happens to work in your example because both the left hand side and right hand side are boolean expressions that convert to 1 or 0 (see again 1).
The boolean exclusive-or is in fact !=.
Breaking down the expression
To understand your professor's solution better, it's easiest to replace the boolean operators with their "alternative token" equivalents, which turns it into better redable (imho) and completely equivalent C++ code:
Using 'not' for '!' and 'and' for '&&' you get
(not a and not b) != c
Unfortunately, there is no logical exclusive_or operator other than not_eq, which isn't helpful in this case.
If we break down the natural language expression:
Either a and b are both false or c is true, but not both.
first into a sentence about boolean propositions A and B:
Either A or B, but not both.
this translates into A != B (only for booleans, not for any type A and B).
Then proposition A was
a and b are both false
which can be stated as
a is false and b is false
which translates into (not a and not b), and finally
c is true
Which simply translates into c.
Combining them you get again (not a and not b) != c.
For further explanation how this expression then works, I defer to the truth tables that others have given in their answers.
You're both wrong
And if I may nitpick: The original assignment stated that a, b and c can be non-negative numbers, but did not unambiguously state that if they were numbers, they should be limited to the values 0 and 1. If any number that is not 0 represents true, as is customary, then the following code would yield a surprising answer:
auto c = 2; // "true" in some way
auto a = 0; // "false"
auto b = 0; // "false"
std::cout << ((!a && !b) != c);
// this will output: 1 (!)
// fix by making sure that != compares booleans:
std::cout << ((!a && !b) != (bool)c);
I will tryto explain with some more words: Numbers can be implicitly converted to boolean values:
The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false. All other values become true.
Source on cppreference
This leads to the following conclusions:
a == 0 is the same as !a, because a is converted to a boolean and then inverted, which equals !(a != 0). The same goes for b.
c==1 will become only true when c equals 1. Using the conversion (bool)c would yield true when c != 0 not just if c == 1. So it can work, because one usually uses the value 1 to represent true, but it's not garantued.
a != b is the same as a xor b when a and b ar boolean expressions. It's true, when one value or the other is true, but not both. In this case the left hand side (a==0 && b==0) is boolean, so the right hand side c is converted to boolean too, thus, both sides are interpreted as boolean expressions, thus != is the same as xor in this case.
You can check all of this yourself with the truthtables that the other answers provided.
As we can see from the truth tables:
!(not) and ==0 give the same results.
!= and xor give the same results.
c==1 is the same as just c
So one under the other, shows why these 2 expressions give the same result:
(a==0 && b==0) xor (c==1)
(!a && !b) != c
Truth tables :
Not
| | ! |
| 0 | 1 |
| 1 | 0 |
==0
| |==0|
| 0 | 1 |
| 1 | 0 |
==1
| |==1|
| 0 | 0 |
| 1 | 1 |
And
| a | b | && |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Not equal
| a | b | != |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
XOR
| a | b |xor|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
This question already has an answer here:
Generating a new variable using conditional statements
(1 answer)
Closed 3 years ago.
I am doing data clean-up in Stata and I need to recode a variable to equal 1 if a whole set of other variables are equal to 1, 6, or 7.
I can do this using the code below:
replace anyadl = 1 if diffdress==1 | diffdress==6 | diffdress==7 | ///
diffwalk==1 | diffwalk==6 | diffwalk==7 | ///
diffbath==1 | diffbath==6 | diffbath==7 | ///
diffeat==1 | diffeat==6 | diffeat==7 | ///
diffbed==1 | diffbed==6 | diffbed==7 | ///
difftoi==1 | difftoi==6 | difftoi==7
However, this is very inefficient to type out and it is easy to make errors.
Is there a simpler way to do this?
For example, something along the following lines:
replace anyadl = 1 if diff* == (1 | 6 | 7)
Your fantasy syntax wouldn't do what you want even if it were legal, as for example 1|6|7 would be evaluated as 1. That is, in Stata 1 OR 6 OR 7 is in effect true OR true OR true, so true, and thus 1, given the rules non-zero is true as input and true is 1 as output. The expression is 1|6|7 is legal; it's the wildcard in an equality or inequality that isn't.
Stepping back, your code is producing an indicator (some people say dummy) variable with values 1 or missing. In practice such a variable is much more useful if created with values 0 and 1 (and in some instances missing too).
generate anyad1 = 0
foreach v in dress walk bath eat bed toi {
replace anyad1 = 1 if inlist(diff`v', 1, 6, 7)
}
is one approach. In general, note both inlist(foo, 1, 6, 7) and inlist(1, foo, bar, bazz) as useful constructs.
Reading:
This paper on generating indicators
This one on useful functions
This one on inlist() and inrange()
FAQ on true and false in Stata
I'm playing around with the Julia testsuite functionality and I quite like it.
What i however fail to figure out is how to make the testsuite report the potential message upon completion.
Let's say I have a test suite like the one below, where each of the functions performs a bunch of tests in turn before returning
#testset "MyTestSuite" begin
#testset "Subtest1" begin #test my_test_1() end
#testset "Subtest2" begin #test my_test_2() end
#testset "Subtest3" begin #test my_test_3() end
#testset "Subtest4" begin #test my_test_4() end
end
If now say my_test_4 fails or throws an error, then the ouput would look like below
Test Summary: | Pass Error Total
MyTestSuite | 65 1 66
Subtest1 | 5 1 6
Subtest2 | 10 0 10
Subtest3 | 20 0 20
Subtest4 | 30 0 30
ERROR: LoadError: Some tests did not pass: 65 passed, 0 failed, 1 errored, 0 broken.
But there is now way (to my knowledge) for me to see what went wrong without scrolling upwards in the terminal output. If my test suites are long enough, and produce enough diagnostics, the error information could even be lost to me or at least very difficult to find.
So, does anyone know a nice way around this? Are there options that one can give to the macro #testset to make sure it prints of collects the errors for further processing?
You can define your custom AbstractTestSet. It is descirbed here in the Julia manual.
Here is an example adapted from the manual. First define:
using Test
struct CustomTestSet <: Test.AbstractTestSet
description::AbstractString
results::Vector
CustomTestSet(desc) = new(desc, [])
end
Test.record(ts::CustomTestSet, child::Test.AbstractTestSet) = push!(ts.results, child)
Test.record(ts::CustomTestSet, res::Test.Result) = push!(ts.results, res)
function Test.finish(ts::CustomTestSet)
if Test.get_testset_depth() > 0
Test.record(Test.get_testset(), ts)
end
ts
end
and now you can write:
julia> res = #testset CustomTestSet "custom testset" begin
# this testset should inherit the type, but not the argument.
#testset "custom testset inner" begin
#test 1==1
#test 1==2
#test 2==2
#test 2==3
end
end
CustomTestSet("custom testset", Any[CustomTestSet("custom testset inner", Any[Test Passed, Test Failed at REPL[10]:5
Expression: 1 == 2
Evaluated: 1 == 2, Test Passed, Test Failed at REPL[10]:7
Expression: 2 == 3
Evaluated: 2 == 3])])
julia> res.results[1].results
4-element Array{Any,1}:
Test Passed
Test Failed at REPL[10]:5
Expression: 1 == 2
Evaluated: 1 == 2
Test Passed
Test Failed at REPL[10]:7
Expression: 2 == 3
Evaluated: 2 == 3
and you have an access to a vector that tells you what passed and what failed, and on failure what was the problem.
You can also filter out passed tests:
julia> filter(x -> !(x isa Test.Pass), res.results[1].results)
2-element Array{Any,1}:
Test Failed at REPL[6]:5
Expression: 1 == 2
Evaluated: 1 == 2
Test Failed at REPL[6]:7
Expression: 2 == 3
Evaluated: 2 == 3
If your tests have a more complex nested structure you should do it recursively.
Is this something you wanted?