admino 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
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