How do I use Rhino.Mocks.RhinoMocksExtensions.VoidType with lambda Expect? - rhino-mocks

I get the following error on this line:
session.Expect(s => s.Add("string", null)).IgnoreArguments().Return(SaveMockUser());
cannot convert from 'void' to 'Rhino.Mocks.RhinoMocksExtensions.VoidType'
SaveMockUser is defined as follows
private void SaveMockUser()
{
}
What am I doing wrong?

It's not possible to return a void type. Probably what you want to do is have another expectation that expects that SaveMockUser() is actually called or actually perform the action via a callback - i.e., when you see this function called, then do this.
session.Expect( s => s.Add("string", null) )
.IgnoreArguments()
.WhenCalled( x => SaveMockUser() );
or even better - use the new inline constraints
session.Expect( s => s.Add( Arg<string>.Is.Equal( "string" ), Arg<string>.Is.Anything ) )
.WhenCalled( x => SaveMockUser() );

Related

Using react native async storage getItem

React.useEffect(_ => {
ReactNativeAsyncStorage.getItem("jwt")
|> Js.Promise.then_(jwt => {Js.log(jwt)});
None;
});
Error:
This expression has type unit but an expression was expected of type
Js.Promise.t('a) = Js.Promise.t('a)
I am using https://github.com/reason-react-native/async-storage with https://github.com/react-native-community/async-storage
The type of Js.Promise.then_ is
('a => t('b), t('a)) => t('b)
which means the function passed to it must return a, and that then_ itself will return that promise.
You're making two mistakes in your code:
You are not returning a promise from the function you pass to then_
You are not handling the promise returned by then_.
The following fixes both:
React.useEffect(_ => {
let _: Js.Promise.t(unit) =
Js.Prmoise.(
ReactNativeAsyncStorage.getItem("jwt")
|> then_(jwt => resolve(Js.log(jwt)))
);
None;
});
let _: Js.Promise.t(unit) = ... uses the wildcard pattern to discard the result of the following expression. The type of the result is Js.Result.t(unit), which is annotated to protect against accidental partial application.
resolve(Js.log(jwt)) will return a promise with the result of calling Js.log, which is unit, hence why the resulting promise has the type Js.Promise.t(unit).
See the Reason documentation for more on how to use promises.

Can one perl6 module conditionally 'use' another perl6 module?

Is there a sensible way to have one perl6 module check for the presence of another perl6 module and to 'use' it if and only if it is installed?
Something like this...
module Polygons;
if $available {
use Measure; #only if Measure is installed
}
class Rectangle is export {
has $.width;
has $.height;
method area {
$!width * $!height; #provides operator overload for Measure * Measure
}
}
#====================
module Measure;
class Measure is export {
has $.value;
has $.unit;
method Real {
$!value;
}
method Str {
"$!value $!unit";
}
method multiply( $argument ) {
my $result = $.;
$result.value = $!value * $argument;
$result.unit = "$!unit2";
return $result;
}
}
multi infix:<*> ( Measure:D $left, Measure:D $right ) is export {
return $result.multiply( $argument );
}
#====================
#main.p6
use Polygons;
use Measure;
my $x = Measure.new( value => 10, unit => 'm' );
my $y = Measure.new( value => 20, unit => 'm' );
my $rect = Rectangle.new( width => $x, height => y );
say $rect.area; #'200 m2'
The idea is to propagate the operator overload (infix:<*> in this case) back up the class inheritance so that one store more elaborate objects in the attributes.
(Without tearing up the drains please - since I suspect there is always a way!)
So the first version of this answer was essentially useless.
Here's the first new thing I've come up with that works with what I understand your problem to be. I haven't tried it on the repo yet.
In a file a-module.pm6:
unit module a-module;
our sub infix:<*> ($l,$r) { $l + $r } }
The our means we'll be able to see this routine if we can require it, though it'll only be visible via its fully qualified name &a-module::infix:<*>.
Then in a using file:
use lib '.';
try require a-module;
my &infix:<*> = &a-module::infix:<*> // &OUTER::infix:<*>;
say 1 * 2 # 2 or 3 depending on whether `a-module.pm6` is found
The default routine used if the module is missing can be the one from OUTER (as shown) or from CALLER or whatever other pseudo package you prefer.
This problem/solution seems so basic I suspect it must be on SO or in the doc somewhere. I'll publish what I've got then explore more tomorrow.

Test contents of return array in PHPSpec

Say I have this method of a RuleFactory:
public function makeFromArray($rules)
{
$array = [];
foreach ($rules as $rule) {
$array[] = new Rule($rule[0], $rule[1]);
}
return $array;
}
I want to test that the return array contains Rule elements. Here is my test:
function it_should_create_multiple_rules_at_once()
{
$rules = [
['required', 'Please provide your first name'],
['alpha', 'Please provide a valid first name']
];
$this->makeFromArray($rules)->shouldHaveCount(2);
$this->makeFromArray($rules)[0]->shouldBeInstanceOf('Rule');
$this->makeFromArray($rules)[1]->shouldBeInstanceOf('Rule');
}
But this does not work, it throws an error in PHPSpec.
The strange thing is that I can do this just fine on other methods that return arrays, but for some reason I cannot do that here.
The error I get is this:
! it should create multiple rules at once
method [array:2] not found
How do I test the contents of this return array, WITHOUT creating my own inline matcher?
Your method accepts a single rule, not all of them. The spec should be:
$this->makeFromArray($rules)->shouldHaveCount(2);
$this->makeFromArray($rules[0])[0]->shouldBeAnInstanceOf('Rule');
$this->makeFromArray($rules[1])[1]->shouldBeAnInstanceOf('Rule');
Or, to avoid multiple calls:
$rules = $this->makeFromArray($rules);
$rules->shouldHaveCount(2);
$rules[0]->shouldBeAnInstanceOf('Rule');
$rules[1]->shouldBeAnInstanceOf('Rule');
Still, the most readable version would be the one leveraging a custom matcher:
$rules->shouldHaveCount(2);
$rules->shouldContainOnlyInstancesOf('Rule');

