methodmissing-scrooge 1.0.2 → 1.0.3

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 CHANGED
@@ -20,7 +20,8 @@ There's 3 basic modes of operation :
20
20
 
21
21
  * Scope : Scope the process and related resources to a previously persisted scope profile.
22
22
 
23
- * Track then scope : A multi-stage strategy that tracks attribute access for
23
+ * Track then scope : A multi-stage strategy that tracks attribute access for a given warmup period, aggregates the results
24
+ across multiple processes and enforce a scoping policy representative of the tracking phase.
24
25
 
25
26
  h2. Resources
26
27
 
@@ -29,6 +30,7 @@ A resource is :
29
30
  * A controller and action endpoint ( inferred through framework specific routing )
30
31
  * A content type / format - a PDF representation may have different Model attribute requirements than a vanilla ERB view.
31
32
  * Request method - typically popular public facing GET requests
33
+ * Public or Private as a logged in / authenticated representation likely have different attribute requirements.
32
34
 
33
35
  All Model to attribute mappings is tracked on a per Resource basis.Multiple Models per Resource is supported.
34
36
 
@@ -75,6 +77,7 @@ An example scope / profile, saved to disk :
75
77
  :action: show
76
78
  :controller: hotels
77
79
  :method: :get
80
+ :is_public: true
78
81
  :format: "*/*"
79
82
  :models:
80
83
  - Address:
@@ -95,6 +98,7 @@ An example scope / profile, saved to disk :
95
98
  :action: index
96
99
  :controller: locations
97
100
  :method: :get
101
+ :is_public: true
98
102
  :format: "*/*"
99
103
  :models:
100
104
  - Location:
@@ -108,6 +112,7 @@ An example scope / profile, saved to disk :
108
112
  :action: index
109
113
  :controller: countries
110
114
  :method: :get
115
+ :is_public: true
111
116
  :format: "*/*"
112
117
  :models:
113
118
  - Country:
@@ -122,6 +127,7 @@ An example scope / profile, saved to disk :
122
127
  :action: index
123
128
  :controller: hotels
124
129
  :method: :get
130
+ :is_public: true
125
131
  :format: "*/*"
126
132
  :models:
127
133
  - Hotel:
@@ -371,6 +377,7 @@ Scrooge installs ( see recommended installation above ) a configuration file wit
371
377
  warmup: 600 # warmup / track for 10 minutes
372
378
  scope:
373
379
  on_missing_attribute: :reload # or :raise
380
+ logged_in_session: :user_id # session key that represents the logged in user
374
381
  enabled: true
375
382
  development:
376
383
  orm: :active_record
@@ -379,6 +386,7 @@ Scrooge installs ( see recommended installation above ) a configuration file wit
379
386
  warmup: 600 # warmup / track for 10 minutes
380
387
  scope:
381
388
  on_missing_attribute: :reload # or :raise
389
+ logged_in_session: :user_id # session key that represents the logged in user
382
390
  enabled: true
383
391
  test:
384
392
  orm: :active_record
@@ -387,6 +395,7 @@ Scrooge installs ( see recommended installation above ) a configuration file wit
387
395
  warmup: 600 # warmup / track for 10 minutes
388
396
  scope:
389
397
  on_missing_attribute: :reload # or :raise
398
+ logged_in_session: :user_id # session key that represents the logged in user
390
399
  enabled: true
391
400
  </code>
392
401
  </pre>
@@ -395,13 +404,31 @@ h4. ORM
395
404
 
396
405
  Scrooge is ORM agnostic and ships with an ActiveRecord layer.
397
406
 
407
+ <pre>
408
+ <code>
398
409
  orm: :active_record
410
+ </pre>
411
+ </code>
399
412
 
400
413
  h4. Storage backend
401
414
 
402
- Tracking results can be persisted to a given backend or storage option.Ships with a memory store, but can be extended to file system, memcached etc. as all Tracker components is designed to be Marshal friendly.
415
+ Tracking results can be persisted to a given backend or storage option.Ships with a memory store, but can be extended to file system, memcached etc. as all Tracker components is designed to be Marshal friendly.A stub for future functionality.
403
416
 
