rackamole 0.0.1 → 0.0.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.
- data/README.txt +12 -1
- data/lib/rackamole.rb +1 -1
- data/lib/rackamole/interceptor.rb +8 -0
- data/lib/rackamole/mole.rb +46 -24
- data/lib/rackamole/store/log.rb +2 -0
- data/lib/rackamole/store/mongo.rb +21 -4
- data/samples/rails/moled/app/controllers/application_controller.rb +8 -0
- data/samples/rails/moled/app/controllers/fred_controller.rb +9 -0
- data/samples/rails/moled/app/views/fred/show.html.erb +1 -0
- data/samples/rails/moled/config/routes.rb +1 -38
- data/samples/rails/moled/db/production.sqlite3 +0 -0
- data/samples/rails/moled/log/development.log +50 -0
- data/samples/rails/moled/log/production.log +36 -0
- data/samples/sinatra/blee.rb +7 -0
- data/samples/sinatra/moled.rb +18 -3
- data/samples/sinatra/views/normal.erb +1 -0
- data/samples/sinatra/views/params.erb +1 -0
- data/spec/rackamole/interceptor_spec.rb +13 -1
- metadata +7 -2
data/README.txt
CHANGED
@@ -18,7 +18,10 @@ interactions and leverage these findings for the next iteration of your applicat
|
|
18
18
|
|
19
19
|
== PROJECT INFORMATION
|
20
20
|
|
21
|
-
* Developer: Fernand Galiana
|
21
|
+
* Developer: Fernand Galiana
|
22
|
+
* Blog: liquidrail.com
|
23
|
+
* Site: rackamole.com
|
24
|
+
* Twitter: @rackamole
|
22
25
|
* Forum: http://groups.google.com/group/rackamole
|
23
26
|
* Git: git://github.com/derailed/rackamole.git
|
24
27
|
|
@@ -55,6 +58,14 @@ interactions and leverage these findings for the next iteration of your applicat
|
|
55
58
|
in the session using the :user_name key. There are other options available, please take a look
|
56
59
|
at the docs for more information.
|
57
60
|
|
61
|
+
Given Rails exception handling logic, you can also edit your application_controller.rb file and
|
62
|
+
include the mole interceptor to trap exceptions in production environment
|
63
|
+
|
64
|
+
class ApplicationController
|
65
|
+
include Rackamole::Interceptor
|
66
|
+
|
67
|
+
This will instruct the mole to trap the raised exception from your rails stack.
|
68
|
+
|
58
69
|
=== Sinatra Applications
|
59
70
|
|
60
71
|
Add the following lines in the config section and smoke it...
|
data/lib/rackamole.rb
CHANGED
@@ -6,9 +6,17 @@ module Rackamole
|
|
6
6
|
# ie include Wackamole::Interceptor
|
7
7
|
def self.included( base )
|
8
8
|
base.send( :alias_method_chain, :rescue_action_in_public, :mole )
|
9
|
+
base.send( :alias_method_chain, :rescue_action_locally, :mole )
|
9
10
|
end
|
10
11
|
|
11
12
|
private
|
13
|
+
|
14
|
+
# Instructs the mole to trap the framework exception
|
15
|
+
def rescue_action_locally_with_mole( exception )
|
16
|
+
# Stuff the exception in the env for mole rack retrieval
|
17
|
+
request.env['mole.exception'] = exception
|
18
|
+
rescue_action_locally_without_mole( exception )
|
19
|
+
end
|
12
20
|
|
13
21
|
# Instructs the mole to trap the framework exception
|
14
22
|
def rescue_action_in_public_with_mole( exception )
|
data/lib/rackamole/mole.rb
CHANGED
@@ -17,16 +17,22 @@ module Rack
|
|
17
17
|
init_options( opts )
|
18
18
|
end
|
19
19
|
|
20
|
-
def call( env )
|
20
|
+
def call( env )
|
21
21
|
# Bail if application is not moleable
|
22
22
|
return @app.call( env ) unless moleable?
|
23
|
-
|
24
|
-
|
23
|
+
|
24
|
+
status, headers, body = nil
|
25
25
|
elapsed = Hitimes::Interval.measure do
|
26
|
-
|
26
|
+
begin
|
27
|
+
status, headers, body = @app.call( env )
|
28
|
+
rescue => boom
|
29
|
+
env['mole.exception'] = boom
|
30
|
+
@store.mole( mole_info( env, elapsed, status, headers, body ) )
|
31
|
+
raise boom
|
32
|
+
end
|
27
33
|
end
|
28
|
-
@store.mole( mole_info( env, elapsed ) )
|
29
|
-
|
34
|
+
@store.mole( mole_info( env, elapsed, status, headers, body ) )
|
35
|
+
return status, headers, body
|
30
36
|
end
|
31
37
|
|
32
38
|
# ===========================================================================
|
@@ -34,31 +40,45 @@ module Rack
|
|
34
40
|
|
35
41
|
# Load up configuration options
|
36
42
|
def init_options( opts )
|
37
|
-
options
|
38
|
-
@environment
|
39
|
-
@perf_threshold
|
40
|
-
@moleable
|
41
|
-
@app_name
|
42
|
-
@user_key
|
43
|
-
@store
|
43
|
+
options = default_options.merge( opts )
|
44
|
+
@environment = options[:environment]
|
45
|
+
@perf_threshold = options[:perf_threshold]
|
46
|
+
@moleable = options[:moleable]
|
47
|
+
@app_name = options[:app_name]
|
48
|
+
@user_key = options[:user_key]
|
49
|
+
@store = options[:store]
|
50
|
+
@excluded_paths = options[:excluded_paths]
|
44
51
|
end
|
45
52
|
|
46
53
|
# Mole default options
|
47
54
|
def default_options
|
48
55
|
{
|
49
|
-
:app_name
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
56
|
+
:app_name => "Moled App",
|
57
|
+
:excluded_paths => [/.?\.ico/, /.?\.png/],
|
58
|
+
:moleable => true,
|
59
|
+
:perf_threshold => 10,
|
60
|
+
:store => Rackamole::Store::Log.new
|
53
61
|
}
|
54
62
|
end
|
55
|
-
|
63
|
+
|
64
|
+
# Check if this request should be moled according to the exclude filters
|
65
|
+
def mole_request?( request )
|
66
|
+
@excluded_paths.each do |exclude_path|
|
67
|
+
return false if request.path.match( exclude_path )
|
68
|
+
end
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
56
72
|
# Extract interesting information from the request
|
57
|
-
def mole_info( env, elapsed )
|
58
|
-
request
|
73
|
+
def mole_info( env, elapsed, status, headers, body )
|
74
|
+
request = Rack::Request.new( env )
|
75
|
+
info = OrderedHash.new
|
76
|
+
|
77
|
+
return info unless mole_request?( request )
|
78
|
+
|
59
79
|
session = env['rack.session']
|
60
80
|
route = get_route( request )
|
61
|
-
|
81
|
+
|
62
82
|
ip, browser = identify( env )
|
63
83
|
user_id = nil
|
64
84
|
user_name = nil
|
@@ -105,9 +125,11 @@ module Rack
|
|
105
125
|
info[:ruby_version] = %x[ruby -v]
|
106
126
|
info[:stack] = trim_stack( exception )
|
107
127
|
env['mole.exception'] = nil
|
108
|
-
end
|
109
|
-
|
128
|
+
end
|
110
129
|
info
|
130
|
+
rescue => boom
|
131
|
+
$stderr.puts "!! MOLE RECORDING CRAPPED OUT !! -- #{boom}"
|
132
|
+
boom.backtrace.each { |l| $stderr.puts l }
|
111
133
|
end
|
112
134
|
|
113
135
|
# Trim stack trace
|
@@ -128,7 +150,7 @@ module Rack
|
|
128
150
|
# Fetch route info if any...
|
129
151
|
def get_route( request )
|
130
152
|
return nil unless defined?( RAILS_ENV )
|
131
|
-
::ActionController::Routing::Routes.recognize_path( request.path, {:method => request.request_method } )
|
153
|
+
::ActionController::Routing::Routes.recognize_path( request.path, {:method => request.request_method.downcase.to_sym } )
|
132
154
|
end
|
133
155
|
end
|
134
156
|
end
|
data/lib/rackamole/store/log.rb
CHANGED
@@ -5,12 +5,15 @@ include Mongo
|
|
5
5
|
# TODO !! Need to deal with auth
|
6
6
|
module Rackamole
|
7
7
|
module Store
|
8
|
-
# Mongo adapter. Stores mole info in a mongo database
|
8
|
+
# Mongo adapter. Stores mole info in a mongo database.
|
9
|
+
# Two collections are available namely features and logs. Logs references
|
10
|
+
# the features collection.
|
9
11
|
class Mongo
|
10
12
|
|
11
13
|
attr_reader :connection
|
12
14
|
|
13
|
-
def initialize(
|
15
|
+
def initialize( options )
|
16
|
+
opts = default_options.merge( options )
|
14
17
|
@connection = Connection.new( opts[:hostname], opts[:port] ).db( opts[:database] )
|
15
18
|
end
|
16
19
|
|
@@ -22,6 +25,8 @@ module Rackamole
|
|
22
25
|
|
23
26
|
# Dump mole info to logger
|
24
27
|
def mole( args )
|
28
|
+
return if args.empty?
|
29
|
+
|
25
30
|
feature = find_or_create_feature( args )
|
26
31
|
log_feature( feature, args )
|
27
32
|
rescue => mole_boom
|
@@ -29,17 +34,29 @@ module Rackamole
|
|
29
34
|
$stderr.puts mole_boom.backtrace.join( "\n " )
|
30
35
|
end
|
31
36
|
|
37
|
+
# Convenience to access mole features cltn
|
32
38
|
def features
|
33
39
|
@features ||= @connection['features']
|
34
40
|
end
|
35
41
|
|
42
|
+
# Convenience to access mole log cltn
|
36
43
|
def logs
|
37
44
|
@logs ||= @connection['logs']
|
38
45
|
end
|
39
46
|
|
40
47
|
# =======================================================================
|
41
48
|
private
|
42
|
-
|
49
|
+
|
50
|
+
# Set up mongo default options ie localhost host, default mongo port and
|
51
|
+
# the database being mole_mdb
|
52
|
+
def default_options
|
53
|
+
{
|
54
|
+
:host => 'localhost',
|
55
|
+
:port => 77926,
|
56
|
+
:database => 'mole_mdb'
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
43
60
|
# retrieves a feature if exists or create a new one otherwise
|
44
61
|
def find_or_create_feature( args )
|
45
62
|
if args[:route_info]
|
@@ -88,7 +105,7 @@ module Rackamole
|
|
88
105
|
|
89
106
|
row = {
|
90
107
|
:type => type,
|
91
|
-
:feature => ::DBRef.new( 'features', feature ),
|
108
|
+
:feature => ::DBRef.new( 'features', feature.instance_of?( ObjectID ) ? feature : feature['_id'] ),
|
92
109
|
:created_at => Time.now,
|
93
110
|
:updated_at => Time.now
|
94
111
|
}
|
@@ -1,4 +1,6 @@
|
|
1
1
|
class ApplicationController < ActionController::Base
|
2
|
+
include Rackamole::Interceptor
|
3
|
+
|
2
4
|
helper :all # include all helpers, all the time
|
3
5
|
protect_from_forgery # See ActionController::RequestForgeryProtection for details
|
4
6
|
|
@@ -10,4 +12,10 @@ class ApplicationController < ActionController::Base
|
|
10
12
|
def setup
|
11
13
|
session[:user_name] = "Fernand"
|
12
14
|
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def local_request?
|
19
|
+
return false
|
20
|
+
end
|
13
21
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Hello <%=@id%></h1>
|
@@ -1,43 +1,6 @@
|
|
1
1
|
ActionController::Routing::Routes.draw do |map|
|
2
|
-
|
2
|
+
map.resources :fred
|
3
3
|
|
4
|
-
# Sample of regular route:
|
5
|
-
# map.connect 'products/:id', :controller => 'catalog', :action => 'view'
|
6
|
-
# Keep in mind you can assign values other than :controller and :action
|
7
|
-
|
8
|
-
# Sample of named route:
|
9
|
-
# map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
|
10
|
-
# This route can be invoked with purchase_url(:id => product.id)
|
11
|
-
|
12
|
-
# Sample resource route (maps HTTP verbs to controller actions automatically):
|
13
|
-
# map.resources :products
|
14
|
-
|
15
|
-
# Sample resource route with options:
|
16
|
-
# map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
|
17
|
-
|
18
|
-
# Sample resource route with sub-resources:
|
19
|
-
# map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
|
20
|
-
|
21
|
-
# Sample resource route with more complex sub-resources
|
22
|
-
# map.resources :products do |products|
|
23
|
-
# products.resources :comments
|
24
|
-
# products.resources :sales, :collection => { :recent => :get }
|
25
|
-
# end
|
26
|
-
|
27
|
-
# Sample resource route within a namespace:
|
28
|
-
# map.namespace :admin do |admin|
|
29
|
-
# # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
|
30
|
-
# admin.resources :products
|
31
|
-
# end
|
32
|
-
|
33
|
-
# You can have the root of your site routed with map.root -- just remember to delete public/index.html.
|
34
|
-
# map.root :controller => "welcome"
|
35
|
-
|
36
|
-
# See how all your routes lay out with "rake routes"
|
37
|
-
|
38
|
-
# Install the default routes as the lowest priority.
|
39
|
-
# Note: These default routes make all actions in every controller accessible via GET requests. You should
|
40
|
-
# consider removing the them or commenting them out if you're using named routes and resources.
|
41
4
|
map.connect ':controller/:action/:id'
|
42
5
|
map.connect ':controller/:action/:id.:format'
|
43
6
|
end
|
File without changes
|
@@ -28,3 +28,53 @@ Completed in 113ms (View: 4, DB: 0) | 200 OK [http://localhost/fred]
|
|
28
28
|
Processing FredController#index (for 127.0.0.1 at 2009-11-14 01:18:26) [GET]
|
29
29
|
Rendering fred/index
|
30
30
|
Completed in 6ms (View: 4, DB: 0) | 200 OK [http://localhost/fred]
|
31
|
+
|
32
|
+
|
33
|
+
Processing FredController#index (for 127.0.0.1 at 2009-11-15 11:36:33) [GET]
|
34
|
+
Rendering fred/index
|
35
|
+
Completed in 120ms (View: 4, DB: 0) | 200 OK [http://localhost/fred]
|
36
|
+
|
37
|
+
|
38
|
+
Processing FredController#show (for 127.0.0.1 at 2009-11-15 11:36:59) [GET]
|
39
|
+
Parameters: {"id"=>"list"}
|
40
|
+
Rendering fred/show
|
41
|
+
Completed in 4ms (View: 2, DB: 0) | 200 OK [http://localhost/fred/list]
|
42
|
+
|
43
|
+
|
44
|
+
Processing FredController#edit (for 127.0.0.1 at 2009-11-15 11:38:36) [GET]
|
45
|
+
Parameters: {"id"=>"10"}
|
46
|
+
|
47
|
+
RuntimeError (Oh snap!):
|
48
|
+
app/controllers/fred_controller.rb:7:in `edit'
|
49
|
+
|
50
|
+
Rendered rescues/_trace (27.9ms)
|
51
|
+
Rendered rescues/_request_and_response (1.2ms)
|
52
|
+
Rendering rescues/layout (internal_server_error)
|
53
|
+
|
54
|
+
|
55
|
+
Processing FredController#edit (for 127.0.0.1 at 2009-11-15 11:44:54) [GET]
|
56
|
+
Parameters: {"id"=>"10"}
|
57
|
+
|
58
|
+
RuntimeError (Oh snap!):
|
59
|
+
app/controllers/fred_controller.rb:7:in `edit'
|
60
|
+
|
61
|
+
Rendered rescues/_trace (29.1ms)
|
62
|
+
Rendered rescues/_request_and_response (1.2ms)
|
63
|
+
Rendering rescues/layout (internal_server_error)
|
64
|
+
|
65
|
+
|
66
|
+
Processing FredController#edit (for 127.0.0.1 at 2009-11-15 11:53:40) [GET]
|
67
|
+
Parameters: {"id"=>"10"}
|
68
|
+
|
69
|
+
RuntimeError (Oh snap!):
|
70
|
+
app/controllers/fred_controller.rb:7:in `edit'
|
71
|
+
|
72
|
+
Rendered rescues/_trace (28.4ms)
|
73
|
+
Rendered rescues/_request_and_response (1.3ms)
|
74
|
+
Rendering rescues/layout (internal_server_error)
|
75
|
+
|
76
|
+
|
77
|
+
Processing FredController#show (for 127.0.0.1 at 2009-11-15 11:54:08) [GET]
|
78
|
+
Parameters: {"id"=>"10"}
|
79
|
+
Rendering fred/show
|
80
|
+
Completed in 7ms (View: 6, DB: 0) | 200 OK [http://localhost/fred/10]
|
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
Processing FredController#edit (for 127.0.0.1 at 2009-11-15 11:39:29) [GET]
|
4
|
+
Parameters: {"id"=>"10"}
|
5
|
+
|
6
|
+
RuntimeError (Oh snap!):
|
7
|
+
app/controllers/fred_controller.rb:7:in `edit'
|
8
|
+
|
9
|
+
Rendering rescues/layout (internal_server_error)
|
10
|
+
|
11
|
+
|
12
|
+
Processing FredController#edit (for 127.0.0.1 at 2009-11-15 11:40:41) [GET]
|
13
|
+
Parameters: {"id"=>"10"}
|
14
|
+
|
15
|
+
RuntimeError (Oh snap!):
|
16
|
+
app/controllers/fred_controller.rb:7:in `edit'
|
17
|
+
|
18
|
+
Rendering /Users/fgaliana/work/git/rackamole/samples/rails/moled/public/500.html (500 Internal Server Error)
|
19
|
+
|
20
|
+
|
21
|
+
Processing FredController#edit (for 127.0.0.1 at 2009-11-15 11:41:39) [GET]
|
22
|
+
Parameters: {"id"=>"10"}
|
23
|
+
|
24
|
+
RuntimeError (Oh snap!):
|
25
|
+
app/controllers/fred_controller.rb:7:in `edit'
|
26
|
+
|
27
|
+
Rendering /Users/fgaliana/work/git/rackamole/samples/rails/moled/public/500.html (500 Internal Server Error)
|
28
|
+
|
29
|
+
|
30
|
+
Processing FredController#edit (for 127.0.0.1 at 2009-11-15 11:43:03) [GET]
|
31
|
+
Parameters: {"id"=>"10"}
|
32
|
+
|
33
|
+
RuntimeError (Oh snap!):
|
34
|
+
app/controllers/fred_controller.rb:7:in `edit'
|
35
|
+
|
36
|
+
Rendering /Users/fgaliana/work/git/rackamole/samples/rails/moled/public/500.html (500 Internal Server Error)
|
data/samples/sinatra/moled.rb
CHANGED
@@ -13,8 +13,23 @@ before do
|
|
13
13
|
session[:user_name] = "Fernand"
|
14
14
|
end
|
15
15
|
|
16
|
-
get '/
|
17
|
-
@blee = "
|
16
|
+
get '/normal' do
|
17
|
+
@blee = "Snap!!"
|
18
18
|
session[:fred] = "duh me"
|
19
|
-
|
19
|
+
erb :normal
|
20
|
+
end
|
21
|
+
|
22
|
+
get '/params/:id' do
|
23
|
+
@blee = params[:id]
|
24
|
+
session[:fred] = "duh me"
|
25
|
+
erb :params
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/error' do
|
29
|
+
raise "Oh Shit!!"
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/slow' do
|
33
|
+
sleep 10
|
34
|
+
'<h1> I am the slow one...</h1>'
|
20
35
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Normal -- <%=@blee%></h1>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Params -- <%=@blee%></h1>
|
@@ -6,6 +6,9 @@ describe Rackamole::Interceptor do
|
|
6
6
|
class Fred
|
7
7
|
def rescue_action_in_public( exception )
|
8
8
|
end
|
9
|
+
|
10
|
+
def rescue_action_locally( exception )
|
11
|
+
end
|
9
12
|
|
10
13
|
def request
|
11
14
|
@request ||= OpenStruct.new( :env => {} )
|
@@ -20,10 +23,19 @@ describe Rackamole::Interceptor do
|
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
23
|
-
it "should include the correct methods" do
|
26
|
+
it "should include the correct methods" do
|
27
|
+
Fred.instance_methods.should be_include( 'rescue_action_locally_without_mole' )
|
28
|
+
Fred.private_instance_methods.should be_include( 'rescue_action_locally_with_mole' )
|
29
|
+
|
24
30
|
Fred.instance_methods.should be_include( 'rescue_action_in_public_without_mole' )
|
25
31
|
Fred.private_instance_methods.should be_include( 'rescue_action_in_public_with_mole' )
|
26
32
|
end
|
33
|
+
|
34
|
+
it "should set the env correctly when a local exception is raised" do
|
35
|
+
fred = Fred.new
|
36
|
+
fred.send( :rescue_action_locally, "Fred" )
|
37
|
+
fred.request.env['mole.exception'].should == "Fred"
|
38
|
+
end
|
27
39
|
|
28
40
|
it "should set the env correctly when an exception is raised" do
|
29
41
|
fred = Fred.new
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rackamole
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fernand Galiana
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-15 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- samples/rails/moled/app/controllers/fred_controller.rb
|
97
97
|
- samples/rails/moled/app/helpers/application_helper.rb
|
98
98
|
- samples/rails/moled/app/views/fred/index.html.erb
|
99
|
+
- samples/rails/moled/app/views/fred/show.html.erb
|
99
100
|
- samples/rails/moled/config/boot.rb
|
100
101
|
- samples/rails/moled/config/database.yml
|
101
102
|
- samples/rails/moled/config/environment.rb
|
@@ -110,6 +111,7 @@ files:
|
|
110
111
|
- samples/rails/moled/config/locales/en.yml
|
111
112
|
- samples/rails/moled/config/routes.rb
|
112
113
|
- samples/rails/moled/db/development.sqlite3
|
114
|
+
- samples/rails/moled/db/production.sqlite3
|
113
115
|
- samples/rails/moled/doc/README_FOR_APP
|
114
116
|
- samples/rails/moled/log/development.log
|
115
117
|
- samples/rails/moled/log/production.log
|
@@ -139,7 +141,10 @@ files:
|
|
139
141
|
- samples/rails/moled/script/server
|
140
142
|
- samples/rails/moled/test/performance/browsing_test.rb
|
141
143
|
- samples/rails/moled/test/test_helper.rb
|
144
|
+
- samples/sinatra/blee.rb
|
142
145
|
- samples/sinatra/moled.rb
|
146
|
+
- samples/sinatra/views/normal.erb
|
147
|
+
- samples/sinatra/views/params.erb
|
143
148
|
- spec/expected_results/mole_exception.log
|
144
149
|
- spec/expected_results/mole_feature.log
|
145
150
|
- spec/expected_results/mole_perf.log
|