"bad value for range" is raised in rspec/turnip - ruby-on-rails

I'm using turnip for testing.
I wrote the following test:
session = ActionDispatch::Integration::Session.new(Rails.application)
str = "Basic " + Base64.strict_encode64("#{#token}:#{#secret}")
session.get "/api/v1/recommend/#{n}", nil, {"Authorization" => str}
I used ActionDispatch::Integration::Session.new(Rails.application) because turnip don't support get.
#token and #secret are values for token and token_secret, and I confirmed these values are valid.
n is given at arguments.
Next, I run it and these errors occurred:
Failures:
1) test
Failure/Error: test1
ArgumentError:
bad value for range
# ./spec/features/recommendation.feature:13:in `test1'
# ./app/models/user.rb:682:in `recommendation'
# ./app/controllers/api/v1/users_controller.rb:209:in `recommendation'
# spec/steps/recommendation_steps.rb:32:in `block (2 levels) in <top (required)>'
# ./spec/features/recommendation.feature:14:in `block (6 levels) in run'
# ./spec/features/recommendation.feature:13:in `each'
# ./spec/features/recommendation.feature:13:in `block (5 levels) in run'
# -e:1:in `<main>'
I tried the following cases and confirmed they are successful.
Do same things in rails console
Make a dummy encoded string and use it (of course authentication was failing, but no error)
Why did such errors occur?
(Added)
./app/models/user.rb:682:in recommendation:
def recommendation limit = 10
result = Hash.new{0.0}
unused_recipe_ids = Recipe.where.not(id: self.made_recipes.pluck(:id)).pluck(:id)
self.made_activities.includes(:recipe).each do |activity|
c = coefficient(activity)
similarities = RecipeSimilarity.where(from_recipe_id: activity.recipe.id).where(to_recipe_id: unused_recipe_ids)
similarities.each { |s| result[s.to_recipe_id] += s.score * c }
end
Recipe.where(id: result.sort{|a, b| b[1] <=> a[1]}[0...limit].map{|r| r[0]})
end
def coefficient activity
return 1.5 if activity.type_code == 301
return 0.5 if activity.type_code == 302
if activity.type_code == 100
return 1.0 if activity.evaluation == 0
return 0.1 if activity.evaluation == 1
return 0.6 if activity.evaluation == 2
return 1.1 if activity.evaluation == 3
return 1.6 if activity.evaluation == 4
return 2.5 if activity.evaluation == 5
end
return 1.0
end
./app/controllers/api/v1/users_controller.rb:209:in recommendation:
def recommendation
#recipes = #current_user.recommendation(params[:limit])
render text: #recipes.to_json
end
Recipe.count is 50.
RecipeSimilarity.count is 2500.

Related

Perform arithmetic operations on string in Ruby

input: "20+10/5-1*2"
I want to perform arithmetic operations on that string how can I do it without using eval method in ruby?
expected output: 20
While I hesitate to answer an interview question, and I am completely embarrassed by this code, here is one awful way to do it. I made it Ruby-only and avoided Rails helpers because it seemed more of a Ruby task and not a Rails task.
#
# Evaluate a string representation of an arithmetic formula provided only these operations are expected:
# + | Addition
# - | Subtraction
# * | Multiplication
# / | Division
#
# Also assumes only integers are given for numerics.
# Not designed to handle division by zero.
#
# Example input: '20+10/5-1*2'
# Expected output: 20.0
#
def eval_for_interview(string)
add_split = string.split('+')
subtract_split = add_split.map{ |v| v.split('-') }
divide_split = subtract_split.map do |i|
i.map{ |v| v.split('/') }
end
multiply_these = divide_split.map do |i|
i.map do |j|
j.map{ |v| v.split('*') }
end
end
divide_these = multiply_these.each do |i|
i.each do |j|
j.map! do |k, l|
if l == nil
k.to_i
else
k.to_i * l.to_i
end
end
end
end
subtract_these = divide_these.each do |i|
i.map! do |j, k|
if k == nil
j.to_i
else
j.to_f / k.to_f
end
end
end
add_these = subtract_these.map! do |i, j|
if j == nil
i.to_f
else
i.to_f - j.to_f
end
end
add_these.sum
end
Here is some example output:
eval_for_interview('1+1')
=> 2.0
eval_for_interview('1-1')
=> 0.0
eval_for_interview('1*1')
=> 1.0
eval_for_interview('1/1')
=> 1.0
eval_for_interview('1+2-3*4')
=> -9.0
eval_for_interview('1+2-3/4')
=> 2.25
eval_for_interview('1+2*3/4')
=> 2.5
eval_for_interview('1-2*3/4')
=> -0.5
eval_for_interview('20+10/5-1*2')
=> 20.0
eval_for_interview('20+10/5-1*2*4-2/6+12-1-1-1')
=> 31.0

