I'm trying to make make my app buildable via CodeShip.
It builds nicely when using Travis CI (except some integration tests, but this is an another story) and, of course, on my local machine. However, the same code is failed to be tested just in one certain place if CodeShipping. I wouldn't be suprised if the fail was about feature testing, but it fails within a controller spec!
CodeShip error:
Failures:
1) ParrotsController GET #index with filters returns by id
Failure/Error: expect(json.count).to eq 1
expected: 1
got: 0
(compared using ==)
# ./spec/controllers/parrots_controller_spec.rb:117:in `block (4 levels) in <top (required)>'
It's so weird, because there are nearly the same tests below and upper that one. I wouldn't be surprised if the problem was about javascript and features, but it's just a controller test! I'm really frustrated.
CodeShip setup commands:
npm install -g bower
bower install
rvm use 2.2.3 --install
bundle install
export RAILS_ENV=test
bundle exec rake db:migrate --trace
bundle exec rake db:test:prepare
bundle exec rake db:schema:load
CodeShip test commands:
export CODECLIMATE_REPO_TOKEN=blahblah
xvfb-run -a bundle exec rspec spec
Action code
def index
# TODO Below code is not ideal, needs optimizing
begin
p = Parrot.all # I could use @parrots everywhere, but 'p' is shorter for bunch of selects
[:ancestors, :descendants, :children, :parents].each do |selector|
(p = p & Parrot.find(params[selector].to_i).try(selector)) if params[selector]
end
# Temporary solution for nil elements within 'p' when wrong 'selector' ids given
p.each { |_p| p.delete _p if _p.nil? } if p
(p = p.select { |_p| _p.age >= params[:age_min].to_i }) if params[:age_min]
(p = p.select { |_p| _p.age <= params[:age_max].to_i }) if params[:age_max]
(p = p.select { |_p| _p.sex == params[:sex] }) if params[:sex]
(p = p.select { |_p| _p.id == params[:id].to_i }) if params[:id]
(p = p.select { |_p| _p.tribal == (params[:tribals] == 'true' || params[:tribal] == true) }) unless params[:tribals].nil?
(p = p.select { |_p| _p.color == Color.find_by_name(params[:color]) }) unless params[:color].blank?
(p = p.select { |_p| _p.name.downcase.include?(params[:name].downcase) }) unless params[:name].blank?
@parrots = p
rescue Exception => e
@error = e
end
respond_to do |format|
format.json do
render layout: false, status: (@error ? :unprocessable_entity : :ok)
end
end
end
index.json.jbuilder
if @error
json.error @error.to_s
else
json.array! @parrots, :id, :name, :age, :color_id, :sex, :tribal, :color_hex
end
Test code
describe 'GET #index' do
before do
@grandmother = create(:parrot, name: 'FooMother', age: 40, sex: 'female', tribal: true, color_name: 'green')
@grandfather = create(:parrot, name: 'FooFather', age: 50, sex: 'male', tribal: true, color_name: 'green')
@mother = create(:parrot, name: 'Foo', age: 20, sex: 'female', tribal: true, color_name: 'red', father_id: @grandfather.id, mother_id: @grandmother.id)
@father = create(:parrot, name: 'Bar', age: 30, sex: 'male', tribal: true, color_name: 'red')
@son = create(:parrot, name: 'FoobarSon', age: 3, sex: 'male', tribal: true, color_name: 'green', father_id: @father.id, mother_id: @mother.id)
@daughter = create(:parrot, name: 'FoobarDaughter', age: 5, sex: 'female', tribal: false, color_name: 'blue', father_id: @father.id, mother_id: @mother.id)
end
context 'no filters' do
it ' returns all' do
get :index, format: :json
expect(json.count).to eq 6
end
end
context 'with filters' do
it 'returns older than' do
get :index, format: :json, age_min: 20
expect(json.count).to eq 4
expect(json.collect{ |p| p['id'] }).to include @grandmother.id
end
it 'returns younger than' do
get :index, format: :json, age_max: 30
expect(json.count).to eq 4
expect(json.collect{ |p| p['id'] }).to_not include @grandmother.id
end
it 'returns with age in range' do
get :index, format: :json, age_min: 20, age_max: 40
expect(json.count).to eq 3
expect(json.collect{ |p| p['id'] }).to_not include @grandfather.id
expect(json.collect{ |p| p['id'] }).to_not include @son.id
end
it 'returns by id' do # todo doesn't pass in CodeShip only. Why?!
get :index, format: :json, id: 2
expect(json.count).to eq 1
expect(json.collect{ |p| p['name'] }).to include @grandfather.name
end
# Other tests...
end
end