1

I have an extremely weird issue where a test passes and fails randomly. Meaning, sometimes it'll pass and sometimes it'll fail. It's an issue with paperclip-matchers (https://github.com/thoughtbot/paperclip) with shoulda-matchers (https://github.com/thoughtbot/shoulda-matchers).

Let's say that I have a model that's written like this:

class Import < ActiveRecord::Base
  has_attached_file :document
  validates_attachment :document, presence: true,
                       content_type: { content_type: ['application/vnd.ms-excel', 'application/csv', 'text/csv'] }
end

And tests written like this:

require 'spec_helper'   

describe Import do
  it { should have_attached_file(:document) }
  it { should validate_attachment_presence(:document) }
  it { should validate_attachment_content_type(:document).
    allowing('application/vnd.ms-excel', 'application/csv', 'text/csv') }
end

The error I get is:

Failures:   

  1) Import should require presence of attachment document
     Failure/Error: it { should validate_attachment_presence(:document) }
     NoMethodError:
       undefined method `gsub' for nil:NilClass
     # ./spec/models/import_spec.rb:14:in `block (2 levels) in <top (required)>'

I've been Googling around for this and I can't seem to figure out why it is breaking. I'm simply using the paperclip-matchers, which I have required properly according to the documentation in my spec_helper.rb

Has anyone came across this issue?

Thank you!

Edit:

Finally got the backtrace, except it happened for a different model this time. This is the backtrace. It seems to be an issue with paperclip matchers not being compatible with the latest version of rspec. Has any come across this issue before and maybe have a workaround they can suggest for this specific problem?

   1) Element should require presence of attachment attachment
      Failure/Error: it { should validate_attachment_presence :attachment }
      NoMethodError:
        undefined method `gsub' for nil:NilClass
      # /usr/local/lib/ruby/gems/1.9.1/gems/paperclip-4.2.0/lib/paperclip/io_adapters/abstract_adapter.rb:23:in `original_filename='
      # /usr/local/lib/ruby/gems/1.9.1/gems/paperclip-4.2.0/lib/paperclip/io_adapters/stringio_adapter.rb:13:in `cache_current_values'
      # /usr/local/lib/ruby/gems/1.9.1/gems/paperclip-4.2.0/lib/paperclip/io_adapters/stringio_adapter.rb:5:in `initialize'
      # /usr/local/lib/ruby/gems/1.9.1/gems/paperclip-4.2.0/lib/paperclip/io_adapters/registry.rb:29:in `new'
      # /usr/local/lib/ruby/gems/1.9.1/gems/paperclip-4.2.0/lib/paperclip/io_adapters/registry.rb:29:in `for'
      # /usr/local/lib/ruby/gems/1.9.1/gems/paperclip-4.2.0/lib/paperclip/attachment.rb:96:in `assign'
      # /usr/local/lib/ruby/gems/1.9.1/gems/paperclip-4.2.0/lib/paperclip/matchers/validate_attachment_presence_matcher.rb:48:in `no_error_when_valid?'
      # /usr/local/lib/ruby/gems/1.9.1/gems/paperclip-4.2.0/lib/paperclip/matchers/validate_attachment_presence_matcher.rb:22:in `matches?'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-expectations-3.0.2/lib/rspec/expectations/handler.rb:48:in `handle_matcher'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/memoized_helpers.rb:81:in `should'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:112:in `block (2 levels) in run_specs'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:112:in `map'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:112:in `block in run_specs'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/reporter.rb:54:in `report'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:108:in `run_specs'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:86:in `run'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:70:in `run'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:38:in `invoke'
      # /usr/local/lib/ruby/gems/1.9.1/gems/rspec-core-3.0.2/exe/rspec:4:in `<top (required)>'
      # /usr/local/bin/rspec:23:in `load'
      # /usr/local/bin/rspec:23:in `<main>'
Chris Jeon
  • 1,093
  • 1
  • 11
  • 18
  • Please run your tests from the command line with `rspec spec/models/import_spec.rb --backtrace` to see where the error is really coming from and report back – nort Jul 10 '14 at 18:58
  • The odd thing is, if I run it alone, then it passes. Should I run the entire test suite again with backtrace? – Chris Jeon Jul 10 '14 at 19:01
  • Got backtrace. To me, it looks like an issue with paperclip not playing well with RSpec 3. Any insight? – Chris Jeon Jul 10 '14 at 20:15

2 Answers2

0

I found the answer here:

However, there was a little note, that I don't believe is echoed in the paperclip gems readme, that states that a symbol can be passed to the path attribute that references an instance method. Moving my code from the lambda to a public private method, and using that method name as the value passed to the path attribute worked like a charm.

:path => :path_to_file


def path_to_file
  return "/system/#{sub_domain}/:class/:id/:basename.:extension"
end

private
  def sub_domain
    ...code to get to the sub_domain of the school
  end
frandroid
  • 1,343
  • 16
  • 26
0

I actually resolved the issue by using the master branch of paperclip. It's a bit odd because the version numbers seem to be the same. So basically,in the Gemfile:

gem "paperclip", git: "git://github.com/thoughtbot/paperclip.git"
Chris Jeon
  • 1,093
  • 1
  • 11
  • 18