417
+ <pre>
418
+ <code>
404
419
  storage: :memory
420
+ </pre>
421
+ </code>
422
+
423
+ h4. Verbose
424
+
425
+ Log all tracking interactions to the framework logger when enabled.Disabled for production.
426
+
427
+ <pre>
428
+ <code>
429
+ verbose: false
430
+ </pre>
431
+ </code>
405
432
 
406
433
  h4. Strategy
407
434
 
@@ -411,11 +438,21 @@ h4. Warmup
411
438
 
412
439
  The designated warmup period for the :track_then_scope strategy, given in seconds.Typically 600 to 3600.
413
440
 
441
+ <pre>
442
+ <code>
443
+ warmup: 600
444
+ </pre>
445
+ </code>
446
+
414
447
  h4. Scope
415
448
 
416
449
  A scope is a reference to a timestamped Scrooge run where access to Model attributes is tracked on a per Resource basis.
417
450
 
451
+ <pre>
452
+ <code>
418
453
  scope: 1234567891
454
+ </pre>
455
+ </code>
419
456
 
420
457
  If not scope is given in the configuration, ENV['scope'] would also be considered to facilitate configuration through Capistrano etc.
421
458
 
@@ -423,13 +460,31 @@ h4. Handling Missing Attributes
423
460
 
424
461
  When the contents for a given Model attribute has not been retrieved from the database, most ORM frameworks raise an error by default.This is configurable to reloading the model with all it's columns or raise instead.
425
462
 
463
+ <pre>
464
+ <code>
426
465
  on_missing_attribute: :reload # or :raise
466
+ </pre>
467
+ </code>
468
+
469
+ h4. Private and Public Resources
470
+
471
+ An authenticated or logged in resource likely has different model requirements than it's public counterpart.
472
+
473
+ <pre>
474
+ <code>
475
+ logged_in_session: :user_id # session key that represents the logged in user
476
+ </pre>
477
+ </code>
427
478
 
428
479
  h4. Status
429
480
 
430
481
  Scrooge can be disabled with :
431
482
 
483
+ <pre>
484
+ <code>
432
485
  enabled: false
486
+ </pre>
487
+ </code>
433
488
 
434
489
  h2. Rails specific rake tasks.
435
490
 
@@ -464,4 +519,17 @@ methodmissing:superbreak_app lourens$ rake scope=1234735790 scrooge:inspect
464
519
 
465
520
  h2. Notes
466
521
 
467
- This is an initial release, has not yet been battle tested in production and is pending Ruby 1.9.1 compatibility.
522
+ This is an initial release, has not yet been battle tested in production and is pending Ruby 1.9.1 compatibility.
523
+
524
+ Developed on and for Rails 2.3, known to work with Rails 2.2.2
525
+
526
+ h2. Known pending issues
527
+
528
+ * Do not track columns that isn't explicitly defined ( AR counter caching checks etc. ) :
529
+ <code>
530
+ <pre>
531
+ ActiveRecord::StatementInvalid (Mysql::Error: Unknown column 'orders.brochures_count' in 'field list': SELECT orders.brochures_count, orders.id FROM `orders` WHERE (`orders`.`id` = 1688139) LIMIT 1)
532
+ </code>
533
+ </pre>
534
+
535
+ * alias_attribute compatibility
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 2
3
2
  :major: 1
4
3
  :minor: 0
4
+ :patch: 3
@@ -1,24 +1,27 @@
1
1
  production:
2
2
  orm: :active_record
3
- storage: :memory
4
3
  strategy: :track_then_scope
5
4
  warmup: 600 # warmup / track for 10 minutes
6
5
  scope:
6
+ verbose: false
7
7
  on_missing_attribute: :reload # or :raise
8
+ logged_in_session: :user_id # session key that represents the logged in user
8
9
  enabled: true
9
10
  development:
10
11
  orm: :active_record
11
- storage: :memory
12
12
  strategy: :track
13
13
  warmup: 600 # warmup / track for 10 minutes
14
14
  scope:
15
+ verbose: true
15
16
  on_missing_attribute: :reload # or :raise
17
+ logged_in_session: :user_id # session key that represents the logged in user
16
18
  enabled: true
