assertEquals() fails when comparing '0' to false, but passes when comparing '1' to true
$this->assertEquals( '0', false ); // fails
$this->assertEquals( '1', true ); // passes
Can someone explain this?
A string is not false, nor is it true. PHPUnit does a complete equal, so even 1 does not equal true.
PHPUnit uses the === (triple equals) operator on comparison, so therefore, only TRUE === TRUE, not 1.
PHPUnit has very complex assertion system. For this case there would be use PHPUnit_Framework_Comparator_Scalar class, which has this code:
public function assertEquals($expected, $actual, $delta = 0, $canonicalize = FALSE, $ignoreCase = FALSE)
{
$expectedToCompare = $expected;
$actualToCompare = $actual;
// always compare as strings to avoid strange behaviour
// otherwise 0 == 'Foobar'
if (is_string($expected) || is_string($actual)) {
$expectedToCompare = (string)$expectedToCompare;
$actualToCompare = (string)$actualToCompare;
// omitted
}
if ($expectedToCompare != $actualToCompare) {
throw new PHPUnit_Framework_ComparisonFailure(
// omitted
);
}
}
If one of values is string they both converted to string.
var_dump((string)false); // string(0) ""
var_dump((string)true); // string(1) "1"
Related
This is a function to compare two strings recursively. It works fine as:
compareStr("", ""); --- returns true.
compareStr("house", "houses"); --- returns false.
But for some reason, this invocation returns undefined:
compareStr('tomato', 'tomato');
Even stranger is the fact that the function is making it into the code block and logging "should return true" to the console, but it's completely skipping the return statement, and returning undefined instead.
var compareStr = function (str1, str2) {
if (str1 === '' && str2 === '') {
console.log('Should return true');
return true;
}
var arr1 = str1.split('');
var arr2 = str2.split('');
var frag1 = arr1.pop();
var frag2 = arr2.pop();
if (frag1 === frag2) {
var strA = arr1.join('');
var strB = arr2.join('');
compareStr(strA, strB);
} else {
return false;
}
};
You are missing a return.
return compareStr(strA, strB);
I'm using rxjs map to retrive data in firestore like this:
getArtists(): Observable<DocumentData> {
const users$ = this.firestore.collection('/Users').get()
users$.subscribe((users) => {
users.docs.map(user => user.data().artistName !== "" && user.data().role === 'ARTIST')
});
return users$;
}
but when i'm getting value like this :
this.userService.getArtists().subscribe(
(userDocs) => {
userDocs.docs.map((user) => {
this.artists.push(user.data());
console.log(this.artists)
this.record = this.artists.length;
})
});
it's return always the user when the artistName is equals to "" and role is not equals to 'ARTIST'.
why ?
thank's everybody!
you need to map data in a map operator instead of a subscription and return a value in as a pipe.
Unfortunately, in your code isn't clear what and when you want to filter, why a user is in users.docs when it tend to be a doc.
Please check an example below and consider updating your question with more info.
import {filter, map} from 'rxjs/opreators';
getArtists(): Observable<DocumentData> {
return this.firestore.collection('/Users').get().pipe( // <- use pipe
map(users => {
// here some changes in users if we need.
return users;
}),
),
filter(users => {
returns true; // or false if we don't want to emit this value.
}),
}
I have an array of objects (not primitives) called "streaks" on my state tree and I want to observe only the changes to that array, not simply emit the entire array every time it changes. When I try this using pairwise() I get two identical arrays every time, even though I thought pairwise() would join the previous version and the current version. Why is pairwise() sending two identical arrays? NOTE streaks[1] and streaks[0] are identical, so _.differenceBy() isn't finding any changes because the two arrays are the same.
import {from} from "rxjs";
import {map, pairwise} from "rxjs/operators";
import * as _ from 'lodash';
const state$ = from(store);
const streaks$ = state$.pipe(
map(state => state.streaks),
// distinctUntilChanged(), <-- i've tried this and nothing is output at all
pairwise(),
map(streaks => {
let diff = _.differenceBy(streaks[0], streaks[1], _.isEqual);
console.log('diff', diff); //<-- this is an empty array
return diff;
})
);
streaks$.subscribe((streaksArray) => {
console.log('STREAKS$ 0', streaksArray); //<-- this is never even hit
} );
I solved this issue by creating an distinctUntilChangedArray operator that uses a self written compareArray function
Create compare array function
const compareArray<T> = (first: T[], second: T[], comparator=: (obj: T, obj2: T) => boolean): boolean {
return (first.length === 0 && second.length === 0)
|| (first.length === second.length && first.every((value, index) => {
return comparator
? comparator(value, second[index])
: JSON.stringify(value) === JSON.stringify(second[index]);
}))
}
Maybe you find a better array comparator. This is just my personal implementation of it
Create distinctUntilChangedArray operator
const distinctUntilChangedArray<T> = (comparator?: (prev: T, curr: T) => boolean): MonoTypeOperatorFunction<T[]> {
return distinctUntilChanged((prev: T[], curr: T[]) => {
return compareArray(first, second, comparator);
}
}
Final usage
interface nonPrimitive {
id: number;
name: string;
}
const nonPrimitiveComparator = (prev: nonPrimitive, curr: nonPrimitive): boolean => {
return prev.id === curr.id && prev.name === curr.name;
}
const source$: Observable<nonPrimitive>;
const distinctedSource$ = source$.pipe(
distinctUntilChangedArray(nonPrimitiveComparator)
);
I want to stop automatic conversion of a day that does not exist.
FormType
$builder
->add("start", new DateTimeType(), [
"date_widget" => "single_text",
"minutes" => [0, 20, 40],
"required" => true,
])
;
Validation
//...
start:
- DateTime: ~
- NotBlank: ~
In this case, it will worked automatic conversion of value.
"2017-03-33" value was converted to "2017-04-02" value.
And it passed the form validation check.
I want to make an error if input value of form(the date) does not exist.
Thank you if you know.
This behaviour is caused by the DateTimeType class. It uses DateTime::createFromFormat method for entered value conversion which auto-corrects the value to valid value.
More can be founded in this article https://derickrethans.nl/obtaining-the-next-month-in-php.html
If the converted value was valid or invalid can be figured out by the DateTime::getLastErrors() method, so the solution for your desired behaviour is to custom DateTimeType class.
Quick untested example:
class CustomDateTimeType extends Type
{
...
...
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null || $value instanceof \DateTime) {
return $value;
}
$val = \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);
if( \DateTime::getLastErrors()['warning_count'] > 0 ) {
throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString());
}
...
...
I have a in issue where I would like to swap out Moq for NSubstitute entirely. In most cases, this is extremely straightforward, however I have run across a fairly specialized issue.
Here's the Moq code.
_registrationCommandHandler.Setup(c => c.Execute
(It.Is<CheckUniqueUserCommand>(r => r.Request.UserName == "fred"))).
Callback((CheckUniqueUserCommand c) =>
{
c.Response = new CheckUserNameIsUniqueResponse()
{
IsUnique = true,
Success = true
};
c.Success = true;
});
The closest I seem to be able to get with NSubstitute is
_registrationCommandHandler.When(c => c.Execute
(Arg.Any<CheckUniqueUserCommand>())).Do
((CheckUniqueUserCommand c) =>
{
c.Response = new __Internal.CheckUserNameIsUniqueResponse()
{
IsUnique = true,
Success = true
};
c.Success = true;
});
which won't even compile. This leaves me a bit stuck. Does anyone have any suggestions?
I'm guessing a bit here, but try:
_registrationCommandHandler
.When(c => c.Execute(Arg.Is<CheckUniqueUserCommand>(r => r.Request.UserName == "fred")))
.Do(call => {
var c = call.Arg<CheckUniqueUserCommand>();
c.Response = new __Internal.CheckUserNameIsUniqueResponse()
{
IsUnique = true,
Success = true
};
c.Success = true;
});
NSubstitute does not do the same argument passing as Moq does for callbacks. Instead it passes a parameter with information about the call, and you can access the arguments using call.Arg<T> or call[i].
In addition to changing the .Do block, I also switched from using Arg.Any(..) to Arg.Is(..) to closer match the Moq sample.
Hope this helps.