Rails - RSpec NoMethodError: undefined method

I'm trying to test a very simple method that takes in 2 numbers and uses them to work out a percentage. However, when I try and run the tests it fails with the following error:
NoMethodError: undefined method `pct' for Scorable:Module
./spec/models/concerns/scorable_spec.rb:328:in `block (2 levels) in
<top (required)>'
./spec/rails_helper.rb:97:in `block (3 levels) in <top (required)>'
./spec/rails_helper.rb:96:in `block (2 levels) in <top (required)>'
-e:1:in `<main>'
Here's my spec file for the module:
require 'rails_helper'
RSpec.describe Scorable, :type => :concern do
it "pct should return 0 if den is 0 or nil" do
expect(Scorable.pct(nil, 15)).to eq(0)
expect(Scorable.pct(0, 15)).to eq(0)
end
end
Here is the pct method located in Scorable.rb:
def pct(num,den)
return 0 if num == 0 or num.nil?
return (100.0 * num / den).round
end
And here's my rspec_helper:
if ENV['ENABLE_COVERAGE']
require 'simplecov'
SimpleCov.start do
add_filter "/spec/"
add_filter "/config/"
add_filter '/vendor/'
add_group 'Controllers', 'app/controllers'
add_group 'Models', 'app/models'
add_group 'Helpers', 'app/helpers'
add_group 'Mailers', 'app/mailers'
add_group 'Views', 'app/views'
end
end
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions =
true
end
config.raise_errors_for_deprecations!
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
I'm very new to RSpec and have been puzzling over this one for more than a day. It's definitely pointing to an existing method, as when I use Go To Declaration in RubyMine it opens the method declaration. Can anyone maybe shed some light for me on this one? I'm sure I'm overlooking something incredibly simple.
To make the module method callable with Module.method notation is should be declared in module scope.
module Scorable
def self.pct(num,den)
return 0 if num == 0 or num.nil?
return (100.0 * num / den).round
end
end
or:
module Scorable
class << self
def pct(num,den)
return 0 if num == 0 or num.nil?
return (100.0 * num / den).round
end
end
end
or with Module#module_function:
module Scorable
module_function
def pct(num,den)
return 0 if num == 0 or num.nil?
return (100.0 * num / den).round
end
end
Note, that the latter declares both module method and normal instance method within this module.
Sidenote: using return in the very last line of the method is considered a code smell and should be avoided:
module Scorable
def self.pct(num,den)
return 0 if num == 0 or num.nil?
(100.0 * num / den).round
end
end

Array join function - Ruby on Rails

I wrote below function to return unique years (with unrepeated digits) in a range of years. My results turned out to be fine, however, the spec requires a certain format which my join function returned array of string instead of numbers. How do I convert the end result to an array of numbers as spec required?
def no_repeat?(year)
idx = 1
str = year.to_s
while idx < str.length
if str[0] == str[idx]
return false
end
idx += 1
end
return true
end
def no_repeats(year_start, year_end)
diff = year_end - year_start
idx = 0
new = []
while idx <= diff
year = year_start + idx
if no_repeat?(year)
new.push(year.to_i)
end
idx += 1
end
return [new.join(",")]
end
Test Results:
#no_repeats
should return a no repeat year (FAILED - 1)
should not return a repeat year (FAILED - 2)
should return only those years that have no repeated digits (FAILED - 3)
Failures:
1) #no_repeats should return a no repeat year
Failure/Error: no_repeats(1234, 1234).should == [1234]
expected: [1234]
got: ["1234"] (using ==)
# ./spec/01_no_repeats_spec.rb:16:in `block (2 levels) in <top (required)>'
2) #no_repeats should not return a repeat year
Failure/Error: no_repeats(1123, 1123).should == []
expected: []
got: [""] (using ==)
# ./spec/01_no_repeats_spec.rb:20:in `block (2 levels) in <top (required)>'
3) #no_repeats should return only those years that have no repeated digits
Failure/Error: ]
expected: [1980, 1982, 1983, 1984, 1985, 1986, 1987]
got: ["1980,1982,1983,1984,1985,1986,1987"] (using ==)
# ./spec/01_no_repeats_spec.rb:32:in `block (2 levels) in <top (required)>'
Finished in 0.00139 seconds
3 examples, 3 failures
Failed examples:
rspec ./spec/01_no_repeats_spec.rb:15 # #no_repeats should return a no repeat year
rspec ./spec/01_no_repeats_spec.rb:19 # #no_repeats should not return a repeat year
rspec ./spec/01_no_repeats_spec.rb:23 # #no_repeats should return only those years that have no repeated digits
new.join(",") will coerce the members of the array new to strings - what if you just took this part out, and returned "new"?