17
19
  test:
18
20
  orm: :active_record
19
- storage: :memory
20
21
  strategy: :track
21
22
  warmup: 600 # warmup / track for 10 minutes
22
23
  scope:
24
+ verbose: true
23
25
  on_missing_attribute: :reload # or :raise
24
- enabled: true
26
+ logged_in_session: :user_id # session key that represents the logged in user
27
+ enabled: true
@@ -2,7 +2,7 @@ module Scrooge
2
2
  module Core
3
3
  module Symbol
4
4
 
5
- # See Scrooge::Core::Symbol
5
+ # See Scrooge::Core::String
6
6
 
7
7
  def to_const
8
8
  to_s.to_const
@@ -124,6 +124,7 @@ module Scrooge
124
124
  Thread.scrooge_resource.action = request.path_parameters['action']
125
125
  Thread.scrooge_resource.method = request.method
126
126
  Thread.scrooge_resource.format = request.format.to_s
127
+ Thread.scrooge_resource.is_public = request.session[Scrooge::Base.profile.logged_in_session].nil?
127
128
  end
128
129
 
129
130
  end
@@ -7,30 +7,40 @@ module Scrooge
7
7
 
8
8
  private
9
9
 
10
- # Attach to generated attribute reader methods.
11
-
12
- def define_read_method(symbol, attr_name, column)
13
- register_with_scrooge!( attr_name, 'define read method' )
14
- super(symbol, attr_name, column)
10
+ # Define an attribute reader method. Cope with nil column.
11
+ def define_read_method(symbol, attr_name, column)
12
+ cast_code = column.type_cast_code('v') if column
13
+ access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']"
14
+
15
+ unless attr_name.to_s == self.primary_key.to_s
16
+ access_code = access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ")
15
17
  end
16
-
17
- def define_read_method_for_time_zone_conversion(attr_name)
18
- register_with_scrooge!( attr_name, 'define read method for time zone conversion' )
19
- super(attr_name)
18
+
19
+ if cache_attribute?(attr_name)
20
+ access_code = "@attributes_cache['#{attr_name}'] ||= (#{access_code})"
20
21
  end
22
+ evaluate_attribute_method attr_name, "def #{symbol}; register_with_scrooge!(:#{attr_name}, 'define read method' ); #{access_code}; end"
23
+ end
21
24
 
22
- def define_read_method_for_serialized_attribute(attr_name)
23
- register_with_scrooge!( attr_name, 'define read method for serialized attribute' )
24
- super(attr_name)
25
- end
25
+ # Define read method for serialized attribute.
26
+ def define_read_method_for_serialized_attribute(attr_name)
27
+ evaluate_attribute_method attr_name, "def #{attr_name}; register_with_scrooge!(:#{attr_name}, 'define read method for serialized attribute' ); unserialize_attribute('#{attr_name}'); end"
28
+ end
26
29
 
