sapience 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.simplecov +6 -2
  3. data/.travis.yml +8 -25
  4. data/CODE_OF_CONDUCT.md +1 -1
  5. data/Gemfile +5 -5
  6. data/README.md +146 -15
  7. data/Rakefile +2 -1
  8. data/config/default.yml +29 -0
  9. data/dev-entrypoint.sh +10 -0
  10. data/docker-compose.yml +42 -0
  11. data/lib/sapience/appender/datadog.rb +100 -0
  12. data/lib/sapience/appender/file.rb +11 -22
  13. data/lib/sapience/appender/sentry.rb +61 -55
  14. data/lib/sapience/appender/wrapper.rb +5 -4
  15. data/lib/sapience/base.rb +21 -13
  16. data/lib/sapience/config_loader.rb +66 -0
  17. data/lib/sapience/configuration/grape.rb +9 -0
  18. data/lib/sapience/configuration.rb +32 -22
  19. data/lib/sapience/core_ext/hash.rb +25 -0
  20. data/lib/sapience/core_ext/thread.rb +2 -2
  21. data/lib/sapience/extensions/action_cable/tagged_logger_proxy.rb +6 -0
  22. data/lib/sapience/extensions/action_controller/live.rb +6 -0
  23. data/lib/sapience/extensions/action_controller/log_subscriber.rb +127 -0
  24. data/lib/sapience/extensions/action_controller/log_subscriber_processing.rb +24 -0
  25. data/lib/sapience/extensions/action_dispatch/debug_exceptions.rb +11 -0
  26. data/lib/sapience/extensions/action_view/log_subscriber.rb +9 -0
  27. data/lib/sapience/extensions/action_view/streaming_template_renderer.rb +11 -0
  28. data/lib/sapience/extensions/active_job/logging.rb +14 -0
  29. data/lib/sapience/extensions/active_model_serializers/logging.rb +14 -0
  30. data/lib/sapience/extensions/active_record/log_subscriber.rb +35 -0
  31. data/lib/sapience/extensions/grape/middleware/logging.rb +91 -0
  32. data/lib/sapience/extensions/grape/timings.rb +25 -0
  33. data/lib/sapience/extensions/rails/rack/logger.rb +11 -0
  34. data/lib/sapience/extensions/rails/rack/logger_info_as_debug.rb +24 -0
  35. data/lib/sapience/formatters/color.rb +3 -3
  36. data/lib/sapience/formatters/default.rb +1 -1
  37. data/lib/sapience/grape.rb +25 -0
  38. data/lib/sapience/log.rb +8 -6
  39. data/lib/sapience/loggable.rb +19 -17
  40. data/lib/sapience/logger.rb +46 -126
  41. data/lib/sapience/rails.rb +65 -8
  42. data/lib/sapience/sapience.rb +74 -73
  43. data/lib/sapience/subscriber.rb +5 -1
  44. data/lib/sapience/version.rb +1 -1
  45. data/lib/sapience.rb +4 -1
  46. data/sapience.gemspec +7 -4
  47. data/test_app/Gemfile +5 -1
  48. data/test_app/Rakefile +5 -1
  49. data/test_app/app/controllers/posts_controller.rb +12 -11
  50. data/test_app/config/application.rb +0 -1
  51. data/test_app/spec/controllers/posts_controller_spec.rb +1 -1
  52. data/test_app/spec/fixtures/sapience.yml +14 -0
  53. data/test_app/spec/helpers/posts_helper_spec.rb +1 -1
  54. data/test_app/spec/integration/sapience_spec.rb +14 -0
  55. data/test_app/spec/models/post_spec.rb +1 -1
  56. data/test_app/spec/models/user_spec.rb +1 -1
  57. data/test_app/spec/rails_helper.rb +15 -0
  58. data/test_app/spec/requests/posts_spec.rb +1 -1
  59. data/test_app/spec/routing/posts_routing_spec.rb +8 -10
  60. data/test_app/spec/spec_helper.rb +0 -44
  61. metadata +76 -11
  62. data/lib/sapience/appender/statsd.rb +0 -68
@@ -12,7 +12,7 @@ require "socket"
12
12
  # config.appenders = [
13
13
  # { file: { io: STDOUT, formatter: :color } },
14
14
  # { statsd: { url: 'udp://localhost:2222' } },
15
- # { sentry: { dsn: 'ASDFASDF' } },
15
+ # { sentry: { dsn: 'https://foobar:443' } },
16
16
  # ]
17
17
  # end
