live_record 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -5
  3. data/.travis.yml +12 -0
  4. data/Gemfile +5 -1
  5. data/Gemfile.lock +199 -1
  6. data/README.md +38 -9
  7. data/app/assets/javascripts/live_record/plugins/live_dom.coffee +2 -3
  8. data/lib/live_record.rb +3 -0
  9. data/lib/live_record/.rspec +3 -0
  10. data/lib/live_record/{channel.rb → channel/implement.rb} +1 -4
  11. data/lib/live_record/config.ru +10 -0
  12. data/lib/live_record/generators/install_generator.rb +0 -6
  13. data/lib/live_record/generators/templates/live_record_channel.rb +1 -1
  14. data/lib/live_record/generators/templates/model.rb.rb +3 -0
  15. data/lib/live_record/model/callbacks.rb +36 -0
  16. data/lib/live_record/spec/factories/posts.rb +6 -0
  17. data/lib/live_record/spec/features/live_record_syncing_spec.rb +60 -0
  18. data/lib/live_record/spec/internal/app/assets/config/manifest.js +2 -0
  19. data/lib/live_record/spec/internal/app/assets/javascripts/application.js +17 -0
  20. data/lib/live_record/spec/internal/app/assets/javascripts/cable.js +12 -0
  21. data/lib/live_record/spec/internal/app/assets/javascripts/posts.coffee +14 -0
  22. data/lib/live_record/spec/internal/app/channels/application_cable/channel.rb +4 -0
  23. data/lib/live_record/spec/internal/app/channels/application_cable/connection.rb +8 -0
  24. data/lib/live_record/spec/internal/app/channels/live_record_channel.rb +4 -0
  25. data/lib/live_record/spec/internal/app/controllers/application_controller.rb +3 -0
  26. data/lib/live_record/spec/internal/app/controllers/posts_controller.rb +74 -0
  27. data/lib/live_record/spec/internal/app/models/application_record.rb +3 -0
  28. data/lib/live_record/spec/internal/app/models/live_record_update.rb +3 -0
  29. data/lib/live_record/spec/internal/app/models/post.rb +11 -0
  30. data/lib/live_record/spec/internal/app/views/layouts/application.html.erb +13 -0
  31. data/lib/live_record/spec/internal/app/views/posts/_form.html.erb +27 -0
  32. data/lib/live_record/spec/internal/app/views/posts/_post.json.jbuilder +2 -0
  33. data/lib/live_record/spec/internal/app/views/posts/edit.html.erb +6 -0
  34. data/lib/live_record/spec/internal/app/views/posts/index.html.erb +32 -0
  35. data/lib/live_record/spec/internal/app/views/posts/index.json.jbuilder +1 -0
  36. data/lib/live_record/spec/internal/app/views/posts/new.html.erb +5 -0
  37. data/lib/live_record/spec/internal/app/views/posts/show.html.erb +21 -0
  38. data/lib/live_record/spec/internal/app/views/posts/show.json.jbuilder +1 -0
  39. data/lib/live_record/spec/internal/config/cable.yml +8 -0
  40. data/lib/live_record/spec/internal/config/database.yml +3 -0
  41. data/lib/live_record/spec/internal/config/routes.rb +3 -0
  42. data/lib/live_record/spec/internal/db/schema.rb +16 -0
  43. data/lib/live_record/spec/internal/public/favicon.ico +0 -0
  44. data/lib/live_record/spec/rails_helper.rb +34 -0
  45. data/lib/live_record/spec/spec_helper.rb +12 -0
  46. data/lib/live_record/version.rb +1 -1
  47. data/live_record.gemspec +19 -3
  48. metadata +251 -8
  49. data/lib/live_record/model.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3a7ce4c6e3d1f684926289b479d1acf70eefd870
4
- data.tar.gz: 44c06e78171c35d4c42b76ba90ea8acac76e87d0
3
+ metadata.gz: d45669bf962d28f44bc9bc0be4dffd39fe870267
4
+ data.tar.gz: a11548ef1efad7d80a0cc3d4f04463de2a574832
5
5
  SHA512:
6
- metadata.gz: c9edd5e90852ffed01e349b8b75486d3d8048af00bdc1a66498d5f9b354afc0b00b00789392b66150bcb858bba6affd2fea92af4e0cc830c053403fb4e2076ca
7
- data.tar.gz: fddf629d3b446a73d8db1be047e0d976b11aefe747d69892074d9e12e57e27edfc088f3c1ea621056825207f87b21c7b59be8a9f276ecb5f3e88bebb2146d038
6
+ metadata.gz: 40e8a77a1a61782aab015d500bf447bc923874b1e3464cd666fc326f71406c14741740eaf0791ee357a735d7d356e828e6db2fda0ab8ea514d44fa93aaca3379
7
+ data.tar.gz: 8be21e6154e5995bea77eddebaa50b6b3ae6931b983af99688ab8d62a226c7ff6dc2d57e2665248c7dd9430785de664ccdeafa885f7bc04d6fe68ea2bba2f1bd
data/.gitignore CHANGED
@@ -1,7 +1,8 @@
1
1
  /.bundle
2
- /db/*.sqlite3
3
- /db/*.sqlite3-journal
4
- /log/*
5
- /tmp/*
2
+ *.sqlite
3
+ *.sqlite-journal
4
+ /lib/live_record/spec/internal/log/*
5
+ /lib/live_record/spec/internal/tmp/*
6
6
  .byebug_history
7
- *.gem
7
+ *.gem
8
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ dist: trusty
2
+ addons:
3
+ chrome: stable
4
+ language: ruby
5
+ rvm:
6
+ - 2.2.2
7
+ - 2.2.7
8
+ - 2.3.4
9
+ - 2.4.1
10
+ before_install:
11
+ - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
12
+ script: cd lib/live_record && bundle exec rspec
data/Gemfile CHANGED
@@ -2,4 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '~> 5.0', '< 5.2'
5
+ group :development, :test do
6
+ # issues with Combustion + FactoryGirl factory loading: https://github.com/pat/combustion/issues/33
7
+ # therefore, this gem should not be part of .gemspec but instead is specified here in the Gemfile
8
+ gem 'factory_girl_rails', require: false
9
+ end
data/Gemfile.lock CHANGED
@@ -1,11 +1,209 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ live_record (0.1.0)
5
+ rails (>= 5.0.0, < 5.2)
6
+
1
7
  GEM
2
8
  remote: https://rubygems.org/
3
9
  specs:
10
+ actioncable (5.1.3)
11
+ actionpack (= 5.1.3)
12
+ nio4r (~> 2.0)
13
+ websocket-driver (~> 0.6.1)
14
+ actionmailer (5.1.3)
15
+ actionpack (= 5.1.3)
16
+ actionview (= 5.1.3)
17
+ activejob (= 5.1.3)
18
+ mail (~> 2.5, >= 2.5.4)
19
+ rails-dom-testing (~> 2.0)
20
+ actionpack (5.1.3)
21
+ actionview (= 5.1.3)
22
+ activesupport (= 5.1.3)
23
+ rack (~> 2.0)
24
+ rack-test (~> 0.6.3)
25
+ rails-dom-testing (~> 2.0)
26
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
27
+ actionview (5.1.3)
28
+ activesupport (= 5.1.3)
29
+ builder (~> 3.1)
30
+ erubi (~> 1.4)
31
+ rails-dom-testing (~> 2.0)
32
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
33
+ activejob (5.1.3)
34
+ activesupport (= 5.1.3)
35
+ globalid (>= 0.3.6)
36
+ activemodel (5.1.3)
37
+ activesupport (= 5.1.3)
38
+ activerecord (5.1.3)
39
+ activemodel (= 5.1.3)
40
+ activesupport (= 5.1.3)
41
+ arel (~> 8.0)
42
+ activesupport (5.1.3)
43
+ concurrent-ruby (~> 1.0, >= 1.0.2)
44
+ i18n (~> 0.7)
45
+ minitest (~> 5.1)
46
+ tzinfo (~> 1.1)
47
+ addressable (2.5.1)
48
+ public_suffix (~> 2.0, >= 2.0.2)
49
+ archive-zip (0.7.0)
50
+ io-like (~> 0.3.0)
51
+ arel (8.0.0)
52
+ builder (3.2.3)
53
+ byebug (9.0.6)
54
+ capybara (2.15.1)
55
+ addressable
56
+ mini_mime (>= 0.1.3)
57
+ nokogiri (>= 1.3.3)
58
+ rack (>= 1.0.0)
59
+ rack-test (>= 0.5.4)
60
+ xpath (~> 2.0)
61
+ childprocess (0.7.1)
62
+ ffi (~> 1.0, >= 1.0.11)
63
+ chromedriver-helper (1.1.0)
64
+ archive-zip (~> 0.7.0)
65
+ nokogiri (~> 1.6)
66
+ coffee-rails (4.2.2)
67
+ coffee-script (>= 2.2.0)
68
+ railties (>= 4.0.0)
69
+ coffee-script (2.4.1)
70
+ coffee-script-source
71
+ execjs
72
+ coffee-script-source (1.12.2)
73
+ combustion (0.7.0)
74
+ activesupport (>= 3.0.0)
75
+ railties (>= 3.0.0)
76
+ thor (>= 0.14.6)
77
+ concurrent-ruby (1.0.5)
78
+ database_cleaner (1.6.1)
79
+ diff-lcs (1.3)
80
+ erubi (1.6.1)
81
+ execjs (2.7.0)
82
+ factory_girl (4.8.0)
83
+ activesupport (>= 3.0.0)
84
+ factory_girl_rails (4.8.0)
85
+ factory_girl (~> 4.8.0)
86
+ railties (>= 3.0.0)
87
+ faker (1.8.4)
88
+ i18n (~> 0.5)
89
+ ffi (1.9.18)
90
+ globalid (0.4.0)
91
+ activesupport (>= 4.2.0)
92
+ i18n (0.8.6)
93
+ io-like (0.3.0)
94
+ jbuilder (2.7.0)
95
+ activesupport (>= 4.2.0)
96
+ multi_json (>= 1.2)
97
+ jquery-rails (4.3.1)
98
+ rails-dom-testing (>= 1, < 3)
99
+ railties (>= 4.2.0)
100
+ thor (>= 0.14, < 2.0)
101
+ loofah (2.0.3)
102
+ nokogiri (>= 1.5.9)
103
+ mail (2.6.6)
104
+ mime-types (>= 1.16, < 4)
105
+ method_source (0.8.2)
106
+ mime-types (3.1)
107
+ mime-types-data (~> 3.2015)
108
+ mime-types-data (3.2016.0521)
109
+ mini_mime (0.1.4)
110
+ mini_portile2 (2.2.0)
111
+ minitest (5.10.3)
112
+ multi_json (1.12.1)
113
+ nio4r (2.1.0)
114
+ nokogiri (1.8.0)
115
+ mini_portile2 (~> 2.2.0)
116
+ public_suffix (2.0.5)
117
+ puma (3.10.0)
118
+ rack (2.0.3)
119
+ rack-test (0.6.3)
120
+ rack (>= 1.0)
121
+ rails (5.1.3)
122
+ actioncable (= 5.1.3)
123
+ actionmailer (= 5.1.3)
124
+ actionpack (= 5.1.3)
125
+ actionview (= 5.1.3)
126
+ activejob (= 5.1.3)
127
+ activemodel (= 5.1.3)
128
+ activerecord (= 5.1.3)
129
+ activesupport (= 5.1.3)
130
+ bundler (>= 1.3.0)
131
+ railties (= 5.1.3)
132
+ sprockets-rails (>= 2.0.0)
133
+ rails-dom-testing (2.0.3)
134
+ activesupport (>= 4.2.0)
135
+ nokogiri (>= 1.6)
136
+ rails-html-sanitizer (1.0.3)
137
+ loofah (~> 2.0)
138
+ railties (5.1.3)
139
+ actionpack (= 5.1.3)
140
+ activesupport (= 5.1.3)
141
+ method_source
142
+ rake (>= 0.8.7)
143
+ thor (>= 0.18.1, < 2.0)
144
+ rake (12.0.0)
145
+ redis (3.3.3)
146
+ rspec-core (3.6.0)
147
+ rspec-support (~> 3.6.0)
148
+ rspec-expectations (3.6.0)
149
+ diff-lcs (>= 1.2.0, < 2.0)
150
+ rspec-support (~> 3.6.0)
151
+ rspec-mocks (3.6.0)
152
+ diff-lcs (>= 1.2.0, < 2.0)
153
+ rspec-support (~> 3.6.0)
154
+ rspec-rails (3.6.1)
155
+ actionpack (>= 3.0)
156
+ activesupport (>= 3.0)
157
+ railties (>= 3.0)
158
+ rspec-core (~> 3.6.0)
159
+ rspec-expectations (~> 3.6.0)
160
+ rspec-mocks (~> 3.6.0)
161
+ rspec-support (~> 3.6.0)
162
+ rspec-support (3.6.0)
163
+ rubyzip (1.2.1)
164
+ selenium-webdriver (3.5.1)
165
+ childprocess (~> 0.5)
166
+ rubyzip (~> 1.0)
167
+ sprockets (3.7.1)
168
+ concurrent-ruby (~> 1.0)
169
+ rack (> 1, < 3)
170
+ sprockets-rails (3.2.0)
171
+ actionpack (>= 4.0)
172
+ activesupport (>= 4.0)
173
+ sprockets (>= 3.0.0)
174
+ sqlite3 (1.3.13)
175
+ thor (0.20.0)
176
+ thread_safe (0.3.6)
177
+ tzinfo (1.2.3)
178
+ thread_safe (~> 0.1)
179
+ websocket-driver (0.6.5)
180
+ websocket-extensions (>= 0.1.0)
181
+ websocket-extensions (0.1.2)
182
+ xpath (2.1.0)
183
+ nokogiri (~> 1.3)
4
184
 
5
185
  PLATFORMS
6
186
  ruby
7
187
 
8
188
  DEPENDENCIES
189
+ bundler (~> 1.3)
190
+ byebug (~> 9.0)
191
+ capybara (~> 2.15)
192
+ chromedriver-helper (~> 1.1)
193
+ coffee-rails (~> 4.2)
194
+ combustion (~> 0.7)
195
+ database_cleaner (~> 1.6)
196
+ factory_girl_rails
197
+ faker (~> 1.8)
198
+ jbuilder (~> 2.7)
199
+ jquery-rails (~> 4.3)
200
+ live_record!
201
+ puma (~> 3.10)
202
+ redis (~> 3.3)
203
+ rspec-rails (~> 3.6)
204
+ selenium-webdriver (~> 3.5)
205
+ sprockets-rails (~> 3.2)
206
+ sqlite3 (~> 1.3)
9
207
 
10
208
  BUNDLED WITH
11
- 1.12.5
209
+ 1.15.3
data/README.md CHANGED
@@ -1,15 +1,16 @@
1
- *WIP! (TODO: Tests)*
1
+ [![Build Status](https://travis-ci.org/jrpolidario/live_record.svg?branch=master)](https://travis-ci.org/jrpolidario/live_record)
2
2
 
3
3
  ## About
4
4
 
5
5
  * Auto-syncs records in client-side JS (through a Model DSL) from changes in the backend Rails server through ActionCable
6
- * Auto-updates DOM elements mapped to a record attribute, from changes. **(Optional Plugin)**
6
+ * Auto-updates DOM elements mapped to a record attribute, from changes. **(Optional LiveDOM Plugin)**
7
7
  * Automatically resyncs after client-side reconnection.
8
8
 
9
9
  > `live_record` is intentionally designed for read-only one-way syncing from the backend server, and does not support pushing changes to the Rails server from the client-side JS. Updates from client-side then is intended to use the normal HTTP REST requests.
10
10
 
11
11
  ## Requirements
12
12
 
13
+ * **>= Ruby 2.2.2**
13
14
  * **>= Rails 5.0**
14
15
 
15
16
  ## Demo
@@ -37,10 +38,19 @@
37
38
 
38
39
  // all records in the JS store are automatically subscribed to the backend LiveRecordChannel, which meant syncing (update / destroy) changes from the backend
39
40
 
40
- // you can add a callback that will be invoked whenever the Book object has been updated
41
+ // you can add a callback that will be invoked whenever the Book object has been updated (see all supported callbacks further below)
41
42
  book.addCallback('after:update', function() {
42
43
  // let's say you update the DOM elements here when the attributes have changed
44
+ // `this` refers to the Book record that has been updated
45
+ console.log(this);
43
46
  });
47
+
48
+ // or you can add a Model-wide callback that will be invoked whenever ANY Book object has been updated
49
+ LiveRecord.Model.all.Book.addCallback('after:update', function() {
50
+ // let's say you update the DOM elements here when the attributes have changed
51
+ // `this` refers to the Book record that has been updated
52
+ console.log(this);
53
+ })
44
54
  ```
45
55
 
46
56
  * on the backend-side, you can handle attributes authorisation:
@@ -48,6 +58,8 @@
48
58
  ```ruby
49
59
  # app/models/book.rb
50
60
  class Book < ApplicationRecord
61
+ include LiveRecord::Model::Callbacks
62
+
51
63
  def self.live_record_whitelisted_attributes(book, current_user)
52
64
  # Add attributes to this array that you would like `current_user` to have access to when syncing this particular `book`
53
65
  # empty array means not-authorised
@@ -68,7 +80,7 @@
68
80
  * Add the following to your `Gemfile`:
69
81
 
70
82
  ```ruby
71
- gem 'live_record', '~> 0.0.1'
83
+ gem 'live_record', '~> 0.1.0'
72
84
  ```
73
85
 
74
86
  * Run:
@@ -83,7 +95,7 @@
83
95
  rails generate live_record:install
84
96
  ```
85
97
 
86
- > `rails generate live_record:install --live_dom=false` if you do not need the `LiveDom` plugin; `--live_dom=true` by default
98
+ > `rails generate live_record:install --live_dom=false` if you do not need the `LiveDOM` plugin; `--live_dom=true` by default
87
99
 
88
100
  * Run migration to create the `live_record_updates` table, which is going to be used for client reconnection resyncing:
89
101
 
@@ -154,7 +166,7 @@
154
166
  {
155
167
  modelName: 'Book' // should match the Rails model name
156
168
  plugins: {
157
- LiveDOM: true // remove this if you do not need `LiveDom`
169
+ LiveDOM: true // remove this if you do not need `LiveDOM`
158
170
  }
159
171
  }
160
172
  )
@@ -234,6 +246,14 @@
234
246
  </script>
235
247
  ```
236
248
 
249
+ ```html
250
+ <!-- app/views/books/index.html.erb -->
251
+ <script>
252
+ // `loadRecords` you may also specify a URL to loadRecords (`url` defaults to `window.location.href` which is the current page)
253
+ LiveRecord.helpers.loadRecords({modelName: 'Book', url: '/some/url/that/returns_books_as_a_json'})
254
+ </script>
255
+ ```
256
+
237
257
  ```html
238
258
  <!-- app/views/posts/index.html.erb -->
239
259
  <script>
@@ -275,10 +295,10 @@
275
295
 
276
296
  ## Plugins
277
297
 
278
- ### LiveDom (Requires JQuery)
298
+ ### LiveDOM (Requires JQuery)
279
299
 
280
300
  * enabled by default, unless explicitly removed.
281
- * `LiveDom` allows DOM elements' text content to be automatically updated, whenever the mapped record-attribute has been updated.
301
+ * `LiveDOM` allows DOM elements' text content to be automatically updated, whenever the mapped record-attribute has been updated.
282
302
 
283
303
  > text content is safely escaped using JQuery's `.text()` function
284
304
 
@@ -319,7 +339,7 @@
319
339
  * `before:destroy`: (Array of functions)
320
340
  * `after:destroy`: (Array of functions)
321
341
  * `plugins`: (Object)
322
- * `LiveDom`: (Boolean)
342
+ * `LiveDOM`: (Boolean)
323
343
  * returns the newly create `MODEL`
324
344
 
325
345
  `new LiveRecord.Model.all.MODELNAME(ATTRIBUTES)`
@@ -367,3 +387,12 @@
367
387
  * `CALLBACKKEY` (String) see supported callbacks above
368
388
  * `CALLBACKFUNCTION` (function Object) the function callback that will be removed
369
389
  * returns the function Object if successfully removed, else returns `false` if callback is already removed
390
+
391
+ ## TODOs
392
+ * Change `feature` specs into `system` specs after [this rspec-rails pull request](https://github.com/rspec/rspec-rails/pull/1813) gets merged.
393
+
394
+ ## Contributing
395
+ * pull requests and forks are very much welcomed! :) Let me know if you find any bug! Thanks
396
+
397
+ ## License
398
+ * MIT
@@ -1,8 +1,7 @@
1
1
  this.LiveRecord.plugins.LiveDOM || (this.LiveRecord.plugins.LiveDOM = {});
2
2
 
3
- if (window.jQuery === undefined) {
4
- throw new Error('jQuery is not loaded yet, and is a dependency of LiveRecord')
5
- }
3
+ if window.jQuery == undefined
4
+ throw new Error('jQuery is not loaded yet, and is a dependency of LiveRecord')
6
5
 
7
6
  LiveRecord.plugins.LiveDOM.applyToModel = (Model, pluginValue) ->
8
7
  return if pluginValue != true
data/lib/live_record.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  require 'rails'
2
+ require 'rails/generators'
2
3
  require 'active_support/concern'
3
4
 
4
5
  Dir[__dir__ + '/live_record/*.rb'].each {|file| require file }
6
+ Dir[__dir__ + '/live_record/model/*.rb'].each {|file| require file }
7
+ Dir[__dir__ + '/live_record/channel/*.rb'].each {|file| require file }
5
8
  Dir[__dir__ + '/live_record/generators/*.rb'].each {|file| require file }
6
9
 
7
10
  module LiveRecord
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format=documentation
@@ -1,8 +1,6 @@
1
1
  module LiveRecord
2
2
  module Channel
3
- extend ActiveSupport::Concern
4
-
5
- included do
3
+ module Implement
6
4
  def subscribed
7
5
  find_record_from_params(params) do |record|
8
6
  authorised_attributes = authorised_attributes(record, current_user)
@@ -97,7 +95,6 @@ module LiveRecord
97
95
  transmit error: { 'code' => 'bad_request', 'message' => (message || 'Invalid request parameters') }
98
96
  end
99
97
  end
100
-
101
98
  end
102
99
  end
103
100
  end
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+
3
+ Bundler.require :default, :development
4
+
5
+ require 'live_record'
6
+ require 'action_cable/engine'
7
+
8
+ Combustion.initialize! :all
9
+
10
+ run Combustion::Application
@@ -37,12 +37,6 @@ module LiveRecord
37
37
  template 'live_record_channel.rb', File.join('app/channels', 'live_record_channel.rb')
38
38
  end
39
39
 
40
- def update_application_record
41
- in_root do
42
- insert_into_file 'app/models/application_record.rb', " include LiveRecord::Model\n", after: "self.abstract_class = true\n"
43
- end
44
- end
45
-
46
40
  def update_application_javascript
47
41
  in_root do
48
42
  insert_into_file 'app/assets/javascripts/application.js', "//= require live_record\n", before: "//= require_tree ."