27
- private
28
-
29
- def register_with_scrooge!( attr_name, caller ) #:nodoc:
30
- if ::Scrooge::Base.profile.orm.track?
31
- Thread.scrooge_resource << [self.base_class, attr_name]
32
- end
30
+ # Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
31
+ # This enhanced read method automatically converts the UTC time stored in the database to the time zone stored in Time.zone.
32
+ def define_read_method_for_time_zone_conversion(attr_name)
33
+ method_body = <<-EOV
34
+ def #{attr_name}(reload = false)
35
+ register_with_scrooge!(:#{attr_name}, 'define read method for time zone conversion' )
36
+ cached = @attributes_cache['#{attr_name}']
37
+ return cached if cached && !reload
38
+ time = read_attribute('#{attr_name}')
39
+ @attributes_cache['#{attr_name}'] = time.acts_like?(:time) ? time.in_time_zone : time
33
40
  end
41
+ EOV
42
+ evaluate_attribute_method attr_name, method_body
43
+ end
34
44
 
35
45
  end
36
46
 
@@ -54,6 +64,8 @@ module Scrooge
54
64
 
55
65
  def register_with_scrooge!( attr_name, caller ) #:nodoc:
56
66
  if ::Scrooge::Base.profile.orm.track?
67
+ # Avoid string interpolation if not required
68
+ ::Scrooge::Base.profile.log( "Register attribute #{attr_name.inspect} from #{caller}" ) if ::Scrooge::Base.profile.verbose?
57
69
  Thread.scrooge_resource << [self.class.base_class, attr_name]
58
70
  end
59
71
  end
@@ -89,6 +89,12 @@ module Scrooge
89
89
  def log( message, flush = false )
90
90
  framework.log( message, flush ) rescue ''
91
91
  end
92
+
93
+ # Log a message to the framework's logger.
94
+ #
95
+ def verbose_log( message, flush = false )
96
+ log( message, flush ) if verbose?
97
+ end
92
98
 
93
99
  # Are we tracking ?
94
100
  #
@@ -135,6 +141,12 @@ module Scrooge
135
141
  def enabled?
136
142
  @enabled
137
143
  end
144
+
145
+ # Should Scrooge be chatty ?
146
+ #
147
+ def verbose?
148
+ @verbose
149
+ end
138
150
 
139
151
  # Should we raise on missing attributes ?
140
152
  #
@@ -147,6 +159,12 @@ module Scrooge
147
159
  def warmup
148
160
  @warmup
149
161
  end
162
+
163
+ # A session key that indicates a logged in / private session.
164
+ #
165
+ def logged_in_session
166
+ @logged_in_session
167
+ end
150
168
 
151
169
  private
152
170
 
@@ -158,22 +176,24 @@ module Scrooge
158
176
  @warmup = configure_with( @options['warmup'], 0..14400, 0 )
159
177
  @enabled = configure_with( @options['enabled'], [true, false], false )
160
178
  @on_missing_attribute = configure_with( @options['on_missing_attribute'], [:reload, :raise], :reload )
179
+ @verbose = configure_with( @options['verbose'], [true, false], false )
180
+ @logged_in_session = configure_with( @options['logged_in_session'], nil, :user_id )
161
181
  reset_backends!
162
182
  memoize_backends!
163
183
  end
164
-
165
- def framework_scopes #:nodoc:
166
- framework.scopes rescue []
167
- end
168
-
184
+
169
185
  def configure_with( given, valid, default ) #:nodoc:
170
186
  if given
171
- valid.include?( given ) ? given : default
187
+ valid && valid.include?( given ) ? given : default
172
188
  else
173
189
  default
174
190
  end
175
191
  end
176
192
 
193
+ def framework_scopes #:nodoc:
194
+ framework.scopes rescue []
195
+ end
196
+
177
197
  def reset_backends! #:nodoc:
178
198
  @orm_instance = nil
179
199
  @tracker_instance = nil
@@ -1,7 +1,6 @@
1
1
  module Scrooge
2
2
  module Storage
3
3
 
4
- autoload :Buffer, 'scrooge/storage/buffer'
5
4
  autoload :Memory, 'scrooge/storage/memory'
6
5
 
7
6
  class Base < Scrooge::Base
@@ -9,6 +9,8 @@ module Scrooge
9
9
  @strategy = strategy
10
10
  end
11
11
 
12
+ # Execute a given strategy
13
+ #
12
14
  def run!
13
15
  @thread = Thread.new do
14
16
  Thread.current.abort_on_exception = true
@@ -3,6 +3,7 @@ module Scrooge
3
3
  class Scope < Base
4
4
 
5
5
  stage :scope do
6
+
6
7
  log( "Scope ...", true )
7
8
  self.scope = scope if framework.scope?( scope )
8
9
  framework.install_scope_middleware( tracker )
@@ -143,7 +143,7 @@ module Scrooge
143
143
  def restored_resources( data ) #:nodoc:
144
144
  GUARD.synchronize do
145
145
  data.map do |resource|
146
- Resource.new.marshal_load( resource )
146
+ Resource.load( resource )
147
147
  end
148
148
  end
149
149
  end
@@ -51,6 +51,59 @@ module Scrooge
51
51
  self
52
52
  end
53
53
  end
54
+
55
+ # Return a valid Rack middleware instance for this model.
56
+ #
57
+ def middleware( resource )
58
+ profile.orm.scope_resource_to_model( resource, self )
59
+ klass = Class.new
60
+ klass.class_eval(<<-EOS, __FILE__, __LINE__)
61
+
62
+ class << self
63
+
64
+ def inspect
65
+ "#<Scrooge::Middleware #{inspect}>"
66
+ end
67
+
68
+ # Around Filter compatible implementation for Rails as Dispatcher is
69
+ # the root Rack application and as such don't provide access to the Rails
70
+ # Routing internals from other middleware.
71
+ #
72
+ def filter( controller, &block )
73
+ #{model.to_s}.#{profile.orm.resource_scope_method( resource ).to_s} do
74
+ block.call
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ def initialize(app)
81
+ @app = app
82
+ end
83
+
84
+ def call(env)
85
+ if scope?( env )
86
+ #{model.to_s}.#{profile.orm.resource_scope_method( resource ).to_s} do
87
+ @app.call(env)
88
+ end
89
+ else
90
+ @app.call(env)
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def scope?( env )
97
+ Scrooge::Base.profile.orm.resource_scope_method( resource( env ) ) == :#{profile.orm.resource_scope_method( resource ).to_s}
98
+ end
99
+
100
+ def resource( env )
101
+ Scrooge::Base.profile.framework.resource( env )
102
+ end
103
+
104
+ EOS
105
+ klass
106
+ end
54
107
 
55
108
  # Memoize the name lookup.
56
109
  #
@@ -20,7 +20,8 @@ module Scrooge
20
20
  :action,
21
21
  :method,
22
22
  :format,
23
- :models
23
+ :models,
24
+ :is_public
24
25
 
25
26
  def initialize
26
27
  super()
@@ -45,6 +46,18 @@ module Scrooge
45
46
  !@models.empty?
46
47
  end
47
48
  end
49
+
50
+ # Is this a public ( not authenticated ) resource ?
51
+ #
52
+ def public?
53
+ @is_public == true
54
+ end
55
+
56
+ # Is this a private ( authenticated ) resource ?
57
+ #
58
+ def private?
59
+ !public?
60
+ end
48
61
 
49
62
  # Search for a given model instance
50
63
  #
@@ -55,7 +68,7 @@ module Scrooge
55
68
  # Generates a signature / lookup key.
56
69
  #
57
70
  def signature
58
- @signature ||= "#{controller.to_s}_#{action.to_s}_#{method.to_s}"
71
+ @signature ||= "#{controller.to_s}_#{action.to_s}_#{method.to_s}_#{private_or_public}"
59
72
  end
60
73
 
61
74
  # Only track GET requests
@@ -78,7 +91,8 @@ module Scrooge
78
91
  :action => @action,
79
92
  :method => @method,
80
93
  :format => @format,
81
- :models => dumped_models() } }
94
+ :models => dumped_models(),
95
+ :is_public => @is_public } }
82
96
  end
