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