RSpec how to use a_collection_containing_exactly matcher with an array? - ruby-on-rails

I'd really like to use the a_collection_containing_exactly matcher but with an array in parameters instead of writing values directly, like this
contract_ids_subset = order_summaries_subset.map {|c| c.contract_id.to_i}.compact
allow(Shipping::Owner::Api::Helper).to receive(:order_summaries_by_contract_ids_and_delivery_date).with(
a_collection_containing_exactly(contract_ids_subset),
delivery_date) {
order_summaries_subset
}
( assume that contract_ids_subset = [11111, 22222, 99999] )
This work if I hardcode
a_collection_containing_exactly(11111, 22222, 99999)
But I cant figure out how to use an array [11111, 22222, 99999] with the same results ???

You're looking for the splat operator in ruby to deconstruct the array. It'll basically take the single argument of the array and deconstruct it such that each value becomes an argument.
So you'd do something like:
a_collection_containing_exactly(*contact_ids_subset)

Related

Lua equivalent of dictionary.get() method?

How do I access a dictionary using a parameter?
In python I can do dictionary.get(param)
Is there an equivalent to this in lua?
I want to do something like this:
function make_object_from_flag(x, y, flag)
local flag_obj = {
[1] = make_impassable_object(x, y),
[2] = make_coin(x,y),
[4] = make_screen_transition_object(x, y),
}
flag_obj.get(flag)
end
Lua only has a single data structure, which is essentially a map (or dictionary) just called "table".
Table indexing in Lua usually works using brackets [], just like python does with arrays.
So basically, as Egor Skriptunoff pointed out in his comment, you want flag_obj[flag] to access the value associated with the key flag in the table flag_obj.
Note though that using bit flags as is done in C is very uncommon and not very performant in Lua, and shouldn't normally be done unless there's some good reason for it.

Use isEqualByComparingTo in Predicate