18
18
 
@@ -27,17 +27,46 @@ module Sapience
27
27
  LEVELS = [:trace, :debug, :info, :warn, :error, :fatal]
28
28
 
29
29
  def self.config
30
- @@config ||= Configuration.new
30
+ @@config ||= begin
31
+ config = ConfigLoader.load_from_file
32
+ env = config[environment]
33
+ unless env
34
+ puts "Missing configuration for #{environment} environment. Sapience is going to use default configuration"
35
+ env = config.fetch("default")
36
+ end
37
+ Configuration.new(env)
38
+ end
39
+ end
40
+
41
+ def self.reset!
42
+ @@config = nil
43
+ @@logger = nil
44
+ @@metrix = nil
45
+ reset_appenders!
46
+ end
47
+
48
+ def self.reset_appenders!
49
+ @@appenders = Concurrent::Array.new
50
+ end
51
+
52
+ def self.environment
53
+ ENV.fetch("RAILS_ENV") do
54
+ ENV.fetch("RACK_ENV") do
55
+ ::Rails.env if defined?(::Rails) && ::Rails.respond_to?(:env)
56
+ end
57
+ end
31
58
  end
32
59
 
33
60
  def self.configure
34
- yield @@config
61
+ yield config if block_given?
35
62
 
36
63
  config.appenders.each do |appender|
37
64
  appender.each do |name, options|
38
65
  add_appender(name, options)
39
66
  end
40
67
  end
68
+
69
+ config
41
70
  end
42
71
 
43
72
  # Return a logger for the supplied class or class_name
@@ -123,24 +152,36 @@ module Sapience
123
152
  # logger = Sapience['Example']
124
153
  # logger.info "Hello World"
125
154
  # logger.debug("Login time", user: 'Joe', duration: 100, ip_address: '127.0.0.1')
126
- def self.add_appender(appender, options, _deprecated_level = nil, &block)
155
+ def self.add_appender(appender, options = {}, _deprecated_level = nil, &_block)
127
156
  fail ArgumentError, "options should be a hash" unless options.is_a?(Hash)
157
+ options.deep_symbolize_keys!
128
158
  appender_class = constantize_symbol(appender)
129
159
  appender = appender_class.new(options)
130
160
  @@appenders << appender
131
161
 
132
162
  # Start appender thread if it is not already running
133
163
  Sapience::Logger.start_appender_thread
134
- Sapience::Logger.logger = appender if appender.is_a?(Sapience::Appender::File)
164
+ Sapience.logger = appender if appender.is_a?(Sapience::Appender::File)
165
+ Sapience.metrix = appender if appender.is_a?(Sapience::Appender::Datadog)
135
166
  appender
136
167
  end
137
168
 
169
+
138
170
  # Remove an existing appender
139
171
  # Currently only supports appender instances
172
+ # TODO: Make it possible to remove appenders by type
173
+ # Maybe create a concurrent collection that allows this by inheriting from concurrent array.
140
174
  def self.remove_appender(appender)
141
175
  @@appenders.delete(appender)
142
176
  end
143
177
 
178
+ # Remove specific appenders or all existing
179
+ def self.remove_appenders(appenders = @@appenders)
180
+ appenders.each do |appender|
181
+ remove_appender(appender)
182
+ end
183
+ end
184
+
144
185
  # Returns [Sapience::Subscriber] a copy of the list of active
145
186
  # appenders for debugging etc.
146
187
  # Use Sapience.add_appender and Sapience.remove_appender
@@ -149,6 +190,22 @@ module Sapience
149
190
  @@appenders.clone
150
191
  end
151
192
 
193
+ def self.metrix=(metrix)
194
+ @@metrix = metrix
195
+ end
196
+
197
+ def self.metrix
198
+ @@metrix ||= Sapience.add_appender(:datadog)
199
+ end
200
+
201
+ def self.logger=(logger)
202
+ @@logger = Sapience::Logger.logger = logger
203
+ end
204
+
205
+ def self.logger
206
+ @@logger ||= Sapience::Logger.logger
207
+ end
208
+
152
209
  # Wait until all queued log messages have been written and flush all active
153
210
  # appenders
154
211
  def self.flush
@@ -170,63 +227,6 @@ module Sapience
170
227
  Sapience::Logger.start_appender_thread
171
228
  end
172
229
 
