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