autoforme 1.1.0 → 1.2.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 +4 -4
- data/CHANGELOG +4 -0
- data/Rakefile +15 -43
- data/lib/autoforme/action.rb +28 -2
- data/lib/autoforme/frameworks/rails.rb +7 -1
- data/lib/autoforme/frameworks/roda.rb +9 -3
- data/lib/autoforme/frameworks/sinatra.rb +10 -3
- data/lib/autoforme/model.rb +2 -2
- data/lib/autoforme/models/sequel.rb +9 -8
- data/lib/autoforme/version.rb +1 -1
- data/spec/associations_spec.rb +63 -63
- data/spec/basic_spec.rb +156 -146
- data/spec/mtm_spec.rb +67 -67
- data/spec/rails_spec_helper.rb +0 -9
- data/spec/roda_spec_helper.rb +6 -0
- data/spec/sequel_spec_helper.rb +0 -16
- data/spec/spec_helper.rb +12 -4
- data/spec/unit_spec.rb +178 -177
- metadata +59 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b02fdd6446457bcda7559cde3424ffe3cebeffc0
|
4
|
+
data.tar.gz: 830e5ab7011c6f853726f3406e46011e5a081c57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee758d94d0f5faca90f0f496140bed42ee4fb30a3dda54ab77ecc451151a02d336b8a369ac17b6ea4aff803ec1791b2a9255382199d494ed5c2c916c5dfd73ca
|
7
|
+
data.tar.gz: 119472906c1fff16ee74cc8babe3656151aadb7ee02cc71241c5263ae39e8fb6e1aeac7cd3b8b6e3785bfbe5474c93afcfd2e224a4191417feaefb72aef2ca95
|
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
@@ -10,53 +10,25 @@ end
|
|
10
10
|
|
11
11
|
### Specs
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
desc d
|
20
|
-
RSpec::Core::RakeTask.new(name) do |t|
|
21
|
-
t.pattern= files
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
spec_with_cov = lambda do |name, files, d|
|
26
|
-
spec.call(name, files, d)
|
27
|
-
desc "#{d} with coverage"
|
28
|
-
task "#{name}_cov" do
|
29
|
-
ENV['COVERAGE'] = '1'
|
30
|
-
Rake::Task[name].invoke
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
task :default => [:spec]
|
35
|
-
spec_with_cov.call("spec", Dir["spec/*_spec.rb"], "Run specs with sinatra/sequel")
|
13
|
+
spec = proc do |env|
|
14
|
+
env.each{|k,v| ENV[k] = v}
|
15
|
+
sh "#{FileUtils::RUBY} -rubygems -I lib -e 'ARGV.each{|f| require f}' ./spec/*_spec.rb"
|
16
|
+
env.each{|k,v| ENV.delete(k)}
|
17
|
+
end
|
18
|
+
task :default => :roda_spec
|
36
19
|
|
37
|
-
|
38
|
-
|
39
|
-
begin
|
40
|
-
ENV['FRAMEWORK'] = 'roda'
|
41
|
-
Rake::Task[:spec].invoke
|
42
|
-
ensure
|
43
|
-
ENV.delete('FRAMEWORK')
|
44
|
-
end
|
45
|
-
end
|
20
|
+
desc "Run specs for all frameworks"
|
21
|
+
task :spec => [:roda_spec, :sinatra_spec, :rails_spec]
|
46
22
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
Rake::Task[:spec].invoke
|
52
|
-
ensure
|
53
|
-
ENV.delete('FRAMEWORK')
|
54
|
-
end
|
23
|
+
%w'roda sinatra rails'.each do |framework|
|
24
|
+
desc "Run specs with for #{framework} with coverage"
|
25
|
+
task "#{framework}_spec" do
|
26
|
+
spec.call('FRAMEWORK'=>framework)
|
55
27
|
end
|
56
28
|
|
57
|
-
|
58
|
-
task
|
59
|
-
|
29
|
+
desc "Run specs with for #{framework}"
|
30
|
+
task "#{framework}_spec_cov" do
|
31
|
+
spec.call('FRAMEWORK'=>framework, 'COVERAGE'=>'1')
|
60
32
|
end
|
61
33
|
end
|
62
34
|
|
data/lib/autoforme/action.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'enum_csv'
|
2
|
+
|
1
3
|
module AutoForme
|
2
4
|
# Represents an action on a model in response to a web request.
|
3
5
|
class Action
|
@@ -20,6 +22,12 @@ module AutoForme
|
|
20
22
|
# The type symbols related to the current action (e.g. :new, :create).
|
21
23
|
attr_reader :type
|
22
24
|
|
25
|
+
# The type of output, currently nil for normal output, and 'csv' for csv output
|
26
|
+
attr_reader :output_type
|
27
|
+
|
28
|
+
# The filename to use for file output
|
29
|
+
attr_reader :output_filename
|
30
|
+
|
23
31
|
# Array of strings for all action types currently supported
|
24
32
|
ALL_SUPPORTED_ACTIONS = %w'new create show edit update delete destroy browse search mtm_edit mtm_update association_links autocomplete'.freeze
|
25
33
|
|
@@ -174,6 +182,17 @@ module AutoForme
|
|
174
182
|
label
|
175
183
|
end
|
176
184
|
|
185
|
+
# Return a string in CSV format with the results
|
186
|
+
def csv(meth)
|
187
|
+
@output_type = 'csv'
|
188
|
+
@output_filename = "#{model.link.downcase}_#{normalized_type}.csv"
|
189
|
+
columns = model.columns_for(type, request)
|
190
|
+
headers = columns.map{|column| column_label_for(type, request, model, column)}
|
191
|
+
EnumCSV.csv(model.send(meth, normalized_type, request, :all_results=>true), :headers=>headers) do |obj|
|
192
|
+
columns.map{|column| model.column_value(type, request, obj, column)}
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
177
196
|
# HTML fragment for the default page header, which uses tabs for each supported action.
|
178
197
|
def tabs
|
179
198
|
content = '<ul class="nav nav-tabs">'
|
@@ -392,6 +411,7 @@ module AutoForme
|
|
392
411
|
html << '<li class="disabled"><a href="#">Next</a></li>'
|
393
412
|
end
|
394
413
|
html << "</ul>"
|
414
|
+
html << "<p><a href=\"#{url_for("#{type}/csv?#{h request.query_string}")}\">CSV Format</a></p>"
|
395
415
|
end
|
396
416
|
|
397
417
|
# Show page used for browse/search pages.
|
@@ -403,13 +423,19 @@ module AutoForme
|
|
403
423
|
|
404
424
|
# Handle browse action by showing a table containing model objects.
|
405
425
|
def handle_browse
|
406
|
-
|
426
|
+
if request.id == 'csv'
|
427
|
+
csv(:browse)
|
428
|
+
else
|
429
|
+
table_page(*model.browse(type, request))
|
430
|
+
end
|
407
431
|
end
|
408
432
|
|
409
433
|
# Handle browse action by showing a search form if no page is selected, or the correct page of search results
|
410
434
|
# if there is a page selected.
|
411
435
|
def handle_search
|
412
|
-
if request.id
|
436
|
+
if request.id == 'csv'
|
437
|
+
csv(:search_results)
|
438
|
+
elsif request.id
|
413
439
|
table_page(*model.search_results(normalized_type, request))
|
414
440
|
else
|
415
441
|
page do
|
@@ -48,8 +48,14 @@ module AutoForme
|
|
48
48
|
if @autoforme_action = framework.action_for(Request.new(self))
|
49
49
|
if redirect = catch(:redirect){@autoforme_text = @autoforme_action.handle; nil}
|
50
50
|
redirect_to redirect
|
51
|
+
elsif @autoforme_action.output_type == 'csv'
|
52
|
+
response.headers['Content-Type'] = 'text/csv'
|
53
|
+
response.headers['Content-Disposition'] = "attachment; filename=#{@autoforme_action.output_filename}"
|
54
|
+
render :text=>@autoforme_text
|
55
|
+
elsif @autoforme_action.request.xhr?
|
56
|
+
render :text=>@autoforme_text
|
51
57
|
else
|
52
|
-
render :inline=>"<%=raw @autoforme_text %>", :layout
|
58
|
+
render :inline=>"<%=raw @autoforme_text %>", :layout=>true
|
53
59
|
end
|
54
60
|
else
|
55
61
|
render :text=>'Unhandled Request', :status=>404
|
@@ -61,9 +61,15 @@ module AutoForme
|
|
61
61
|
|
62
62
|
r.on *current_matchers do
|
63
63
|
@autoforme_text = @autoforme_action.handle
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
if @autoforme_action.output_type == 'csv'
|
65
|
+
response['Content-Type'] = 'text/csv'
|
66
|
+
response['Content-Disposition'] = "attachment; filename=#{@autoforme_action.output_filename}"
|
67
|
+
@autoforme_text
|
68
|
+
elsif @autoforme_action.request.xhr?
|
69
|
+
@autoforme_text
|
70
|
+
else
|
71
|
+
view(:content=>@autoforme_text)
|
72
|
+
end
|
67
73
|
end
|
68
74
|
end
|
69
75
|
end
|
@@ -40,9 +40,16 @@ module AutoForme
|
|
40
40
|
block = lambda do
|
41
41
|
if @autoforme_action = framework.action_for(Request.new(self))
|
42
42
|
@autoforme_text = @autoforme_action.handle
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
|
44
|
+
if @autoforme_action.output_type == 'csv'
|
45
|
+
response['Content-Type'] = 'text/csv'
|
46
|
+
response['Content-Disposition'] = "attachment; filename=#{@autoforme_action.output_filename}"
|
47
|
+
@autoforme_text
|
48
|
+
elsif @autoforme_action.request.xhr?
|
49
|
+
@autoforme_text
|
50
|
+
else
|
51
|
+
erb "<%= @autoforme_text %>"
|
52
|
+
end
|
46
53
|
else
|
47
54
|
pass
|
48
55
|
end
|
data/lib/autoforme/model.rb
CHANGED
@@ -76,12 +76,12 @@ module AutoForme
|
|
76
76
|
|
77
77
|
# Whether an mtm_edit can be displayed for the given association
|
78
78
|
def supported_mtm_edit?(assoc, request)
|
79
|
-
mtm_association_select_options(request).map
|
79
|
+
mtm_association_select_options(request).map(&:to_s).include?(assoc)
|
80
80
|
end
|
81
81
|
|
82
82
|
# Whether an mtm_update can occur for the given association
|
83
83
|
def supported_mtm_update?(assoc, request)
|
84
|
-
supported_mtm_edit?(assoc, request) || inline_mtm_assocs(request).map
|
84
|
+
supported_mtm_edit?(assoc, request) || inline_mtm_assocs(request).map(&:to_s).include?(assoc)
|
85
85
|
end
|
86
86
|
|
87
87
|
# An array of many to many association symbols to handle inline on the edit forms.
|
@@ -58,7 +58,7 @@ module AutoForme
|
|
58
58
|
def association?(column)
|
59
59
|
case column
|
60
60
|
when String
|
61
|
-
model.associations.map
|
61
|
+
model.associations.map(&:to_s).include?(column)
|
62
62
|
else
|
63
63
|
model.association_reflection(column)
|
64
64
|
end
|
@@ -103,7 +103,7 @@ module AutoForme
|
|
103
103
|
|
104
104
|
# Array of association name strings for given association types
|
105
105
|
def association_names(types=SUPPORTED_ASSOCIATION_TYPES)
|
106
|
-
model.all_association_reflections.select{|r| types.include?(r[:type])}.map{|r| r[:name]}.sort_by
|
106
|
+
model.all_association_reflections.select{|r| types.include?(r[:type])}.map{|r| r[:name]}.sort_by(&:to_s)
|
107
107
|
end
|
108
108
|
|
109
109
|
# Save the object, returning the object if successful, or nil if not.
|
@@ -142,7 +142,7 @@ module AutoForme
|
|
142
142
|
columns[i] = reflection[:name]
|
143
143
|
end
|
144
144
|
end
|
145
|
-
columns.sort_by
|
145
|
+
columns.sort_by(&:to_s)
|
146
146
|
end
|
147
147
|
|
148
148
|
# Add a filter restricting access to only rows where the column name
|
@@ -158,7 +158,7 @@ module AutoForme
|
|
158
158
|
end
|
159
159
|
|
160
160
|
# Returning array of matching objects for the current search page using the given parameters.
|
161
|
-
def search_results(type, request)
|
161
|
+
def search_results(type, request, opts={})
|
162
162
|
params = request.params
|
163
163
|
ds = apply_associated_eager(:search, request, all_dataset_for(type, request))
|
164
164
|
columns_for(:search_form, request).each do |c|
|
@@ -178,17 +178,18 @@ module AutoForme
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
end
|
181
|
-
paginate(type, request, ds)
|
181
|
+
paginate(type, request, ds, opts)
|
182
182
|
end
|
183
183
|
|
184
184
|
# Return array of matching objects for the current page.
|
185
|
-
def browse(type, request)
|
186
|
-
paginate(type, request, apply_associated_eager(:browse, request, all_dataset_for(type, request)))
|
185
|
+
def browse(type, request, opts={})
|
186
|
+
paginate(type, request, apply_associated_eager(:browse, request, all_dataset_for(type, request)), opts)
|
187
187
|
end
|
188
188
|
|
189
189
|
# Do very simple pagination, by selecting one more object than necessary,
|
190
190
|
# and noting if there is a next page by seeing if more objects are returned than the limit.
|
191
|
-
def paginate(type, request, ds)
|
191
|
+
def paginate(type, request, ds, opts={})
|
192
|
+
return ds.all if opts[:all_results]
|
192
193
|
limit = limit_for(type, request)
|
193
194
|
offset = ((request.id.to_i||1)-1) * limit
|
194
195
|
objs = ds.limit(limit+1, (offset if offset > 0)).all
|
data/lib/autoforme/version.rb
CHANGED
data/spec/associations_spec.rb
CHANGED
@@ -38,17 +38,17 @@ describe AutoForme do
|
|
38
38
|
click_link 'Show'
|
39
39
|
select 'Album1'
|
40
40
|
click_button 'Show'
|
41
|
-
page.html.
|
42
|
-
page.html.
|
41
|
+
page.html.must_match /Name.+Album1b/m
|
42
|
+
page.html.must_match /Artist.+Artist2/m
|
43
43
|
|
44
44
|
click_link 'Search'
|
45
45
|
fill_in 'Name', :with=>'1b'
|
46
46
|
select 'Artist2'
|
47
47
|
click_button 'Search'
|
48
|
-
page.all('td').map{|s| s.text}.
|
48
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "Artist2", "Show", "Edit", "Delete"]
|
49
49
|
|
50
50
|
click_link 'Album'
|
51
|
-
page.all('td').map{|s| s.text}.
|
51
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "Artist2", "Show", "Edit", "Delete"]
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should use text boxes for associated objects on new/edit/search forms if associated model uses autocompleting" do
|
@@ -68,7 +68,7 @@ describe AutoForme do
|
|
68
68
|
fill_in 'Name', :with=>'Album1'
|
69
69
|
fill_in 'Artist', :with=>a.id.to_s
|
70
70
|
click_button 'Create'
|
71
|
-
Album.first.artist_id.
|
71
|
+
Album.first.artist_id.must_equal a.id
|
72
72
|
|
73
73
|
click_link 'Edit'
|
74
74
|
select 'Album1'
|
@@ -76,13 +76,13 @@ describe AutoForme do
|
|
76
76
|
fill_in 'Name', :with=>'Album1b'
|
77
77
|
fill_in 'Artist', :with=>b.id.to_s
|
78
78
|
click_button 'Update'
|
79
|
-
Album.first.artist_id.
|
79
|
+
Album.first.artist_id.must_equal b.id
|
80
80
|
|
81
81
|
click_link 'Search'
|
82
82
|
fill_in 'Name', :with=>'1b'
|
83
83
|
fill_in 'Artist', :with=>b.id.to_s
|
84
84
|
click_button 'Search'
|
85
|
-
page.all('td').map{|s| s.text}.
|
85
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "TestArtist2", "Show", "Edit", "Delete"]
|
86
86
|
end
|
87
87
|
|
88
88
|
it "should be able to used specified name formatting in other model" do
|
@@ -109,8 +109,8 @@ describe AutoForme do
|
|
109
109
|
click_link 'Show'
|
110
110
|
select 'Album1'
|
111
111
|
click_button 'Show'
|
112
|
-
page.html.
|
113
|
-
page.html.
|
112
|
+
page.html.must_match /Name.+Album1/m
|
113
|
+
page.html.must_match /Artist.+A1A1/m
|
114
114
|
|
115
115
|
click_link 'Edit'
|
116
116
|
select 'Album1'
|
@@ -123,10 +123,10 @@ describe AutoForme do
|
|
123
123
|
fill_in 'Name', :with=>'1b'
|
124
124
|
select 'A2A2'
|
125
125
|
click_button 'Search'
|
126
|
-
page.all('td').map{|s| s.text}.
|
126
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "A2A2", "Show", "Edit", "Delete"]
|
127
127
|
|
128
128
|
click_link 'Album'
|
129
|
-
page.all('td').map{|s| s.text}.
|
129
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "A2A2", "Show", "Edit", "Delete"]
|
130
130
|
end
|
131
131
|
|
132
132
|
it "should be able to used specified name formatting for current association" do
|
@@ -152,8 +152,8 @@ describe AutoForme do
|
|
152
152
|
click_link 'Show'
|
153
153
|
select 'Album1'
|
154
154
|
click_button 'Show'
|
155
|
-
page.html.
|
156
|
-
page.html.
|
155
|
+
page.html.must_match /Name.+Album1/m
|
156
|
+
page.html.must_match /Artist.+A1A1/m
|
157
157
|
|
158
158
|
click_link 'Edit'
|
159
159
|
select 'Album1'
|
@@ -166,10 +166,10 @@ describe AutoForme do
|
|
166
166
|
fill_in 'Name', :with=>'1b'
|
167
167
|
select 'A2A2'
|
168
168
|
click_button 'Search'
|
169
|
-
page.all('td').map{|s| s.text}.
|
169
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "A2A2", "Show", "Edit", "Delete"]
|
170
170
|
|
171
171
|
click_link 'Album'
|
172
|
-
page.all('td').map{|s| s.text}.
|
172
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "A2A2", "Show", "Edit", "Delete"]
|
173
173
|
end
|
174
174
|
|
175
175
|
it "should be able to eager load associations when loading model" do
|
@@ -196,8 +196,8 @@ describe AutoForme do
|
|
196
196
|
click_link 'Show'
|
197
197
|
select 'A1-Album1'
|
198
198
|
click_button 'Show'
|
199
|
-
page.html.
|
200
|
-
page.html.
|
199
|
+
page.html.must_match /Name.+Album1/m
|
200
|
+
page.html.must_match /Artist.+A1/m
|
201
201
|
|
202
202
|
click_link 'Edit'
|
203
203
|
select 'A1-Album1'
|
@@ -210,10 +210,10 @@ describe AutoForme do
|
|
210
210
|
fill_in 'Name', :with=>'1b'
|
211
211
|
select 'A2'
|
212
212
|
click_button 'Search'
|
213
|
-
page.all('td').map{|s| s.text}.
|
213
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "A2", "Show", "Edit", "Delete"]
|
214
214
|
|
215
215
|
click_link 'Album'
|
216
|
-
page.all('td').map{|s| s.text}.
|
216
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "A2", "Show", "Edit", "Delete"]
|
217
217
|
|
218
218
|
click_link 'Delete', :match=>:first
|
219
219
|
select 'A2-Album1b'
|
@@ -271,14 +271,14 @@ describe AutoForme do
|
|
271
271
|
click_button 'Create'
|
272
272
|
|
273
273
|
click_link 'Show'
|
274
|
-
page.all('select option').map{|s| s.text}.
|
274
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'A-Y', 'B-X', 'B-Z']
|
275
275
|
select 'B-X'
|
276
276
|
click_button 'Show'
|
277
|
-
page.html.
|
278
|
-
page.html.
|
277
|
+
page.html.must_match /Name.+X/m
|
278
|
+
page.html.must_match /Artist.+B/m
|
279
279
|
|
280
280
|
click_link 'Edit'
|
281
|
-
page.all('select option').map{|s| s.text}.
|
281
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'X (B)', 'Y (A)', 'Z (B)']
|
282
282
|
select 'Z (B)'
|
283
283
|
click_button 'Edit'
|
284
284
|
fill_in 'Name', :with=>'ZZ'
|
@@ -288,13 +288,13 @@ describe AutoForme do
|
|
288
288
|
click_link 'Search'
|
289
289
|
select 'A'
|
290
290
|
click_button 'Search'
|
291
|
-
page.all('tr td:first-child').map{|s| s.text}.
|
291
|
+
page.all('tr td:first-child').map{|s| s.text}.must_equal %w'Y ZZ'
|
292
292
|
|
293
293
|
click_link 'Album'
|
294
|
-
page.all('tr td:first-child').map{|s| s.text}.
|
294
|
+
page.all('tr td:first-child').map{|s| s.text}.must_equal %w'Y ZZ X'
|
295
295
|
|
296
296
|
click_link 'Delete', :match=>:first
|
297
|
-
page.all('select option').map{|s| s.text}.
|
297
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'A-Y', 'A-ZZ', 'B-X']
|
298
298
|
select 'B-X'
|
299
299
|
click_button 'Delete'
|
300
300
|
end
|
@@ -325,42 +325,42 @@ describe AutoForme do
|
|
325
325
|
|
326
326
|
visit("/Album/new")
|
327
327
|
fill_in 'Name', :with=>'E'
|
328
|
-
page.all('select option').map{|s| s.text}.
|
328
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'X 0', 'Y 0', 'Z 0']
|
329
329
|
select 'X 0'
|
330
330
|
click_button 'Create'
|
331
331
|
fill_in 'Name', :with=>'D'
|
332
|
-
page.all('select option').map{|s| s.text}.
|
332
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'X 1', 'Y 0', 'Z 0']
|
333
333
|
select 'Y 0'
|
334
334
|
click_button 'Create'
|
335
335
|
fill_in 'Name', :with=>'C'
|
336
|
-
page.all('select option').map{|s| s.text}.
|
336
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'X 1', 'Y 1', 'Z 0']
|
337
337
|
select 'Y 1'
|
338
338
|
click_button 'Create'
|
339
339
|
|
340
340
|
click_link 'Show'
|
341
341
|
select 'D'
|
342
342
|
click_button 'Show'
|
343
|
-
page.html.
|
344
|
-
page.html.
|
343
|
+
page.html.must_match /Name.+D/m
|
344
|
+
page.html.must_match /Artist.+Y 2/m
|
345
345
|
|
346
346
|
click_link 'Edit'
|
347
347
|
select 'C'
|
348
348
|
click_button 'Edit'
|
349
|
-
page.all('select option').map{|s| s.text}.
|
349
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'X 1', 'Y 2', 'Z 0']
|
350
350
|
select 'X 1'
|
351
351
|
click_button 'Update'
|
352
352
|
|
353
353
|
click_link 'Search'
|
354
|
-
page.all('select option').map{|s| s.text}.
|
354
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'X 2', 'Y 1', 'Z 0']
|
355
355
|
select 'X 2'
|
356
356
|
click_button 'Search'
|
357
|
-
page.all('tr td:first-child').map{|s| s.text}.
|
357
|
+
page.all('tr td:first-child').map{|s| s.text}.must_equal %w'C E'
|
358
358
|
|
359
359
|
click_link 'Album'
|
360
|
-
page.all('tr td:first-child').map{|s| s.text}.
|
360
|
+
page.all('tr td:first-child').map{|s| s.text}.must_equal %w'C D E'
|
361
361
|
|
362
362
|
click_link 'Delete', :match=>:first
|
363
|
-
page.all('select option').map{|s| s.text}.
|
363
|
+
page.all('select option').map{|s| s.text}.must_equal ['', 'C', 'D', 'E']
|
364
364
|
select 'C'
|
365
365
|
click_button 'Delete'
|
366
366
|
click_button 'Delete'
|
@@ -369,13 +369,13 @@ describe AutoForme do
|
|
369
369
|
Artist.where(:name=>'Y').update(:name=>'A')
|
370
370
|
fill_in 'Name', :with=>'F'
|
371
371
|
select 'Y 1'
|
372
|
-
proc{click_button 'Create'}.
|
372
|
+
proc{click_button 'Create'}.must_raise(Sequel::NoMatchingRow)
|
373
373
|
|
374
374
|
visit("/Album/search")
|
375
375
|
select 'X 1'
|
376
376
|
Artist.where(:name=>'X').update(:name=>'B')
|
377
377
|
click_button 'Search'
|
378
|
-
page.all('tr td:first-child').map{|s| s.text}.
|
378
|
+
page.all('tr td:first-child').map{|s| s.text}.must_equal []
|
379
379
|
end
|
380
380
|
|
381
381
|
it "should have working one to many and many to one association links on show and edit pages" do
|
@@ -404,21 +404,21 @@ describe AutoForme do
|
|
404
404
|
select 'Album1'
|
405
405
|
click_button 'Show'
|
406
406
|
click_link 'Artist1'
|
407
|
-
page.current_path.
|
407
|
+
page.current_path.must_match %r{Artist/show/\d+}
|
408
408
|
click_link 'Album1'
|
409
|
-
page.current_path.
|
409
|
+
page.current_path.must_match %r{Album/show/\d+}
|
410
410
|
click_link 'Artist'
|
411
|
-
page.current_path.
|
411
|
+
page.current_path.must_equal '/Artist/browse'
|
412
412
|
|
413
413
|
click_link 'Edit', :match=>:first
|
414
414
|
select 'Artist1'
|
415
415
|
click_button 'Edit'
|
416
416
|
click_link 'Album1'
|
417
|
-
page.current_path.
|
417
|
+
page.current_path.must_match %r{Album/edit/\d+}
|
418
418
|
click_link 'Artist1'
|
419
|
-
page.current_path.
|
419
|
+
page.current_path.must_match %r{Artist/edit/\d+}
|
420
420
|
click_link 'Albums'
|
421
|
-
page.current_path.
|
421
|
+
page.current_path.must_equal '/Album/browse'
|
422
422
|
end
|
423
423
|
|
424
424
|
it "should display but not link if the action is not supported " do
|
@@ -447,8 +447,8 @@ describe AutoForme do
|
|
447
447
|
visit("/Artist/edit")
|
448
448
|
select 'Artist1'
|
449
449
|
click_button 'Edit'
|
450
|
-
page.html.
|
451
|
-
page.html.
|
450
|
+
page.html.must_match /Album1/
|
451
|
+
page.html.wont_match />edit</
|
452
452
|
end
|
453
453
|
|
454
454
|
it "should support lazy loading association links on show and edit pages" do
|
@@ -471,7 +471,7 @@ describe AutoForme do
|
|
471
471
|
click_link 'Edit'
|
472
472
|
select 'Artist1'
|
473
473
|
click_button 'Edit'
|
474
|
-
page.html.
|
474
|
+
page.html.wont_match /create/
|
475
475
|
click_link 'Show Associations'
|
476
476
|
click_link 'create'
|
477
477
|
fill_in 'Name', :with=>'Album1'
|
@@ -482,26 +482,26 @@ describe AutoForme do
|
|
482
482
|
click_button 'Show'
|
483
483
|
click_link 'Show Associations'
|
484
484
|
click_link 'Artist1'
|
485
|
-
page.current_path.
|
485
|
+
page.current_path.must_match %r{Artist/show/\d+}
|
486
486
|
click_link 'Show Associations'
|
487
487
|
click_link 'Album1'
|
488
|
-
page.current_path.
|
488
|
+
page.current_path.must_match %r{Album/show/\d+}
|
489
489
|
click_link 'Show Associations'
|
490
490
|
click_link 'Artist'
|
491
|
-
page.current_path.
|
491
|
+
page.current_path.must_equal '/Artist/browse'
|
492
492
|
|
493
493
|
click_link 'Edit', :match=>:first
|
494
494
|
select 'Artist1'
|
495
495
|
click_button 'Edit'
|
496
496
|
click_link 'Show Associations'
|
497
497
|
click_link 'Album1'
|
498
|
-
page.current_path.
|
498
|
+
page.current_path.must_match %r{Album/edit/\d+}
|
499
499
|
click_link 'Show Associations'
|
500
500
|
click_link 'Artist1'
|
501
|
-
page.current_path.
|
501
|
+
page.current_path.must_match %r{Artist/edit/\d+}
|
502
502
|
click_link 'Show Associations'
|
503
503
|
click_link 'Albums'
|
504
|
-
page.current_path.
|
504
|
+
page.current_path.must_equal '/Album/browse'
|
505
505
|
end
|
506
506
|
end
|
507
507
|
|
@@ -545,17 +545,17 @@ describe AutoForme do
|
|
545
545
|
click_link 'Show'
|
546
546
|
select 'Album1'
|
547
547
|
click_button 'Show'
|
548
|
-
page.html.
|
549
|
-
page.html.
|
548
|
+
page.html.must_match /Name.+Album1b/m
|
549
|
+
page.html.must_match /Artist.+Artist2/m
|
550
550
|
|
551
551
|
click_link 'Search'
|
552
552
|
fill_in 'Name', :with=>'1b'
|
553
553
|
select 'Artist2'
|
554
554
|
click_button 'Search'
|
555
|
-
page.all('td').map{|s| s.text}.
|
555
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "Artist2", "Show", "Edit", "Delete"]
|
556
556
|
|
557
557
|
click_link 'Album'
|
558
|
-
page.all('td').map{|s| s.text}.
|
558
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "Artist2", "Show", "Edit", "Delete"]
|
559
559
|
end
|
560
560
|
|
561
561
|
it "should have basic many to one associations working" do
|
@@ -589,17 +589,17 @@ describe AutoForme do
|
|
589
589
|
click_link 'Show'
|
590
590
|
select 'Album1'
|
591
591
|
click_button 'Show'
|
592
|
-
page.html.
|
593
|
-
page.html.
|
592
|
+
page.html.must_match /Name.+Album1b/m
|
593
|
+
page.html.must_match /Artist.+Artist2/m
|
594
594
|
|
595
595
|
click_link 'Search'
|
596
596
|
fill_in 'Name', :with=>'1b'
|
597
597
|
select 'Artist2'
|
598
598
|
click_button 'Search'
|
599
|
-
page.all('td').map{|s| s.text}.
|
599
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "Artist2", "Show", "Edit", "Delete"]
|
600
600
|
|
601
601
|
click_link 'Album'
|
602
|
-
page.all('td').map{|s| s.text}.
|
602
|
+
page.all('td').map{|s| s.text}.must_equal ["Album1b", "Artist2", "Show", "Edit", "Delete"]
|
603
603
|
end
|
604
604
|
end
|
605
605
|
|
@@ -624,9 +624,9 @@ describe AutoForme do
|
|
624
624
|
|
625
625
|
%w'A1 E1 L1 N1'.each{|n| Artist.create(:name=>n)}
|
626
626
|
visit("/Album/new")
|
627
|
-
page.all('select option').map{|s| s.text}.
|
627
|
+
page.all('select option').map{|s| s.text}.must_equal ["", "A1", "E1", "L1"]
|
628
628
|
|
629
629
|
visit("/Album/edit/#{Album.create(:name=>'Album1').id}")
|
630
|
-
page.all('select option').map{|s| s.text}.
|
630
|
+
page.all('select option').map{|s| s.text}.must_equal ["", "L1", "E1"]
|
631
631
|
end
|
632
632
|
end
|