NHibernate check for same join in QueryOver

Using QueryOver I am creating a query like this
BulkActionItem bulkActionItemAlias1 = null;
BulkActionItem bulkActionItemAlias2 = null;
var query = GetSession().QueryOver<Student>(() => studentAlias)
.JoinAlias(() => studentAlias.BulkNotifications, () => bulkActionItemAlias1, NHibernate.SqlCommand.JoinType.LeftOuterJoin);
if (query.UnderlyingCriteria.GetCriteriaByAlias("bulkActionItemAlias2") == null
query = query.JoinAlias(() => studentAlias.BulkNotifications, () => bulkActionItemAlias2, NHibernate.SqlCommand.JoinType.LeftOuterJoin);
This will crash because I have the same join twice with different aliases. Is it possible to check if a join already exists on a query, even with a different alias?
I haven't found a built-in way to accomplish this. Typically I use an out parameter with extension methods to keep track of what tables are part of the query. For example:
bool joinedOnBulkNotifications;
BulkNotification notificationAlias = null;
Expression<Func<object>> aliasExpr = () => notificationAlias;
var query = GetSession().QueryOver<Student>(() => studentAlias)
.FilterByBulkNotificationStatus(
someCondition, aliasExpr, out joinedOnBulkNotifications);
public static class QueryExtensions
{
public static IQueryOver<Student, Student> FilterByBulkNotificationStatus(
this IQueryOver<Student, Student> query,
bool someCondition,
Expression<Func<object>> aliasExpr,
out bool joinedOnBulkNotifications)
{
joinedOnBulkNotifications = false;
if (someCondition)
{
joinedOnBulkNotifications = true;
query.JoinAlias(s => s.BulkNotifications, aliasExpr);
}
return query;
}
}
The issue is that you might need to reuse the alias you created later. You might be tempted to pass in a BulkNotification and use that, but this only works if the parameter name matches the name of the variable you pass to the extension method. NHibernate uses the name of the variable to create an alias name, so if these two do not match, you'll get an error. Because of this, you need to wrap the alias in an Expression and use that instead.
This isn't a very clean option, so I hope someone has a better solution.

How do I do a String.IsNullOrEmpty() test in an NHibernate Queryover where clause?

I hit a situation today where a field in our legacy db that should never be empty... was empty.
I am using NHibernate 3.2 against this database and the queries that are affected are written in QueryOver.
My current query is this
return Session
.QueryOver<FacilityGroup>()
.Where(fg => fg.Owner.Id == Token.OwnerId &&
fg.UserName == Token.UserName)
.OrderBy(fg => fg.Code).Asc
.TransformUsing(Transformers.DistinctRootEntity);
I want it to be this:
return Session
.QueryOver<FacilityGroup>()
.Where(fg => fg.Owner.Id == Token.OwnerId &&
fg.UserName == Token.UserName &&
!string.IsNullOrEmpty(fg.Code))
.OrderBy(fg => fg.Code).Asc
.TransformUsing(Transformers.DistinctRootEntity);
When I try this I get an exception "Unrecognised method call: System.String:Boolean IsNullOrEmpty(System.String)"
So NHibernate can't translate string.IsNullOrEmpty. Fair enough. However when I try this
return Session
.QueryOver<FacilityGroup>()
.Where(fg => fg.Owner.Id == Token.OwnerId &&
fg.UserName == Token.UserName &&
!(fg.Code == null || fg.Code.Trim() == "" ))
.OrderBy(fg => fg.Code).Asc
.TransformUsing(Transformers.DistinctRootEntity);
I get an InvalidOperationException "variable 'fg' of type 'Domain.Entities.FacilityGroup' referenced from scope '', but it is not defined"
Any thoughts?
Ok... I guess I asked this question too soon. I figured out a way around this.
What I was able to do was invoke the 'trim' function from hql via a SQL Function Projection. I ended up writing it as IQueryOver Extention method to keep it flexible. I will post it here in case anyone needs it.
public static class QueriesExtentions
{
public static IQueryOver<E, F> WhereStringIsNotNullOrEmpty<E, F>(this IQueryOver<E, F> query, Expression<Func<E, object>> propExpression)
{
var prop = Projections.Property(propExpression);
var criteria = Restrictions.Or(Restrictions.IsNull(prop), Restrictions.Eq(Projections.SqlFunction("trim", NHibernateUtil.String, prop), ""));
return query.Where(Restrictions.Not(criteria));
}
}
and here it is in use
return Session
.QueryOver<FacilityGroup>()
.Where(fg => fg.Owner.Id == Token.OwnerId && fg.UserName == Token.UserName )
.WhereStringIsNotNullOrEmpty(fg => fg.Code)
.OrderBy(fg => fg.Code).Asc
.TransformUsing(Transformers.DistinctRootEntity);