173
- # Add signal handlers for Sapience
174
- #
175
- # Two signal handlers will be registered by default:
176
- #
177
- # 1. Changing the log_level:
178
- #
179
- # The log level can be changed without restarting the process by sending the
180
- # log_level_signal, which by default is 'USR2'
181
- #
182
- # When the log_level_signal is raised on this process, the global default log level
183
- # rotates through the following log levels in the following order, starting
184
- # from the current global default level:
185
- # :warn, :info, :debug, :trace
186
- #
187
- # If the current level is :trace it wraps around back to :warn
188
- #
189
- # 2. Logging a Ruby thread dump
190
- #
191
- # When the signal is raised on this process, Sapience will write the list
192
- # of threads to the log file, along with their back-traces when available
193
- #
194
- # It is recommended to name any threads you create in the application, by
195
- # calling the following from within the thread itself:
196
- # Thread.current.name = 'My Worker'
197
- #
198
- #
199
- # Note:
200
- # To only register one of the signal handlers, set the other to nil
201
- # rubocop:disable AbcSize, CyclomaticComplexity, PerceivedComplexity
202
- def self.add_signal_handler(log_level_signal = "USR2", thread_dump_signal = "TTIN", _gc_log_microseconds = 100_000)
203
- Signal.trap(log_level_signal) do
204
- index = (default_level == :trace) ? LEVELS.find_index(:error) : LEVELS.find_index(default_level)
205
- new_level = LEVELS[index - 1]
206
- self["Sapience"].warn "Changed global default log level to #{new_level.inspect}"
207
- self.default_level = new_level
208
- end if log_level_signal
209
-
210
- Signal.trap(thread_dump_signal) do
211
- logger = Sapience["Thread Dump"]
212
- Thread.list.each do |thread|
213
- next if thread == Thread.current
214
- message = thread.name
215
- if (backtrace = thread.backtrace)
216
- message += "\n"
217
- message << backtrace.join("\n")
218
- end
219
- tags = thread[:sapience_tags]
220
- tags = tags.nil? ? [] : tags.clone
221
- logger.tagged(tags) { logger.warn(message) }
222
- end
223
- end if thread_dump_signal
224
-
225
- true
226
- end
227
-
228
- # rubocop:enable AbcSize, CyclomaticComplexity, PerceivedComplexity
229
-
230
230
  # If the tag being supplied is definitely a string then this fast
231
231
  # tag api can be used for short lived tags
232
232
  def self.fast_tag(tag)
@@ -327,20 +327,21 @@ module Sapience
327
327
  Thread.current[:sapience_silence] = current_index
328
328
  end
329
329
 
330
- private
331
-
332
- @@appenders = Concurrent::Array.new
330
+ reset_appenders!
333
331
 
334
332
  def self.constantize_symbol(symbol, namespace = "Sapience::Appender")
335
333
  klass = "#{namespace}::#{camelize(symbol.to_s)}"
336
- begin
337
- if RUBY_VERSION.to_i >= 2
338
- Object.const_get(klass)
339
- else
340
- klass.split("::").inject(Object) { |o, name| o.const_get(name) } # rubocop:disable SingleLineBlockParams
341
- end
342
- rescue NameError
343
- raise(ArgumentError, "Could not convert symbol: #{symbol} to a class in: #{namespace}. Looking for: #{klass}")
334
+ constantize(klass)
335
+ rescue NameError
336
+ raise(ArgumentError, "Could not convert symbol: #{symbol} to a class in: #{namespace}. Looking for: #{klass}")
337
+ end
338
+
339
+ def self.constantize(class_name)
340
+ return class_name unless class_name.is_a?(String)
341
+ if RUBY_VERSION.to_i >= 2
342
+ Object.const_get(class_name)
343
+ else
344
+ class_name.split("::").inject(Object) { |o, name| o.const_get(name) } # rubocop:disable SingleLineBlockParams
344
345
  end
345
346
  end
346
347
 
@@ -96,10 +96,13 @@ module Sapience
96
96
  # - Any object that responds to :call
97
97
  # - If none of the above apply, then the supplied block is returned as the formatter.
98
98
  # - Otherwise an instance of the default formatter is returned.
99
- def extract_formatter(formatter, &block) # rubocop:disable Metrics/CyclomaticComplexity
99
+ # rubocop:disable CyclomaticComplexity, AbcSize, PerceivedComplexity
100
+ def extract_formatter(formatter, &block)
100
101
  case
101
102
  when formatter.is_a?(Symbol)
102
103
  Sapience.constantize_symbol(formatter, "Sapience::Formatters").new