83
97
  end
84
98
 
@@ -90,6 +104,7 @@ module Scrooge
90
104
  @method = data[:method]
91
105
  @format = data[:format]
92
106
  @models = restored_models( data[:models] )
107
+ @is_public = data[:is_public]
93
108
  self
94
109
  end
95
110
  end
@@ -101,72 +116,22 @@ module Scrooge
101
116
  @middleware ||= begin
102
117
  GUARD.synchronize do
103
118
  models.map do |model|
104
- middleware_for_model( model )
119
+ model.middleware( self )
105
120
  end
106
121
  end
107
122
  end
108
123
  end
109
-
110
- # Return a valid Rack middleware instance for a given model.
111
- #
112
- def middleware_for_model( model )
113
- resource = self
114
- profile.orm.scope_resource_to_model( resource, model )
115
- klass = Class.new
116
- klass.class_eval(<<-EOS, __FILE__, __LINE__)
117
-
118
- class << self
119
-
120
- def inspect
121
- "#<Scrooge::Middleware #{model.inspect}>"
122
- end
123
-
124
- # Around Filter compatible implementation for Rails as Dispatcher is
125
- # the root Rack application and as such don't provide access to the Rails
126
- # Routing internals from other middleware.
127
- #
128
- def filter( controller, &block )
129
- #{model.model.to_s}.#{profile.orm.resource_scope_method( resource ).to_s} do
130
- block.call
131
- end
132
- end
133
-
134
- end
135
-
136
- def initialize(app)
137
- @app = app
138
- end
139
124
 