normal use of nice assertj-matchers like isEqualByComparingTo:
BigDecimal number = ...
assertThat(number).isEqualByComparingTo(BigDecimal.valueOf(...));
however I have a list of BigDecimals and want to check each element in the list for equality by using assertj's matchers like isEqualByComparingTo:
List<BigDecimal> numbers = ...
assertThat(numbers).allMatch( ???.isEqualByComparingTo(BigDecimal.valueOf(...) )
instead i have to use the tedious low-level comparisons:
List<BigDecimal> numbers = ...
assertThat(numbers).allMatch( number -> number.compareTo(...) == 0 )
is it somehow possible, to use the nice matchers inside a predicate?
Try usingElementComparator with BigDecimalComparator (or write your own BigDecimalComparator).
Example:
List<BigDecimal> numbers = list(new BigDecimal("1.00"), new BigDecimal("2.00"));
assertThat(numbers).usingElementComparator(new BigDecimalComparator())
.contains(new BigDecimal("1.0"), new BigDecimal("2"));

Find sum of all elements using ruby and selenium

In my web page there are 5 values given in the text field(like $10, $20, $30, $40 and $50) and I am trying to sum the values using ruby and selenium WebDriver.
Here is my code:
def get_sum_of_all_elements()
#logger.info("Searching element #{value1, value2, value3, value4, value5}");
allelements = #driver.find_elements(:id = "lbl_val_")
#logger.info("Total Elements Found with locator #{locator} are : #{allelements.size}");
if allelements.start_with?("$")
allelements = "((allelements))".tr('$', '') #removing '$' sign from values
iSum =0
allelements.each do|i|
iSum += i
end
end
end
I am expecting to see output as 150. Do I need to store values in an array?
Any help would be appreciated.
There a couple of things you should modify in your code to make it work:
Fix how arguments are passed to find_elements; it should be id: "lbl_val_".
find_elements returns an array of WebDriver::Element objects, so you must check the value for each object.
The string "Searching element #{value1, value2, value3, value4, value5}" is not valid since you are trying to interpolate the value of 5 variables chained with a comma. You either need to interplate only the variable (keeping commas as strings) or use square brackets ([]) to interpolate an array.
Now your code should look something like this1:
def get_sum_of_all_elements
#logger.info("Searching element #{[value1, value2, value3, value4, value5]}")
allelements = #driver.find_elements(id: "lbl_val_")
#logger.info("Total Elements Found with locator #{locator} are : #{allelements.size}");
if allelements.all? { |elem| elem.value.start_with?("$") }
elements = allelements.map { |elem| elem.value.tr('$', '').to_i }
elements.reduce(:+)
end
end
A few things to note:
Parenthesis (()) were removed in method definition, ruby doesn't need them when no arguments are passed.
There is no longer need to assign the final value to a variable (e.g iSum) since ruby will return the result of last evaluated code.
If any value doesn't start with "$", it will return false. You could change this by adding a default value after if block.
Semicolons (;) were removed, you don't need them in ruby (unless you want to chain multiple statements in a singe line).
One more thing, the variables value1, value2, value3, value4, value5 and locator doesn't seem to be set anywhere in your method; you must set them within your method (or pass them as arguments) or you will get an error.
1 This considers the same logic that you seemed to be looking for in your code, that is, sum all values only if all of them start with "$".
It's hard to say exactly what you are trying to do, but this might help. I assume you have an array of string values with dollar signs:
>> allelements = ["$10", "$20", "$30", "$40", "$50"]
=> ["$10", "$20", "$30", "$40", "$50"]
We can make a new array stripping out all non-numeric characters and transforming the string values to integers:
>> integers = allelements.map { |e| e.gsub(/[^\d]/, '').to_i }
=> [10, 20, 30, 40, 50]
Now use inject to sum the values:
>> integers.inject(:+)
=> 150

Difference between passing &:method and :method as function arguments in ruby

I'm struggling in understanding when to use the ampersand in passing symbols to functions representing a method. For example, If I wanted to calculate the sum of the range 1..10, I could do the following:
(1..10).inject(:+)
This originally lead me to believe that if you wanted to pass a symbol to define a method to "Magically" be used in the function, you would pass the function name as a symbol. But then I see something like this in rails:
total = Product.find(product_list).sum(&:price)
If I understand correctly, &:price is the same as calling :price.to_proc. I don't understand how the above works.
In actual parameter list of a method call, &object is built-in syntax, which will
convert object to a Proc using object.to_proc
pass the Proc as the block parameter of the method
Symbol#to_proc converts the symbol (eg. :the_symbol) to proc {|obj| obj.send(:the_symbol)}. And you can use this syntax whenever object responds to to_proc method and returns a Proc.
abc = "aha~"
class << abc
def to_proc
proc {|obj| obj.to_i * 2 }
end
end
p ["1", "2", "3"].map(&abc)
#=> [2, 4, 6]
(1..10).inject(:+) shows that inject accepts a symbol as parameter. How the symbol is used is method specific behavior. In inject's special case, it has the same effect as (1..10).inject{|a, b| a.send(:+, b)}. It's just a simple, normal parameter, the effect depends on the implementation of the method that accept the symbol as parameter.
Note that sum in ActiveSupport accepts a block with single parameter, which has the effect "map values in the original sequence to new ones and calculate the sum of them", so
total = Product.find(product_list).sum(&:price)
is equivalent as
total = Product.find(product_list).sum(&proc{|p| p.send(:price)})
# or you may write
total = Product.find(product_list).sum{|p| p.price }
which has the same return value as the following but won't produce intermediate temp array:
total = Product.find(product_list).map{|p| p.price}.sum

lua modify arrays inside function

I am trying to modify a collection of arrays inside of a variadic function. I end up working on a copy when trying to add to the arrays and they get lost after the call. Is there any way to pass values by ref in Lua?
function myfunc(...)
local args = {...}
--do work on args--
end
"do work" doesn't actually end up doing anything but it works outside the function just fine.
Obviously I could pass an array of arrays and not use ... but that kinda defeats the purpose of using ...
In Lua, you can't just choose to pass variables by reference or not. Basic types are never passed by reference (like numbers and booleans), others are always passed by reference (like tables, userdata and strings). In the case of strings this does not matter much, because they are immutable anyhow.
So either you pass your arguments you want to work on globally as strings like this:
a=2
b=3
function myfunc(...)
local args={...}
for k,v in pairs(args) do
_G[v]=_G[v]+k
end
end
myfunc('a')
print(a) -- 3
myfunc('a','b')
print(a,b) -- 4 5
Note that this only works on globals, since locals are not kept in a table.
Working with tables makes this kind of things less painful:
function myfunc(t)
for k,v in pairs(t) do
t[k]=v+k
end
end
tab1={a=2}
myfunc(tab1)
print(tab1.a) -- 3
tab2={a=2,b=3}
myfunc(tab2)
print(tab2.a,tab2.b) -- 3 5
The purpose of using ... is grouping the whole parameter list in one varible. That has little to do with the by-reference or by-value nature of the parameters.
All natural types in Lua are passed by value, with tables being the only exception.
The simplest way to do what you want is to pass an array of arrays. If the two extra characters seem like too much typing, know that you can remove the parenthesis instead:
foo({a,b,c})
foo{a,b,c} -- equivalent

Resources