I am modifying a test method from single parameter to multiple:
#ParameterizedTest
#NullSource
#ValueSource({"foo", "bar"..})
void shouldReturnFalse(String x) {
assertThat(someMethod(x)).isFalse();
}
#ParameterizedTest
#CsvSource({
"null, null",
"foo, bar"
})
void shouldReturnFalse(String x, String y) {
assertThat(someMethod(x, y)).isFalse();
}
null here is passed in as a String literal instead of a null literal. As a result, this test fails. This test previously works with single argument with #NullSource, but it gives following error when switched to multiple:
org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter...
I couldn't find a workaround for this and the solutions I saw were rather hacky and cumbersome. Is there a easier way for providing values with null?
#CsvSource has an attribute called nullValues.
See the documentation.
A list of strings that should be interpreted as null references.
#CsvSource(value= {"null, null",
"foo, bar"}
, nullValues={"null"})
The other option is to simply don't pass any value as stated in the previously linked documentation.
Please note that unquoted empty values will always be converted to null references regardless of the value of this nullValues attribute; whereas, a quoted empty string will be treated as an emptyValue().
#CsvSource({",",
"foo, bar"})
You can use nullValues as explained above by #Jan Schmitz, or you can just discard null values like this:
#CsvSource({
",",
"foo, bar"
})
Related
I have two parameters , let's say P1 and P2. The sample expression I used for P2 is
IIF(P1.Label="string", "null" ,Split(P1.Label," ").GetValue(0))
When the condition is false, the split expression is working fine. But if the condition is true, I'm getting 'Index was outside the bounds of the array' error. If the condition is true, I need to pass the value "null" as varchar type.
Can someone please advice on this?
The problem with the IIF function is that it is a function not a language construct. This means that it evaluates both parameters before passing the parameters to the function. Consequently, if you are trying to do a Split on a parameter that can't be split, you will still get the 'Index was outside the bounds of the array' error, even when it looks like that code shouldn't be executed due to boolean condition of the IIF statement.
The best way to solve this is to create a safe string splitter function in custom code where you can use real language constructs. Also, check that the string is splittable by checking it contains a space instead of checking for a special string:
Public Function SafeSplit(ByVal SplitThis As String) As String
If InStr(SplitThis, " ") Then
Return Split(SplitThis, " ")(0)
End If
Return "null"
End Function
and then use this in your report for the Value expression instead of IIF:
=Code.SafeSplit(Parameters!P1.Label)
I was wondering why this is valid go code:
func FindUserInfo(id string) (Info, bool) {
it, present := all[id]
return it, present
}
but this isn't
func FindUserInfo(id string) (Info, bool) {
return all[id]
}
is there a way to avoid the temporary variables?
To elaborate on my comment, the Effective Go mentions that the multi-value assignment from accessing a map key is called the "comma ok" pattern.
Sometimes you need to distinguish a missing entry from a zero value. Is there an entry for "UTC" or is that the empty string because it's not in the map at all? You can discriminate with a form of multiple assignment.
var seconds int
var ok bool
seconds, ok = timeZone[tz]
For obvious reasons this is called the “comma ok” idiom. In this example, if tz is present, seconds will be set appropriately and ok will be true; if not, seconds will be set to zero and ok will be false.
Playground demonstrating this
We can see that this differs from calling a regular function where the compiler would tell you that something is wrong:
package main
import "fmt"
func multiValueReturn() (int, int) {
return 0, 0
}
func main() {
fmt.Println(multiValueReturn)
asgn1, _ := multiValueReturn()
asgn2 := multiValueReturn()
}
On the playground this will output
# command-line-arguments
/tmp/sandbox592492597/main.go:14: multiple-value multiValueReturn() in single-value context
This gives us a hint that it may be something the compiler is doing. Searching the source code for "commaOk" gives us a few places to look, including types.unpack
At the time of writing this it this the method's godoc reads:
// unpack takes a getter get and a number of operands n. If n == 1, unpack
// calls the incoming getter for the first operand. If that operand is
// invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a
// function call, or a comma-ok expression and allowCommaOk is set, the result
// is a new getter and operand count providing access to the function results,
// or comma-ok values, respectively. The third result value reports if it
// is indeed the comma-ok case. In all other cases, the incoming getter and
// operand count are returned unchanged, and the third result value is false.
//
// In other words, if there's exactly one operand that - after type-checking
// by calling get - stands for multiple operands, the resulting getter provides
// access to those operands instead.
//
// If the returned getter is called at most once for a given operand index i
// (including i == 0), that operand is guaranteed to cause only one call of
// the incoming getter with that i.
//
The key bits of this being that this method appears to determine whether or not something is actually a "comma ok" case.
Digging into that method tells us that it will check to see if the mode of the operands is indexing a map or if the mode is set to commaok (where this is defined does give us many hints on when it's used, but searching the source for assignments to commaok we can see it's used when getting a value from a channel and type assertions). Remember the bolded bit for later!
if x0.mode == mapindex || x0.mode == commaok {
// comma-ok value
if allowCommaOk {
a := [2]Type{x0.typ, Typ[UntypedBool]}
return func(x *operand, i int) {
x.mode = value
x.expr = x0.expr
x.typ = a[i]
}, 2, true
}
x0.mode = value
}
allowCommaOk is a parameter to the function. Checking out where unpack is called in that file we can see that all callers pass false as an argument. Searching the rest of the repository leads us to assignments.go in the Checker.initVars() method.
l := len(lhs)
get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid())
Since it seems that we can only use the "comma ok" pattern to get two return values when doing a multi-value assignment this seems like the right place to look! In the above code the length of the left hand side is checked, and when unpack is called the allowCommaOk parameter is the result of l == 2 && !returnPos.IsValid(). The !returnPos.IsValid() is somewhat confusing here as that would mean that the position has no file or line information associated with it, but we'll just ignore that.
Further down in that method we've got:
var x operand
if commaOk {
var a [2]Type
for i := range a {
get(&x, i)
a[i] = check.initVar(lhs[i], &x, returnPos.IsValid())
}
check.recordCommaOkTypes(rhs[0], a)
return
}
So what does all of this tell us?
Since the unpack method takes an allowCommaOk parameter that's hardcoded to false everywhere except in assignment.go's Checker.initVars() method, we can probably assume that you will only ever get two values when doing an assignment and have two variables on the left-hand side.
The unpack method will determine whether or not you actually do get an ok value in return by checking if you are indexing a slice, grabbing a value from a channel, or doing a type assertion
Since you can only get the ok value when doing an assignment it looks like in your specific case you will always need to use variables
You may save a couple of key strokes by using named returns:
func FindUserInfo(id string) (i Info, ok bool) {
i, ok = all[id]
return
}
But apart from that, I don't think what you want is possible.
Simply put: the reason why your second example isn't valid Go code is because the language specification says so. ;)
Indexing a map only yields a secondary value in an assignment to two variables. Return statement is not an assignment.
An index expression on a map a of type map[K]V used in an assignment or initialization of the special form
v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]
yields an additional untyped boolean value. The value of ok is true if the key x is present in the map, and false otherwise.
Furthermore, indexing a map is not a "single call to a multi-valued function", which is one of the three ways to return values from a function (the second one, the other two not being relevant here):
There are three ways to return values from a function with a result type:
The return value or values may be explicitly listed in the "return" statement. Each expression must be single-valued and assignable to the corresponding element of the function's result type.
The expression list in the "return" statement may be a single call to a multi-valued function. The effect is as if each value returned from that function were assigned to a temporary variable with the type of the respective value, followed by a "return" statement listing these variables, at which point the rules of the previous case apply.
The expression list may be empty if the function's result type specifies names for its result parameters. The result parameters act as ordinary local variables and the function may assign values to them as necessary. The "return" statement returns the values of these variables.
As for your actual question: the only way to avoid temporary variables would be using non-temporary variables, but usually that would be quite unwise - and probably not much of an optimization even when safe.
So, why doesn't the language specification allow this kind of special use of map indexing (or type assertion or channel receive, both of which can also utilize the "comma ok" idiom) in return statements? That's a good question. My guess: to keep the language specification simple.
I'm no Go expert but I believe you are getting compile time error when you are trying to return the array i.e. return all[id]. The reason could be because the functions return type is specially mentioned as (Info, bool) and when you are doing return all[id] it can't map the return type of all[id] to (Info, bool).
However the solution mentioned above, the variables being returned i and ok are the same that are mentioned in the return type of the function (i Info, ok bool) and hence the compiler knows what it's returning as opposed to just doing (i Info, ok bool).
By default, maps in golang return a single value when accessing a key
https://blog.golang.org/go-maps-in-action
Hence, return all[id] won't compile for a function that expects 2 return values.
I want to save a true/false in my MySQL database. I'm saving 1/0 in an INT column to do this. When I select it, I get the 1 or 0, but I want it to return true/false to my PHP code, without having to rewrite the database.
Can I use another column type? Should I save it differently?
Update: My question is about not wanting to rewrite the returned value. I'm getting a lot of results from my database. Many of those are true/false, but some are 0s because the price is 0, so I don't want to universally rewrite all 1s and 0s. I also don't want to manually rewrite 10 columns.
To follow up my comment, here's a more detailed response which also covers the PHP side, although this probably belongs on StackOverflow.
I've always just used tinyint, although you can use bool/boolean which are synonyms for tinyint(1)
However as of MySQL 5.0.3 you can use the bit type:
As of MySQL 5.0.3, the BIT data type is used to store bit-field values. A type of BIT(M) enables storage of M-bit values. M can range from 1 to 64.
Next, assuming you have an active column, perhaps to store if a user is active, you could use PHP's automatic type conversion to handle this quite simply.
// Obviously you'd replace this with your database call
$results = [['active' => 1], ['active' => 0]];
foreach($results as $row) {
if ($row['active'] == true) {
echo "true\n";
}
else {
echo "false\n";
}
}
You don't strictly need to do anything.
PHP does not, and can not, use strongly typed variables. So, if you receive an (int) 1 from your query results, you can simply use this 1 as a boolean without rewriting or changing anything.
$intOne = (int) 1; //explicitly treat the variable as an integer
var_dump((bool) $intOne); //treat the variable as a boolean
When used in any boolean context, like if ($variable)... then any of these types will be considered to be false by PHP:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
... And, most importantly;
Every other value is considered TRUE (including any resource).
Source: PHP Manual > Booleans (english)
So while you can change the storage type of your column in mysql, this won't really change the way PHP handles the variable retrieved from your results at all.
Historically, I've always used a column of type TINYINT(1) to store boolean values in mysql, and as Tom Green points out, recent mysql versions provide a new BIT type, which might be appropriate. To the best of my knowledge, mysql does not currently have an actual boolean data type.
You could just as easily use a column of type VARCHAR(1), though, because PHP can and will use any value as a boolean, thanks to the glorious, majestic, and sometimes maddening, PHP Type Juggling.
If you're trying to use the values you're retrieving for boolean logic, just use the values you receive from mysql like booleans and it will work:
if ($valueFromResults) {
//The value was something like true
} else {
//The value was something like false
}
If you're trying to actually echo out the words "true" and "false", then you're probably best served by explicitly echoing the words out yourself, like this;
if ($valueFromResults) {
echo "true";
} else {
echo "false";
}
or, in my preferred shorthand;
echo ($valueFromResults) ? "true" : "false" ;
Update You mentioned in a comment that you want to pass the values through json_encode() and use them in javascript.
JavaScript treats any real value, like int 1, as true and any empty value, like int 0, or an empty string, as false. So if your json_encode() output gets used in actual JavaScript, the int values will still work as boolean values. So the integer values from your database should still work as they are.
Just check that your integer results are encoded as integers by PHP and not as strings - they should be encoded correctly by default - because "0" == true in javascript, but 0 == false.
For a boolean value (true/false), you should use the mySql type bit or tinyint(1).
$boolean = $mysql_data ? true : false;
I am trying to insert a value from a text box into a SQL table. Although when I leave the text box blank it is adding a blank value which then causes the rest of the form functions to not work.
I want the if statement to check if $animal is blank do nothing. And if $animal has something in it, then to perform the insert into the table.
I am not quite sure what to put where I have put.
if ($animal = " ") {
}
else
if ($animal = "???") {
insertTable("INSERT INTO $table(name) VALUE ('".$animal."')");
Line 24 - 27 is this
sub insertTable {
$statement = shift (#_);
$dbh->do($statement);
} # sub
Perl uses scalar variables, which are quite versatile little things. One of the gotchas with them is that their 'truthiness' isn't always obvious.
If you test a scalar with a Boolean test it will be false if:
It's undefined.
It's an empty string.
It's the number 0.
It's the string "0".
(Arrays test as false if they're undefined or have no elements.)
So the correct answer would be - either used defined to check if the value is defined. Or use a regular expression to pattern match a 'valid' value.
E.g.
if ( $animal =~ m/\w+/ ) {
# Do something
}
\w+ is the Perl regular expression for saying 'one or more word characters' which is alphanumeric and underscore. So your empty string, whitespace only string, or undefined string will all not match this pattern.
Quite a few problems here. Addressing the worst of them:
You're using = which is for assignment, not comparison. Use == to compare numbers and eq to compare strings.
You're comparing your variable to a single space. It's very unlikely that you'll get a single space character in $animal. You'll want to do something either far simpler (if ($animal) { ... }) or more complex (perhaps if ($animal =~ /\w/) { ... }).
You are interpolating user input directly into SQL which you then run against your database. This leads to SQL injection attacks. Far better to use a bind point in your SQL.
In Perl there isn't a null value, only an undefined!
if (defined $value)
{
# Do that
}
else
{
# Do this
}
Just wanted to know if someone can explain the difference between these two conditionals:
if ( !object )
if ( object == null )
where object is an instance of a user-defined class.
I'm sure that these two cannot be used in an interchangeable manner, or are they?
Thanks.
The effect is in practice the same, so I guess you could say they're interchangeable.
In a boolean context (such as a conditional), an expresion is evaluated to either true or false.
In Actionscript 3.0, the following values evaluate to false:
false
null
0
NaN
"" (the empty string)
undefined
void
Everything else evaluates to true.
A reference to an user-defined class instance can either be null or not null.
So, in this case:
if ( object == null )
Obviously, the condition is met only if object is null.
In this other case:
if ( !object )
The expression object will evaluate to false if object is null. If it is null, the expression is false. Since this is in turn negated, the final value will be true and so the condition will be satisfied. So, just like in the first case, if object is null, the condition is met. And like in the first case, again, if object is not null, the condition is not met.
There's no other option if your variable is typed to a user-defined class; such a variable can only contain a valid reference or null; i.e. it can't hold any value evaluable to false in a boolean context, except for null; so, again, it's either null or not null. Which is why both code samples have the same effect.
The first is making a boolean comparison. If the object is false, the not(!) operation will make the condition true, if the object has a value other than false the statement will fail.
The second conditional is evaluating if the object has the value of null or not.
The reason these may be interchangeable is that various languages allow some equivalence between 0, false, null (or "\0") and other values of similar meaning.
I do not know actionscript, but testing equivalence of false, null, 0 etc., or reading the docs on boolean values, will be of some benefit.
Sure not :)
The first one means that the proposition is true only if different from the object;
The second one is true only if the object equals to null.
"!" means "is not the object"
"==" means that the the object has to have the value equal to the one at the right of the symbol