140
- def call(env)
141
- if scope?( env )
142
- #{model.model.to_s}.#{profile.orm.resource_scope_method( resource ).to_s} do
143
- @app.call(env)
144
- end
145
- else
146
- @app.call(env)
147
- end
148
- end
149
-
150
- private
151
-
152
- def scope?( env )
153
- Scrooge::Base.profile.orm.resource_scope_method( resource( env ) ) == :#{profile.orm.resource_scope_method( resource ).to_s}
154
- end
155
-
156
- def resource( env )
157
- Scrooge::Base.profile.framework.resource( env )
158
- end
159
-
160
- EOS
161
- klass
162
- end
163
-
164
125
  def inspect #:nodoc:
165
- "#<#{@method.to_s.upcase} :#{@controller}/#{@action} (#{@format})\n#{models_for_inspect()}"
126
+ "#<#{@method.to_s.upcase} #{private_or_public} :#{@controller}/#{@action} (#{@format})\n#{models_for_inspect()}"
166
127
  end
167
128
 
168
129
  private
169
130
 
131
+ def private_or_public #:nodoc:
132
+ @is_public ? 'public' : 'private'
133
+ end
134
+
170
135
  def track_model_from( model ) #:nodoc:
171
136
  model.is_a?( Array ) ? model_from_enumerable( model ) : setup_model( model )
172
137
  end
@@ -1,16 +1,20 @@
1
1
  production:
2
2
  orm: :active_record
3
3
  storage: :memory
4
+ verbose: false
4
5
  scope: 1234567891
5
6
  on_missing_attribute: :reload
6
7
  strategy: :track_then_scope
7
8
  warmup: 600 # warmup / track for 10 minutes
9
+ logged_in_session: :user_id # session key that represents the logged in user
8
10
  enabled: true
9
11
  test:
10
12
  orm: :active_record
11
13
  storage: :memory
14
+ verbose: true
12
15
  scope:
13
16
  on_missing_attribute: :reload
14
17
  strategy: :track_then_scope
15
18
  warmup: 600 # warmup / track for 10 minutes
19
+ logged_in_session: :user_id # session key that represents the logged in user
16
20
  enabled: true
data/spec/spec_helper.rb CHANGED
@@ -11,9 +11,13 @@ require 'spec/helpers/framework/rails/cache'
11
11
 
12
12
  Spec::Runner.configure do |config|
13
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)
14
+ def self.set_constant( const, value )
15
+ eval( "Kernel.const_set :#{const.to_s}, #{value.inspect} unless defined?( #{const.to_s} )" )
16
+ end
17
+
18
+ set_constant( :FIXTURES, "#{Dir.pwd}/spec/fixtures" )
19
+ set_constant( :TMP, "#{Dir.pwd}/spec/tmp" )
20
+ set_constant( :CONFIG, "#{Dir.pwd}/spec/config" )
17
21
 
18
22
  config.before :all do
19
23
  [TMP, CONFIG].each do |dir|
@@ -67,5 +67,13 @@ describe "Scrooge::Profile instance" do
67
67
  it "should be able to expose it's warmup tracking period" do
68
68
  @profile.warmup.should == 0
69
69
  end
70
-
70
+
71
+ it "should be able to return a session key that indicates a logged in session" do
72
+ @profile.logged_in_session.should == :user_id
73
+ end
74
+
75
+ it "should be able to determine if logging should be verbose" do
76
+ @profile.verbose?().should == false
77
+ end
78
+
71
79
  end
@@ -9,6 +9,7 @@ describe Scrooge::Tracker::App do
9
9
  resource.action = 'show'
10
10
  resource.method = :get
11
11
  resource.format = :html
12
+ resource.is_public = true
12
13
  end
13
14
  end
14
15
 
@@ -27,11 +28,12 @@ describe Scrooge::Tracker::App do
27
28
  it "should be able to dump itself to a serializeable representation" do
