tablets 1.1.0 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5e96cdb1c2b3d97a936ff7d2c8f9db941468990
4
- data.tar.gz: 5337d9aa657c9c69aa82281778f0fe2316837a4c
3
+ metadata.gz: a1b6c2a3367aa2d3d1a85c849259390a61bd66e9
4
+ data.tar.gz: '093dd43af37ae99f4f5997da3f166af019adf33a'
5
5
  SHA512:
6
- metadata.gz: 90d6403fb216b57abf8e4284f82295ee946b3abce57d5b456f0cfbc2fa343d52ded1c741e71f37d10c3f4e5e0efda68c290dac6e3351469c93328189b2125726
7
- data.tar.gz: c991fccc8065312bf592cdd23f587da5007852c7981187b539e28cab8f6987fd91362c1c53afb0d9ff7f8baec4af0ed1b4c8df649ed320c8a94f65021c012a01
6
+ metadata.gz: 89467c8e0d974dc4763b45752b46ba498af5b48a7bb3db41d4b6120072f5a961482014ede0bca39a7004ef1cb11fb8049c646926cd6816be592341a0802201c0
7
+ data.tar.gz: 57640ae54b8fea65a99457eb403a4243ddec1f9f832d3e7a1b333aad4283a16cc3ee62a3f181efe2361963403628cafd28b144e0ad4870f0deba49c9322eba5e
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/tablets.svg)](http://badge.fury.io/rb/tablets)
4
4
  [![Code Climate](https://codeclimate.com/github/zenedge/tablets/badges/gpa.svg)](https://codeclimate.com/github/zenedge/tablets)
5
+ [![Build Status](https://travis-ci.org/zenedge/tablets.svg?branch=master)](https://travis-ci.org/zenedge/tablets)
5
6
 
6
7
  ## Installation
7
8
 
@@ -36,19 +37,19 @@ mount Tablets::Engine, at: '/tablets'
36
37
  In `app/tablets/posts.rb`:
37
38
 
38
39
  ``` ruby
39
- Tablets.register :posts do
40
+ PostsTablet < Tablets::Base
40
41
  # Authorization logic.
41
- authorize do |controller|
42
+ def authorize(controller)
42
43
  controller.current_user.id == params[:author_id]
43
44
  end
44
45
 
45
46
  # jQuery-datatables options overrides.
46
- options do
47
+ def options
47
48
  { order: [0, 'asc'] }
48
49
  end
49
50
 
50
51
  # Columns definitions.
51
- columns do
52
+ def columns
52
53
  [{
53
54
  title: 'Title',
54
55
  data: :title,
@@ -70,23 +71,23 @@ Tablets.register :posts do
70
71
  end
71
72
 
72
73
  # HTML for details area.
73
- details do |post|
74
+ def details(post)
74
75
  post.content.html_safe
75
76
  end
76
77
 
77
78
  # Process records before extracting data.
78
- process do |posts|
79
+ def process(posts)
79
80
  posts.map { |post| post.use_wrapper }
80
81
  end
81
82
 
82
83
  # Data relation.
83
- relation do |params|
84
+ def relation(params:, **)
84
85
  # Note: users joined to enable ordering.
85
86
  Post.joins(:users).where(user_id: params[:user_id])
86
87
  end
87
88
 
88
89
  # Additional data added to response.
89
- payload do
90
+ def payload
90
91
  { hash_with: 'data' }
91
92
  end
92
93
  end
@@ -10,7 +10,7 @@ module Tablets
10
10
  private
11
11
 
12
12
  def tablet
13
- @tablet ||= Tablets[params[:name].to_sym]
13
+ @tablet ||= Tablets[params[:name].to_s].new
14
14
  end
15
15
 
16
16
  def authorize!
@@ -0,0 +1,65 @@
1
+ module Tablets
2
+ # Incapsulates tablet related information
3
+ class Base
4
+ def self.inherited(child_class)
5
+ tablet_name = child_class.tablet_name
6
+ Tablets.register_tablet(tablet_name, child_class)
7
+ end
8
+
9
+ def self.tablet_name
10
+ name.underscore.sub(/_tablet$/, '')
11
+ end
12
+
13
+ def name
14
+ self.class.tablet_name
15
+ end
16
+
17
+ # Returns general jquery-datatable configuration overrides
18
+ def options
19
+ {}
20
+ end
21
+
22
+ # Determines is user authorized
23
+ def authorize(controller)
24
+ true
25
+ end
26
+
27
+ # Allows to make additional processing before records would be used
28
+ def process(records)
29
+ records
30
+ end
31
+
32
+ # Returns details HTML for the record
33
+ def details(record)
34
+ nil
35
+ end
36
+
37
+ # Returns columns definitions
38
+ def columns
39
+ deduct_columns_from_relation
40
+ end
41
+
42
+ # Returns database relation to fetch data
43
+ def relation(options = {})
44
+ name.camelize.constantize.where(nil)
45
+ end
46
+
47
+ # Returns additional data returned to client
48
+ def payload
49
+ {}
50
+ end
51
+
52
+ private
53
+
54
+ # Returns default columns definititions, deducted from relation
55
+ def deduct_columns_from_relation
56
+ relation.columns.map(&:name).map do |name|
57
+ {
58
+ title: name.humanize.capitalize,
59
+ data: name.to_sym,
60
+ order: name
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end
data/lib/tablets/data.rb CHANGED
@@ -34,7 +34,7 @@ module Tablets
34
34
 
35
35
  # Relation with concretized parameters
36
36
  def concrete_relation
37
- tablet.relation(relation_params, controller)
37
+ tablet.relation(params: relation_params, controller: controller)
38
38
  end
39
39
 
40
40
  # Relation params. Empty hash by default
@@ -3,20 +3,8 @@ module Tablets
3
3
  # Tablets loader
4
4
  # Manages files loading from app tablets directory
5
5
  module Loader
6
- # Unloads tablet
7
- def unload!
8
- @tablets = nil
9
- end
10
-
11
- # Checks if tablet is loading
12
- # Tablets is not loaded only if tablets is nil
13
- def loaded?
14
- !@tablets.nil?
15
- end
16
-
17
6
  # Loads tablets files
18
7
  def load!
19
- @tablets = {}
20
8
  files.each { |file| load file }
21
9
  end
22
10
 
@@ -1,4 +1,4 @@
1
- require 'tablets/tablet'
1
+ require 'tablets/base'
2
2
 
3
3
  module Tablets
4
4
  module Global
@@ -7,18 +7,16 @@ module Tablets
7
7
  module Store
8
8
  extend Forwardable
9
9
 
10
- attr_reader :tablets
11
-
12
10
  def_delegators :tablets, :[]
13
11
 
14
- # Initializes tablet and put tablet into store
15
- #
16
- # Tablets.register(:user) do
17
- # # Tablet configuration.
18
- # end
19
- #
20
- def register(name, &block)
21
- @tablets[name] = Tablets::Tablet.new(name, &block)
12
+ def tablets
13
+ @tablets || {}
14
+ end
15
+
16
+ # put tablet into store
17
+ def register_tablet(name, tablet_class)
18
+ @tablets ||= {}
19
+ @tablets[name] = tablet_class
22
20
  end
23
21
  end
24
22
  end
@@ -20,15 +20,7 @@ module Tablets
20
20
  # Manages tablets loading and cleanup
21
21
  # Also ensures tablets reloading in development environment
22
22
  initializer 'tablets.reloader' do |app|
23
- if app.config.reload_classes_only_on_change
24
- reloader_class.to_prepare(prepend: true) { Tablets.unload! }
25
- else
26
- reloader_class.to_cleanup { Tablets.unload! }
27
- end
28
-
29
- reloader_class.to_prepare do
30
- Tablets.load! unless Tablets.loaded?
31
- end
23
+ reloader_class.to_prepare { Tablets.load! }
32
24
  end
33
25
  end
34
26
  end
@@ -1,8 +1,8 @@
1
1
  module Tablets
2
2
  # Tablets gem version
3
3
  module Version
4
- MAJOR = 1
5
- MINOR = 1
4
+ MAJOR = 2
5
+ MINOR = 0
6
6
  TINY = 0
7
7
  PRE = nil
8
8
 
@@ -12,7 +12,7 @@ module Tablets
12
12
  locals = opts.fetch(:locals, {})
13
13
  initialize_instantly = opts.fetch(:initialize_instantly, false)
14
14
 
15
- Tablets::Renderer.new(Tablets[name], locals, initialize_instantly: initialize_instantly).render(self)
15
+ Tablets::Renderer.new(Tablets[name.to_s].new, locals, initialize_instantly: initialize_instantly).render(self)
16
16
  end
17
17
  end
18
18
  end
data/lib/tablets.rb CHANGED
@@ -13,8 +13,6 @@ end
13
13
 
14
14
  require 'tablets/version'
15
15
 
16
- require 'tablets/tablet'
17
-
18
16
  if defined? Rails
19
17
  require 'tablets/railtie'
20
18
  require 'tablets/engine'
@@ -20,11 +20,12 @@ RSpec.describe Tablets::Data::Processing::Order do
20
20
  context 'simple' do
21
21
  let(:field) { 'field' }
22
22
  let(:direction) { 'DESC' }
23
+ let(:nulls) { 'NULLS LAST' }
23
24
  let(:columns) { [{ order: field }] }
24
25
  let(:values) { [{ column: 0, dir: direction }] }
25
26
 
26
27
  it 'applies order' do
27
- expect(relation).to have_received(:order).with("#{field} #{direction}")
28
+ expect(relation).to have_received(:order).with("#{field} #{direction} #{nulls}")
28
29
  end
29
30
 
30
31
  it 'returns relation' do
@@ -38,7 +39,7 @@ RSpec.describe Tablets::Data::Processing::Order do
38
39
  let(:values) { [{ column: 0 }] }
39
40
 
40
41
  it 'applies order with default direction' do
41
- expect(relation).to have_received(:order).with("#{field} ASC")
42
+ expect(relation).to have_received(:order).with("#{field} ASC NULLS FIRST")
42
43
  end
43
44
 
44
45
  it 'returns relation' do
@@ -49,7 +50,7 @@ RSpec.describe Tablets::Data::Processing::Order do
49
50
  context 'multiple' do
50
51
  let(:orders) do
51
52
  (0..1).map do |index|
52
- { field: "field#{index}", direction: 'DESC' }
53
+ { field: "field#{index}", direction: 'DESC', nulls: 'NULLS LAST' }
53
54
  end
54
55
  end
55
56
  let(:columns) { orders.map { |order| { order: order[:field] } } }
@@ -62,7 +63,7 @@ RSpec.describe Tablets::Data::Processing::Order do
62
63
  it 'applies order' do
63
64
  orders.each do |order|
64
65
  expect(relation).to have_received(:order)
65
- .with("#{order[:field]} #{order[:direction]}")
66
+ .with("#{order[:field]} #{order[:direction]} #{order[:nulls]}")
66
67
  end
67
68
  end
68
69
 
@@ -7,42 +7,6 @@ require 'tablets/global/loader'
7
7
  RSpec.describe Tablets::Global::Loader do
8
8
  subject { Object.new.tap { |object| object.extend(described_class) } }
9
9
 
10
- def self.set_tablets
11
- before do
12
- subject.instance_variable_set(:@tablets, yield)
13
- end
14
- end
15
-
16
- def tablets
17
- subject.instance_variable_get(:@tablets)
18
- end
19
-
20
- describe '#unload!' do
21
- set_tablets { {} }
22
-
23
- before { subject.unload! }
24
-
25
- it 'sets tablets to nil' do
26
- expect(tablets).to be_nil
27
- end
28
- end
29
-
30
- describe '#loaded?' do
31
- context 'if tablets is not nil' do
32
- set_tablets { {} }
33
-
34
- it 'returns true' do
35
- expect(subject.loaded?).to eq(true)
36
- end
37
- end
38
-
39
- context 'if tablets is nil' do
40
- it 'returns false' do
41
- expect(subject.loaded?).to eq(false)
42
- end
43
- end
44
- end
45
-
46
10
  describe '#load!' do
47
11
  let(:files) { %w(file1 file2) }
48
12
  let(:tablets_dir) { 'dir' }
@@ -56,16 +20,10 @@ RSpec.describe Tablets::Global::Loader do
56
20
  allow(subject).to receive(:load)
57
21
  end
58
22
 
59
- before { subject.load! }
60
-
61
- it 'sets tablets to empty hash' do
62
- expect(tablets).to eq({})
63
- end
64
-
65
- it 'loads each file' do
66
- files.each do |file|
67
- expect(subject).to have_received(:load).with(file)
68
- end
23
+ it 'loads files from tablets directory' do
24
+ expect(subject).to receive(:load).with 'file1'
25
+ expect(subject).to receive(:load).with 'file2'
26
+ subject.load!
69
27
  end
70
28
  end
71
29
  end
@@ -7,20 +7,13 @@ RSpec.describe Tablets::Global::Store do
7
7
 
8
8
  describe '#register' do
9
9
  let(:name) { :posts }
10
- let(:block) { proc {} }
11
10
  let(:tablet) { double }
12
11
 
13
12
  before do
14
13
  subject.instance_eval { @tablets = {} }
15
- allow(Tablets::Tablet).to receive(:new)
16
- .with(name, &block).and_return(tablet)
17
14
  end
18
15
 
19
- let!(:result) { subject.register(name, &block) }
20
-
21
- it 'initializes tablet' do
22
- expect(Tablets::Tablet).to have_received(:new).with(name, &block)
23
- end
16
+ let!(:result) { subject.register_tablet(name, tablet) }
24
17
 
25
18
  it 'stores tablet' do
26
19
  expect(subject.tablets).to eq(name => tablet)
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ require 'tablets'
4
+
5
+ require 'tablets/base'
6
+
7
+ RSpec.describe Tablets::Base do
8
+ class PostTablet < Tablets::Base; end
9
+
10
+ subject { PostTablet.new }
11
+
12
+ describe '#name' do
13
+ let(:result) { subject.name }
14
+
15
+ it 'returns tablet name' do
16
+ expect(result).to eq('post')
17
+ end
18
+ end
19
+
20
+ describe '#options' do
21
+ let(:result) { subject.options }
22
+
23
+ it 'returns tablet options' do
24
+ expect(result).to eq({})
25
+ end
26
+ end
27
+
28
+ describe '#authorize' do
29
+ let(:result) { subject.authorize(nil) }
30
+
31
+ it 'returns tablet authorization response' do
32
+ expect(result).to eq(true)
33
+ end
34
+ end
35
+
36
+ describe '#process' do
37
+ let(:result) { subject.process([1, 2]) }
38
+
39
+ it 'returns tablet processings' do
40
+ expect(result).to eq([1, 2])
41
+ end
42
+ end
43
+
44
+ describe '#details' do
45
+ let(:result) { subject.details(nil) }
46
+
47
+ it 'returns tablet details' do
48
+ expect(result).to eq(nil)
49
+ end
50
+ end
51
+
52
+ describe '#payload' do
53
+ let(:result) { subject.payload }
54
+
55
+ it 'returns tablet payload' do
56
+ expect(result).to eq({})
57
+ end
58
+ end
59
+
60
+ describe '#tablet_name' do
61
+ let(:result) { PostTablet.tablet_name }
62
+
63
+ it 'returns tablet name' do
64
+ expect(result).to eq('post')
65
+ end
66
+ end
67
+ end
@@ -9,15 +9,16 @@ RSpec.describe Tablets::ViewHelpers do
9
9
 
10
10
  describe '#render_tablet' do
11
11
  let(:name) { :name }
12
- let(:params) { 'params' }
12
+ let(:params) { {} }
13
+ let(:initialize_param) { { initialize_instantly: false } }
13
14
  let(:tablet) { double }
14
15
  let(:renderer) { double }
15
16
  let(:render_result) { 'render_result' }
16
17
 
17
18
  before do
18
- allow(Tablets).to receive(:[]).with(name).and_return(tablet)
19
+ allow(Tablets).to receive_message_chain(:[], :new).and_return(tablet)
19
20
  allow(Tablets::Renderer).to receive(:new)
20
- .with(tablet, params).and_return(renderer)
21
+ .with(tablet, params, initialize_param).and_return(renderer)
21
22
  allow(renderer).to receive(:render)
22
23
  .with(subject).and_return(render_result)
23
24
  end
@@ -25,11 +26,11 @@ RSpec.describe Tablets::ViewHelpers do
25
26
  let!(:result) { subject.render_tablet(name, params) }
26
27
 
27
28
  it 'finds tablet' do
28
- expect(Tablets).to have_received(:[]).with(name)
29
+ expect(Tablets).to have_received(:[]).with(name.to_s)
29
30
  end
30
31
 
31
32
  it 'initializes renderer' do
32
- expect(Tablets::Renderer).to have_received(:new).with(tablet, params)
33
+ expect(Tablets::Renderer).to have_received(:new).with(tablet, params, initialize_param)
33
34
  end
34
35
 
35
36
  it 'renders in current view context' do
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tablets
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
+ - Ramunas Cvirka
7
8
  - Yevhen Shemet
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2016-08-11 00:00:00.000000000 Z
12
+ date: 2018-03-19 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rails
@@ -96,7 +97,7 @@ dependencies:
96
97
  version: 0.30.1
97
98
  description:
98
99
  email:
99
- - yevhene@gmail.com
100
+ - rcvirka@zenedge.com
100
101
  executables: []
101
102
  extensions: []
102
103
  extra_rdoc_files: []
@@ -113,6 +114,7 @@ files:
113
114
  - app/views/tablets/_tablet.html.erb
114
115
  - config/routes.rb
115
116
  - lib/tablets.rb
117
+ - lib/tablets/base.rb
116
118
  - lib/tablets/data.rb
117
119
  - lib/tablets/data/processing/base.rb
118
120
  - lib/tablets/data/processing/filter.rb
@@ -125,7 +127,6 @@ files:
125
127
  - lib/tablets/global/store.rb
126
128
  - lib/tablets/railtie.rb
127
129
  - lib/tablets/renderer.rb
128
- - lib/tablets/tablet.rb
129
130
  - lib/tablets/utils/config.rb
130
131
  - lib/tablets/utils/search_condition_builder.rb
131
132
  - lib/tablets/version.rb
@@ -139,7 +140,7 @@ files:
139
140
  - spec/lib/tablets/global/loader_spec.rb
140
141
  - spec/lib/tablets/global/store_spec.rb
141
142
  - spec/lib/tablets/renderer_spec.rb
142
- - spec/lib/tablets/tablet_spec.rb
143
+ - spec/lib/tablets/tablets_base_spec.rb
143
144
  - spec/lib/tablets/utils/config_spec.rb
144
145
  - spec/lib/tablets/utils/search_condition_builder_spec.rb
145
146
  - spec/lib/tablets/view_helpers_spec.rb
@@ -164,22 +165,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
165
  version: '0'
165
166
  requirements: []
166
167
  rubyforge_project:
167
- rubygems_version: 2.4.8
168
+ rubygems_version: 2.5.2
168
169
  signing_key:
169
170
  specification_version: 4
170
171
  summary: Wrapper around jquery-datatables.
171
172
  test_files:
173
+ - spec/lib/tablets/data/processing/paginate_spec.rb
172
174
  - spec/lib/tablets/data/processing/base_spec.rb
173
175
  - spec/lib/tablets/data/processing/filter_spec.rb
174
176
  - spec/lib/tablets/data/processing/order_spec.rb
175
- - spec/lib/tablets/data/processing/paginate_spec.rb
176
177
  - spec/lib/tablets/data/query_spec.rb
178
+ - spec/lib/tablets/view_helpers_spec.rb
177
179
  - spec/lib/tablets/global/configurator_spec.rb
178
- - spec/lib/tablets/global/loader_spec.rb
179
180
  - spec/lib/tablets/global/store_spec.rb
181
+ - spec/lib/tablets/global/loader_spec.rb
182
+ - spec/lib/tablets/tablets_base_spec.rb
180
183
  - spec/lib/tablets/renderer_spec.rb
181
- - spec/lib/tablets/tablet_spec.rb
182
- - spec/lib/tablets/utils/config_spec.rb
183
184
  - spec/lib/tablets/utils/search_condition_builder_spec.rb
184
- - spec/lib/tablets/view_helpers_spec.rb
185
+ - spec/lib/tablets/utils/config_spec.rb
185
186
  - spec/spec_helper.rb
@@ -1,86 +0,0 @@
1
- require 'tablets/utils/config'
2
-
3
- module Tablets
4
- # Incapsulates tablet related information
5
- class Tablet
6
- attr_reader :name
7
-
8
- # Initializes tablet with name, callbacks fed with block
9
- def initialize(name, &block)
10
- @name = name
11
- @config = Tablets::Utils::Config.new(&block)
12
- end
13
-
14
- # Returns general jquery-datatable configuration overrides
15
- # By default returns empty options
16
- def options
17
- call(:options) { {} }
18
- end
19
-
20
- # Determines is user authorized
21
- # By default returns true
22
- def authorize(controller)
23
- call(:authorize, controller) { true }
24
- end
25
-
26
- # Allows to make additional processing before records would be used
27
- # By default returns records
28
- def process(records)
29
- call(:process, records) { records }
30
- end
31
-
32
- # Returns details HTML for the record
33
- # By default returns nil
34
- def details(record)
35
- call(:details, record) { nil }
36
- end
37
-
38
- # Returns columns definitions
39
- # By default deduct columns from relation
40
- def columns
41
- call(:columns) { deduct_columns_from_relation }
42
- end
43
-
44
- # Returns database relation to fetch data
45
- # By default tries to deduct class from tablet name
46
- def relation(params = {}, controller = nil)
47
- if defined? @name.singularize.camelize.constantize
48
- call(:relation, params, controller) do
49
- @name.camelize.constantize.where(nil)
50
- end
51
- else
52
- call(:relation, params, controller)
53
- end
54
- end
55
-
56
- # Returns additional data returned to client
57
- def payload
58
- call(:payload) { {} }
59
- end
60
-
61
- # Checks if config has callback with specified name
62
- def has?(name)
63
- @config.has?(name)
64
- end
65
-
66
- private
67
-
68
- # Returns default columns definititions, deducted from relation
69
- def deduct_columns_from_relation
70
- relation.columns.map(&:name).map do |name|
71
- {
72
- title: name.humanize.capitalize,
73
- data: name.to_sym,
74
- order: name
75
- }
76
- end
77
- end
78
-
79
- # Calls callback and clarifies error message on error
80
- def call(callback, *params, &block)
81
- @config.call(callback, *params, &block)
82
- rescue ArgumentError
83
- raise ArgumentError, "Please define #{callback} for '#{name}' tablet."
84
- end
85
- end
86
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'tablets'
4
-
5
- require 'tablets/tablet'
6
-
7
- RSpec.describe Tablets::Tablet do
8
- let(:name) { 'example' }
9
- let(:block) { proc {} }
10
-
11
- subject { described_class.new(name, &block) }
12
-
13
- def self.define(callback, value)
14
- let(:block) do
15
- proc { send(callback) { value } }
16
- end
17
- end
18
-
19
- context '#relation' do
20
- context 'if configured' do
21
- define(:relation, 'relation')
22
-
23
- let!(:result) { subject.relation }
24
-
25
- it 'return column configuration' do
26
- expect(result).to eq('relation')
27
- end
28
- end
29
- end
30
-
31
- context '#columns' do
32
- context 'if configured' do
33
- define(:columns, 'columns')
34
-
35
- let!(:result) { subject.columns }
36
-
37
- it 'return column configuration' do
38
- expect(result).to eq('columns')
39
- end
40
- end
41
- end
42
- end