Jack,
Please excuse the delayed response. The message went to Gmail's spam folder.
As I think of it, parameters are most probably an instance of a Hash with
indifferent access, so no conversions are necessary.
I would expect an expectation on `BooksController` to work in a
request/controller spec, but not a system spec. Wondering how it works.
For the argument, you can set a breakpoint in an expectation and see what
the arguments were in that call:
```
expect_any_instance_of(BooksController).to receive(:modify).and_wrap_original
{ |m, *args| puts "called with #{args.inspect}" }
```
Hope it helps.
- Phil
On Tuesday, March 30, 2021 at 3:11:21 AM UTC+3 Jack R-G wrote:
> I have a system spec for a page that has js that makes ajax calls back to
> my server. One of my tests looks like this:
>
> it 'should make a call to the server' do
> expect_any_instance_of(BooksController).to
> receive(:modify).with(hash_including({verb: 'ChangeBook', book_id:
> @book.id.to_s, status: to.to_s}.stringify_keys)).and_return([200, nil])
> @control.click()
> end
>
>
> If I remove the “.with (…)” part of the call, the test passes. The error
> message says something about “double render” but I think that must be
> misleading because I don’t get a double-render error without the “.with”
> and I also do not get a double render error when I run the page live.
> Following is the full output of the test (highlighted sections show the
> partial hash I’m searching for and the params that are in the call:
>
> Failure/Error: super.tap { default_render unless performed? }
>
> (#<BooksController:0x00007f8a8f380ce0 @_action_has_layout=true,
> @_routes=nil, @_request=#<ActionDispatch::Request:0x00007f8a8f382338
> @env={"rack.version"=>[1,
> 6], "rack.errors"=>#<StringIO:0x00007f8a8cb81168>,
> "rack.multithread"=>false, "rack.multiprocess"=>false,
> "rack.run_once"=>false, "SCRIPT_NAME"=>"",
> "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma
> 5.1.0 At Your Service", "GATEWAY_INTERFACE"=>"CGI/1.2",
> "REQUEST_METHOD"=>"PUT",
> "REQUEST_PATH"=>"/books/modify.js", "REQUEST_URI"=>"/books/modify.js",
> "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"127.0.0.1:63499",
> "HTTP_CONNECTION"=>"keep-alive",
> "CONTENT_LENGTH"=>"62", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel
> Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko)
> HeadlessChrome/89.0.4389.90
> Safari/537.36", "HTTP_X_REQUESTED_WITH"=>"XMLHttpRequest",
> "CONTENT_TYPE"=>"application/x-www-form-urlencoded; charset=UTF-8",
> "HTTP_ACCEPT"=>"*/*", "HTTP_ORIGIN"=>"http://127.0.0.1:63499",
> "HTTP_SEC_FETCH_SITE"=>"same-origin",
> "HTTP_SEC_FETCH_MODE"=>"cors", "HTTP_SEC_FETCH_DEST"=>"empty",
> "HTTP_REFERER"=>"http://127.0.0.1:63499/skus", "HTTP_ACCEPT_ENCODING"=>"gzip,
> deflate, br",
> "HTTP_ACCEPT_LANGUAGE"=>"en-US",
> "HTTP_COOKIE"=>"auth_token=21a2cc0b56ce2911c4af42c092d0f595;
> _Novelty-Stats_session=dm9NS1JnaTFkWjhCVEhpRGtPUHNZUzk5TW56WXl1aWxoYXFYVmU3SVAyZlJkRGppbUR2QzE1bHVqQkxvUUt0YVc2WXd3MW5yMXNKYWsvdExPSDMyZHpja1B1dUFuY0JEc0ZSNDQ3TTJldFVOeUd3WVAzcG1lcWVNUEhHc1hmRVFaSXN0Y2diaHV1eFNZYy8vYllaNWFQSWNGbGdqUno1RlpFTFh5ZWRHeW9YNmFIc3lMTElEVmhLUXFHTEkvT2ExWFVXdEE4dU9veUJjU3ozQytiSTRNbUpEWVNaNWxsbHlvWWdNYWFmTTBJSEpiQjNFRm9laS9BaXpPNitwUkFwTS0tWmlWNncrMnhZcUYvR25IZ0lyU0wwdz09--43473ba27a643f2655b418b79eefdecb599f173c",
> "puma.request_body_wait"=>0,
> "SERVER_NAME"=>"127.0.0.1",
> "SERVER_PORT"=>"63499", "PATH_INFO"=>"/books/modify.js",
> "REMOTE_ADDR"=>"127.0.0.1", "puma.socket"=>#<TCPSocket:fd 20>,
> "rack.hijack?"=>true, "rack.hijack"=>#<Puma::Client:0x3fc5539d076c
> @ready=false>, "rack.input"=>#<StringIO:0x00007f8aa0876130>,
> "rack.url_scheme"=>"http", "rack.after_reply"=>[],
> "puma.config"=>#<Puma::Configuration:0x00007f8a8cb81618
> @options=#<Puma::UserFileDefaultOptions:0x00007f8a8cb81438
> @user_options={:Port=>63499, :workers=>0, :daemon=>false, :min_threads=>0,
> :max_threads=>1, :binds=>["tcp://0.0.0.0:63499"],
> :app=>#<Capybara::Server::Middleware:0x00007f8a9d6ee310
> @app=#<Rack::Builder:0x00007f8aa76933e8 @freeze_app=false, @warmup=nil,
> @run=nil,
> @map={"/"=>#<Proc:0x00007f8aa76932a8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/actionpack-5.1.7/lib/action_dispatch/system_test_case.rb:101>},
>
> @use=[]>, @extended_app=#<Rack::Builder:0x00007f8aa76933e8
> @freeze_app=false, @warmup=nil, @run=nil,
> @map={"/"=>#<Proc:0x00007f8aa76932a8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/actionpack-5.1.7/lib/action_dispatch/system_test_case.rb:101>},
>
> @use=[]>,
> @counter=#<Capybara::Server::Middleware::Counter:0x00007f8a9d6ee298
> @value=0, @mutex=#<Thread::Mutex:0x00007f8a9d6ee270>>,
> @server_errors=[StandardError]>,
> :environment=>"test"}, @file_options={:min_threads=>5, :max_threads=>5,
> :binds=>["tcp://0.0.0.0:3000"], :environment=>"test"},
> @default_options={:min_threads=>0, :max_threads=>5, :log_requests=>false,
> :debug=>false, :binds=>["tcp://0.0.0.0:9292"], :workers=>0, :mode=>:http,
> :worker_timeout=>60, :worker_boot_timeout=>60,
> :worker_shutdown_timeout=>30, :remote_address=>:socket,
> :tag=>"Novelty-Stats", :environment=>"test", :rackup=>"config.ru",
> :logger=>#<IO:<STDOUT>>,
> :persistent_timeout=>20,
> :first_data_timeout=>30, :raise_exception_on_sigterm=>true,
> :max_fast_inline=>10, :Verbose=>false,
> :Silent=>false, :preload_app=>false}>,
> @plugins=#<Puma::PluginLoader:0x00007f8a8cb813e8
> @instances=[#<#<Class:0x00007f8a8cb73770>:0x00007f8a8cb731a8>]>,
> @user_dsl=#<Puma::DSL:0x00007f8a8cb81398
> @config=#<Puma::Configuration:0x00007f8a8cb81618
> ...>, @options={:Port=>63499, :workers=>0, :daemon=>false, :min_threads=>0,
> :max_threads=>1, :binds=>["tcp://0.0.0.0:63499"],
> :app=>#<Capybara::Server::Middleware:0x00007f8a9d6ee310
> @app=#<Rack::Builder:0x00007f8aa76933e8 @freeze_app=false, @warmup=nil,
> @run=nil,
> @map={"/"=>#<Proc:0x00007f8aa76932a8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/actionpack-5.1.7/lib/action_dispatch/system_test_case.rb:101>},
>
> @use=[]>, @extended_app=#<Rack::Builder:0x00007f8aa76933e8
> @freeze_app=false, @warmup=nil, @run=nil,
> @map={"/"=>#<Proc:0x00007f8aa76932a8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/actionpack-5.1.7/lib/action_dispatch/system_test_case.rb:101>},
>
> @use=[]>,
> @counter=#<Capybara::Server::Middleware::Counter:0x00007f8a9d6ee298
> @value=0, @mutex=#<Thread::Mutex:0x00007f8a9d6ee270>>,
> @server_errors=[StandardError]>, :environment=>"test"}, @plugins=[]>,
> @file_dsl=#<Puma::DSL:0x00007f8a8cb81348
> @config=#<Puma::Configuration:0x00007f8a8cb81618 ...>,
> @options={:min_threads=>5, :max_threads=>5, :binds=>["tcp://0.0.0.0:3000"],
> :environment=>"test"}, @plugins=[],
> @path="config/puma.rb">, @default_dsl=#<Puma::DSL:0x00007f8a8cb812f8
> @config=#<Puma::Configuration:0x00007f8a8cb81618 ...>,
> @options={:min_threads=>0, :max_threads=>5, :log_requests=>false,
> :debug=>false, :binds=>["tcp://0.0.0.0:9292"], :workers=>0, :mode=>:http,
> :worker_timeout=>60, :worker_boot_timeout=>60,
> :worker_shutdown_timeout=>30,
> :remote_address=>:socket, :tag=>"Novelty-Stats", :environment=>"test",
> :rackup=>"config.ru", :logger=>#<IO:<STDOUT>>, :persistent_timeout=>20,
> :first_data_timeout=>30,
> :raise_exception_on_sigterm=>true, :max_fast_inline=>10, :Verbose=>false,
> :Silent=>false, :preload_app=>false},
> @plugins=[]>>, "action_dispatch.parameter_filter"=>[:password,
> :ranking_lists, :country_list,
> :password], "action_dispatch.redirect_filter"=>[],
> "action_dispatch.secret_token"=>nil,
> "action_dispatch.secret_key_base"=>"a0b4013fe28a80ef1439d5830ac763a03d87fcb9ea0eb1ebded8c4f956905d3397c597731f43ee9e50aa9dcd18e4ebf3cda6c9a754cbfe7dc823bd2cd2a6964b",
> "action_dispatch.show_exceptions"=>false,
> "action_dispatch.show_detailed_exceptions"=>true,
> "action_dispatch.logger"=>#<ActiveSupport::Logger:0x00007f8aa4a5bc08
> @level=2, @progname=nil,
> @default_formatter=#<Logger::Formatter:0x00007f8aa4a5bb18
> @datetime_format=nil>,
> @formatter=#<ActiveSupport::Logger::SimpleFormatter:0x00007f8aa4f5f5d8
> @datetime_format=nil,
> @thread_key="activesupport_tagged_logging_tags:70116724898540">,
> @logdev=#<Logger::LogDevice:0x00007f8aa4a5bac8 @shift_period_suffix=nil,
> @shift_size=nil, @shift_age=nil, @filename=nil,
> @dev=#<File:/Users/jackrg/Documents/Novelty-Stats/log/test.log>,
> @mon_owner=nil, @mon_count=0,
> @mon_mutex=#<Thread::Mutex:0x00007f8aa4a5ba50>>,
> @local_levels=#<Concurrent::Map:0x00007f8aa4a5b960 entries=0
> default_proc=nil>>,
> "action_dispatch.backtrace_cleaner"=>#<Rails::BacktraceCleaner:0x00007f8aaae28830
>
> @filters=[#<Proc:0x00007f8aaae28718@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:14>,
>
> #<Proc:0x00007f8aaae286f0@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:15>,
>
> #<Proc:0x00007f8aaae286c8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:16>,
>
> #<Proc:0x00007f8aaae2bbc0@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:29>],
>
> @silencers=[#<Proc:0x00007f8aaae13f98@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:19>],
>
> @root="/Users/jackrg/Documents/Novelty-Stats/">,
> "action_dispatch.key_generator"=>#<ActiveSupport::CachingKeyGenerator:0x00007f8a9d48c6d0
>
> @key_generator=#<ActiveSupport::KeyGenerator:0x00007f8a9d48c6f8
> @secret="a0b4013fe28a80ef1439d5830ac763a03d87fcb9ea0eb1ebded8c4f956905d3397c597731f43ee9e50aa9dcd18e4ebf3cda6c9a754cbfe7dc823bd2cd2a6964b",
>
> @iterations=1000>, @cache_keys=#<Concurrent::Map:0x00007f8a9d48c658
> entries=3 default_proc=nil>>, "action_dispatch.http_auth_salt"=>"http
> authentication", "action_dispatch.signed_cookie_salt"=>"signed
> cookie", "action_dispatch.encrypted_cookie_salt"=>"encrypted
> cookie", "action_dispatch.encrypted_signed_cookie_salt"=>"signed encrypted
> cookie", "action_dispatch.cookies_serializer"=>:marshal,
> "action_dispatch.cookies_digest"=>nil,
> "action_dispatch.routes"=>#<ActionDispatch::Routing::RouteSet:0x00007f8aa4ada490>,
> "ROUTES_70116722528840_SCRIPT_NAME"=>"",
> "ORIGINAL_FULLPATH"=>"/books/modify.js", "ORIGINAL_SCRIPT_NAME"=>"",
> "action_dispatch.request_id"=>"dbb37c76-180b-448d-a6dc-01a05ce225c9",
> "action_dispatch.remote_ip"=>#<ActionDispatch::RemoteIp::GetIp:0x00007f8aa08752a8
>
> @req=#<ActionDispatch::Request:0x00007f8aa08752d0 @env={...},
> @filtered_parameters=nil, @filtered_env=nil, @filtered_path=nil,
> @protocol=nil, @port=nil, @method=nil, @request_method=nil, @remote_ip=nil,
> @original_fullpath=nil, @fullpath=nil, @ip=nil>, @check_ip=true,
> @proxies=[#<IPAddr: IPv4:127.0.0.1/255.255.255.255>,
> #<IPAddr:
> IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>,
>
> #<IPAddr:
> IPv6:fc00:0000:0000:0000:0000:0000:0000:0000/fe00:0000:0000:0000:0000:0000:0000:0000>,
>
> #<IPAddr: IPv4:10.0.0.0/255.0.0.0>, #<IPAddr: IPv4:172.16.0.0/255.240.0.0>,
> #<IPAddr: IPv4:192.168.0.0/255.255.0.0>], @ip="127.0.0.1">,
> "rack.session"=>#<ActionDispatch::Request::Session:0x7f8aa0874f60 not yet
> loaded>,
> "rack.session.options"=>#<ActionDispatch::Request::Session::Options:0x00007f8aa0874f10
>
> @by=#<ActionDispatch::Session::CookieStore:0x00007f8a9e2e8eb8
> @app=#<Rack::Head:0x00007f8a9e2e8f80
> @app=#<Rack::ConditionalGet:0x00007f8a9e2e8fa8
> @app=#<Rack::ETag:0x00007f8a9e2e8ff8
> @app=#<OmniAuth::Builder:0x00007f8a9e2ea7b8 @freeze_app=false, @warmup=nil,
> @run=#<ActionDispatch::Routing::RouteSet:0x00007f8aa4ada490>, @map=nil,
> @use=[#<Proc:0x00007f8a9e2e9020@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/rack-2.2.3/lib/rack/builder.rb:158>],
>
> @options={}>, @cache_control="max-age=0, private, must-revalidate",
> @no_cache_control="no-cache">>>, @default_options={:path=>"/",
> :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true,
> :defer=>false, :renew=>false}, @key="_Novelty-Stats_session",
> @cookie_only=true, @same_site=nil>, @delegate={:path=>"/", :domain=>nil,
> :expire_after=>nil, :secure=>false, :httponly=>true,
> :defer=>false, :renew=>false}>,
> "action_dispatch.request.path_parameters"=>{:controller=>"books",
> :action=>"modify",
> :format=>"js"},
> "action_controller.instance"=>#<BooksController:0x00007f8a8f380ce0 ...>,
> "action_dispatch.request.content_type"=>#<Mime::Type:0x00007f8a9cd84428
> @synonyms=[],
> @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded",
> @hash=1420162111980396459>, "rack.tempfiles"=>[],
> "rack.request.form_hash"=>{"verb"=>"ChangeBook",
> "book_id"=>"34880", "status"=>"inactive",
> "ts"=>"1617061982022"},
> "rack.request.form_vars"=>"verb=ChangeBook&book_id=34880&status=inactive&ts=1617061982022",
> "rack.request.form_input"=>#<StringIO:0x00007f8aa0876130>,
> "action_dispatch.request.request_parameters"=>{"verb"=>"ChangeBook",
> "book_id"=>"34880", "status"=>"inactive", "ts"=>"1617061982022"},
> "rack.request.query_string"=>"", "rack.request.query_hash"=>{},
> "action_dispatch.request.query_parameters"=>{},
> "action_dispatch.request.parameters"=>{"verb"=>"ChangeBook",
> "book_id"=>"34880", "status"=>"inactive", "ts"=>"1617061982022",
> "controller"=>"books", "action"=>"modify", "format"=>"js"},
> "action_dispatch.request.formats"=>[#<Mime::Type:0x00007f8a9cd86a70
> @synonyms=["application/javascript",
> "application/x-javascript"], @symbol=:js, @string="text/javascript",
> @hash=-2007623201317620867>],
> "rack.request.cookie_hash"=>{"auth_token"=>"21a2cc0b56ce2911c4af42c092d0f595",
>
> "_Novelty-Stats_session"=>"dm9NS1JnaTFkWjhCVEhpRGtPUHNZUzk5TW56WXl1aWxoYXFYVmU3SVAyZlJkRGppbUR2QzE1bHVqQkxvUUt0YVc2WXd3MW5yMXNKYWsvdExPSDMyZHpja1B1dUFuY0JEc0ZSNDQ3TTJldFVOeUd3WVAzcG1lcWVNUEhHc1hmRVFaSXN0Y2diaHV1eFNZYy8vYllaNWFQSWNGbGdqUno1RlpFTFh5ZWRHeW9YNmFIc3lMTElEVmhLUXFHTEkvT2ExWFVXdEE4dU9veUJjU3ozQytiSTRNbUpEWVNaNWxsbHlvWWdNYWFmTTBJSEpiQjNFRm9laS9BaXpPNitwUkFwTS0tWmlWNncrMnhZcUYvR25IZ0lyU0wwdz09--43473ba27a643f2655b418b79eefdecb599f173c"},
> "rack.request.cookie_string"=>"auth_token=21a2cc0b56ce2911c4af42c092d0f595;
> _Novelty-Stats_session=dm9NS1JnaTFkWjhCVEhpRGtPUHNZUzk5TW56WXl1aWxoYXFYVmU3SVAyZlJkRGppbUR2QzE1bHVqQkxvUUt0YVc2WXd3MW5yMXNKYWsvdExPSDMyZHpja1B1dUFuY0JEc0ZSNDQ3TTJldFVOeUd3WVAzcG1lcWVNUEhHc1hmRVFaSXN0Y2diaHV1eFNZYy8vYllaNWFQSWNGbGdqUno1RlpFTFh5ZWRHeW9YNmFIc3lMTElEVmhLUXFHTEkvT2ExWFVXdEE4dU9veUJjU3ozQytiSTRNbUpEWVNaNWxsbHlvWWdNYWFmTTBJSEpiQjNFRm9laS9BaXpPNitwUkFwTS0tWmlWNncrMnhZcUYvR25IZ0lyU0wwdz09--43473ba27a643f2655b418b79eefdecb599f173c",
>
> "action_dispatch.cookies"=>#<ActionDispatch::Cookies::CookieJar:0x00007f8a8ebc4c40
> @set_cookies={},
> @delete_cookies={},
> @request=#<ActionDispatch::Request:0x00007f8a8f382338 ...>,
> @cookies={"auth_token"=>"21a2cc0b56ce2911c4af42c092d0f595",
> "_Novelty-Stats_session"=>"dm9NS1JnaTFkWjhCVEhpRGtPUHNZUzk5TW56WXl1aWxoYXFYVmU3SVAyZlJkRGppbUR2QzE1bHVqQkxvUUt0YVc2WXd3MW5yMXNKYWsvdExPSDMyZHpja1B1dUFuY0JEc0ZSNDQ3TTJldFVOeUd3WVAzcG1lcWVNUEhHc1hmRVFaSXN0Y2diaHV1eFNZYy8vYllaNWFQSWNGbGdqUno1RlpFTFh5ZWRHeW9YNmFIc3lMTElEVmhLUXFHTEkvT2ExWFVXdEE4dU9veUJjU3ozQytiSTRNbUpEWVNaNWxsbHlvWWdNYWFmTTBJSEpiQjNFRm9laS9BaXpPNitwUkFwTS0tWmlWNncrMnhZcUYvR25IZ0lyU0wwdz09--43473ba27a643f2655b418b79eefdecb599f173c"},
>
> @committed=false>}, @filtered_parameters={"verb"=>"ChangeBook",
> "book_id"=>"34880", "status"=>"inactive", "ts"=>"1617061982022",
> "controller"=>"books", "action"=>"modify",
> "format"=>"js"}, @filtered_env=nil, @filtered_path=nil, @protocol=nil,
> @port=nil, @method=nil, @request_method="PUT", @remote_ip="127.0.0.1",
> @original_fullpath=nil, @fullpath="/books/modify.js", @ip=nil,
> @headers=#<ActionDispatch::Http::Headers:0x00007f8a8ebc61f8
> @req=#<ActionDispatch::Request:0x00007f8a8f382338 ...>>>,
> @_response=#<ActionDispatch::Response:0x00007f8a8f380f10 @mon_owner=nil,
> @mon_count=0, @mon_mutex=#<Thread::Mutex:0x00007f8a8f380ec0>,
> @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1;
> mode=block", "X-Content-Type-Options"=>"nosniff",
> "Heartbleed"=>"REKEYED: 2014-04-08; see http://heartbleedheader.com"},
> @stream=#<ActionDispatch::Response::Buffer:0x00007f8a8f380e70
> @response=#<ActionDispatch::Response:0x00007f8a8f380f10 ...>, @buf=[],
> @closed=false, @str_body=nil>, @status=200,
> @cv=#<MonitorMixin::ConditionVariable:0x00007f8a8f380e48
> @monitor=#<ActionDispatch::Response:0x00007f8a8f380f10 ...>,
> @cond=#<Thread::ConditionVariable:0x00007f8a8f380e20>>, @committed=false,
> @sending=false, @sent=false, @cache_control={},
> @request=#<ActionDispatch::Request:0x00007f8a8f382338
> @env={"rack.version"=>[1, 6],
> "rack.errors"=>#<StringIO:0x00007f8a8cb81168>, "rack.multithread"=>false,
> "rack.multiprocess"=>false, "rack.run_once"=>false, "SCRIPT_NAME"=>"",
> "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"puma
> 5.1.0 At Your Service",
> "GATEWAY_INTERFACE"=>"CGI/1.2", "REQUEST_METHOD"=>"PUT",
> "REQUEST_PATH"=>"/books/modify.js", "REQUEST_URI"=>"/books/modify.js",
> "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"127.0.0.1:63499",
> "HTTP_CONNECTION"=>"keep-alive",
> "CONTENT_LENGTH"=>"62", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel
> Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko)
> HeadlessChrome/89.0.4389.90
> Safari/537.36", "HTTP_X_REQUESTED_WITH"=>"XMLHttpRequest",
> "CONTENT_TYPE"=>"application/x-www-form-urlencoded; charset=UTF-8",
> "HTTP_ACCEPT"=>"*/*", "HTTP_ORIGIN"=>"http://127.0.0.1:63499",
> "HTTP_SEC_FETCH_SITE"=>"same-origin",
> "HTTP_SEC_FETCH_MODE"=>"cors", "HTTP_SEC_FETCH_DEST"=>"empty",
> "HTTP_REFERER"=>"http://127.0.0.1:63499/skus", "HTTP_ACCEPT_ENCODING"=>"gzip,
> deflate, br",
> "HTTP_ACCEPT_LANGUAGE"=>"en-US",
> "HTTP_COOKIE"=>"auth_token=21a2cc0b56ce2911c4af42c092d0f595;
> _Novelty-Stats_session=dm9NS1JnaTFkWjhCVEhpRGtPUHNZUzk5TW56WXl1aWxoYXFYVmU3SVAyZlJkRGppbUR2QzE1bHVqQkxvUUt0YVc2WXd3MW5yMXNKYWsvdExPSDMyZHpja1B1dUFuY0JEc0ZSNDQ3TTJldFVOeUd3WVAzcG1lcWVNUEhHc1hmRVFaSXN0Y2diaHV1eFNZYy8vYllaNWFQSWNGbGdqUno1RlpFTFh5ZWRHeW9YNmFIc3lMTElEVmhLUXFHTEkvT2ExWFVXdEE4dU9veUJjU3ozQytiSTRNbUpEWVNaNWxsbHlvWWdNYWFmTTBJSEpiQjNFRm9laS9BaXpPNitwUkFwTS0tWmlWNncrMnhZcUYvR25IZ0lyU0wwdz09--43473ba27a643f2655b418b79eefdecb599f173c",
> "puma.request_body_wait"=>0,
> "SERVER_NAME"=>"127.0.0.1",
> "SERVER_PORT"=>"63499", "PATH_INFO"=>"/books/modify.js",
> "REMOTE_ADDR"=>"127.0.0.1", "puma.socket"=>#<TCPSocket:fd 20>,
> "rack.hijack?"=>true, "rack.hijack"=>#<Puma::Client:0x3fc5539d076c
> @ready=false>, "rack.input"=>#<StringIO:0x00007f8aa0876130>,
> "rack.url_scheme"=>"http", "rack.after_reply"=>[],
> "puma.config"=>#<Puma::Configuration:0x00007f8a8cb81618
> @options=#<Puma::UserFileDefaultOptions:0x00007f8a8cb81438
> @user_options={:Port=>63499, :workers=>0, :daemon=>false, :min_threads=>0,
> :max_threads=>1, :binds=>["tcp://0.0.0.0:63499"],
> :app=>#<Capybara::Server::Middleware:0x00007f8a9d6ee310
> @app=#<Rack::Builder:0x00007f8aa76933e8 @freeze_app=false, @warmup=nil,
> @run=nil,
> @map={"/"=>#<Proc:0x00007f8aa76932a8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/actionpack-5.1.7/lib/action_dispatch/system_test_case.rb:101>},
>
> @use=[]>, @extended_app=#<Rack::Builder:0x00007f8aa76933e8
> @freeze_app=false, @warmup=nil, @run=nil,
> @map={"/"=>#<Proc:0x00007f8aa76932a8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/actionpack-5.1.7/lib/action_dispatch/system_test_case.rb:101>},
>
> @use=[]>,
> @counter=#<Capybara::Server::Middleware::Counter:0x00007f8a9d6ee298
> @value=0, @mutex=#<Thread::Mutex:0x00007f8a9d6ee270>>,
> @server_errors=[StandardError]>,
> :environment=>"test"}, @file_options={:min_threads=>5, :max_threads=>5,
> :binds=>["tcp://0.0.0.0:3000"], :environment=>"test"},
> @default_options={:min_threads=>0, :max_threads=>5, :log_requests=>false,
> :debug=>false, :binds=>["tcp://0.0.0.0:9292"], :workers=>0, :mode=>:http,
> :worker_timeout=>60, :worker_boot_timeout=>60,
> :worker_shutdown_timeout=>30, :remote_address=>:socket,
> :tag=>"Novelty-Stats", :environment=>"test", :rackup=>"config.ru",
> :logger=>#<IO:<STDOUT>>,
> :persistent_timeout=>20,
> :first_data_timeout=>30, :raise_exception_on_sigterm=>true,
> :max_fast_inline=>10, :Verbose=>false,
> :Silent=>false, :preload_app=>false}>,
> @plugins=#<Puma::PluginLoader:0x00007f8a8cb813e8
> @instances=[#<#<Class:0x00007f8a8cb73770>:0x00007f8a8cb731a8>]>,
> @user_dsl=#<Puma::DSL:0x00007f8a8cb81398
> @config=#<Puma::Configuration:0x00007f8a8cb81618
> ...>, @options={:Port=>63499, :workers=>0, :daemon=>false, :min_threads=>0,
> :max_threads=>1, :binds=>["tcp://0.0.0.0:63499"],
> :app=>#<Capybara::Server::Middleware:0x00007f8a9d6ee310
> @app=#<Rack::Builder:0x00007f8aa76933e8 @freeze_app=false, @warmup=nil,
> @run=nil,
> @map={"/"=>#<Proc:0x00007f8aa76932a8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/actionpack-5.1.7/lib/action_dispatch/system_test_case.rb:101>},
>
> @use=[]>, @extended_app=#<Rack::Builder:0x00007f8aa76933e8
> @freeze_app=false, @warmup=nil, @run=nil,
> @map={"/"=>#<Proc:0x00007f8aa76932a8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/actionpack-5.1.7/lib/action_dispatch/system_test_case.rb:101>},
>
> @use=[]>,
> @counter=#<Capybara::Server::Middleware::Counter:0x00007f8a9d6ee298
> @value=0, @mutex=#<Thread::Mutex:0x00007f8a9d6ee270>>,
> @server_errors=[StandardError]>, :environment=>"test"}, @plugins=[]>,
> @file_dsl=#<Puma::DSL:0x00007f8a8cb81348
> @config=#<Puma::Configuration:0x00007f8a8cb81618 ...>,
> @options={:min_threads=>5, :max_threads=>5, :binds=>["tcp://0.0.0.0:3000"],
> :environment=>"test"}, @plugins=[],
> @path="config/puma.rb">, @default_dsl=#<Puma::DSL:0x00007f8a8cb812f8
> @config=#<Puma::Configuration:0x00007f8a8cb81618 ...>,
> @options={:min_threads=>0, :max_threads=>5, :log_requests=>false,
> :debug=>false, :binds=>["tcp://0.0.0.0:9292"], :workers=>0, :mode=>:http,
> :worker_timeout=>60, :worker_boot_timeout=>60,
> :worker_shutdown_timeout=>30,
> :remote_address=>:socket, :tag=>"Novelty-Stats", :environment=>"test",
> :rackup=>"config.ru", :logger=>#<IO:<STDOUT>>, :persistent_timeout=>20,
> :first_data_timeout=>30,
> :raise_exception_on_sigterm=>true, :max_fast_inline=>10, :Verbose=>false,
> :Silent=>false, :preload_app=>false},
> @plugins=[]>>, "action_dispatch.parameter_filter"=>[:password,
> :ranking_lists, :country_list,
> :password], "action_dispatch.redirect_filter"=>[],
> "action_dispatch.secret_token"=>nil,
> "action_dispatch.secret_key_base"=>"a0b4013fe28a80ef1439d5830ac763a03d87fcb9ea0eb1ebded8c4f956905d3397c597731f43ee9e50aa9dcd18e4ebf3cda6c9a754cbfe7dc823bd2cd2a6964b",
> "action_dispatch.show_exceptions"=>false,
> "action_dispatch.show_detailed_exceptions"=>true,
> "action_dispatch.logger"=>#<ActiveSupport::Logger:0x00007f8aa4a5bc08
> @level=2, @progname=nil,
> @default_formatter=#<Logger::Formatter:0x00007f8aa4a5bb18
> @datetime_format=nil>,
> @formatter=#<ActiveSupport::Logger::SimpleFormatter:0x00007f8aa4f5f5d8
> @datetime_format=nil,
> @thread_key="activesupport_tagged_logging_tags:70116724898540">,
> @logdev=#<Logger::LogDevice:0x00007f8aa4a5bac8 @shift_period_suffix=nil,
> @shift_size=nil, @shift_age=nil, @filename=nil,
> @dev=#<File:/Users/jackrg/Documents/Novelty-Stats/log/test.log>,
> @mon_owner=nil, @mon_count=0,
> @mon_mutex=#<Thread::Mutex:0x00007f8aa4a5ba50>>,
> @local_levels=#<Concurrent::Map:0x00007f8aa4a5b960 entries=0
> default_proc=nil>>,
> "action_dispatch.backtrace_cleaner"=>#<Rails::BacktraceCleaner:0x00007f8aaae28830
>
> @filters=[#<Proc:0x00007f8aaae28718@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:14>,
>
> #<Proc:0x00007f8aaae286f0@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:15>,
>
> #<Proc:0x00007f8aaae286c8@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:16>,
>
> #<Proc:0x00007f8aaae2bbc0@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:29>],
>
> @silencers=[#<Proc:0x00007f8aaae13f98@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/railties-5.1.7/lib/rails/backtrace_cleaner.rb:19>],
>
> @root="/Users/jackrg/Documents/Novelty-Stats/">,
> "action_dispatch.key_generator"=>#<ActiveSupport::CachingKeyGenerator:0x00007f8a9d48c6d0
>
> @key_generator=#<ActiveSupport::KeyGenerator:0x00007f8a9d48c6f8
> @secret="a0b4013fe28a80ef1439d5830ac763a03d87fcb9ea0eb1ebded8c4f956905d3397c597731f43ee9e50aa9dcd18e4ebf3cda6c9a754cbfe7dc823bd2cd2a6964b",
>
> @iterations=1000>, @cache_keys=#<Concurrent::Map:0x00007f8a9d48c658
> entries=3 default_proc=nil>>, "action_dispatch.http_auth_salt"=>"http
> authentication", "action_dispatch.signed_cookie_salt"=>"signed
> cookie", "action_dispatch.encrypted_cookie_salt"=>"encrypted
> cookie", "action_dispatch.encrypted_signed_cookie_salt"=>"signed encrypted
> cookie", "action_dispatch.cookies_serializer"=>:marshal,
> "action_dispatch.cookies_digest"=>nil,
> "action_dispatch.routes"=>#<ActionDispatch::Routing::RouteSet:0x00007f8aa4ada490>,
> "ROUTES_70116722528840_SCRIPT_NAME"=>"",
> "ORIGINAL_FULLPATH"=>"/books/modify.js", "ORIGINAL_SCRIPT_NAME"=>"",
> "action_dispatch.request_id"=>"dbb37c76-180b-448d-a6dc-01a05ce225c9",
> "action_dispatch.remote_ip"=>#<ActionDispatch::RemoteIp::GetIp:0x00007f8aa08752a8
>
> @req=#<ActionDispatch::Request:0x00007f8aa08752d0 @env={...},
> @filtered_parameters=nil, @filtered_env=nil, @filtered_path=nil,
> @protocol=nil, @port=nil, @method=nil, @request_method=nil, @remote_ip=nil,
> @original_fullpath=nil, @fullpath=nil, @ip=nil>, @check_ip=true,
> @proxies=[#<IPAddr: IPv4:127.0.0.1/255.255.255.255>,
> #<IPAddr:
> IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>,
>
> #<IPAddr:
> IPv6:fc00:0000:0000:0000:0000:0000:0000:0000/fe00:0000:0000:0000:0000:0000:0000:0000>,
>
> #<IPAddr: IPv4:10.0.0.0/255.0.0.0>, #<IPAddr: IPv4:172.16.0.0/255.240.0.0>,
> #<IPAddr: IPv4:192.168.0.0/255.255.0.0>], @ip="127.0.0.1">,
> "rack.session"=>#<ActionDispatch::Request::Session:0x7f8aa0874f60 not yet
> loaded>,
> "rack.session.options"=>#<ActionDispatch::Request::Session::Options:0x00007f8aa0874f10
>
> @by=#<ActionDispatch::Session::CookieStore:0x00007f8a9e2e8eb8
> @app=#<Rack::Head:0x00007f8a9e2e8f80
> @app=#<Rack::ConditionalGet:0x00007f8a9e2e8fa8
> @app=#<Rack::ETag:0x00007f8a9e2e8ff8
> @app=#<OmniAuth::Builder:0x00007f8a9e2ea7b8 @freeze_app=false, @warmup=nil,
> @run=#<ActionDispatch::Routing::RouteSet:0x00007f8aa4ada490>, @map=nil,
> @use=[#<Proc:0x00007f8a9e2e9020@/Users/jackrg/.rbenv/versions/2.4.10/lib/ruby/gems/2.4.0/gems/rack-2.2.3/lib/rack/builder.rb:158>],
>
> @options={}>, @cache_control="max-age=0, private, must-revalidate",
> @no_cache_control="no-cache">>>, @default_options={:path=>"/",
> :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true,
> :defer=>false, :renew=>false}, @key="_Novelty-Stats_session",
> @cookie_only=true, @same_site=nil>, @delegate={:path=>"/", :domain=>nil,
> :expire_after=>nil, :secure=>false, :httponly=>true,
> :defer=>false, :renew=>false}>,
> "action_dispatch.request.path_parameters"=>{:controller=>"books",
> :action=>"modify",
> :format=>"js"},
> "action_controller.instance"=>#<BooksController:0x00007f8a8f380ce0 ...>,
> "action_dispatch.request.content_type"=>#<Mime::Type:0x00007f8a9cd84428
> @synonyms=[],
> @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded",
> @hash=1420162111980396459>, "rack.tempfiles"=>[],
> "rack.request.form_hash"=>{"verb"=>"ChangeBook",
> "book_id"=>"34880", "status"=>"inactive",
> "ts"=>"1617061982022"},
> "rack.request.form_vars"=>"verb=ChangeBook&book_id=34880&status=inactive&ts=1617061982022",
> "rack.request.form_input"=>#<StringIO:0x00007f8aa0876130>,
> "action_dispatch.request.request_parameters"=>{"verb"=>"ChangeBook",
> "book_id"=>"34880", "status"=>"inactive", "ts"=>"1617061982022"},
> "rack.request.query_string"=>"", "rack.request.query_hash"=>{},
> "action_dispatch.request.query_parameters"=>{},
> "action_dispatch.request.parameters"=>{"verb"=>"ChangeBook",
> "book_id"=>"34880", "status"=>"inactive", "ts"=>"1617061982022",
> "controller"=>"books", "action"=>"modify", "format"=>"js"},
> "action_dispatch.request.formats"=>[#<Mime::Type:0x00007f8a9cd86a70
> @synonyms=["application/javascript",
> "application/x-javascript"], @symbol=:js, @string="text/javascript",
> @hash=-2007623201317620867>],
> "rack.request.cookie_hash"=>{"auth_token"=>"21a2cc0b56ce2911c4af42c092d0f595",
>
> "_Novelty-Stats_session"=>"dm9NS1JnaTFkWjhCVEhpRGtPUHNZUzk5TW56WXl1aWxoYXFYVmU3SVAyZlJkRGppbUR2QzE1bHVqQkxvUUt0YVc2WXd3MW5yMXNKYWsvdExPSDMyZHpja1B1dUFuY0JEc0ZSNDQ3TTJldFVOeUd3WVAzcG1lcWVNUEhHc1hmRVFaSXN0Y2diaHV1eFNZYy8vYllaNWFQSWNGbGdqUno1RlpFTFh5ZWRHeW9YNmFIc3lMTElEVmhLUXFHTEkvT2ExWFVXdEE4dU9veUJjU3ozQytiSTRNbUpEWVNaNWxsbHlvWWdNYWFmTTBJSEpiQjNFRm9laS9BaXpPNitwUkFwTS0tWmlWNncrMnhZcUYvR25IZ0lyU0wwdz09--43473ba27a643f2655b418b79eefdecb599f173c"},
> "rack.request.cookie_string"=>"auth_token=21a2cc0b56ce2911c4af42c092d0f595;
> _Novelty-Stats_session=dm9NS1JnaTFkWjhCVEhpRGtPUHNZUzk5TW56WXl1aWxoYXFYVmU3SVAyZlJkRGppbUR2QzE1bHVqQkxvUUt0YVc2WXd3MW5yMXNKYWsvdExPSDMyZHpja1B1dUFuY0JEc0ZSNDQ3TTJldFVOeUd3WVAzcG1lcWVNUEhHc1hmRVFaSXN0Y2diaHV1eFNZYy8vYllaNWFQSWNGbGdqUno1RlpFTFh5ZWRHeW9YNmFIc3lMTElEVmhLUXFHTEkvT2ExWFVXdEE4dU9veUJjU3ozQytiSTRNbUpEWVNaNWxsbHlvWWdNYWFmTTBJSEpiQjNFRm9laS9BaXpPNitwUkFwTS0tWmlWNncrMnhZcUYvR25IZ0lyU0wwdz09--43473ba27a643f2655b418b79eefdecb599f173c",
>
> "action_dispatch.cookies"=>#<ActionDispatch::Cookies::CookieJar:0x00007f8a8ebc4c40
> @set_cookies={},
> @delete_cookies={},
> @request=#<ActionDispatch::Request:0x00007f8a8f382338 ...>,
> @cookies={"auth_token"=>"21a2cc0b56ce2911c4af42c092d0f595",
> "_Novelty-Stats_session"=>"dm9NS1JnaTFkWjhCVEhpRGtPUHNZUzk5TW56WXl1aWxoYXFYVmU3SVAyZlJkRGppbUR2QzE1bHVqQkxvUUt0YVc2WXd3MW5yMXNKYWsvdExPSDMyZHpja1B1dUFuY0JEc0ZSNDQ3TTJldFVOeUd3WVAzcG1lcWVNUEhHc1hmRVFaSXN0Y2diaHV1eFNZYy8vYllaNWFQSWNGbGdqUno1RlpFTFh5ZWRHeW9YNmFIc3lMTElEVmhLUXFHTEkvT2ExWFVXdEE4dU9veUJjU3ozQytiSTRNbUpEWVNaNWxsbHlvWWdNYWFmTTBJSEpiQjNFRm9laS9BaXpPNitwUkFwTS0tWmlWNncrMnhZcUYvR25IZ0lyU0wwdz09--43473ba27a643f2655b418b79eefdecb599f173c"},
>
> @committed=false>}, @filtered_parameters={"verb"=>"ChangeBook",
> "book_id"=>"34880", "status"=>"inactive", "ts"=>"1617061982022",
> "controller"=>"books", "action"=>"modify",
> "format"=>"js"}, @filtered_env=nil, @filtered_path=nil, @protocol=nil,
> @port=nil, @method=nil, @request_method="PUT", @remote_ip="127.0.0.1",
> @original_fullpath=nil, @fullpath="/books/modify.js", @ip=nil,
> @headers=#<ActionDispatch::Http::Headers:0x00007f8a8ebc61f8
> @req=#<ActionDispatch::Request:0x00007f8a8f382338 ...>>>>,
> @_lookup_context=#<ActionView::LookupContext:0x00007f8a8f380bc8
> @details_key=nil, @cache=true, @prefixes=["books", "application"],
> @rendered_format=nil, @details={:locale=>[:en], :formats=>[:js, :html],
> :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby,
> :coffee]}, @view_paths=#<ActionView::PathSet:0x00007f8a8f380ad8
> @paths=[#<ActionView::OptimizedFileSystemResolver:0x00007f8aa485ab98
> @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}",
> @cache=#<ActionView::Resolver::Cache:0x7f8aa485a968 keys=1
> queries=0>, @path="/Users/jackrg/Documents/Novelty-Stats/app/views">]>,
> @html_fallback_for_js=true>, @_action_name="modify", @_response_body=nil,
> @marked_for_same_origin_verification=false, @_config={},
> @_params=<ActionController::Parameters
> {"verb"=>"ChangeBook", "book_id"=>"34880", "status"=>"inactive",
> "ts"=>"1617061982022", "controller"=>"books", "action"=>"modify",
> "format"=>"js"} permitted: false>, @current_user=#<User id: 31610, email: "
> [email protected]",
> password_digest: "$2a$04$dUuyYQDle.NHmNRnZB5sG.HWgZXMzbaFmNKM9jKIV00...",
> auth_token: "21a2cc0b56ce2911c4af42c092d0f595", activation_token:
> "53ecd2ac5d36e531171609630b7f2354", activated_at: "2021-03-29 23:52:58",
> password_reset_token: nil, password_reset_sent_at: nil, created_at:
> "2021-03-29 23:52:58", updated_at: "2021-03-29 23:52:59", currency:
> nil, time_zone: nil, completed_setup_steps: ["profile", "amazon",
> "barnes_and_noble", "apple", "smashwords", "kobo", "create_space",
> "google", "d2d", "review", "scrape"], full_name: "Full Name",
> friendly_name: "Name", no_book_activation_help: nil, daily_email:
> -2, daily_update_email_status: nil, daily_update_email_sent_at: nil,
> scrape_status: nil, deleted_at: nil, stripe_id: nil, plan_name: "Basic",
> has_card: nil, cancelled_at: nil, cc_billing_failed_at: nil, extra_emails:
> nil, country_list: [], ranking_lists: [], min_date: nil, max_date: nil,
> payment_attempts: nil, referred_by: nil, referral_paid_at:
> nil, billing_period: "month", referral_code: nil,
> store_token:
> "4a98523a41fce0dbec56f693494182b9">>).modify(hash_including("verb"=>"ChangeBook",
> "book_id"=>"34880",
> "status"=>"inactive"))
> expected: 1 time with arguments:
> (hash_including("verb"=>"ChangeBook", "book_id"=>"34880",
> "status"=>"inactive"))
> received: 0 times
>
>
> Am I wrong in mistrusting the message, given that removing the “.with”
> causes the test to pass? Or is there something not obvious going on? And
> while I’m at it, is there an easy way of coding the test so that it will
> automagically do all the conversions on the matching hash to prepare it for
> comparison to the params hash?
>
> Software versions:
>
> Ruby 2.4.10
> Rails 5.1
> RSpec 3.9.3
> Capybara 3.9
>
>
>
--
You received this message because you are subscribed to the Google Groups
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/rspec/52f8d609-3317-4959-9faa-5c672ed5d7a0n%40googlegroups.com.