104
+ when formatter.is_a?(String)
105
+ Sapience.constantize_symbol(formatter, "Sapience::Formatters").new
103
106
  when formatter.is_a?(Hash) && formatter.size > 0
104
107
  fmt, options = formatter.first
105
108
  Sapience.constantize_symbol(fmt.to_sym, "Sapience::Formatters").new(options)
@@ -113,6 +116,7 @@ module Sapience
113
116
  default_formatter
114
117
  end
115
118
  end
119
+ # rubocop:enable CyclomaticComplexity, AbcSize, PerceivedComplexity
116
120
 
117
121
  SUBSCRIBER_OPTIONS = [:level, :formatter, :filter, :application, :host].freeze
118
122
 
@@ -1,3 +1,3 @@
1
1
  module Sapience
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/sapience.rb CHANGED
@@ -11,8 +11,11 @@ require "sapience/formatters/default"
11
11
  require "sapience/formatters/color"
12
12
  require "sapience/formatters/json"
13
13
 
14
+ require "sapience/config_loader"
14
15
  require "sapience/configuration"
16
+ require "sapience/configuration/grape"
15
17
  require "sapience/ansi_colors"
18
+ require "sapience/core_ext/hash"
16
19
  require "sapience/core_ext/thread"
17
20
  require "sapience/base"
18
21
  require "sapience/log"
@@ -23,7 +26,7 @@ require "sapience/subscriber"
23
26
  require "sapience/appender/file"
24
27
  require "sapience/appender/sentry"
25
28
  require "sapience/appender/wrapper"
26
- require "sapience/appender/statsd"
29
+ require "sapience/appender/datadog"
27
30
 
28
31
  # @formatter:on
29
32
 
data/sapience.gemspec CHANGED
@@ -9,9 +9,9 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Mikael Henriksson", "Alex Malkov"]
10
10
  spec.email = ["mika@reevoo.com", "alex.malkov@reevoo.com"]
11
11
 
12
- spec.summary = "Write a short summary, because Rubygems requires one."
13
- spec.description = "Write a longer description or delete this line."
14
- spec.homepage = "https://sapience.github.io"
12
+ spec.summary = "Hasslefree autoconfiguration for logging, metrics and exception collection."
13
+ spec.description = "Hasslefree autoconfiguration for logging, metrics and exception collection."
14
+ spec.homepage = "https://github.com/reevoo/sapience"
15
15
  spec.license = "MIT"
16
16
 
17
17
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
- spec.add_dependency "concurrent-ruby"
30
+ spec.add_dependency "concurrent-ruby", "~> 1.0"
31
31
  spec.add_development_dependency "bundler", "~> 1.12"
32
32
  spec.add_development_dependency "rake", "~> 10.0"
33
33
  spec.add_development_dependency "rspec", "~> 3.0"
@@ -36,4 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency "simplecov"
37
37
  spec.add_development_dependency "simplecov-json"
38
38
  spec.add_development_dependency "rspec-its"
39
+ spec.add_development_dependency "codeclimate-test-reporter"
40
+ spec.add_development_dependency "coveralls"
41
+ spec.add_development_dependency "gem-release"
39
42
  end
data/test_app/Gemfile CHANGED
@@ -14,7 +14,7 @@ gem "puma", "~> 3.0"
14
14
 
15
15
  # Use Capistrano for deployment
16
16
  # gem 'capistrano-rails', group: :development
17
- gem "sapience", path: "../"
17
+ gem "sapience", path: "../", require: "sapience/rails"
18
18
  gem "sentry-raven"
19
19
  gem "statsd-ruby"
20
20
 
@@ -32,5 +32,9 @@ group :development do
32
32
  gem "listen", "~> 3.0.5"
33
33
  end
34
34
 
35
+ group :test do
36
+ gem "rspec-its"
37
+ end
38
+
35
39
  # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
36
40
  gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
data/test_app/Rakefile CHANGED
@@ -1,6 +1,10 @@
1
1
  # Add your own tasks in files placed in lib/tasks ending in .rake,
2
2
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
-
4
3
  require_relative "config/application"
5
4
 
6
5
  Rails.application.load_tasks
6
+
7
+ require "rspec/core/rake_task"
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: [:spec]
@@ -24,7 +24,7 @@ class PostsController < ApplicationController
24
24
  @post = Post.new(post_params)
25
25
 
26
26
  if @post.save
27
- redirect_to @post, notice: 'Post was successfully created.'
27
+ redirect_to @post, notice: "Post was successfully created."
28
28
  else
