admino 0.0.12 → 0.0.13

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: c4eb78eff1dce04c14a06aaa131711c1b9041045
4
- data.tar.gz: 2e30ce30aea3d5d2c7997560ef2440fdd7dc6eac
3
+ metadata.gz: 02804bb71709b2b990d69c156f4bc6e1c1598a13
4
+ data.tar.gz: 1cf458d64706709d71ab562730c4b7bfff9e5db9
5
5
  SHA512:
6
- metadata.gz: 093b7d660f83546c7df47b8227105c2874cc2a37e611c902c068d083692998f436ed44c91bab10c5d7e8e3ee0d4e31c1a60a8f7f9e35a2377d2d7be7496d6fed
7
- data.tar.gz: 409a2614cf6fbe3d024f1424e6e893ec7b7d7f3a8673056f90187fe8eeaa18a81522213d8400f4e121baf2ba9fe423c67d3b098e21bd5035eb0c2e092864978c
6
+ metadata.gz: afe27118fbab995ae04dbd9dad10495a347259d601fb375d6c9eceb950b94cf5fcac1f46b5a240f219f556fa99cebb902f23b7832eee6c0fc930af19c171e21b
7
+ data.tar.gz: 62e10b186cab528cf6227415b1b1a4a374475220952c157748799efa09de2a88722927f509ba5d2a194faffcc2a0ad3b7a8a8e0dbae627ac66efda91afaa1874
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Admino
1
+ ![Admino Logo](https://raw.github.com/cantierecreativo/admino/master/logo.jpg)
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/admino.png)](http://badge.fury.io/rb/admino)
4
4
  [![Build Status](https://travis-ci.org/cantierecreativo/admino.png?branch=v0.0.1)](https://travis-ci.org/cantierecreativo/admino)
@@ -222,14 +222,11 @@ sorting.ascending? # => true
222
222
 
223
223
  ### Presenting search form and filters to the user
224
224
 
225
- Admino also offers a [Showcase presenter](https://github.com/stefanoverna/showcase) that makes it really easy to generate search forms and filtering links:
225
+ Admino offers some helpers that make it really easy to generate search forms and filtering links:
226
226
 
227
227
  ```erb
228
- <%# instanciate the the query object presenter %>
229
- <% query = present(@query) %>
230
-
231
228
  <%# generate the search form %>
232
- <%= query.form do |q| %>
229
+ <%= search_form_for(query) do |q| %>
233
230
  <p>
234
231
  <%= q.label :title_matches %>
235
232
  <%= q.text_field :title_matches %>
@@ -240,13 +237,11 @@ Admino also offers a [Showcase presenter](https://github.com/stefanoverna/showca
240
237
  <% end %>
241
238
 
242
239
  <%# generate the filtering links %>
243
- <% query.filter_groups.each do |filter_group| %>
240
+ <% filters_for(query) do |filter_group| %>
244
241
  <h6><%= filter_group.name %></h6>
245
242
  <ul>
246
- <% filter_group.scopes.each do |scope| %>
247
- <li>
248
- <%= filter_group.scope_link(scope) %>
249
- <li>
243
+ <% filter_group.each_scope do |scope| %>
244
+ <li><%= scope.link %><li>
250
245
  <% end %>
251
246
  </ul>
252
247
  <% end %>
@@ -254,14 +249,11 @@ Admino also offers a [Showcase presenter](https://github.com/stefanoverna/showca
254
249
  <%# generate the sorting links %>
255
250
  <h6>Sort by</h6>
256
251
  <ul>
257
- <% query.sorting.scopes.each do |scope| %>
258
- <li>
259
- <%= query.sorting.scope_link(scope) %>
260
- </li>
252
+ <% sortings_for(query) do |scope| %>
253
+ <li><%= scope.link %></li>
261
254
  <% end %>
262
255
  </ul>
263
256
  ```
264
-
265
257
  The great thing is that:
266
258
 
267
259
  * the search form gets automatically filled in with the last input the user submitted
@@ -272,20 +264,19 @@ The great thing is that:
272
264
 
273
265
  ### Simple Form support
274
266
 
275
- The presenter also offers a `#simple_form` method to make it work with [Simple Form](https://github.com/plataformatec/simple_form) out of the box.
267
+ If you prefer using [Simple Form](https://github.com/plataformatec/simple_form), please use the `simple_search_form_for` helper instead.
276
268
 
277
269
  ### Output customization
278
270
 
279
- The `#scope_link` methods are very flexible, allowing you to change almost every aspect of the generated links:
271
+ The `#link` methods are very flexible, allowing you to change almost every aspect of the generated links:
280
272
 
281
273
  ```erb
282
- <% status_filter = query.filter_group_by_name(:status) %>
283
-
284
- <%= status_filter.scope_link :completed,
285
- 'Custom title',
286
- active_class: 'active',
287
- class: 'custom-class'
288
- %>
274
+ <% filter_group.each_scope do |scope| %>
275
+ <li><%= scope.link 'Custom title',
276
+ active_class: 'active',
277
+ class: 'custom-class'
278
+ %><li>
279
+ <% end %>
289
280
  ```
290
281
 
291
282
  Please refer to the tests for the details.
@@ -374,10 +365,10 @@ en:
374
365
 
375
366
  ## Admino::Table::Presenter
376
367
 
377
- Admino offers a [Showcase collection presenter](https://github.com/stefanoverna/showcase) that makes it really easy to generate HTML tables from a set of records:
368
+ Admino offers a `table_for` helper that makes it really easy to generate HTML tables from a set of records:
378
369
 
379
370
  ```erb
380
- <%= Admino::Table::Presenter.new(@tasks, Task, self).to_html do |row, record| %>
371
+ <%= table_for(@tasks, class: Task) do |row, record| %>
381
372
  <%= row.column :title %>
382
373
  <%= row.column :completed do %>
383
374
  <%= record.completed ? '✓' : '✗' %>
@@ -386,6 +377,8 @@ Admino offers a [Showcase collection presenter](https://github.com/stefanoverna/
386
377
  <% end %>
387
378
  ```
388
379
 
380
+ With produces the following output:
381
+
389
382
  ```html
390
383
  <table>
391
384
  <thead>
@@ -410,10 +403,10 @@ Admino offers a [Showcase collection presenter](https://github.com/stefanoverna/
410
403
 
411
404
  ### Record actions
412
405
 
413
- Often tables need to offer some kind of action associated with the records. The presenter implements the following DSL to support that:
406
+ Often tables need to offer some kind of action associated with the records. The table builder implements the following DSL to support that:
414
407
 
415
408
  ```erb
416
- <%= Admino::Table::Presenter.new(@tasks, Task, self).to_html do |row, record| %>
409
+ <%= table_for(@tasks, class: Task) do |row, record| %>
417
410
  <%# ... %>
418
411
  <%= row.actions do %>
419
412
  <%= row.action :show, admin_task_path(record) %>
@@ -459,7 +452,7 @@ You can then pass the query object as a parameter to the table presenter initial
459
452
  ```erb
460
453
  <% query = present(@query) %>
461
454
 
462
- <%= Admino::Table::Presenter.new(@tasks, Task, query, self).to_html do |row, record| %>
455
+ <%= table_for(@tasks, class: Task) do |row, record| %>
463
456
  <%= row.column :title, sorting: :by_title %>
464
457
  <%= row.column :due_date, sorting: :by_due_date %>
465
458
  <% end %>
@@ -488,7 +481,7 @@ This generates links that allow the visitor to sort the result set in ascending
488
481
  The `#column` and `#action` methods are very flexible, allowing you to change almost every aspect of the generated table cells:
489
482
 
490
483
  ```erb
491
- <%= Admino::Table::Presenter.new(@tasks, Task, self).to_html(class: 'table-class') do |row, record| %>
484
+ <%= table_for(@tasks, class: Task, html: { class: 'table-class' }) do |row, record| %>
492
485
  <%= row.column :title, 'Custom title',
493
486
  class: 'custom-class', role: 'custom-role', data: { custom: 'true' },
494
487
  sorting: :by_title, sorting_html_options: { desc_class: 'down' }
@@ -550,6 +543,18 @@ class CustomTablePresenter < Admino::Table::Presenter
550
543
  end
551
544
  ```
552
545
 
546
+ ```erb
547
+ <%= table_for(@tasks, class: Task, presenter: CustomTablePresenter) do |row, record| %>
548
+ <%= row.column :title, 'Custom title',
549
+ class: 'custom-class', role: 'custom-role', data: { custom: 'true' },
550
+ sorting: :by_title, sorting_html_options: { desc_class: 'down' }
551
+ %>
552
+ <%= row.action :show, admin_task_path(record), 'Custom label',
553
+ class: 'custom-class', role: 'custom-role', data: { custom: 'true' }
554
+ %>
555
+ <% end %>
556
+ ```
557
+
553
558
  Please refer to the tests for all the details.
554
559
 
555
560
  ### Inherited resources (and similar)
@@ -589,7 +594,7 @@ end
589
594
  This will enable you to generate row actions even faster, simply declaring them as arguments to the `#actions` DSL method:
590
595
 
591
596
  ```erb
592
- <%= CustomTablePresenter.new(@tasks, Task, self).to_html do |row, record| %>
597
+ <%= table_for(@tasks, class: Task, presenter: CustomTablePresenter) do |row, record| %>
593
598
  <%# ... %>
594
599
  <%= row.actions :show, :edit, :destroy %>
595
600
  <% end %>
data/admino.gemspec CHANGED
@@ -30,5 +30,6 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency 'i18n'
31
31
  spec.add_development_dependency 'rspec-html-matchers'
32
32
  spec.add_development_dependency 'actionpack'
33
+ spec.add_development_dependency 'simple_form'
33
34
  end
34
35
 
data/lib/admino.rb CHANGED
@@ -3,7 +3,12 @@ require 'active_support/core_ext/module/delegation'
3
3
  require "admino/version"
4
4
  require "admino/query"
5
5
  require "admino/table"
6
+ require "admino/action_view_extension"
6
7
 
7
8
  module Admino
8
9
  end
9
10
 
11
+ ActiveSupport.on_load(:action_view) do
12
+ include Admino::ActionViewExtension
13
+ end
14
+
@@ -0,0 +1,48 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'admino/table/presenter'
3
+ require 'admino/query/base_presenter'
4
+
5
+ module Admino
6
+ module ActionViewExtension
7
+ module Internals
8
+ def self.present_query(query, context, options)
9
+ presenter_klass = options.fetch(:presenter, Admino::Query::BasePresenter)
10
+ presenter_klass.new(query, context)
11
+ end
12
+ end
13
+
14
+ def table_for(collection, options = {}, &block)
15
+ options.symbolize_keys!
16
+ options.assert_valid_keys(:presenter, :class, :html)
17
+ presenter_klass = options.fetch(:presenter, Admino::Table::Presenter)
18
+ presenter = presenter_klass.new(collection, options[:class], self)
19
+ html_options = options.fetch(:html, {})
20
+ presenter.to_html(html_options, &block)
21
+ end
22
+
23
+ def filters_for(query, options = {}, &block)
24
+ options.symbolize_keys!
25
+ options.assert_valid_keys(:presenter)
26
+ Internals.present_query(query, self, options).filter_groups.each(&block)
27
+ end
28
+
29
+ def sortings_for(query, options = {}, &block)
30
+ options.symbolize_keys!
31
+ options.assert_valid_keys(:presenter)
32
+ Internals.present_query(query, self, options).sorting.scopes.each(&block)
33
+ end
34
+
35
+ def search_form_for(query, options = {}, &block)
36
+ options.symbolize_keys!
37
+ options.assert_valid_keys(:presenter)
38
+ Internals.present_query(query, self, options).form(&block)
39
+ end
40
+
41
+ def simple_search_form_for(query, options = {}, &block)
42
+ options.symbolize_keys!
43
+ options.assert_valid_keys(:presenter)
44
+ Internals.present_query(query, self, options).simple_form(&block)
45
+ end
46
+ end
47
+ end
48
+
data/lib/admino/query.rb CHANGED
@@ -6,6 +6,7 @@ require 'admino/query/filter_group'
6
6
  require 'admino/query/filter_group_presenter'
7
7
  require 'admino/query/sorting'
8
8
  require 'admino/query/sorting_presenter'
9
+ require 'admino/query/scope_presenter'
9
10
 
10
11
  module Admino
11
12
  module Query
@@ -24,6 +24,16 @@ module Admino
24
24
  h.link_to label, scope_path(scope), options.to_h
25
25
  end
26
26
 
27
+ def scopes
28
+ @scopes ||= super.map do |scope|
29
+ ScopePresenter.new(scope, self, view_context)
30
+ end
31
+ end
32
+
33
+ def each_scope(&block)
34
+ scopes.each(&block)
35
+ end
36
+
27
37
  def scope_path(scope)
28
38
  h.request.path + "?" + scope_params(scope).to_query
29
39
  end
@@ -0,0 +1,17 @@
1
+ require 'showcase'
2
+
3
+ module Admino
4
+ module Query
5
+ class ScopePresenter < Showcase::Presenter
6
+ def initialize(object, parent, view_context)
7
+ super(object, view_context)
8
+ @parent = parent
9
+ end
10
+
11
+ def link(*args)
12
+ @parent.scope_link(object, *args)
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -25,6 +25,12 @@ module Admino
25
25
  h.request.path + "?" + scope_params(scope).to_query
26
26
  end
27
27
 
28
+ def scopes
29
+ @scopes ||= super.map do |scope|
30
+ ScopePresenter.new(scope, self, view_context)
31
+ end
32
+ end
33
+
28
34
  def scope_params(scope)
29
35
  params = ActiveSupport::HashWithIndifferentAccess.new(
30
36
  h.request.query_parameters.deep_dup
@@ -34,12 +34,22 @@ module Admino
34
34
  collection = args.shift
35
35
 
36
36
  @collection_klass = args.shift
37
+
38
+ if !@collection_klass && !collection.empty?
39
+ @collection_klass = collection.first.class
40
+ end
41
+
37
42
  @query = args.shift
38
43
 
39
44
  super(collection, context)
40
45
  end
41
46
 
42
47
  def to_html(options = {}, &block)
48
+
49
+ if @collection_klass.nil?
50
+ raise ArgumentError, 'collection is empty and no explicit class is specified'
51
+ end
52
+
43
53
  table_tag(options) do
44
54
  thead_tag do
45
55
  thead_tr_tag do
@@ -1,4 +1,4 @@
1
1
  module Admino
2
- VERSION = "0.0.12"
2
+ VERSION = "0.0.13"
3
3
  end
4
4
 
data/logo.jpg ADDED
Binary file
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Action View integration' do
4
+ let(:context) { RailsViewContext.new }
5
+
6
+ describe '#simple_table_for' do
7
+ let(:collection) { [ first_post, second_post ] }
8
+ let(:first_post) { Post.new('1') }
9
+ let(:second_post) { Post.new('2') }
10
+
11
+ it 'produces HTML' do
12
+ result = context.table_for(collection) do |table, record|
13
+ table.column :title
14
+ table.actions do
15
+ table.action :show, '/foo', 'Show'
16
+ end
17
+ end
18
+ expect(result).to eq <<-HTML.strip
19
+ <table><thead><tr><th role=\"title\">Title</th><th role=\"actions\">Actions</th></tr></thead><tbody><tr class=\"is-even\"><td role=\"title\">Post 1</td><td role=\"actions\"><a href=\"/foo\" role=\"show\">Show</a></td></tr><tr class=\"is-odd\"><td role=\"title\">Post 2</td><td role=\"actions\"><a href=\"/foo\" role=\"show\">Show</a></td></tr></tbody></table>
20
+ HTML
21
+ end
22
+ end
23
+
24
+ describe '#filters_for' do
25
+ let(:params) {
26
+ {
27
+ query: { bar: 'one' }
28
+ }
29
+ }
30
+ let(:query) { TestQuery.new(params) }
31
+
32
+ it 'produces HTML' do
33
+ result = ""
34
+ context.filters_for(query) do |group|
35
+ result << "#{group.name}: "
36
+ group.each_scope do |scope|
37
+ result << scope.link
38
+ end
39
+ end
40
+
41
+ expect(result).to eq <<-HTML.strip
42
+ Bar: <a href="/?query%5Bbar%5D=empty">Empty</a><a class="is-active" href="/?">One</a><a href="/?query%5Bbar%5D=two">Two</a>
43
+ HTML
44
+ end
45
+ end
46
+
47
+ describe '#sortings_for' do
48
+ let(:params) {
49
+ {
50
+ sorting: 'by_title',
51
+ sort_order: 'desc'
52
+ }
53
+ }
54
+ let(:query) { TestQuery.new(params) }
55
+
56
+ it 'produces HTML' do
57
+ result = ""
58
+ context.sortings_for(query) do |scope|
59
+ result << scope.link
60
+ end
61
+
62
+ expect(result).to eq <<-HTML.strip
63
+ <a class=\"is-desc\" href=\"/?sort_order=asc&amp;sorting=by_title\">By title</a><a href=\"/?sort_order=asc&amp;sorting=by_date\">By date</a>
64
+ HTML
65
+ end
66
+ end
67
+
68
+ describe '#search_form_for' do
69
+ let(:params) {
70
+ {
71
+ query: { foo: 'test' }
72
+ }
73
+ }
74
+ let(:query) { TestQuery.new(params) }
75
+
76
+ it 'produces HTML' do
77
+ result = context.search_form_for(query) do |f|
78
+ f.text_field :foo
79
+ end
80
+
81
+ expect(result).to eq <<-HTML.strip
82
+ <form accept-charset=\"UTF-8\" action=\"/?p=1\" class=\"new_query\" id=\"new_query\" method=\"get\"><div style=\"display:none\"><input name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /></div><input id=\"query_foo\" name=\"query[foo]\" type=\"text\" value=\"test\" /></form>
83
+ HTML
84
+ end
85
+ end
86
+
87
+ describe '#simple_search_form_for' do
88
+ let(:params) {
89
+ {
90
+ query: { foo: 'test' }
91
+ }
92
+ }
93
+ let(:query) { TestQuery.new(params) }
94
+
95
+ it 'produces HTML' do
96
+ result = context.simple_search_form_for(query) do |f|
97
+ f.input :foo
98
+ end
99
+
100
+ expect(result).to eq <<-HTML.strip
101
+ <form accept-charset=\"UTF-8\" action=\"/?p=1\" class=\"simple_form new_query\" id=\"new_query\" method=\"get\"><div style=\"display:none\"><input name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /></div><div class=\"input string required query_foo\"><label class=\"string required\" for=\"query_foo\"><abbr title=\"required\">*</abbr> Foo</label><input aria-required=\"true\" class=\"string required\" id=\"query_foo\" name=\"query[foo]\" required=\"required\" type=\"text\" value=\"test\" /></div></form>
102
+ HTML
103
+ end
104
+ end
105
+ end
106
+
@@ -16,7 +16,7 @@ module Admino
16
16
  end
17
17
 
18
18
  before do
19
- view.stub(:request).and_return(request_object)
19
+ allow(view).to receive(:request).and_return(request_object)
20
20
  end
21
21
 
22
22
  describe '#form' do
@@ -122,17 +122,17 @@ module Admino
122
122
  sorting_config
123
123
  query
124
124
 
125
- query.search_field_by_name(:search_field).
126
- stub(:augment_scope).
125
+ allow(query.search_field_by_name(:search_field)).
126
+ to receive(:augment_scope).
127
127
  with(starting_scope).
128
128
  and_return(scope_chained_with_search_field)
129
129
 
130
- query.filter_group_by_name(:filter_group).
131
- stub(:augment_scope).
130
+ allow(query.filter_group_by_name(:filter_group)).
131
+ to receive(:augment_scope).
132
132
  with(scope_chained_with_search_field).
133
133
  and_return(scope_chained_with_group_filter)
134
134
 
135
- query.sorting.stub(:augment_scope).
135
+ allow(query.sorting).to receive(:augment_scope).
136
136
  with(scope_chained_with_group_filter).
137
137
  and_return(final_chain)
138
138
  end
@@ -16,7 +16,7 @@ module Admino
16
16
  filter_group = config.filter_groups.first
17
17
  expect(filter_group.name).to eq :bar
18
18
  expect(filter_group.scopes).to eq [:one, :two]
19
- expect(filter_group.include_empty_scope?).to be_true
19
+ expect(filter_group.include_empty_scope?).to be_truthy
20
20
  end
21
21
 
22
22
  it 'allows #sortings declaration' do
@@ -38,7 +38,7 @@ module Admino
38
38
  let(:search_field) { double('SearchField', value: 'value') }
39
39
 
40
40
  before do
41
- instance.stub(:search_field_by_name).
41
+ allow(instance).to receive(:search_field_by_name).
42
42
  with(:foo).
43
43
  and_return(search_field)
44
44
  end
@@ -28,7 +28,7 @@ module Admino
28
28
  end
29
29
 
30
30
  before do
31
- view.stub(:request).and_return(request_object)
31
+ allow(view).to receive(:request).and_return(request_object)
32
32
  end
33
33
 
34
34
  describe '#scope_link' do
@@ -36,7 +36,7 @@ module Admino
36
36
  let(:scope_active) { false }
37
37
 
38
38
  before do
39
- filter_group.stub(:is_scope_active?).
39
+ allow(filter_group).to receive(:is_scope_active?).
40
40
  with(:foo).and_return(scope_active)
41
41
  end
42
42
 
@@ -44,49 +44,49 @@ module Admino
44
44
  let(:scope_active) { true }
45
45
 
46
46
  it 'adds an is-active class' do
47
- should have_tag(:a, with: { class: 'is-active' })
47
+ is_expected.to have_tag(:a, with: { class: 'is-active' })
48
48
  end
49
49
 
50
50
  context 'if an :active_class option is specified' do
51
51
  subject { presenter.scope_link(:foo, active_class: 'active') }
52
52
 
53
53
  it 'adds it' do
54
- should have_tag(:a, with: { class: 'active' })
54
+ is_expected.to have_tag(:a, with: { class: 'active' })
55
55
  end
56
56
  end
57
57
  end
58
58
 
59
59
  context 'else' do
60
60
  it 'does not add it' do
61
- should_not have_tag(:a, with: { class: 'is-active' })
61
+ is_expected.not_to have_tag(:a, with: { class: 'is-active' })
62
62
  end
63
63
  end
64
64
 
65
65
  context 'label' do
66
66
  before do
67
- presenter.stub(:scope_name).with(:foo).and_return('scope_name')
67
+ allow(presenter).to receive(:scope_name).with(:foo).and_return('scope_name')
68
68
  end
69
69
 
70
70
  it 'uses #scope_name method' do
71
- should have_tag(:a, text: 'scope_name')
71
+ is_expected.to have_tag(:a, text: 'scope_name')
72
72
  end
73
73
 
74
74
  context 'if a second parameter is supplied' do
75
75
  subject { presenter.scope_link(:foo, 'test', active_class: 'active') }
76
76
 
77
77
  it 'uses it' do
78
- should have_tag(:a, text: 'test')
78
+ is_expected.to have_tag(:a, text: 'test')
79
79
  end
80
80
  end
81
81
  end
82
82
 
83
83
  context 'URL' do
84
84
  before do
85
- presenter.stub(:scope_path).with(:foo).and_return('URL')
85
+ allow(presenter).to receive(:scope_path).with(:foo).and_return('URL')
86
86
  end
87
87
 
88
88
  it 'uses #scope_path method' do
89
- should have_tag(:a, href: 'URL')
89
+ is_expected.to have_tag(:a, href: 'URL')
90
90
  end
91
91
  end
92
92
  end
@@ -96,7 +96,7 @@ module Admino
96
96
  subject { presenter.scope_params(:foo) }
97
97
 
98
98
  before do
99
- filter_group.stub(:is_scope_active?).with(:foo).and_return(scope_active)
99
+ allow(filter_group).to receive(:is_scope_active?).with(:foo).and_return(scope_active)
100
100
  end
101
101
 
102
102
  context 'if scope is active' do
@@ -110,7 +110,7 @@ module Admino
110
110
  let(:params) { { 'query' => { 'foo' => 'bar' } } }
111
111
 
112
112
  it 'returns true if the provided scope is the one currently active' do
113
- expect(filter_group.is_scope_active?('bar')).to be_true
113
+ expect(filter_group.is_scope_active?('bar')).to be_truthy
114
114
  end
115
115
  end
116
116
 
@@ -120,11 +120,11 @@ module Admino
120
120
  context 'if include_empty_scope is true' do
121
121
  let(:options) { { include_empty_scope: true } }
122
122
 
123
- it { should eq [:empty, :bar, :other] }
123
+ it { is_expected.to eq [:empty, :bar, :other] }
124
124
  end
125
125
 
126
126
  context 'else' do
127
- it { should eq [:bar, :other] }
127
+ it { is_expected.to eq [:bar, :other] }
128
128
  end
129
129
  end
130
130
  end
@@ -24,53 +24,53 @@ module Admino
24
24
  end
25
25
 
26
26
  before do
27
- view.stub(:request).and_return(request_object)
27
+ allow(view).to receive(:request).and_return(request_object)
28
28
  end
29
29
 
30
30
  describe '#scope_link' do
31
31
  subject { presenter.scope_link(:by_title, 'Titolo') }
32
32
 
33
33
  before do
34
- sorting.stub(:is_scope_active?).with(:by_title).and_return(false)
34
+ allow(sorting).to receive(:is_scope_active?).with(:by_title).and_return(false)
35
35
  end
36
36
 
37
37
  context 'scope is active' do
38
38
  before do
39
- sorting.stub(:is_scope_active?).with(:by_title).and_return(true)
39
+ allow(sorting).to receive(:is_scope_active?).with(:by_title).and_return(true)
40
40
  end
41
41
 
42
42
  context 'ascending' do
43
43
  before do
44
- sorting.stub(:ascending?).and_return(true)
44
+ allow(sorting).to receive(:ascending?).and_return(true)
45
45
  end
46
46
 
47
47
  it 'adds an is-asc class' do
48
- should have_tag(:a, with: { class: 'is-asc' })
48
+ is_expected.to have_tag(:a, with: { class: 'is-asc' })
49
49
  end
50
50
 
51
51
  context 'if an :asc_class option is specified' do
52
52
  subject { presenter.scope_link(:by_title, 'Titolo', asc_class: 'asc') }
53
53
 
54
54
  it 'adds it' do
55
- should have_tag(:a, with: { class: 'asc' })
55
+ is_expected.to have_tag(:a, with: { class: 'asc' })
56
56
  end
57
57
  end
58
58
  end
59
59
 
60
60
  context 'descendent' do
61
61
  before do
62
- sorting.stub(:ascending?).and_return(false)
62
+ allow(sorting).to receive(:ascending?).and_return(false)
63
63
  end
64
64
 
65
65
  it 'adds an is-desc class' do
66
- should have_tag(:a, with: { class: 'is-desc' })
66
+ is_expected.to have_tag(:a, with: { class: 'is-desc' })
67
67
  end
68
68
 
69
69
  context 'if a :desc_class option is specified' do
70
70
  subject { presenter.scope_link(:by_title, 'Titolo', desc_class: 'desc') }
71
71
 
72
72
  it 'adds it' do
73
- should have_tag(:a, with: { class: 'desc' })
73
+ is_expected.to have_tag(:a, with: { class: 'desc' })
74
74
  end
75
75
  end
76
76
  end
@@ -78,23 +78,23 @@ module Admino
78
78
 
79
79
  context 'else' do
80
80
  it 'does not add it' do
81
- should_not have_tag(:a, with: { class: 'is-asc' })
81
+ is_expected.not_to have_tag(:a, with: { class: 'is-asc' })
82
82
  end
83
83
  end
84
84
 
85
85
  context 'label' do
86
86
  it 'uses the provided argument' do
87
- should have_tag(:a, text: 'Titolo')
87
+ is_expected.to have_tag(:a, text: 'Titolo')
88
88
  end
89
89
  end
90
90
 
91
91
  context 'URL' do
92
92
  before do
93
- presenter.stub(:scope_path).with(:by_title).and_return('URL')
93
+ allow(presenter).to receive(:scope_path).with(:by_title).and_return('URL')
94
94
  end
95
95
 
96
96
  it 'uses #scope_path method' do
97
- should have_tag(:a, href: 'URL')
97
+ is_expected.to have_tag(:a, href: 'URL')
98
98
  end
99
99
  end
100
100
  end
@@ -103,7 +103,7 @@ module Admino
103
103
  subject { presenter.scope_params(:by_title) }
104
104
 
105
105
  before do
106
- sorting.stub(:is_scope_active?).with(:by_title).and_return(false)
106
+ allow(sorting).to receive(:is_scope_active?).with(:by_title).and_return(false)
107
107
  end
108
108
 
109
109
  it 'preserves other params' do
@@ -121,12 +121,12 @@ module Admino
121
121
 
122
122
  context 'scope is active' do
123
123
  before do
124
- sorting.stub(:is_scope_active?).with(:by_title).and_return(true)
124
+ allow(sorting).to receive(:is_scope_active?).with(:by_title).and_return(true)
125
125
  end
126
126
 
127
127
  context 'is currently ascending' do
128
128
  before do
129
- sorting.stub(:ascending?).and_return(true)
129
+ allow(sorting).to receive(:ascending?).and_return(true)
130
130
  end
131
131
 
132
132
  it 'sets the sorting order to descending' do
@@ -136,7 +136,7 @@ module Admino
136
136
 
137
137
  context 'is currently descending' do
138
138
  before do
139
- sorting.stub(:ascending?).and_return(false)
139
+ allow(sorting).to receive(:ascending?).and_return(false)
140
140
  end
141
141
 
142
142
  it 'sets the sorting order to ascending' do
@@ -150,7 +150,7 @@ module Admino
150
150
 
151
151
  context 'default scope is ascending' do
152
152
  before do
153
- sorting.stub(:default_direction).and_return(:asc)
153
+ allow(sorting).to receive(:default_direction).and_return(:asc)
154
154
  end
155
155
 
156
156
  it 'sets the sorting order to ascending' do
@@ -160,7 +160,7 @@ module Admino
160
160
 
161
161
  context 'default scope is descending' do
162
162
  before do
163
- sorting.stub(:default_direction).and_return(:desc)
163
+ allow(sorting).to receive(:default_direction).and_return(:desc)
164
164
  end
165
165
 
166
166
  it 'sets the sorting order to descending' do
@@ -171,7 +171,7 @@ module Admino
171
171
 
172
172
  context 'else' do
173
173
  before do
174
- sorting.stub(:is_scope_active?).with(:by_title).and_return(false)
174
+ allow(sorting).to receive(:is_scope_active?).with(:by_title).and_return(false)
175
175
  end
176
176
 
177
177
  it 'sets the sorting order to ascending' do
@@ -128,7 +128,7 @@ module Admino
128
128
  let(:params) { { 'sorting' => 'by_date' } }
129
129
 
130
130
  it 'returns true if the provided scope is the one currently active' do
131
- expect(sorting.is_scope_active?(:by_date)).to be_true
131
+ expect(sorting.is_scope_active?(:by_date)).to be_truthy
132
132
  end
133
133
  end
134
134
  end
@@ -23,7 +23,7 @@ module Admino
23
23
  end
24
24
 
25
25
  it 'generates a label with it' do
26
- should have_tag(:th, text: 'This is a title')
26
+ is_expected.to have_tag(:th, text: 'This is a title')
27
27
  end
28
28
  end
29
29
 
@@ -40,7 +40,7 @@ module Admino
40
40
  end
41
41
 
42
42
  it 'generates a label with the human attribute name' do
43
- should have_tag(:th, text: 'This is foo')
43
+ is_expected.to have_tag(:th, text: 'This is foo')
44
44
  end
45
45
  end
46
46
 
@@ -48,7 +48,7 @@ module Admino
48
48
  before { row.column(:title) }
49
49
 
50
50
  it 'generates a label with the titleized attribute name' do
51
- should have_tag(:th, text: 'Title')
51
+ is_expected.to have_tag(:th, text: 'Title')
52
52
  end
53
53
 
54
54
  context 'with I18n set up' do
@@ -62,7 +62,7 @@ module Admino
62
62
  before { row.column(:title) }
63
63
 
64
64
  it 'generates a label with the human attribute name' do
65
- should have_tag(:th, text: 'Post title')
65
+ is_expected.to have_tag(:th, text: 'Post title')
66
66
  end
67
67
  end
68
68
  end
@@ -80,14 +80,14 @@ module Admino
80
80
  let(:sorting) { double('Sorting') }
81
81
 
82
82
  before do
83
- sorting.stub(:scope_link).with(:by_title, 'Title', {}).
83
+ allow(sorting).to receive(:scope_link).with(:by_title, 'Title', {}).
84
84
  and_return('Link')
85
85
  end
86
86
 
87
87
  before { row.column(:title, sorting: :by_title) }
88
88
 
89
89
  it 'generates a sorting scope link' do
90
- should have_tag(:th, text: 'Link')
90
+ is_expected.to have_tag(:th, text: 'Link')
91
91
  end
92
92
  end
93
93
  end
@@ -96,7 +96,7 @@ module Admino
96
96
  before { row.column(:author_name) }
97
97
 
98
98
  it 'generates a role attribute with the snake-cased name of the attribute' do
99
- should have_tag(:th, with: { role: 'author-name' })
99
+ is_expected.to have_tag(:th, with: { role: 'author-name' })
100
100
  end
101
101
  end
102
102
 
@@ -104,7 +104,7 @@ module Admino
104
104
  before { row.column(:title, class: 'foo') }
105
105
 
106
106
  it 'uses it to build attributes' do
107
- should have_tag(:th, with: { class: 'foo' })
107
+ is_expected.to have_tag(:th, with: { class: 'foo' })
108
108
  end
109
109
  end
110
110
  end
@@ -116,11 +116,11 @@ module Admino
116
116
  before { row.actions }
117
117
 
118
118
  it 'renders a th cell with role "actions"' do
119
- should have_tag(:th, with: { role: 'actions' })
119
+ is_expected.to have_tag(:th, with: { role: 'actions' })
120
120
  end
121
121
 
122
122
  it 'renders a th cell with text "Actions"' do
123
- should have_tag(:th, text: 'Actions')
123
+ is_expected.to have_tag(:th, text: 'Actions')
124
124
  end
125
125
  end
126
126
 
@@ -134,7 +134,7 @@ module Admino
134
134
 
135
135
  it 'renders a th cell with I18n text' do
136
136
  row.actions
137
- should have_tag(:th, text: 'Available actions')
137
+ is_expected.to have_tag(:th, text: 'Available actions')
138
138
  end
139
139
 
140
140
  context 'and specific I18n set up' do
@@ -147,7 +147,7 @@ module Admino
147
147
 
148
148
  it 'uses the specific I18n text' do
149
149
  row.actions
150
- should have_tag(:th, text: 'Post actions')
150
+ is_expected.to have_tag(:th, text: 'Post actions')
151
151
  end
152
152
  end
153
153
  end
@@ -17,12 +17,12 @@ module Admino
17
17
  let(:resource_row) { double('ResourceRow', to_html: '<td id="tbody_td"></td>'.html_safe) }
18
18
 
19
19
  before do
20
- HeadRow.stub(:new).with(Post, query, view).and_return(head_row)
21
- ResourceRow.stub(:new).with(first_post, view).and_return(resource_row)
22
- ResourceRow.stub(:new).with(second_post, view).and_return(resource_row)
20
+ allow(HeadRow).to receive(:new).with(Post, query, view).and_return(head_row)
21
+ allow(ResourceRow).to receive(:new).with(first_post, view).and_return(resource_row)
22
+ allow(ResourceRow).to receive(:new).with(second_post, view).and_return(resource_row)
23
23
  end
24
24
 
25
- describe '#.to_html' do
25
+ describe '#to_html' do
26
26
  let(:result) { presenter.to_html }
27
27
 
28
28
  it 'outputs a table' do
@@ -39,8 +39,8 @@ module Admino
39
39
 
40
40
  context 'if the record responds to #dom_id' do
41
41
  before do
42
- first_post.stub(:dom_id).and_return('post_1')
43
- second_post.stub(:dom_id).and_return('post_2')
42
+ allow(first_post).to receive(:dom_id).and_return('post_1')
43
+ allow(second_post).to receive(:dom_id).and_return('post_2')
44
44
  end
45
45
 
46
46
  it 'adds a record identifier to each collection row' do
@@ -164,6 +164,15 @@ module Admino
164
164
  expect(presenter.to_html).to have_tag('tbody tr td#custom_tbody_td')
165
165
  end
166
166
  end
167
+
168
+ context 'with empty collection and no collection_klass' do
169
+ let(:collection) { [] }
170
+ subject(:presenter) { presenter_klass.new(collection, nil, query, view) }
171
+
172
+ it 'raises an Exception' do
173
+ expect { result }.to raise_error(ArgumentError)
174
+ end
175
+ end
167
176
  end
168
177
  end
169
178
  end
@@ -21,7 +21,7 @@ module Admino
21
21
  end
22
22
 
23
23
  it 'fills the cell with the block content' do
24
- should have_tag(:td, text: 'foo')
24
+ is_expected.to have_tag(:td, text: 'foo')
25
25
  end
26
26
  end
27
27
 
@@ -29,7 +29,7 @@ module Admino
29
29
  before { row.column(:title) }
30
30
 
31
31
  it 'fills the cell with the attribute value' do
32
- should have_tag(:td, text: 'Post 1')
32
+ is_expected.to have_tag(:td, text: 'Post 1')
33
33
  end
34
34
  end
35
35
 
@@ -43,7 +43,7 @@ module Admino
43
43
  before { row.column(:author_name) }
44
44
 
45
45
  it 'generates a role attribute with the snake-cased name of the attribute' do
46
- should have_tag(:td, with: { role: 'author-name' })
46
+ is_expected.to have_tag(:td, with: { role: 'author-name' })
47
47
  end
48
48
  end
49
49
 
@@ -51,7 +51,7 @@ module Admino
51
51
  before { row.column(:title, class: 'title') }
52
52
 
53
53
  it 'uses it to build attributes' do
54
- should have_tag(:td, with: { class: 'title' })
54
+ is_expected.to have_tag(:td, with: { class: 'title' })
55
55
  end
56
56
 
57
57
  context 'with a class that implements a <action_name>_html_options' do
@@ -65,7 +65,7 @@ module Admino
65
65
  end
66
66
 
67
67
  it 'renders them as attributes' do
68
- should have_tag(:td, with: { class: 'attribute title' })
68
+ is_expected.to have_tag(:td, with: { class: 'attribute title' })
69
69
  end
70
70
  end
71
71
  end
@@ -79,13 +79,13 @@ module Admino
79
79
  called = true
80
80
  end
81
81
 
82
- expect(called).to be_true
82
+ expect(called).to be_truthy
83
83
  end
84
84
  end
85
85
 
86
86
  context 'no block' do
87
87
  before do
88
- row.stub(:action)
88
+ allow(row).to receive(:action)
89
89
  end
90
90
 
91
91
  before do
@@ -107,7 +107,7 @@ module Admino
107
107
  before { row.action(:show, '/') }
108
108
 
109
109
  it 'generates a link with the specified URL' do
110
- should have_tag(:a, with: { href: '/' })
110
+ is_expected.to have_tag(:a, with: { href: '/' })
111
111
  end
112
112
  end
113
113
 
@@ -124,7 +124,7 @@ module Admino
124
124
  before { row.action(:show) }
125
125
 
126
126
  it 'uses a method to build the URL (ie. show_url)' do
127
- should have_tag(:a, with: { href: '/posts/1' })
127
+ is_expected.to have_tag(:a, with: { href: '/posts/1' })
128
128
  end
129
129
  end
130
130
 
@@ -145,7 +145,7 @@ module Admino
145
145
  before { row.action(:show, '/') }
146
146
 
147
147
  it 'generates a td cell with actions role' do
148
- should have_tag(:td, with: { role: 'actions' })
148
+ is_expected.to have_tag(:td, with: { role: 'actions' })
149
149
  end
150
150
  end
151
151
 
@@ -153,7 +153,7 @@ module Admino
153
153
  before { row.action(:show, '/') }
154
154
 
155
155
  it 'generates a link with role' do
156
- should have_tag(:a, with: { role: 'show' })
156
+ is_expected.to have_tag(:a, with: { role: 'show' })
157
157
  end
158
158
  end
159
159
 
@@ -162,7 +162,7 @@ module Admino
162
162
  before { row.action(:show, '/') }
163
163
 
164
164
  it 'generates a link with a titleized attribute' do
165
- should have_tag(:a, text: 'Show')
165
+ is_expected.to have_tag(:a, text: 'Show')
166
166
  end
167
167
  end
168
168
 
@@ -177,7 +177,7 @@ module Admino
177
177
  before { row.action(:show, '/') }
178
178
 
179
179
  it 'generates a I18n text' do
180
- should have_tag(:a, text: 'Show post')
180
+ is_expected.to have_tag(:a, text: 'Show post')
181
181
  end
182
182
  end
183
183
  end
@@ -186,7 +186,7 @@ module Admino
186
186
  before { row.action(:show, '/', class: 'foo') }
187
187
 
188
188
  it 'renders them as attributes' do
189
- should have_tag(:a, with: { class: 'foo' })
189
+ is_expected.to have_tag(:a, with: { class: 'foo' })
190
190
  end
191
191
 
192
192
  context 'with a class that implements a <action_name>_html_options' do
@@ -204,7 +204,7 @@ module Admino
204
204
  end
205
205
 
206
206
  it 'renders them as attributes' do
207
- should have_tag(:a, with: { class: 'foo show-button button' })
207
+ is_expected.to have_tag(:a, with: { class: 'foo show-button button' })
208
208
  end
209
209
  end
210
210
  end
@@ -215,7 +215,7 @@ module Admino
215
215
  end
216
216
 
217
217
  it 'renders it' do
218
- should have_tag(:td, text: 'Foo')
218
+ is_expected.to have_tag(:td, text: 'Foo')
219
219
  end
220
220
  end
221
221
  end
@@ -21,27 +21,27 @@ module Admino
21
21
 
22
22
  context 'with a symbol param' do
23
23
  let(:arguments) { [:title] }
24
- it { should eq [:title, nil, {}] }
24
+ it { is_expected.to eq [:title, nil, {}] }
25
25
  end
26
26
 
27
27
  context 'with a string param' do
28
28
  let(:arguments) { ['Title'] }
29
- it { should eq [nil, 'Title', {}] }
29
+ it { is_expected.to eq [nil, 'Title', {}] }
30
30
  end
31
31
 
32
32
  context 'with a symbol and string param' do
33
33
  let(:arguments) { [:title, 'Title'] }
34
- it { should eq [:title, 'Title', {}] }
34
+ it { is_expected.to eq [:title, 'Title', {}] }
35
35
  end
36
36
 
37
37
  context 'with two symbol params' do
38
38
  let(:arguments) { [:title, :foo] }
39
- it { should eq [:title, :foo, {}] }
39
+ it { is_expected.to eq [:title, :foo, {}] }
40
40
  end
41
41
 
42
42
  context 'with options' do
43
43
  let(:arguments) { [{ foo: 'bar' }] }
44
- it { should eq [nil, nil, { foo: 'bar' }] }
44
+ it { is_expected.to eq [nil, nil, { foo: 'bar' }] }
45
45
  end
46
46
  end
47
47
 
@@ -52,22 +52,22 @@ module Admino
52
52
 
53
53
  context 'with a symbol param' do
54
54
  let(:arguments) { [:show] }
55
- it { should eq [:show, nil, nil, {}] }
55
+ it { is_expected.to eq [:show, nil, nil, {}] }
56
56
  end
57
57
 
58
58
  context 'with a one string param' do
59
59
  let(:arguments) { ['/'] }
60
- it { should eq [nil, '/', nil, {}] }
60
+ it { is_expected.to eq [nil, '/', nil, {}] }
61
61
  end
62
62
 
63
63
  context 'with a two string params' do
64
64
  let(:arguments) { ['/', 'Details'] }
65
- it { should eq [nil, '/', 'Details', {}] }
65
+ it { is_expected.to eq [nil, '/', 'Details', {}] }
66
66
  end
67
67
 
68
68
  context 'with options' do
69
69
  let(:arguments) { [{ foo: 'bar' }] }
70
- it { should eq [nil, nil, nil, { foo: 'bar' }] }
70
+ it { is_expected.to eq [nil, nil, nil, { foo: 'bar' }] }
71
71
  end
72
72
  end
73
73
  end
data/spec/spec_helper.rb CHANGED
@@ -69,9 +69,21 @@ class Post < Struct.new(:key, :dom_id)
69
69
  end
70
70
 
71
71
  require 'action_view'
72
+ require 'simple_form'
73
+ require 'simple_form/action_view_extensions/form_helper'
72
74
 
73
75
  class RailsViewContext < ActionView::Base
74
76
  include ActionView::Helpers::TagHelper
77
+ include SimpleForm::ActionViewExtensions::FormHelper
78
+ include Admino::ActionViewExtension
79
+
80
+ def request
81
+ OpenStruct.new(path: '/', fullpath: '/?p=1')
82
+ end
83
+
84
+ def polymorphic_path(*args)
85
+ '/'
86
+ end
75
87
  end
76
88
 
77
89
  RSpec.configure do |c|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: admino
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Verna
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-25 00:00:00.000000000 Z
11
+ date: 2014-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: showcase
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - '>='
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simple_form
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - '>='
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: Make administrative views creation less repetitive
168
182
  email:
169
183
  - s.verna@cantierecreativo.net
@@ -182,6 +196,7 @@ files:
182
196
  - TODO.md
183
197
  - admino.gemspec
184
198
  - lib/admino.rb
199
+ - lib/admino/action_view_extension.rb
185
200
  - lib/admino/query.rb
186
201
  - lib/admino/query/base.rb
187
202
  - lib/admino/query/base_presenter.rb
@@ -189,6 +204,7 @@ files:
189
204
  - lib/admino/query/dsl.rb
190
205
  - lib/admino/query/filter_group.rb
191
206
  - lib/admino/query/filter_group_presenter.rb
207
+ - lib/admino/query/scope_presenter.rb
192
208
  - lib/admino/query/search_field.rb
193
209
  - lib/admino/query/sorting.rb
194
210
  - lib/admino/query/sorting_presenter.rb
@@ -198,6 +214,9 @@ files:
198
214
  - lib/admino/table/resource_row.rb
199
215
  - lib/admino/table/row.rb
200
216
  - lib/admino/version.rb
217
+ - logo.jpg
218
+ - occurred at /Users/stefanoverna/.dotfiles/vim/rspec_formatter.rb
219
+ - spec/admino/integration_spec.rb
201
220
  - spec/admino/query/base_presenter_spec.rb
202
221
  - spec/admino/query/base_spec.rb
203
222
  - spec/admino/query/dsl_spec.rb
@@ -236,6 +255,7 @@ signing_key:
236
255
  specification_version: 4
237
256
  summary: Make administrative views creation less repetitive
238
257
  test_files:
258
+ - spec/admino/integration_spec.rb
239
259
  - spec/admino/query/base_presenter_spec.rb
240
260
  - spec/admino/query/base_spec.rb
241
261
  - spec/admino/query/dsl_spec.rb