primer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/README.rdoc +213 -0
  2. data/example/README.rdoc +69 -0
  3. data/example/application.rb +26 -0
  4. data/example/config.ru +5 -0
  5. data/example/environment.rb +31 -0
  6. data/example/models/blog_post.rb +4 -0
  7. data/example/models/connection.rb +10 -0
  8. data/example/public/style.css +75 -0
  9. data/example/script/setup_database.rb +11 -0
  10. data/example/views/index.erb +13 -0
  11. data/example/views/layout.erb +26 -0
  12. data/example/views/show.erb +7 -0
  13. data/example/worker.rb +3 -0
  14. data/lib/javascript/primer.js +36 -0
  15. data/lib/primer/bus/amqp.rb +43 -0
  16. data/lib/primer/bus/memory.rb +12 -0
  17. data/lib/primer/bus.rb +30 -0
  18. data/lib/primer/cache/memory.rb +60 -0
  19. data/lib/primer/cache/redis.rb +70 -0
  20. data/lib/primer/cache.rb +84 -0
  21. data/lib/primer/enabler.rb +18 -0
  22. data/lib/primer/helpers.rb +66 -0
  23. data/lib/primer/real_time.rb +80 -0
  24. data/lib/primer/route_set.rb +50 -0
  25. data/lib/primer/watcher/active_record_macros.rb +70 -0
  26. data/lib/primer/watcher/macros.rb +70 -0
  27. data/lib/primer/watcher.rb +62 -0
  28. data/lib/primer/worker/active_record_agent.rb +120 -0
  29. data/lib/primer/worker.rb +34 -0
  30. data/lib/primer.rb +31 -0
  31. data/spec/models/artist.rb +10 -0
  32. data/spec/models/blog_post.rb +5 -0
  33. data/spec/models/calendar.rb +7 -0
  34. data/spec/models/concert.rb +6 -0
  35. data/spec/models/performance.rb +6 -0
  36. data/spec/models/person.rb +14 -0
  37. data/spec/models/watchable.rb +17 -0
  38. data/spec/primer/bus_spec.rb +31 -0
  39. data/spec/primer/cache_spec.rb +309 -0
  40. data/spec/primer/helpers/erb_spec.rb +89 -0
  41. data/spec/primer/watcher/active_record_spec.rb +189 -0
  42. data/spec/primer/watcher_spec.rb +101 -0
  43. data/spec/schema.rb +31 -0
  44. data/spec/spec_helper.rb +60 -0
  45. data/spec/templates/page.erb +3 -0
  46. metadata +235 -0