29
29
  render :new
30
30
  end
@@ -33,7 +33,7 @@ class PostsController < ApplicationController
33
33
  # PATCH/PUT /posts/1
34
34
  def update
35
35
  if @post.update(post_params)
36
- redirect_to @post, notice: 'Post was successfully updated.'
36
+ redirect_to @post, notice: "Post was successfully updated."
37
37
  else
38
38
  render :edit
39
39
  end
@@ -42,17 +42,18 @@ class PostsController < ApplicationController
42
42
  # DELETE /posts/1
43
43
  def destroy
44
44
  @post.destroy
45
- redirect_to posts_url, notice: 'Post was successfully destroyed.'
45
+ redirect_to posts_url, notice: "Post was successfully destroyed."
46
46
  end
47
47
 
48
48
  private
49
- # Use callbacks to share common setup or constraints between actions.
50
- def set_post
51
- @post = Post.find(params[:id])
52
- end
53
49
 
54
- # Only allow a trusted parameter "white list" through.
55
- def post_params
56
- params.require(:post).permit(:title, :body, :author_id)
57
- end
50
+ # Use callbacks to share common setup or constraints between actions.
51
+ def set_post
52
+ @post = Post.find(params[:id])
53
+ end
54
+
55
+ # Only allow a trusted parameter "white list" through.
56
+ def post_params
57
+ params.require(:post).permit(:title, :body, :author_id)
58
+ end
58
59
  end
@@ -9,7 +9,6 @@ require "action_controller/railtie"
9
9
  require "action_mailer/railtie"
10
10
  require "action_view/railtie"
11
11
  require "action_cable/engine"
12
- require "sapience/rails"
13
12
  # require "sprockets/railtie"
14
13
  # require "rails/test_unit/railtie"
15
14
 
@@ -1,4 +1,4 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
3
  RSpec.describe PostsController, type: :controller do
4
4
  specify do
@@ -0,0 +1,14 @@
1
+ ---
2
+ default:
3
+ log_level: error
4
+ appenders:
5
+ - file:
6
+ file_name: log/error.log
7
+ formatter: default
8
+
9
+ test:
10
+ log_level: fatal
11
+ appenders:
12
+ - file:
13
+ file_name: log/fatal.log
14
+ formatter: json
@@ -1,4 +1,4 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
3
  # Specs in this file have access to a helper object that includes
4
4
  # the PostsHelper. For example:
@@ -0,0 +1,14 @@
1
+ require "rails_helper"
2
+ require "fileutils"
3
+
4
+ describe Sapience, "rails integration", :integration do
5
+ context "with a sapience.yml present in config/" do
6
+ describe ".config" do
7
+ subject(:config) { Sapience.config }
8
+ its(:default_level) { is_expected.to eq(:fatal) }
9
+ its(:default_level_index) { is_expected.to eq(5) }
10
+ its(:backtrace_level) { is_expected.to eq(:fatal) }
11
+ its(:backtrace_level_index) { is_expected.to eq(5) }
12
+ end
13
+ end
14
+ end
@@ -1,4 +1,4 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
3
  RSpec.describe Post, type: :model do
4
4
  pending "add some examples to (or delete) #{__FILE__}"
@@ -1,4 +1,4 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
3
  RSpec.describe User, type: :model do
4
4
  pending "add some examples to (or delete) #{__FILE__}"
@@ -5,6 +5,7 @@ require File.expand_path("../../config/environment", __FILE__)
5
5
  abort("The Rails environment is running in production mode!") if Rails.env.production?
6
6
  require "spec_helper"
7
7
  require "rspec/rails"
8
+ require "rspec/its"
8
9
 
9
10
  Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
10
11
 
@@ -20,4 +21,18 @@ RSpec.configure do |config|
20
21
 
21
22
  config.infer_spec_type_from_file_location!
22
23
  config.filter_rails_from_backtrace!
24
+ config.before(:each) do
25
+ Sapience.reset!
26
+ end
27
+
28
+ config.before(:suite) do
29
+ FileUtils.cp(
30
+ Rails.root.join("spec/fixtures/sapience.yml"),
31
+ Rails.root.join("config/sapience.yml"),
32
+ )
33
+ end
34
+
35
+ config.after(:suite) do
36
+ FileUtils.rm(Rails.root.join("config/sapience.yml"))
37
+ end
23
38
  end
@@ -1,4 +1,4 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
3
  RSpec.describe "Posts", type: :request do
4
4
  describe "GET /posts" do
