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.
- checksums.yaml +4 -4
- data/.simplecov +6 -2
- data/.travis.yml +8 -25
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +5 -5
- data/README.md +146 -15
- data/Rakefile +2 -1
- data/config/default.yml +29 -0
- data/dev-entrypoint.sh +10 -0
- data/docker-compose.yml +42 -0
- data/lib/sapience/appender/datadog.rb +100 -0
- data/lib/sapience/appender/file.rb +11 -22
- data/lib/sapience/appender/sentry.rb +61 -55
- data/lib/sapience/appender/wrapper.rb +5 -4
- data/lib/sapience/base.rb +21 -13
- data/lib/sapience/config_loader.rb +66 -0
- data/lib/sapience/configuration/grape.rb +9 -0
- data/lib/sapience/configuration.rb +32 -22
- data/lib/sapience/core_ext/hash.rb +25 -0
- data/lib/sapience/core_ext/thread.rb +2 -2
- data/lib/sapience/extensions/action_cable/tagged_logger_proxy.rb +6 -0
- data/lib/sapience/extensions/action_controller/live.rb +6 -0
- data/lib/sapience/extensions/action_controller/log_subscriber.rb +127 -0
- data/lib/sapience/extensions/action_controller/log_subscriber_processing.rb +24 -0
- data/lib/sapience/extensions/action_dispatch/debug_exceptions.rb +11 -0
- data/lib/sapience/extensions/action_view/log_subscriber.rb +9 -0
- data/lib/sapience/extensions/action_view/streaming_template_renderer.rb +11 -0
- data/lib/sapience/extensions/active_job/logging.rb +14 -0
- data/lib/sapience/extensions/active_model_serializers/logging.rb +14 -0
- data/lib/sapience/extensions/active_record/log_subscriber.rb +35 -0
- data/lib/sapience/extensions/grape/middleware/logging.rb +91 -0
- data/lib/sapience/extensions/grape/timings.rb +25 -0
- data/lib/sapience/extensions/rails/rack/logger.rb +11 -0
- data/lib/sapience/extensions/rails/rack/logger_info_as_debug.rb +24 -0
- data/lib/sapience/formatters/color.rb +3 -3
- data/lib/sapience/formatters/default.rb +1 -1
- data/lib/sapience/grape.rb +25 -0
- data/lib/sapience/log.rb +8 -6
- data/lib/sapience/loggable.rb +19 -17
- data/lib/sapience/logger.rb +46 -126
- data/lib/sapience/rails.rb +65 -8
- data/lib/sapience/sapience.rb +74 -73
- data/lib/sapience/subscriber.rb +5 -1
- data/lib/sapience/version.rb +1 -1
- data/lib/sapience.rb +4 -1
- data/sapience.gemspec +7 -4
- data/test_app/Gemfile +5 -1
- data/test_app/Rakefile +5 -1
- data/test_app/app/controllers/posts_controller.rb +12 -11
- data/test_app/config/application.rb +0 -1
- data/test_app/spec/controllers/posts_controller_spec.rb +1 -1
- data/test_app/spec/fixtures/sapience.yml +14 -0
- data/test_app/spec/helpers/posts_helper_spec.rb +1 -1
- data/test_app/spec/integration/sapience_spec.rb +14 -0
- data/test_app/spec/models/post_spec.rb +1 -1
- data/test_app/spec/models/user_spec.rb +1 -1
- data/test_app/spec/rails_helper.rb +15 -0
- data/test_app/spec/requests/posts_spec.rb +1 -1
- data/test_app/spec/routing/posts_routing_spec.rb +8 -10
- data/test_app/spec/spec_helper.rb +0 -44
- metadata +76 -11
- data/lib/sapience/appender/statsd.rb +0 -68
data/lib/sapience/sapience.rb
CHANGED
@@ -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: '
|
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 ||=
|
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
|
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, &
|
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
|
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
|
-
|
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
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
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
|
|
data/lib/sapience/subscriber.rb
CHANGED
@@ -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
|
-
|
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
|
|
data/lib/sapience/version.rb
CHANGED
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/
|
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 = "
|
13
|
-
spec.description = "
|
14
|
-
spec.homepage = "https://
|
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:
|
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:
|
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:
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
@@ -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
|
@@ -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
|
@@ -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(:
|
6
|
+
expect(get: "/posts").to route_to("posts#index")
|
8
7
|
end
|
9
8
|
|
10
9
|
it "routes to #new" do
|
11
|
-
expect(:
|
10
|
+
expect(get: "/posts/new").to route_to("posts#new")
|
12
11
|
end
|
13
12
|
|
14
13
|
it "routes to #show" do
|
15
|
-
expect(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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
|