@@ -0,0 +1,189 @@
1
+ require 'spec_helper'
2
+
3
+ describe Primer::Watcher::ActiveRecordMacros do
4
+ before do
5
+ @person = Person.create(:name => "Abe")
6
+ @impostor = Person.create(:name => "Aaron")
7
+ @post = @person.blog_posts.create(:title => "web scale")
8
+ @id = @person.id
9
+
10
+ @artist = Artist.create(:name => "Wolf Parade")
11
+ @concert = Concert.create(:date => 6.months.ago, :venue => "Borderline")
12
+ @festival = Concert.create(:date => 3.months.ago, :venue => "End of the Road")
13
+ @calendar = Calendar.create(:artists => [@artist])
14
+
15
+ @artist.concerts << @festival
16
+
17
+ Primer::Worker::ActiveRecordAgent.bind_to_bus
18
+ Primer::Watcher.enable!
19
+ end
20
+
21
+ after do
22
+ @person.delete
23
+ end
24
+
25
+ def should_publish(topic, *message)
26
+ @publish ||= Primer.bus.method(:publish)
27
+ Primer.bus.should_receive(:publish).with(topic, message) do |*args|
28
+ @publish.call(*args)
29
+ end
30
+ end
31
+
32
+ describe "#primer_identifier" do
33
+ it "returns a tuple that tells us enough to find the object" do
34
+ @person.primer_identifier.should == ["ActiveRecord", "Person", @person.id]
35
+ end
36
+ end
37
+
38
+ it "is mixed in automatically when using Primer with ActiveRecord" do
39
+ Person.should be_kind_of(Primer::Watcher::ActiveRecordMacros)
40
+ end
41
+
42
+ it "watches ActiveRecord attributes" do
43
+ @person.name.should == "Abe"
44
+ Primer::Watcher.call_log.should == [[@person, :name, [], nil, "Abe"]]
45
+ end
46
+
47
+ it "watches calls to has_many associations" do
48
+ @person.blog_posts.count.should == 1
49
+ Primer::Watcher.call_log.should include([@person, :blog_posts, [], nil, [@post]])
50
+ end
51
+
52
+ it "watches calls to belongs_to associations" do
53
+ @post.person.should == @person
54
+ Primer::Watcher.call_log.should include([@post, :person, [], nil, @person])
55
+ end
56
+
57
+ it "logs calls made inside other methods" do
58
+ @person.all_attributes.should == [@id, "Abe"]
59
+ Primer::Watcher.call_log.should == [
60
+ [@person, :id, [], nil, @id ],
61
+ [@person, :name, [], nil, "Abe"]
62
+ ]
63
+ end
64
+
65
+ it "publishes a message when an attribute changes" do
66
+ should_publish(:active_record, :update, "Person", anything, anything)
67
+ should_publish(:changes, "ActiveRecord", "Person", @person.id, "name")
68
+ @person.update_attribute(:name, "Aaron")
69
+ end
70
+
71
+ it "publishes messages when an object is deleted" do
72
+ should_publish(:active_record, :destroy, "Person", anything)
73
+ should_publish(:changes, "ActiveRecord", "Person", @person.id, "id")
74
+ should_publish(:changes, "ActiveRecord", "Person", @person.id, "name")
75
+ should_publish(:changes, "ActiveRecord", "Person", @person.id, "age")
76
+ should_publish(:changes, "ActiveRecord", "BlogPost", @post.id, "person")
77
+ @person.destroy
78
+ end
79
+
80
+ it "publishes a message about a belongs_to association when the foreign key changes" do
81
+ should_publish(:active_record, :create, "BlogPost", anything)
82
+ should_publish(:changes, "ActiveRecord", "Person", @person.id, "blog_posts")
83
+ BlogPost.create(:person => @person, :title => "How to make a time machine")
84
+ end
85
+
86
+ it "publishes a message about a belongs_to association when the object changes" do
87
+ should_publish(:active_record, :update, "BlogPost", anything, anything)
88
+ should_publish(:changes, "ActiveRecord", "BlogPost", @post.id, "person_id")
89
+ should_publish(:changes, "ActiveRecord", "BlogPost", @post.id, "person")
90
+ should_publish(:changes, "ActiveRecord", "Person", @impostor.id, "blog_posts")
91
+ should_publish(:changes, "ActiveRecord", "Person", @person.id, "blog_posts")
92
+ @post.update_attribute(:person, @impostor)
93
+ end
94
+
95
+ it "publishes a message when a has_many collection gains a member" do
96
+ should_publish(:active_record, :create, "BlogPost", anything)
97
+ should_publish(:changes, "ActiveRecord", "Person", @person.id, "blog_posts")
98
+ BlogPost.create(:person => @person, :title => "How to make a time machine")
99
+ end
100
+
101
+ it "publishes a message when a has_many collection loses a member" do
102
+ should_publish(:active_record, :destroy, "BlogPost", anything)
103
+ should_publish(:changes, "ActiveRecord", "BlogPost", @post.id, "id")
104
+ should_publish(:changes, "ActiveRecord", "BlogPost", @post.id, "person_id")
105
+ should_publish(:changes, "ActiveRecord", "BlogPost", @post.id, "title")
106
+ should_publish(:changes, "ActiveRecord", "BlogPost", @post.id, "person")
107
+ should_publish(:changes, "ActiveRecord", "Person", @person.id, "blog_posts")
108
+ @post.destroy
109
+ end
110
+
111
+ it "publishes a message when an object is pushed to a has_many :through has_many" do
112
+ should_publish(:active_record, :create, "Performance", anything)
113
+ should_publish(:changes, "ActiveRecord", "Concert", @concert.id, "performances")
114
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "performances")
115
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "concerts")
116
+ @artist.concerts << @concert
117
+ end
118
+
119
+ it "publishes a message when a join object is pushed to a has_many :through has_many" do
120
+ should_publish(:active_record, :create, "Performance", anything)
121
+ should_publish(:changes, "ActiveRecord", "Concert", @concert.id, "performances")
122
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "performances")
123
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "concerts")
124
+ @artist.performances << Performance.new(:concert => @concert)
125
+ end
126
+
127
+ it "publishes a message when a join object is created for has_many :through has_many" do
128
+ should_publish(:active_record, :create, "Performance", anything)
129
+ should_publish(:changes, "ActiveRecord", "Concert", @concert.id, "performances")
130
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "performances")
131
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "concerts")
132
+ Performance.create(:concert => @concert, :artist => @artist)
133
+ end
134
+
135
+ it "publishes messages when a join object is deleted from a has_many :through has_many collection" do
136
+ @performance = @festival.performances.first
137
+ should_publish(:active_record, :destroy, "Performance", anything)
138
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "artist_id")
139
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "artist")
140
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "concert_id")
141
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "concert")
142
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "id")
143
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "performances")
144
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "concerts")
145
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "performances")
146
+ @artist.performances.first.destroy
147
+ end
148
+
149
+ it "publishes messages when a member is deleted from a has_many :through has_many collection" do
150
+ @performance = @festival.performances.first
151
+ should_publish(:active_record, :destroy, "Performance", anything)
152
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "artist_id")
153
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "artist")
154
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "performances")
155
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "concerts")
156
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "concert_id")
157
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "concert")
158
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "performances")
159
+ should_publish(:changes, "ActiveRecord", "Performance", @performance.id, "id")
160
+ should_publish(:active_record, :destroy, "Concert", anything)
161
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "id")
162
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "calendar_id")
163
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "calendar")
164
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "date")
165
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "venue")
166
+ @artist.concerts.first.destroy
167
+ end
168
+
169
+ it "publishes messages when a join object is pushed to a has_many :through belongs_to" do
170
+ should_publish(:active_record, :update, "Concert", anything, anything)
171
+ should_publish(:changes, "ActiveRecord", "Concert", @concert.id, "calendar_id")
172
+ should_publish(:changes, "ActiveRecord", "Concert", @concert.id, "calendar")
173
+ should_publish(:changes, "ActiveRecord", "Calendar", @calendar.id, "gigs")
174
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "upcoming_gigs")
175
+ @calendar.gigs << @concert
176
+ end
177
+
178
+ it "publishes messages when a join object is removed from a has_many :through belongs_to" do
179
+ @calendar.gigs << @festival
180
+ should_publish(:active_record, :update, "Concert", anything, anything)
181
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "calendar_id")
182
+ should_publish(:changes, "ActiveRecord", "Concert", @festival.id, "calendar")
183
+ should_publish(:changes, "ActiveRecord", "Calendar", @calendar.id, "gigs")
184
+ should_publish(:changes, "ActiveRecord", "Artist", @artist.id, "upcoming_gigs")
185
+ @festival.calendar = nil
186
+ @festival.save
187
+ end
188
+ end
189
+
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Primer::Watcher do
4
+ let(:watchable) { Watchable.new("Aaron") }
5
+
6
+ describe "#primer_identifier" do
7
+ it "returns a tuple that tells us enough to find the object" do
8
+ watchable.primer_identifier.should == ["Object", "Watchable", watchable.object_id]
9
+ end
10
+ end
11
+
12
+ describe "with watching disabled" do
13
+ before { Primer::Watcher.disable! }
14
+
15
+ it "lets methods run as usual" do
16
+ watchable.name.should == "Aaron"
17
+ end
18
+
19
+ it "does not log method calls" do
20
+ watchable.name
21
+ Primer::Watcher.call_log.should be_empty
22
+ end
23
+ end
24
+
25
+ describe "with watching enabled" do
26
+ before { Primer::Watcher.enable! }
27
+
28
+ it "lets methods return their usual return values" do
29
+ watchable.name.should == "Aaron"
30
+ end
31
+
32
+ it "logs the monitored method calls" do
33
+ watchable.name
34
+ Primer::Watcher.call_log.should == [[watchable, :name, [], nil, "Aaron"]]
35
+ end
36
+
37
+ it "logs arguments given to methods" do
38
+ watchable.is_called?("Aaron")
39
+ watchable.is_called?("Abe")
40
+ Primer::Watcher.call_log.should == [
41
+ [watchable, :is_called?, ["Aaron"], nil, true ],
42
+ [watchable, :is_called?, ["Abe"], nil, false]
43
+ ]
44
+ end
45
+
46
+ it "logs blocks passed to methods" do
47
+ block = lambda {}
48
+ watchable.name(&block)
49
+ Primer::Watcher.call_log.should == [[watchable, :name, [], block, "Aaron"]]
50
+ end
51
+
52
+ it "does not log after you disable the watcher" do
53
+ Primer::Watcher.disable!
54
+ watchable.name.should == "Aaron"
55
+ watchable.is_called?("Aaron").should be_true
56
+ watchable.is_called?("Abe").should be_false
57
+ Primer::Watcher.call_log.should be_empty
58
+ end
59
+ end
60
+
61
+ describe ".watching" do
62
+ it "returns the value of the block" do
63
+ Primer::Watcher.watching { watchable.name }.should == "Aaron"
64
+ end
65
+
66
+ it "logs calls during the block to a list you supply" do
67
+ calls = []
68
+ Primer::Watcher.watching(calls) { watchable.name }
69
+ calls.should == [[watchable, :name, [], nil, "Aaron"]]
70
+ end
71
+
72
+ it "does not log calls outside of the block" do
73
+ Primer::Watcher.watching { watchable.name }
74
+ watchable.name
75
+ Primer::Watcher.call_log.should == [[watchable, :name, [], nil, "Aaron"]]
76
+ end
77
+
78
+ it "allows nested blocks to just capture specific scopes" do
79
+ block = lambda {}
80
+
81
+ all_calls, inner_calls = [], []
82
+ Primer::Watcher.watching(all_calls) do
83
+ watchable.name
84
+ Primer::Watcher.watching(inner_calls) do
85
+ watchable.is_called?("Abe")
86
+ end
87
+ watchable.is_called?("Aaron", &block)
88
+ end
89
+
90
+ all_calls.should == [
91
+ [watchable, :name, [], nil, "Aaron"],
92
+ [watchable, :is_called?, ["Abe"], nil, false ],
93
+ [watchable, :is_called?, ["Aaron"], block, true ]
94
+ ]
95
+ inner_calls.should == [
96
+ [watchable, :is_called?, ["Abe"], nil, false ]
97
+ ]
98
+ end
99
+ end
100
+ end
101
+
data/spec/schema.rb ADDED
@@ -0,0 +1,31 @@
1
+ ActiveRecord::Schema.define do |version|
2
+ create_table :artists, :force => true do |t|
3
+ t.belongs_to :calendar
4
+ t.string :name
5
+ end
6
+
7
+ create_table :calendars, :force => true do |t|
8
+ end
9
+
10
+ create_table :concerts, :force => true do |t|
11
+ t.belongs_to :calendar
12
+ t.date :date
13
+ t.string :venue
14
+ end
15
+
16
+ create_table :performances, :force => true do |t|
17
+ t.belongs_to :artist
18
+ t.belongs_to :concert
19
+ end
20
+
21
+ create_table :blog_posts, :force => true do |t|
22
+ t.belongs_to :person
23
+ t.string :title
24
+ end
25
+
26
+ create_table :people, :force => true do |t|
27
+ t.string :name
28
+ t.integer :age
29
+ end
30
+ end
31
+
@@ -0,0 +1,60 @@
1
+ dir = File.expand_path(File.dirname(__FILE__))
2
+ $:.unshift(dir)
3
+
4
+ require dir + '/../lib/primer'
5
+ require 'tilt'
6
+ require 'erb'
7
+ require 'action_controller'
8
+
9
+ require 'fileutils'
10
+ require 'active_record'
11
+ FileUtils.mkdir_p(dir + '/db')
12
+ ActiveRecord::Base.establish_connection(
13
+ :adapter => 'sqlite3',
14
+ :database => dir + '/db/test.sqlite3')
15
+
16
+ require 'schema'
17
+
18
+ require 'models/watchable'
19
+ require 'models/artist'
20
+ require 'models/calendar'
21
+ require 'models/concert'
22
+ require 'models/performance'
23
+ require 'models/blog_post'
24
+ require 'models/person'
25
+
26
+ module Helper
27
+ def self.next_id
28
+ @next_id ||= 0
29
+ @next_id += 1
30
+ @next_id
31
+ end
32
+ end
33
+
34
+ RSpec.configure do |config|
35
+ config.before do
36
+ Primer::Watcher.disable!
37
+ Primer.bus = Primer::Bus::Memory.new
38
+ Primer.cache = nil
39
+ Primer.real_time = false
40
+ end
41
+
42
+ config.after do
43
+ if Primer.cache
44
+ Primer.cache.clear
45
+ Primer.cache.routes = nil
46
+ end
47
+ Primer::Watcher.reset!
48
+ Primer.bus.unsubscribe_all
49
+
50
+ [ BlogPost,
51
+ Person,
52
+ Artist,
53
+ Calendar,
54
+ Concert,
55
+ Performance
56
+
57
+ ].each { |m| m.delete_all }
58
+ end
59
+ end
60
+
@@ -0,0 +1,3 @@
1
+ Welcome, <%= primer '/user' %>
2
+ <% primer '/cache/key' do %>Hello, <%= name %><% end %>
3
+ Thanks
metadata ADDED
@@ -0,0 +1,235 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: primer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - James Coglan
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-25 00:00:00 +00:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: redis
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 1
31
+ - 1
32
+ version: 2.1.1
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: sinatra
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 1
45
+ - 1
46
+ - 0
47
+ version: 1.1.0
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: amqp
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ - 6
61
+ - 7
62
+ version: 0.6.7
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: faye
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ - 5
76
+ version: "0.5"
77
+ type: :runtime
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: rspec
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ type: :development
91
+ version_requirements: *id005
92
+ - !ruby/object:Gem::Dependency
93
+ name: activerecord
94
+ prerelease: false
95
+ requirement: &id006 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ type: :development
104
+ version_requirements: *id006
105
+ - !ruby/object:Gem::Dependency
106
+ name: sqlite3
107
+ prerelease: false
108
+ requirement: &id007 !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ segments:
114
+ - 0
115
+ version: "0"
116
+ type: :development
117
+ version_requirements: *id007
118
+ - !ruby/object:Gem::Dependency
119
+ name: actionpack
120
+ prerelease: false
121
+ requirement: &id008 !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ segments:
127
+ - 0
128
+ version: "0"
129
+ type: :development
130
+ version_requirements: *id008
131
+ - !ruby/object:Gem::Dependency
132
+ name: tilt
133
+ prerelease: false
134
+ requirement: &id009 !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ segments:
140
+ - 0
141
+ version: "0"
142
+ type: :development
143
+ version_requirements: *id009
144
+ description:
145
+ email: jcoglan@gmail.com
146
+ executables: []
147
+
148
+ extensions: []
149
+
150
+ extra_rdoc_files:
151
+ - README.rdoc
152
+ - example/README.rdoc
153
+ files:
154
+ - README.rdoc
155
+ - spec/spec_helper.rb
156
+ - spec/primer/bus_spec.rb
157
+ - spec/primer/watcher_spec.rb
158
+ - spec/primer/helpers/erb_spec.rb
159
+ - spec/primer/watcher/active_record_spec.rb
160
+ - spec/primer/cache_spec.rb
161
+ - spec/templates/page.erb
162
+ - spec/schema.rb
163
+ - spec/models/calendar.rb
164
+ - spec/models/blog_post.rb
165
+ - spec/models/watchable.rb
166
+ - spec/models/performance.rb
167
+ - spec/models/artist.rb
168
+ - spec/models/person.rb
169
+ - spec/models/concert.rb
170
+ - lib/javascript/primer.js
171
+ - lib/primer/enabler.rb
172
+ - lib/primer/cache/memory.rb
173
+ - lib/primer/cache/redis.rb
174
+ - lib/primer/real_time.rb
175
+ - lib/primer/watcher.rb
176
+ - lib/primer/route_set.rb
177
+ - lib/primer/worker/active_record_agent.rb
178
+ - lib/primer/bus/memory.rb
179
+ - lib/primer/bus/amqp.rb
180
+ - lib/primer/worker.rb
181
+ - lib/primer/bus.rb
182
+ - lib/primer/watcher/active_record_macros.rb
183
+ - lib/primer/watcher/macros.rb
184
+ - lib/primer/cache.rb
185
+ - lib/primer/helpers.rb
186
+ - lib/primer.rb
187
+ - example/application.rb
188
+ - example/config.ru
189
+ - example/README.rdoc
190
+ - example/script/setup_database.rb
191
+ - example/public/style.css
192
+ - example/worker.rb
193
+ - example/environment.rb
194
+ - example/views/show.erb
195
+ - example/views/layout.erb
196
+ - example/views/index.erb
197
+ - example/models/blog_post.rb
198
+ - example/models/connection.rb
199
+ has_rdoc: true
200
+ homepage: http://github.com/jcoglan/primer
201
+ licenses: []
202
+
203
+ post_install_message:
204
+ rdoc_options:
205
+ - --main
206
+ - README.rdoc
207
+ - --title
208
+ - Primer
209
+ require_paths:
210
+ - lib
211
+ required_ruby_version: !ruby/object:Gem::Requirement
212
+ none: false
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ segments:
217
+ - 0
218
+ version: "0"
219
+ required_rubygems_version: !ruby/object:Gem::Requirement
220
+ none: false
221
+ requirements:
222
+ - - ">="
223
+ - !ruby/object:Gem::Version
224
+ segments:
225
+ - 0
226
+ version: "0"
227
+ requirements: []
228
+
229
+ rubyforge_project:
230
+ rubygems_version: 1.3.7
231
+ signing_key:
232
+ specification_version: 3
233
+ summary: Intelligent caching, no observers necessary
234
+ test_files: []
235
+