28
29
  @app << @resource
29
30
  with_rails do
30
- @app.marshal_dump().should eql( [ { "products_show_get" => { :method => :get,
31
- :models => [],
32
- :format => :html,
33
- :action => "show",
34
- :controller => "products" } } ] )
31
+ @app.marshal_dump().should eql( [ { "products_show_get_public" => { :method => :get,
32
+ :models => [],
33
+ :format => :html,
34
+ :action => "show",
35
+ :controller => "products",
36
+ :is_public => true } } ] )
35
37
  end
36
38
  end
37
39
 
@@ -9,6 +9,13 @@ describe Scrooge::Tracker::Model do
9
9
  @model.stub!(:primary_key).and_return( 'id' )
10
10
  @other_model = Scrooge::Tracker::Model.new( 'OtherPost' )
11
11
  @another_model = Scrooge::Tracker::Model.new( 'AnotherPost' )
12
+ @resource = Scrooge::Tracker::Resource.new do |resource|
13
+ resource.controller = 'products'
14
+ resource.action = 'show'
15
+ resource.method = :get
16
+ resource.format = :html
17
+ resource.is_public = true
18
+ end
12
19
  end
13
20
 
14
21
  it "should be able to determine if any attributes has been tracked" do
@@ -60,4 +67,13 @@ describe Scrooge::Tracker::Model do
60
67
  @another_model.merge( nil )
61
68
  end
62
69
 
70
+ it "should be able to setup Rack middleware" do
71
+ @model << %w(name description)
72
+ @model.middleware( @resource ).class.should equal( Class )
73
+ @model.middleware( @resource ).inspect.should match( /Middleware/ )
74
+ @model.middleware( @resource ).inspect.should match( /Product/ )
75
+ @model.middleware( @resource ).inspect.should match( /description/ )
76
+ @model.middleware( @resource ).new( @model ).should respond_to( :call )
77
+ end
78
+
63
79
  end
@@ -8,6 +8,7 @@ describe Scrooge::Tracker::Resource do
8
8
  resource.action = 'show'
9
9
  resource.method = :get
10
10
  resource.format = :html
11
+ resource.is_public = true
11
12
  end
12
13
  @model = Scrooge::Tracker::Model.new( 'Class' )
13
14
  @model.stub!(:name).and_return( 'Product' )
@@ -18,12 +19,21 @@ describe Scrooge::Tracker::Resource do
18
19
  resource.action = 'show'
19
20
  resource.method = :get
20
21
  resource.format = :html
22
+ resource.is_public = true
21
23
  end
22
24
  end
23
25
 
24
26
  it "should be able to determine if any models has been tracked" do
25
27
  @resource.any?().should equal( false )
26
28
  end
29
+
30
+ it "should be able to determine if it's a public resource" do
31
+ @resource.public?().should equal( true )
32
+ end
33
+
34
+ it "should be able to determine if it's a private resource" do
35
+ @resource.private?().should equal( false )
36
+ end
27
37
 
28
38
  it "should initialize with an empty set of models" do
29
39
  @resource.models.should eql( Set.new )
@@ -50,15 +60,16 @@ describe Scrooge::Tracker::Resource do
50
60
  end
51
61
 
52
62
  it "should be able to generate a lookup signature" do
53
- @resource.signature().should eql( "products_show_get" )
63
+ @resource.signature().should eql( "products_show_get_public" )
54
64
  end
55
65
 
56
66
  it "should be able to dump itself to a serializeable representation" do
57
- @resource.marshal_dump().should eql( { "products_show_get" => { :models => [],
58
- :method => :get,
59
- :format => :html,
60
- :action => "show",
61
- :controller => "products"} } )
67
+ @resource.marshal_dump().should eql( { "products_show_get_public" => { :models => [],
68
+ :method => :get,
69
+ :format => :html,
70
+ :action => "show",
71
+ :controller => "products",
72
+ :is_public => true} } )
62
73
  end
63
74
 
64
75
  it "should be able to restore itself from a serialized representation" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: methodmissing-scrooge
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Lourens Naud\xC3\xA9"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-16 00:00:00 -08:00
12
+ date: 2009-03-03 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15