@@ -2,38 +2,36 @@ require "rails_helper"
2
2
 
3
3
  RSpec.describe PostsController, type: :routing do
4
4
  describe "routing" do
5
-
6
5
  it "routes to #index" do
7
- expect(:get => "/posts").to route_to("posts#index")
6
+ expect(get: "/posts").to route_to("posts#index")
8
7
  end
9
8
 
10
9
  it "routes to #new" do
11
- expect(:get => "/posts/new").to route_to("posts#new")
10
+ expect(get: "/posts/new").to route_to("posts#new")
12
11
  end
13
12
 
14
13
  it "routes to #show" do
15
- expect(:get => "/posts/1").to route_to("posts#show", :id => "1")
14
+ expect(get: "/posts/1").to route_to("posts#show", id: "1")
16
15
  end
17
16
 
18
17
  it "routes to #edit" do
19
- expect(:get => "/posts/1/edit").to route_to("posts#edit", :id => "1")
18
+ expect(get: "/posts/1/edit").to route_to("posts#edit", id: "1")
20
19
  end
21
20
 
22
21
  it "routes to #create" do
23
- expect(:post => "/posts").to route_to("posts#create")
22
+ expect(post: "/posts").to route_to("posts#create")
24
23
  end
25
24
 
26
25
  it "routes to #update via PUT" do
27
- expect(:put => "/posts/1").to route_to("posts#update", :id => "1")
26
+ expect(put: "/posts/1").to route_to("posts#update", id: "1")
28
27
  end
29
28
 
30
29
  it "routes to #update via PATCH" do
31
- expect(:patch => "/posts/1").to route_to("posts#update", :id => "1")
30
+ expect(patch: "/posts/1").to route_to("posts#update", id: "1")
32
31
  end
33
32
 
34
33
  it "routes to #destroy" do
35
- expect(:delete => "/posts/1").to route_to("posts#destroy", :id => "1")
34
+ expect(delete: "/posts/1").to route_to("posts#destroy", id: "1")
36
35
  end
37
-
38
36
  end
39
37
  end
@@ -7,54 +7,10 @@ RSpec.configure do |config|
7
7
  mocks.verify_partial_doubles = true
8
8
  end
9
9
 
10
- # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
11
- # have no way to turn it off -- the option exists only for backwards
12
- # compatibility in RSpec 3). It causes shared context metadata to be
13
- # inherited by the metadata hash of host groups and examples, rather than
14
- # triggering implicit auto-inclusion in groups with matching metadata.
15
10
  config.shared_context_metadata_behavior = :apply_to_host_groups
16
-
17
- # This allows you to limit a spec run to individual examples or groups
18
- # you care about by tagging them with `:focus` metadata. When nothing
19
- # is tagged with `:focus`, all examples get run. RSpec also provides
20
- # aliases for `it`, `describe`, and `context` that include `:focus`
21
- # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
22
11
  config.filter_run_when_matching :focus
23
-
24
- # Allows RSpec to persist some state between runs in order to support
25
- # the `--only-failures` and `--next-failure` CLI options. We recommend
26
- # you configure your source control system to ignore this file.
27
12
  config.example_status_persistence_file_path = "spec/examples.txt"
28
-
29
- # Limits the available syntax to the non-monkey patched syntax that is
30
- # recommended. For more details, see:
31
- # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
32
- # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
33
- # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
34
- config.disable_monkey_patching!
35
-
36
- # Many RSpec users commonly either run the entire suite or an individual
37
- # file, and it's useful to allow more verbose output when running an
38
- # individual spec file.
39
- # Use the documentation formatter for detailed output,
40
- # unless a formatter has already been configured
41
- # (e.g. via a command-line flag).
42
13
  config.default_formatter = "doc" if config.files_to_run.one?
43
-
44
- # Print the 10 slowest examples and example groups at the
45
- # end of the spec run, to help surface which specs are running
46
- # particularly slow.
47
- # config.profile_examples = 10
48
-
49
- # Run specs in random order to surface order dependencies. If you find an
50
- # order dependency and want to debug it, you can fix the order by providing
51
- # the seed, which is printed after each run.
52
- # --seed 1234
53
14
  config.order = :random
54
-
55
- # Seed global randomization in this process using the `--seed` CLI option.
56
- # Setting this allows you to use `--seed` to deterministically reproduce
57
- # test failures related to randomization by passing the same `--seed` value
58
- # as the one that triggered the failure.
59
15
  Kernel.srand config.seed
60
16
  end