methodmissing-scrooge 1.0.0
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.textile +262 -0
- data/lib/scrooge/core/string.rb +29 -0
- data/lib/scrooge/core/symbol.rb +21 -0
- data/lib/scrooge/core/thread.rb +26 -0
- data/lib/scrooge/framework/base.rb +304 -0
- data/lib/scrooge/framework/rails.rb +107 -0
- data/lib/scrooge/middleware/tracker.rb +47 -0
- data/lib/scrooge/orm/active_record.rb +143 -0
- data/lib/scrooge/orm/base.rb +102 -0
- data/lib/scrooge/profile.rb +204 -0
- data/lib/scrooge/storage/base.rb +47 -0
- data/lib/scrooge/storage/memory.rb +25 -0
- data/lib/scrooge/tracker/app.rb +101 -0
- data/lib/scrooge/tracker/base.rb +56 -0
- data/lib/scrooge/tracker/model.rb +90 -0
- data/lib/scrooge/tracker/resource.rb +201 -0
- data/lib/scrooge.rb +62 -0
- data/spec/fixtures/config/scrooge/scopes/1234567891/scope.yml +2 -0
- data/spec/fixtures/config/scrooge.yml +12 -0
- data/spec/helpers/framework/rails/cache.rb +25 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/units/scrooge/core/string_spec.rb +21 -0
- data/spec/units/scrooge/core/symbol_spec.rb +13 -0
- data/spec/units/scrooge/core/thread_spec.rb +15 -0
- data/spec/units/scrooge/framework/base_spec.rb +154 -0
- data/spec/units/scrooge/framework/rails_spec.rb +40 -0
- data/spec/units/scrooge/orm/base_spec.rb +61 -0
- data/spec/units/scrooge/profile_spec.rb +73 -0
- data/spec/units/scrooge/storage/base_spec.rb +35 -0
- data/spec/units/scrooge/storage/memory_spec.rb +20 -0
- data/spec/units/scrooge/tracker/app_spec.rb +62 -0
- data/spec/units/scrooge/tracker/base_spec.rb +21 -0
- data/spec/units/scrooge/tracker/model_spec.rb +50 -0
- data/spec/units/scrooge/tracker/resource_spec.rb +83 -0
- data/spec/units/scrooge_spec.rb +13 -0
- metadata +110 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
module Scrooge
|
2
|
+
module Tracker
|
3
|
+
class App < Scrooge::Tracker::Base
|
4
|
+
|
5
|
+
# Application container for various Resources.
|
6
|
+
|
7
|
+
GUARD = Monitor.new
|
8
|
+
|
9
|
+
attr_accessor :resources
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super()
|
13
|
+
@resources = Set.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# Has any Resources been tracked ?
|
17
|
+
#
|
18
|
+
def any?
|
19
|
+
GUARD.synchronize do
|
20
|
+
!@resources.empty?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add a Resource instance to this tracker.
|
25
|
+
#
|
26
|
+
def <<( resource )
|
27
|
+
GUARD.synchronize do
|
28
|
+
@resources << setup_resource( resource )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def marshal_dump #:nodoc:
|
33
|
+
GUARD.synchronize do
|
34
|
+
dumped_resources()
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def marshal_load( data ) #:nodoc:
|
39
|
+
GUARD.synchronize do
|
40
|
+
@resources = Set.new( restored_resources( data ) )
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
# Track a given Resource.
|
46
|
+
#
|
47
|
+
def track( resource )
|
48
|
+
profile.log "Track with resource #{resource.inspect}"
|
49
|
+
begin
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
self << resource if resource.any?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect #:nodoc:
|
57
|
+
if any?
|
58
|
+
@resources.map{|r| r.inspect }.join( "\n\n" )
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# If we've seen this resource before, return the original, else, returns
|
65
|
+
# the given resource.
|
66
|
+
#
|
67
|
+
def resource_for( resource )
|
68
|
+
@resources.detect{|r| r.signature == resource.signature } || resource
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def setup_resource( resource ) #:nodoc:
|
74
|
+
GUARD.synchronize do
|
75
|
+
resource_for( resource )
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def environment #:nodoc:
|
80
|
+
profile.framework.environment
|
81
|
+
end
|
82
|
+
|
83
|
+
def restored_resources( data ) #:nodoc:
|
84
|
+
GUARD.synchronize do
|
85
|
+
data.map do |resource|
|
86
|
+
Resource.new.marshal_load( resource )
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def dumped_resources #:nodoc:
|
92
|
+
GUARD.synchronize do
|
93
|
+
@resources.to_a.map do |resource|
|
94
|
+
resource.marshal_dump
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Scrooge
|
4
|
+
module Tracker
|
5
|
+
|
6
|
+
autoload :App, 'scrooge/tracker/app'
|
7
|
+
autoload :Resource, 'scrooge/tracker/resource'
|
8
|
+
autoload :Model, 'scrooge/tracker/model'
|
9
|
+
|
10
|
+
class Base < Scrooge::Base
|
11
|
+
include Comparable
|
12
|
+
|
13
|
+
# Scrooge Tracker base class.
|
14
|
+
|
15
|
+
class NotImplemented < StandardError
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :counter
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@counter = 0
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_i
|
25
|
+
@counter
|
26
|
+
end
|
27
|
+
|
28
|
+
# Requires subclasses to implement a custom marshal_dump
|
29
|
+
#
|
30
|
+
def marshal_dump
|
31
|
+
raise NotImplemented
|
32
|
+
end
|
33
|
+
|
34
|
+
# Requires subclasses to implement a custom marshal_load
|
35
|
+
#
|
36
|
+
def marshal_load( data )
|
37
|
+
raise NotImplemented
|
38
|
+
end
|
39
|
+
|
40
|
+
# Compare trackers through their Marshal representations.
|
41
|
+
#
|
42
|
+
def ==( tracker )
|
43
|
+
compare_to( tracker )
|
44
|
+
end
|
45
|
+
alias :eql? :==
|
46
|
+
alias :<=> :==
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def compare_to( tracker ) #:nodoc:
|
51
|
+
marshal_dump == tracker.marshal_dump
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Scrooge
|
2
|
+
module Tracker
|
3
|
+
class Model < Base
|
4
|
+
|
5
|
+
GUARD = Monitor.new
|
6
|
+
|
7
|
+
attr_accessor :model,
|
8
|
+
:attributes
|
9
|
+
|
10
|
+
def initialize( model )
|
11
|
+
super()
|
12
|
+
@model = model
|
13
|
+
@attributes = Set.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# Has any Attributes been tracked ?
|
17
|
+
#
|
18
|
+
def any?
|
19
|
+
GUARD.synchronize do
|
20
|
+
!@attributes.empty?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add a Model attribute to this tracker.
|
25
|
+
#
|
26
|
+
def <<( attribute )
|
27
|
+
GUARD.synchronize do
|
28
|
+
Array( attribute ).each do |attr|
|
29
|
+
attributes << attr
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def marshal_dump #:nodoc:
|
35
|
+
GUARD.synchronize do
|
36
|
+
{ name() => @attributes.to_a }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def marshal_load( data ) #:nodoc:
|
41
|
+
GUARD.synchronize do
|
42
|
+
@model = data.keys.first
|
43
|
+
@attributes = Set.new( data[@model] )
|
44
|
+
self
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Memoize the name lookup.
|
49
|
+
#
|
50
|
+
def name
|
51
|
+
@name ||= profile.orm.name( @model )
|
52
|
+
end
|
53
|
+
|
54
|
+
# Memoize the table name lookup.
|
55
|
+
#
|
56
|
+
def table_name
|
57
|
+
@table_name ||= profile.orm.table_name( @model )
|
58
|
+
end
|
59
|
+
|
60
|
+
# Memoize the primary key lookup.
|
61
|
+
#
|
62
|
+
def primary_key
|
63
|
+
@primary_key ||= profile.orm.primary_key( @model )
|
64
|
+
end
|
65
|
+
|
66
|
+
# Dump to a SQL SELECT snippet.
|
67
|
+
#
|
68
|
+
def to_sql
|
69
|
+
GUARD.synchronize do
|
70
|
+
attributes_with_primary_key().map{|a| "#{table_name}.#{a.to_s}" }.join(', ')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def inspect #:nodoc:
|
75
|
+
"#<#{name()} #{attributes_for_inspect}>"
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def attributes_for_inspect #:nodoc:
|
81
|
+
@attributes.map{|a| ":#{a}" }.join(', ')
|
82
|
+
end
|
83
|
+
|
84
|
+
def attributes_with_primary_key #:nodoc:
|
85
|
+
@attributes << primary_key
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
module Scrooge
|
2
|
+
module Tracker
|
3
|
+
class Resource < Base
|
4
|
+
|
5
|
+
# A Resource tracker is scoped to a
|
6
|
+
#
|
7
|
+
# * controller
|
8
|
+
# * action
|
9
|
+
# * request method
|
10
|
+
# * content type
|
11
|
+
#
|
12
|
+
# and is a container for any Models referenced during the active
|
13
|
+
# request / response cycle.
|
14
|
+
|
15
|
+
GET = /get/i
|
16
|
+
|
17
|
+
GUARD = Monitor.new
|
18
|
+
|
19
|
+
attr_accessor :controller,
|
20
|
+
:action,
|
21
|
+
:method,
|
22
|
+
:format,
|
23
|
+
:models
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
super()
|
27
|
+
@models = Set.new
|
28
|
+
yield self if block_given?
|
29
|
+
end
|
30
|
+
|
31
|
+
# Has any Models been tracked ?
|
32
|
+
#
|
33
|
+
def any?
|
34
|
+
GUARD.synchronize do
|
35
|
+
!@models.empty?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Generates a signature / lookup key.
|
40
|
+
#
|
41
|
+
def signature
|
42
|
+
@signature ||= "#{controller.to_s}_#{action.to_s}_#{method.to_s}"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Only track GET requests
|
46
|
+
#
|
47
|
+
def trackable?
|
48
|
+
!( method || '' ).to_s.match( GET ).nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
# Add a Model to this resource.
|
52
|
+
#
|
53
|
+
def <<( model )
|
54
|
+
GUARD.synchronize do
|
55
|
+
@models << track_model_from( model )
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def marshal_dump #:nodoc:
|
60
|
+
GUARD.synchronize do
|
61
|
+
{ signature => { :controller => @controller,
|
62
|
+
:action => @action,
|
63
|
+
:method => @method,
|
64
|
+
:format => @format,
|
65
|
+
:models => dumped_models() } }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def marshal_load( data ) #:nodoc:
|
70
|
+
GUARD.synchronize do
|
71
|
+
data = data.to_a.flatten.last
|
72
|
+
@controller = data[:controller]
|
73
|
+
@action = data[:action]
|
74
|
+
@method = data[:method]
|
75
|
+
@format = data[:format]
|
76
|
+
@models = restored_models( data[:models] )
|
77
|
+
self
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Yields a collection of Rack middleware to scope Model attributes to the
|
82
|
+
# tracked dataset.
|
83
|
+
#
|
84
|
+
def middleware
|
85
|
+
@middleware ||= begin
|
86
|
+
GUARD.synchronize do
|
87
|
+
models.map do |model|
|
88
|
+
middleware_for_model( model )
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return a valid Rack middleware instance for a given model.
|
95
|
+
#
|
96
|
+
def middleware_for_model( model )
|
97
|
+
resource = self
|
98
|
+
profile.orm.scope_resource_to_model( resource, model )
|
99
|
+
klass = Class.new
|
100
|
+
klass.class_eval(<<-EOS, __FILE__, __LINE__)
|
101
|
+
|
102
|
+
class << self
|
103
|
+
|
104
|
+
def inspect
|
105
|
+
"#<Scrooge::Middleware #{model.inspect}>"
|
106
|
+
end
|
107
|
+
|
108
|
+
# Around Filter compatible implementation for Rails as Dispatcher is
|
109
|
+
# the root Rack application and as such don't provide access to the Rails
|
110
|
+
# Routing internals from other middleware.
|
111
|
+
#
|
112
|
+
def filter( controller, &block )
|
113
|
+
#{model.model.to_s}.#{profile.orm.resource_scope_method( resource ).to_s} do
|
114
|
+
Scrooge::Base.profile.log "Scope for Model #{model.inspect}"
|
115
|
+
block.call
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
def initialize(app)
|
122
|
+
@app = app
|
123
|
+
end
|
124
|
+
|
125
|
+
def call(env)
|
126
|
+
if scope?( env )
|
127
|
+
#{model.model.to_s}.#{profile.orm.resource_scope_method( resource ).to_s} do
|
128
|
+
@app.call(env)
|
129
|
+
end
|
130
|
+
else
|
131
|
+
@app.call(env)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
def scope?( env )
|
138
|
+
Scrooge::Base.profile.orm.resource_scope_method( resource( env ) ) == :#{profile.orm.resource_scope_method( resource ).to_s}
|
139
|
+
end
|
140
|
+
|
141
|
+
def resource( env )
|
142
|
+
Scrooge::Base.profile.framework.resource( env )
|
143
|
+
end
|
144
|
+
|
145
|
+
EOS
|
146
|
+
klass
|
147
|
+
end
|
148
|
+
|
149
|
+
def inspect #:nodoc:
|
150
|
+
"#<#{@method.to_s.upcase} :#{@controller}/#{@action} (#{@format})\n#{models_for_inspect()}"
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def track_model_from( model ) #:nodoc:
|
156
|
+
model.is_a?( Array ) ? model_from_enumerable( model ) : setup_model( model )
|
157
|
+
end
|
158
|
+
|
159
|
+
def model_from_enumerable( model ) #:nodoc:
|
160
|
+
model, attribute = model
|
161
|
+
model = setup_model( model )
|
162
|
+
model << attribute
|
163
|
+
model
|
164
|
+
end
|
165
|
+
|
166
|
+
def models_for_inspect #:nodoc:
|
167
|
+
models.map{|m| " - #{m.inspect}" }.join( "\n" )
|
168
|
+
end
|
169
|
+
|
170
|
+
def dumped_models #:nodoc:
|
171
|
+
GUARD.synchronize do
|
172
|
+
@models.to_a.map{|m| m.marshal_dump }
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def restored_models( models ) #:nodoc:
|
177
|
+
GUARD.synchronize do
|
178
|
+
models.map do |model|
|
179
|
+
m = model.keys.first # TODO: cleanup
|
180
|
+
Model.new( m ).marshal_load( model )
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def setup_model( model ) #:nodoc:
|
186
|
+
GUARD.synchronize do
|
187
|
+
if model.is_a?( Scrooge::Tracker::Model )
|
188
|
+
model
|
189
|
+
else
|
190
|
+
model_for( model ) || Scrooge::Tracker::Model.new( model )
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def model_for( model ) #:nodoc:
|
196
|
+
@models.detect{|m| m.model.name == model.name }
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
data/lib/scrooge.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'scrooge/core/string'
|
6
|
+
require 'scrooge/core/symbol'
|
7
|
+
require 'scrooge/core/thread'
|
8
|
+
require 'thread'
|
9
|
+
|
10
|
+
module Scrooge
|
11
|
+
class Base
|
12
|
+
|
13
|
+
GUARD = ::Mutex.new
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
# Active Profile reader
|
18
|
+
#
|
19
|
+
def profile
|
20
|
+
@@profile ||= Scrooge::Profile.new
|
21
|
+
end
|
22
|
+
|
23
|
+
# Active Profile writer.
|
24
|
+
#
|
25
|
+
def profile=( profile )
|
26
|
+
@@profile = profile
|
27
|
+
end
|
28
|
+
|
29
|
+
# Installs a YAML configuration template in the host framework's config
|
30
|
+
# directory.
|
31
|
+
#
|
32
|
+
def setup!
|
33
|
+
unless File.exist?( profile.framework.configuration_file )
|
34
|
+
FileUtils.cp( configuration_template(), profile.framework.configuration_file )
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def configuration_template #:nodoc:
|
41
|
+
File.join( File.dirname(__FILE__), '..', 'assets', 'config', 'scrooge.yml.template' )
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def profile
|
47
|
+
self.class.profile
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
module Middleware
|
53
|
+
autoload :Tracker, 'scrooge/middleware/tracker'
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
require 'scrooge/profile'
|
59
|
+
require 'scrooge/storage/base'
|
60
|
+
require 'scrooge/orm/base'
|
61
|
+
require 'scrooge/framework/base'
|
62
|
+
require 'scrooge/tracker/base'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Spec
|
2
|
+
module Helpers
|
3
|
+
module Framework
|
4
|
+
module Rails
|
5
|
+
class Cache
|
6
|
+
|
7
|
+
attr_reader :storage
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@storage = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def read( key )
|
14
|
+
@storage[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def write( key, value )
|
18
|
+
@storage[key] = value
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'logger'
|
6
|
+
require 'stringio'
|
7
|
+
require 'lib/scrooge'
|
8
|
+
require 'spec/helpers/framework/rails/cache'
|
9
|
+
|
10
|
+
#ActiveRecord::Base.logger = Logger.new(StringIO.new)
|
11
|
+
|
12
|
+
Spec::Runner.configure do |config|
|
13
|
+
|
14
|
+
Kernel.const_set :FIXTURES, "#{Dir.pwd}/spec/fixtures" unless defined?(FIXTURES)
|
15
|
+
Kernel.const_set :TMP, "#{Dir.pwd}/spec/tmp" unless defined?(TMP)
|
16
|
+
Kernel.const_set :CONFIG, "#{Dir.pwd}/spec/config" unless defined?(CONFIG)
|
17
|
+
|
18
|
+
config.before :all do
|
19
|
+
[TMP, CONFIG].each do |dir|
|
20
|
+
FileUtils.mkdir_p dir
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
config.before :each do
|
25
|
+
end
|
26
|
+
|
27
|
+
config.after :each do
|
28
|
+
end
|
29
|
+
|
30
|
+
config.after :all do
|
31
|
+
[TMP, CONFIG].each do |dir|
|
32
|
+
FileUtils.rm_r( dir ) rescue nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def with_rails
|
37
|
+
begin
|
38
|
+
Kernel.const_set :RAILS_ROOT, "#{Dir.pwd}/spec" unless defined?(RAILS_ROOT)
|
39
|
+
Kernel.const_set :Rails, Class.new unless defined?(Rails)
|
40
|
+
Kernel.const_set :RAILS_ENV, "test" unless defined?(RAILS_ENV)
|
41
|
+
::Rails.stub!(:cache).and_return( Spec::Helpers::Framework::Rails::Cache.new )
|
42
|
+
::Rails.stub!(:root).and_return( RAILS_ROOT )
|
43
|
+
yield
|
44
|
+
ensure
|
45
|
+
[:RAILS_ROOT, :RAILS_ENV, :Rails].each do |const|
|
46
|
+
Kernel.send( :remove_const, const )
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Scrooge::Core::String do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@string = 'scrooge/base'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be able to convert itself to a constant" do
|
10
|
+
@string.to_const().should == 'Scrooge::Base'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to convert itself to a class" do
|
14
|
+
@string.to_const!( false ).should == Scrooge::Base
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return self if it's not able to constantize" do
|
18
|
+
'not/defined'.to_const!( false ).should == 'not/defined'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe "Scrooge::Core::Thread singleton" do
|
4
|
+
|
5
|
+
it "should be able to yield the current scrooge resource" do
|
6
|
+
Thread.scrooge_resource.class.should equal( Scrooge::Tracker::Resource )
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be able to reset the current scrooge resource" do
|
10
|
+
@resource = Thread.scrooge_resource
|
11
|
+
Thread.reset_scrooge_resource!
|
12
|
+
@resource.object_id.should_not equal( Thread.scrooge_resource.object_id )
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|