How I can resize a image using fast image?

I'm using FastImage on Ruby to resize some images :
https://github.com/sdsykes/fastimage_resize/blob/master/test/test.rb
And this is my code, so I had this error since yesterday :
class IconExport
def initialize(img_url,target_directory,tab)
#img_url=img_url
#target = target_directory
#tab = tab
end
def export
#tab.each do |fn, info|
puts"#{fn} ,#{info}"
outfile = File.join(#target, "fixtures", "resized_" + fn)
puts "#{outfile}"
puts "#{info[1][0] / 3}"
FastImage.resize(#img_url + fn, info[1][0] / 3, info[1][1] / 2, :outfile=>outfile)
assert_equal [info[1][0] / 3, info[1][1] / 2], FastImage.size(outfile)
File.unlink outfile
end
end
end
Error :
icon2.rb:59:in `block in export': uninitialized constant IconExport::FastImage (NameError)
from icon2.rb:54:in `each'
from icon2.rb:54:in `export'
from icon2.rb:82:in `<main>'
Help me please !

RSPEC - Test says object is nil, but works fine in practice

I can't figure out why this object keeps coming up as nil.
Here is the error:
1) Item Calculate with just Total
Failure/Error: subject.calculate_tax(tax, sub_category)
TypeError:
nil can't be coerced into Fixnum
# ./app/models/item.rb:111:in `+'
# ./app/models/item.rb:111:in `calculate_tax'
# ./spec/models/item_spec.rb:26:in `block (2 levels) in <top (required)>'
Here is the line it applies to - it thinks "self.tax_rate" is nill (second last argument)
self.tax_amount = ((self.total - self.deduction) - ((self.total - self.deduction) / (1 + self.tax_rate))) * self.tax_adjustment
Here is my Test
describe Item do
subject {Item.new(:report_id => 26 , :name => 'Gas' ,:tax_rate => 0.13, :tax_id => 1 , :category_id => 15 , :sub_category_id => 31 , :job_id => 1 , :total => 20 )}
let(:tax) {Tax.where(id: subject.tax_id).first}
let(:sub_category) {SubCategory.where(id: subject.sub_category_id).first}
it 'Calculate with just Total' do
subject.name.should be == 'Gas'
tax = Tax.find_by_id(subject.tax_id)
subject.sub_category_id.should be == 31
subject.set_nil_values
sub_category.should_receive(:taxable).exactly(3).times.and_return(sub_category.taxable)
tax.should_receive(:rate).exactly(4).times.and_return(tax.rate)
sub_category.should_receive(:tax_adjustment).and_return(sub_category.tax_adjustment)
subject.calculate_tax(tax, sub_category)
subject.should_receive(:tax_rate).exactly(2).times.and_return(tax.rate)
subject.calculate_cost
subject.cost.should be_within(0.01).of(17.70)
subject.tax_amount.should be_within(0.01).of(2.30)
subject.save
end
Your taxes table in your test database appears not to have an entry with id equal to 1 whose tax.rate is not nil

Resources