sapience 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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