I want to check that an array contains only objects of a specific class, let's say Float.
A working example at the moment:
it "tests array_to_test class of elements" do
expect(array_to_test.count).to eq(2)
expect(array_to_test[0]).to be_a(Float)
expect(array_to_test[1]).to be_a(Float)
end
Is there a way to validate if the array_to_test contains only Float instances?
Sample non-working pseudocode:
it "tests array_to_test class of elements" do
expect(array_to_test).to be_a(Array[Float])
end
Do not consider Ruby and Rspec version as a restriction.
Try all:
expect(array_to_test).to all(be_a(Float))
You could use ruby methods:
expect(array_to_test.map(&:class).uniq.length) to eq(1)
Or for better practice, implement a Helper using those methods:
RSpec::Matchers.define :all_be_same_type do
match do |thing|
thing.map(&:class).uniq.length == 1
end
end
and then use it this way:
expect(array_to_test) to all_be_same_type
Related
Is there a way to remove a number from an attibute array in an update? For example, if I want to update all of an alchy's booze stashes if he runs out of a particular type of booze:
Alchy has_many :stashes
Stash.available_booze_types = [] (filled with booze.ids)
Booze is also a class
#booze.id = 7
if #booze.is_all_gone
#alchy.stashes.update(available_booze_types: "remove #booze.id")
end
update: #booze.id may or may not be present in the available_booze_types array
... so if #booze.id was in any of the Alchy.stash instances (in the available_booze_types attribute array), it would be removed.
I think you can do what you want in the following way:
if #booze.is_all_gone
#alchy.stashes.each do |stash|
stash.available_booze_types.delete(#booze.id)
end
end
However, it looks to me like there are better ways to do what you are trying to do. Rails gives you something like that array by using relations. Also, the data in the array will be lost if you reset the app (if as I understand available_booze_types is an attribute which is not stored in a database). If your application is correctly set up (an stash has many boozes), an scope like the following in Stash class seems to me like the correct approach:
scope :available_boozes, -> { joins(:boozes).where("number > ?", 0) }
You can use it in the following way:
#alchy.stashes.available_boozes
which would only return the ones that are available.
I have files in folder that I want to read all at once, bind and make new dataframe.
Code:
using CSV, DataFrames
path="somepath"
files=readdir(path)
d=DataFrame()
for file=files
x=CSV.read(file)
d=vcat(d,x)
end
Produces:
Error: UndefVarError: d not defined
You can use append! in such cases (change allowing this approach is on master but is not released yet):
d=DataFrame()
for file=files
append!(d, CSV.read(file))
end
or, if you want to use vcat (this option will use a bit more memory):
reduce(vcat, [CSV.read(file) for file in files])
The original code should be rewritten as:
d=DataFrame()
for file=files
x=CSV.read(file)
global d=vcat(d,x)
end
(note global in front of d) but this is not a recommended way to perform this operation.
I'm writing automated tests for one site. There's a page with all items added to the cart. Maximum items is 58. Instead of verification of each element one by one I decided to create 2 arrays filled with strings: 1 with correct names : String and 1 with names : String I got from the site. Then I compare those 2 arrays with contentEquals.
If that comparison fails, how do I know which element exactly caused comparison fail?
Short simple of what I have now:
#Test
fun verifyNamesOfAddedItems () {
val getAllElementsNames = arrayOf(materials.text, element2.text,
element3.text...)
val correctElementsNames = arrayOf("name1", "name2", "name3"...)
val areArraysEqual = getAllElementsNames contentEquals correctElementsNames
if (!areArraysEqual) {
assert(false)
} else {
assert(true)
}
}
This test fails if 2 arrays are not the same but it doesn't show me the details, so is there a way to see more details of fail, e.g. element that failed comparison?
Thanks.
I recommend using a matcher library like Hamcrest or AssertJ in tests. They provide much better error messages for cases like this. In this case with Hamcrest it would be:
import org.hamcrest.Matchers.*
assertThat(getAllElementsNames, contains(*correctElementsNames))
// or just
assertThat(getAllElementsNames, contains("name1", "name2", "name3", ...))
There are also matcher libraries made specifically for Kotlin: https://github.com/kotlintest/kotlintest, https://yobriefca.se/expect.kt/, https://github.com/winterbe/expekt, https://github.com/MarkusAmshove/Kluent, probably more. Tests using them should be even more readable, but I haven't tried any of them. Look at their documentation and examples and pick the one you like.
You need to find the intersection between the two collections. Intersection will be the common elements. After than removing the intersection collection from the collection you want to perform the test will give you the complementary elements.
val intersection = getAllElementsNames.intersect(correctElementsNames)
getAllElementsNames.removeAll(intersection)
Given:
class Thing
def initialize(object)
#object = object
end
end
items = [1,2,3]
I'd like to know of a more elegant way to convert each item to the Thing than this:
items.map{ |item| Thing.new item }
# => [<Thing #object=1>, <Thing #object=2>, <Thing #object=3>]
You can use the unary prefix & operator:
items.map(&Thing.method(:new))
I have suggested that Classes should behave as Factory Functions, which would allow you to write it like this:
items.map(&Thing)
However, there doesn't seem to be much interest in the proposal. You can monkey-patch it yourself, though, the implementation is trivial:
class Class
def to_proc
method(:new).to_proc
end
end
I would argue that your example is perfectly fine. But perhaps you like something like this:
# in item.rb
def to_thing
Thing.new(self)
end
That would allow you to write:
items.map(&:to_thing)
I am using Rails 4.2 with PostGIS, rgeo and the activerecord-postgis-adapter gem on Ubuntu. I have also installed the following libraries: libgeos++-dev libgeos-3.4.2 libgeos-c1 libgeos-dbg libgeos-dev libgeos-doc libgeos-ruby1.8 ruby-geos. An RGeo::Error::UnsupportedOperation is being raised when I call contains? on an RGeo::Geographic::SphericalMultiPolygonImpl. How do I make the Feature::Geometry methods available to my RGeo::Geographic::SphericalMultiPolygonImpl?
You probably need to break up that multipolygon into pieces and run a "contains" call on each of them. I'm guessing the #contains method must be run on one polygon at a time. Here's what that operation might look like:
responses = {}
n = this_shape.num_geometries
(0..n).to_a.each do |i|
responses[i] = this_shape.geometry_n(i).contains?(other_shape)
end
Alternatively, you could break up those multipolygons into individual polygons and then run the loop on the array...