forme 1.5.0 → 1.6.0

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: fb06104f826067a8f31ba5778bed02029abdbb7a
4
- data.tar.gz: 910a345e355680be66a4d049edaa35e8ecca6186
3
+ metadata.gz: 617e4bb020afdaf14cb5a13ec71c57bc0c33f173
4
+ data.tar.gz: 05ee61e281799560dd9c9eb84911a11bf9ca0c0c
5
5
  SHA512:
6
- metadata.gz: c829a2fb78d66a347f6ae65ea600aabd80a2ef7373ca0c3ea4894a0409c75c8959df45b096413796f5140590ea8f7fa4b32c0c8b02a5f78f4ce6d7b103abde77
7
- data.tar.gz: fd6f0b68a9aadbedcd53d0087e8e5c3ea215c53363834fe9c9e39ea54c728113afc0d6459119cf65bda15355eb2757ac26688cba23266c93179047c16c5cd270
6
+ metadata.gz: 90d0384542f59034b2428aeff330e0e9379b9c732877bbfa22d8be3be4cbeb89a24c635495ab638423ca2126dc7cea89ca07c74e4eea49193cd770fe521d67e5
7
+ data.tar.gz: 6aab3b04c4658e2c104f056104d5e2480580f51b1328e9540bc52b9c6ab0c9941b0bf7bfe5ddb9051b6d501e1bad7b8a6c5b115133caba05b689b28dbee1eb0c
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ === 1.6.0 (2017-05-03)
2
+
3
+ * Use thead/tbody tags for table inputs_wrapper transformer and Sequel plugin subform :grid option (jeremyevans)
4
+
5
+ * Do not create a hidden input for checkboxes when using disabled/readonly formatters (jeremyevans)
6
+
7
+ * Add support for overriding forme_namespace on the Sequel::Model instance to change forme's namespacing (mwpastore, jeremyevans) (#17)
8
+
9
+ * Allow :label_attr for checkboxset and radioset to set attributes for individual labels in the set (jeremyevans)
10
+
1
11
  === 1.5.0 (2016-08-09)
2
12
 
3
13
  * Add forme_set Sequel plugin, for handling the intake of submitted params based on form fields (jeremyevans)
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011-2016 Jeremy Evans
1
+ Copyright (c) 2011-2017 Jeremy Evans
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
data/README.rdoc CHANGED
@@ -48,31 +48,50 @@ data is broken down to the following steps (called transformers):
48
48
  +Serializer+ :: converts a <tt>Forme::Tag</tt> instance into an
49
49
  html string.
50
50
 
51
- Technically, only the +Serializer+ is necessary. The +input+
52
- and +tag+ methods return +Input+ and +Tag+ objects. These objects
51
+ Technically, only the +Serializer+ is necessary. The <tt>Forme::Form#input</tt>
52
+ and <tt>Forme::Form#tag</tt> methods return +Input+ and +Tag+ objects. These objects
53
53
  both have +to_s+ defined to call the appropriate +Serializer+ with
54
54
  themselves. The +Serializer+ calls the appropriate +Formatter+ if
55
55
  it encounters an +Input+ instance, and attempts to serialize the
56
56
  output of that (which is usually a +Tag+ instance). It is up to
57
- the +Formatter+ to call the +Labeler+ and/or +ErrorHandler+ (if
58
- necessary) and the +Wrapper+.
59
-
60
- There is also an +InputsWrapper+ transformer, that is called by
61
- <tt>Forme::Form#inputs</tt>. It's used to wrap up a group of
62
- related options (in a fieldset by default).
57
+ the +Formatter+ to call the +Labeler+, +ErrorHandler+, +Helper+,
58
+ and/or +Wrapper+.
63
59
 
64
60
  The <tt>Forme::Form</tt> object takes the 6 transformers as options (:formatter,
65
61
  :labeler, :error_handler, :helper, :wrapper, :inputs_wrapper, and :serializer), all of which
66
62
  should be objects responding to +call+ (so you can use +Proc+s) or be symbols
67
63
  registered with the library using <tt>Forme.register_transformer</tt>:
68
64
 
69
- Forme.register_transformer(:wrapper, :p){|t| t.tag(:p, {}, t)}
65
+ Forme.register_transformer(:wrapper, :p) do |tag, input|
66
+ input.tag(:p, {}, tag)
67
+ end
68
+
69
+ Most transformers are called with two arguments, +tag+ and +input+. +tag+
70
+ is a <tt>Forme::Tag</tt> instance, and +input+ is a <tt>Forme::Input</tt>
71
+ instance. The +Formatter+ and +Serializer+ transformers are the two
72
+ exceptions, with +Formatter+ being called with just an +input+, and
73
+ +Serializer+ potentionally being called with any object. The +Serializer+
74
+ will in general recursively call itself with children of the argument
75
+ given.
76
+
77
+ There is also an +InputsWrapper+ transformer, that is called by
78
+ <tt>Forme::Form#inputs</tt>. It's used to wrap up a group of
79
+ related options (in a fieldset by default). It takes +form+
80
+ (<tt>Forme::Form</tt> instance) and +input_opts+ (+Hash+) arguments.
70
81
 
71
82
  Most of the transformers can be overridden on a per instance basis by
72
- passing the appopriate option to +input+ or +inputs+:
83
+ passing the appropriate option to +input+ or +inputs+:
73
84
 
74
85
  f.input(:name, :wrapper=>:p)
75
86
 
87
+ Existing transformers can be easily extended (ie, to set the class attribute),
88
+ by creating your own transformer and then calling the existing transformer.
89
+
90
+ Forme.register_transformer(:labeler, :explicit) do |tag, input|
91
+ input.opts[:label_attr] ||= { :class => 'label' }
92
+ Forme::Labeler::Explicit.new.call(tag, input)
93
+ end
94
+
76
95
  = Installation
77
96
 
78
97
  gem install forme
@@ -351,6 +370,17 @@ object in the enumerable, and includes the index in the namespace:
351
370
 
352
371
  Forme ships with a Sequel plugin (use <tt>Sequel::Model.plugin :forme</tt> to enable), that makes
353
372
  Sequel::Model instances support the +forme_config+ and +forme_input+ methods and return customized inputs.
373
+ An additional instance method, +forme_namespace+ can optionally be defined to customize how model classnames
374
+ are transformed into form classes and input IDs and names. This can be useful if your Sequel::Model classes
375
+ are nested under a parent namespace. It falls back to the behaviour of Sequel::Model#underscore.
376
+
377
+ module Admin
378
+ class Albums < Sequel::Model
379
+ def forme_namespace
380
+ self.class.name.underscore.tr('/', '_')
381
+ end
382
+ end
383
+ end
354
384
 
355
385
  == Basics
356
386
 
@@ -494,6 +524,8 @@ subform options:
494
524
  :inputs :: Automatically call +inputs+ with the given values. Using
495
525
  this, it is not required to pass a block to the method,
496
526
  though it will still work if you do.
527
+ :inputs_opts :: When using the :grid option, this allows you to specify options
528
+ to pass to the table InputsWrapper.
497
529
  :legend :: Overrides the default :legend used (which is based on the
498
530
  association name). You can also use a proc as the value,
499
531
  which will called with each associated object (and the position
@@ -505,8 +537,8 @@ subform options:
505
537
  be created via the :inputs option. If you are not providing
506
538
  an :inputs option or are using a block with additional inputs,
507
539
  you should specify this option.
508
- :inputs_opts :: When using the :grid option, this allows you to specify options
509
- to pass to the table InputsWrapper.
540
+ :skip_primary_key :: Skip adding a hidden primary key field for existing
541
+ objects.
510
542
 
511
543
  == Handling form submissions
512
544
 
@@ -603,7 +635,7 @@ storing Forme::Form objects and later using them on forms, it is fairly simple t
603
635
  Forme::Forme object creation to a method, that you can call both in the initial display
604
636
  and when processing the input:
605
637
 
606
- def show_form(album)
638
+ def album_form(album)
607
639
  Forme.form(album, :action=>'/foo') do |f|
608
640
  f.input :name
609
641
  f.input :copies_sold
data/Rakefile CHANGED
@@ -55,9 +55,15 @@ end
55
55
  task :default => :spec
56
56
 
57
57
  desc "Run specs with coverage"
58
- task :spec do
58
+ task :spec_cov do
59
59
  ENV['COVERAGE'] = '1'
60
- Rake::Task['spec'].invoke
60
+ sh "#{FileUtils::RUBY} spec/all.rb"
61
+ end
62
+
63
+ desc "Run specs with -w, some warnings filtered"
64
+ task :spec_w do
65
+ ENV['WARNING'] = '1'
66
+ sh "#{FileUtils::RUBY} -w spec/all.rb"
61
67
  end
62
68
 
63
69
  ### Other
data/lib/forme/bs3.rb CHANGED
@@ -92,10 +92,6 @@ module Forme
92
92
  end
93
93
  end
94
94
 
95
- def set_label
96
- form._tag(:span, {:class=>'set-label'}, @opts[:set_label])
97
- end
98
-
99
95
  def _add_set_error(tags)
100
96
  tags << input.tag(:span, {:class=>'help-block with-errors'}, @opts[:set_error])
101
97
  end
data/lib/forme/form.rb CHANGED
@@ -16,10 +16,6 @@ module Forme
16
16
  # The hidden tags to automatically add to the form.
17
17
  attr_reader :hidden_tags
18
18
 
19
- # The namespaces if any for the receiver's inputs. This can be used to
20
- # automatically setup namespaced class and id attributes.
21
- attr_accessor :namespaces
22
-
23
19
  # The +serializer+ determines how +Tag+ objects are transformed into strings.
24
20
  # Must respond to +call+ or be a registered symbol.
25
21
  attr_reader :serializer
@@ -238,7 +234,7 @@ module Forme
238
234
  # Create a +Tag+ associated to the receiver with the given arguments and block,
239
235
  # doing no other processing.
240
236
  def _tag(*a, &block)
241
- tag = Tag.new(self, *a, &block)
237
+ Tag.new(self, *a, &block)
242
238
  end
243
239
 
244
240
  # The object associated with this form, if any. If the +Form+ has an associated
@@ -248,7 +244,8 @@ module Forme
248
244
  @opts[:obj]
249
245
  end
250
246
 
251
- # The current namespaces for the form, if any.
247
+ # The namespaces if any for the receiver's inputs. This can be used to
248
+ # automatically setup namespaced class and id attributes.
252
249
  def namespaces
253
250
  @opts[:namespace]
254
251
  end
data/lib/forme/input.rb CHANGED
@@ -24,12 +24,6 @@ module Forme
24
24
  @form_opts = form.opts
25
25
  end
26
26
 
27
- # Replace the +opts+ by merging the given +hash+ into +opts+,
28
- # without modifying +opts+.
29
- def merge_opts(hash)
30
- @opts = @opts.merge(hash)
31
- end
32
-
33
27
  # Create a new +Tag+ instance with the given arguments and block
34
28
  # related to the receiver's +form+.
35
29
  def tag(*a, &block)
@@ -234,7 +234,9 @@ module Forme
234
234
 
235
235
  tags = process_select_optgroups(:_format_set_optgroup) do |label, value, sel, attrs|
236
236
  value ||= label
237
- r_opts = attrs.merge(tag_attrs).merge(:label=>label||value, :label_attr=>{:class=>:option}, :wrapper=>tag_wrapper)
237
+ label_attr = {:class=>:option}
238
+ label_attr.merge!(@opts[:label_attr]) if @opts[:label_attr]
239
+ r_opts = attrs.merge(tag_attrs).merge(:label=>label||value, :label_attr=>label_attr, :wrapper=>tag_wrapper)
238
240
  r_opts[:value] ||= value if value
239
241
  r_opts[:checked] ||= :checked if sel
240
242
  r_opts[:formatter] = @opts[:formatter] if @opts[:formatter]
@@ -476,6 +478,12 @@ module Forme
476
478
 
477
479
  private
478
480
 
481
+ # Disabled checkbox inputs, without a hidden input.
482
+ def format_checkbox
483
+ @opts[:no_hidden] = true unless @opts.has_key?(:no_hidden)
484
+ super
485
+ end
486
+
479
487
  # Unless the :disabled option is specifically set
480
488
  # to +false+, set the :disabled attribute on the
481
489
  # resulting tag.
@@ -498,9 +506,10 @@ module Forme
498
506
 
499
507
  private
500
508
 
501
- # Disabled checkbox inputs.
509
+ # Disabled checkbox inputs, without a hidden input.
502
510
  def format_checkbox
503
511
  @attr[:disabled] = :disabled
512
+ @opts[:no_hidden] = true unless @opts.has_key?(:no_hidden)
504
513
  super
505
514
  end
506
515
 
@@ -87,10 +87,14 @@ module Forme
87
87
  end
88
88
 
89
89
  if (labels = opts[:labels]) && !labels.empty?
90
- form.emit(form.tag(:tr, {}, labels.map{|l| form._tag(:th, {}, l)}))
90
+ form.tag(:thead) do
91
+ form.emit(form.tag(:tr, {}, labels.map{|l| form._tag(:th, {}, l)}))
92
+ end
91
93
  end
92
94
 
93
- yield
95
+ form.tag(:tbody) do
96
+ yield
97
+ end
94
98
  end
95
99
  end
96
100
  end
@@ -36,9 +36,6 @@ module Forme
36
36
  if labels.length == 1
37
37
  ltd = labels
38
38
  rtd = other
39
- elsif a.length == 1
40
- ltd = [a.first]
41
- rtd = a[1..-1]
42
39
  else
43
40
  ltd = a
44
41
  end
data/lib/forme/version.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Forme
4
4
  # Version constant, use <tt>Forme.version</tt> instead.
5
- VERSION = '1.5.0'.freeze
5
+ VERSION = '1.6.0'.freeze
6
6
 
7
7
  # Returns the version as a frozen string (e.g. '0.1.0')
8
8
  def self.version
@@ -22,7 +22,7 @@ module Sequel # :nodoc:
22
22
  # overridden with the :method attribute.
23
23
  def form(attr={}, &block)
24
24
  attr = {:method=>:post}.merge(attr)
25
- attr[:class] = ::Forme.merge_classes(attr[:class], "forme", obj.model.send(:underscore, obj.model.name))
25
+ attr[:class] = ::Forme.merge_classes(attr[:class], "forme", obj.forme_namespace)
26
26
  super(attr, &block)
27
27
  end
28
28
 
@@ -44,6 +44,8 @@ module Sequel # :nodoc:
44
44
  # :inputs :: Automatically call +inputs+ with the given values. Using
45
45
  # this, it is not required to pass a block to the method,
46
46
  # though it will still work if you do.
47
+ # :inputs_opts :: When using the :grid option, this allows you to specify options
48
+ # to pass to the table InputsWrapper.
47
49
  # :legend :: Overrides the default :legend used (which is based on the
48
50
  # association name). You can also use a proc as the value,
49
51
  # which will called with each associated object (and the position
@@ -461,7 +463,7 @@ module Sequel # :nodoc:
461
463
  # Configure the +form+ with support for <tt>Sequel::Model</tt>
462
464
  # specific code, such as support for nested attributes.
463
465
  def forme_config(form)
464
- form.namespaces << model.send(:underscore, model.name)
466
+ form.namespaces << forme_namespace
465
467
  end
466
468
 
467
469
  # Return subclass of base form that includes the necessary Sequel form methods.
@@ -479,6 +481,11 @@ module Sequel # :nodoc:
479
481
  def forme_input(form, field, opts)
480
482
  SequelInput.new(self, form, field, opts).input
481
483
  end
484
+
485
+ # Use the underscored model name as the default namespace.
486
+ def forme_namespace
487
+ model.send(:underscore, model.name)
488
+ end
482
489
  end
483
490
  end
484
491
  end
@@ -424,23 +424,23 @@ describe "Forme Sequel::Model BS3 forms" do
424
424
  end
425
425
 
426
426
  it "should have #subform :grid option create a grid" do
427
- Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true)}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><tr><th>Name</th></tr><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
427
+ Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true)}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
428
428
  end
429
429
 
430
430
  it "should have #subform :grid option respect :inputs_opts option to pass options to inputs" do
431
- Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :inputs_opts=>{:attr=>{:class=>'foo'}})}.to_s.must_equal '<form class="forme album" method="post"><table class="foo"><caption>Artist</caption><tr><th>Name</th></tr><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
431
+ Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :inputs_opts=>{:attr=>{:class=>'foo'}})}.to_s.must_equal '<form class="forme album" method="post"><table class="foo"><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
432
432
  end
433
433
 
434
434
  it "should have #subform :grid option handle :legend and :labels options" do
435
- Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>'Foo', :labels=>%w'Bar')}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Foo</caption><tr><th>Bar</th></tr><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
435
+ Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>'Foo', :labels=>%w'Bar')}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Foo</caption><thead><tr><th>Bar</th></tr></thead><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
436
436
  end
437
437
 
438
438
  it "should have #subform :grid option handle :legend and :labels nil values" do
439
- Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>nil, :labels=>nil)}.to_s.must_equal '<form class="forme album" method="post"><table><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
439
+ Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>nil, :labels=>nil)}.to_s.must_equal '<form class="forme album" method="post"><table><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
440
440
  end
441
441
 
442
442
  it "should have #subform :grid option handle :skip_primary_key option" do
443
- Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :skip_primary_key=>true)}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><tr><th>Name</th></tr><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
443
+ Forme.form(@ab, {},{:config=>:bs3}){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :skip_primary_key=>true)}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><tr><td class="string"><input class="form-control" id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
444
444
  end
445
445
 
446
446
  end
data/spec/bs3_spec.rb CHANGED
@@ -217,6 +217,10 @@ describe "Forme Bootstrap3 (BS3) forms" do
217
217
  @f.input(:checkbox, :name=>"foo", :hidden_value=>"no").to_s.must_equal '<div class="checkbox"><input name="foo" type="hidden" value="no"/><input name="foo" type="checkbox"/></div>'
218
218
  end
219
219
 
220
+ it "should create hidden input" do
221
+ @f.input(:hidden).to_s.must_equal '<input type="hidden"/>'
222
+ end
223
+
220
224
  it "should handle :checked option" do
221
225
  @f.input(:checkbox, :checked=>true).to_s.must_equal '<div class="checkbox"><input checked="checked" type="checkbox"/></div>'
222
226
  @f.input(:checkbox, :checked=>false).to_s.must_equal '<div class="checkbox"><input type="checkbox"/></div>'
@@ -375,6 +379,10 @@ describe "Forme Bootstrap3 (BS3) forms" do
375
379
  @f.input(:radioset, :optgroups=>[['d', [[:a, 1], [:b, 2]]], ['e', [[:c, 3]]]], :selected=>2).to_s.must_equal '<div class="radioset"><fieldset><legend>d</legend><div class="radio"><label class="option"><input type="radio" value="1"/> a</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> b</label></div></fieldset><fieldset><legend>e</legend><div class="radio"><label class="option"><input type="radio" value="3"/> c</label></div></fieldset></div>'
376
380
  end
377
381
 
382
+ it "should create set of radio buttons with set label" do
383
+ @f.input(:radioset, :options=>[1, 2, 3], :selected=>2, :label=>'foo').to_s.must_equal '<div class="radioset"><label>foo</label><div class="radio"><label class="option"><input type="radio" value="1"/> 1</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> 2</label></div><div class="radio"><label class="option"><input type="radio" value="3"/> 3</label></div></div>'
384
+ end
385
+
378
386
  it "should create set of checkbox buttons" do
379
387
  @f.input(:checkboxset, :options=>[1, 2, 3], :selected=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> 3</label></div></div>'
380
388
  @f.input(:checkboxset, :options=>[1, 2, 3], :value=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> 3</label></div></div>'
@@ -500,6 +508,10 @@ describe "Forme Bootstrap3 (BS3) forms" do
500
508
  @f.button.to_s.must_equal '<input class="btn btn-default" type="submit"/>'
501
509
  end
502
510
 
511
+ it "#button should return a submit tag without label" do
512
+ @f.button(:label=>'foo').to_s.must_equal '<input class="btn btn-default" type="submit"/>'
513
+ end
514
+
503
515
  it "#button should accept an options hash" do
504
516
  @f.button(:name=>'foo', :value=>'bar').to_s.must_equal '<input class="btn btn-default" name="foo" type="submit" value="bar"/>'
505
517
  end
@@ -588,7 +600,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
588
600
  it "should format dates, times, and datetimes in ISO format" do
589
601
  @f.tag(:div, :foo=>Date.new(2011, 6, 5)).to_s.must_equal '<div foo="2011-06-05"></div>'
590
602
  @f.tag(:div, :foo=>DateTime.new(2011, 6, 5, 4, 3, 2)).to_s.must_equal '<div foo="2011-06-05T04:03:02.000000"></div>'
591
- @f.tag(:div, :foo=>Time.utc(2011, 6, 5, 4, 3, 2)).to_s.must_match /<div foo="2011-06-05T04:03:02.000000"><\/div>/ #/
603
+ @f.tag(:div, :foo=>Time.utc(2011, 6, 5, 4, 3, 2)).to_s.must_equal '<div foo="2011-06-05T04:03:02.000000"></div>'
592
604
  end
593
605
 
594
606
  it "should format bigdecimals in standard notation" do
@@ -621,6 +633,13 @@ describe "Forme Bootstrap3 (BS3) forms" do
621
633
  @f.input(:text, :formatter=>:bs3_readonly, :value=>'1', :label=>'Foo').to_s.must_equal '<div class="form-group"><label>Foo</label> <input class="form-control" readonly="readonly" type="text" value="1"/></div>'
622
634
  end
623
635
 
636
+ it "bs3_readonly formatter should disable checkbox, radio, select, and textarea inputs" do
637
+ @f.input(:checkbox, :formatter=>:bs3_readonly).to_s.must_equal '<div class="checkbox"><input disabled="disabled" type="checkbox"/></div>'
638
+ @f.input(:radio, :formatter=>:bs3_readonly).to_s.must_equal '<div class="radio"><input disabled="disabled" type="radio"/></div>'
639
+ @f.input(:select, :formatter=>:bs3_readonly).to_s.must_equal '<div class="form-group"><select class="form-control" disabled="disabled"></select></div>'
640
+ @f.input(:textarea, :formatter=>:bs3_readonly).to_s.must_equal '<div class="form-group"><textarea class="form-control" readonly="readonly"></textarea></div>'
641
+ end
642
+
624
643
  it "inputs should accept a :labeler option to use a custom labeler" do
625
644
  @f.input(:textarea, :labeler=>:explicit, :label=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><label class="label-before" for="foo">bar</label><textarea class="form-control" id="foo"></textarea></div>'
626
645
  end
@@ -648,6 +667,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
648
667
  it "#inputs should accept a :inputs_wrapper option to use a custom inputs_wrapper" do
649
668
  @f.inputs([:textarea], :inputs_wrapper=>:ol).to_s.must_equal '<ol><div class="form-group"><textarea class="form-control"></textarea></div></ol>'
650
669
  @f.inputs([:textarea], :inputs_wrapper=>:bs3_table, :wrapper=>:trtd).to_s.must_equal '<table class="table table-bordered"><tr><td><textarea class="form-control"></textarea></td><td></td></tr></table>'
670
+ @f.inputs([:textarea], :inputs_wrapper=>:bs3_table, :wrapper=>:trtd, :legend=>'Foo', :labels=>['bar']).to_s.must_equal '<table class="table table-bordered"><caption>Foo</caption><tr><th>bar</th></tr><tr><td><textarea class="form-control"></textarea></td><td></td></tr></table>'
651
671
  end
652
672
 
653
673
  it "inputs should accept a :wrapper=>nil option to not use a wrapper" do
data/spec/forme_spec.rb CHANGED
@@ -10,7 +10,7 @@ describe "Forme plain forms" do
10
10
  end
11
11
 
12
12
  it "Forme.version should return version string" do
13
- Forme.version.must_match /\A\d+\.\d+\.\d+\z/
13
+ Forme.version.must_match(/\A\d+\.\d+\.\d+\z/)
14
14
  end
15
15
 
16
16
  it "should create a simple input tags" do
@@ -216,6 +216,16 @@ describe "Forme plain forms" do
216
216
  @f.input(:checkbox, :name=>"foo").to_s.must_equal '<input name="foo" type="hidden" value="0"/><input name="foo" type="checkbox"/>'
217
217
  end
218
218
 
219
+ it "should not create hidden input with value 0 for readonly or disabled checkboxes" do
220
+ @f.input(:checkbox, :name=>"foo", :formatter=>:disabled).to_s.must_equal '<input disabled="disabled" name="foo" type="checkbox"/>'
221
+ @f.input(:checkbox, :name=>"foo", :formatter=>:readonly).to_s.must_equal '<input disabled="disabled" name="foo" type="checkbox"/>'
222
+ end
223
+
224
+ it "should create hidden input with value 0 for readonly or disabled checkboxes if no_hidden is explicitly given and not true" do
225
+ @f.input(:checkbox, :name=>"foo", :formatter=>:disabled, :no_hidden=>false).to_s.must_equal '<input name="foo" type="hidden" value="0"/><input disabled="disabled" name="foo" type="checkbox"/>'
226
+ @f.input(:checkbox, :name=>"foo", :formatter=>:readonly, :no_hidden=>false).to_s.must_equal '<input name="foo" type="hidden" value="0"/><input disabled="disabled" name="foo" type="checkbox"/>'
227
+ end
228
+
219
229
  it "should not create hidden input with value 0 for each checkbox with a name if :no_hidden option is used" do
220
230
  @f.input(:checkbox, :name=>"foo", :no_hidden=>true).to_s.must_equal '<input name="foo" type="checkbox"/>'
221
231
  end
@@ -390,6 +400,10 @@ describe "Forme plain forms" do
390
400
  @f.input(:radioset, :optgroups=>[['d', [[:a, 1], [:b, 2]]], ['e', [[:c, 3]]]], :selected=>2).to_s.must_equal '<fieldset><legend>d</legend><label class="option"><input type="radio" value="1"/> a</label><label class="option"><input checked="checked" type="radio" value="2"/> b</label></fieldset><fieldset><legend>e</legend><label class="option"><input type="radio" value="3"/> c</label></fieldset>'
391
401
  end
392
402
 
403
+ it "should create set of radio buttons with label attributes" do
404
+ @f.input(:radioset, :options=>[1, 2, 3], :selected=>2, :label_attr=>{:foo=>:bar}).to_s.must_equal '<label class="option" foo="bar"><input type="radio" value="1"/> 1</label><label class="option" foo="bar"><input checked="checked" type="radio" value="2"/> 2</label><label class="option" foo="bar"><input type="radio" value="3"/> 3</label>'
405
+ end
406
+
393
407
  it "should create set of checkbox buttons" do
394
408
  @f.input(:checkboxset, :options=>[1, 2, 3], :selected=>2).to_s.must_equal '<label class="option"><input type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option"><input type="checkbox" value="3"/> 3</label>'
395
409
  @f.input(:checkboxset, :options=>[1, 2, 3], :value=>2).to_s.must_equal '<label class="option"><input type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option"><input type="checkbox" value="3"/> 3</label>'
@@ -436,6 +450,10 @@ describe "Forme plain forms" do
436
450
  @f.input(:checkboxset, :optgroups=>[['d', [[:a, 1], [:b, 2]]], ['e', [[:c, 3]]]], :selected=>2).to_s.must_equal '<fieldset><legend>d</legend><label class="option"><input type="checkbox" value="1"/> a</label><label class="option"><input checked="checked" type="checkbox" value="2"/> b</label></fieldset><fieldset><legend>e</legend><label class="option"><input type="checkbox" value="3"/> c</label></fieldset>'
437
451
  end
438
452
 
453
+ it "should create set of checkbox buttons with label attributes" do
454
+ @f.input(:checkboxset, :options=>[1, 2, 3], :selected=>2, :label_attr=>{:foo=>:bar}).to_s.must_equal '<label class="option" foo="bar"><input type="checkbox" value="1"/> 1</label><label class="option" foo="bar"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option" foo="bar"><input type="checkbox" value="3"/> 3</label>'
455
+ end
456
+
439
457
  it "should raise an Error for empty checkbox sets" do
440
458
  @f.input(:checkboxset, :options=>[], :error=>'foo', :value=>2).to_s.must_equal '<span class="error_message">foo</span>'
441
459
  end
@@ -606,7 +624,7 @@ describe "Forme plain forms" do
606
624
  it "should format dates, times, and datetimes in ISO format" do
607
625
  @f.tag(:div, :foo=>Date.new(2011, 6, 5)).to_s.must_equal '<div foo="2011-06-05"></div>'
608
626
  @f.tag(:div, :foo=>DateTime.new(2011, 6, 5, 4, 3, 2)).to_s.must_equal '<div foo="2011-06-05T04:03:02.000000"></div>'
609
- @f.tag(:div, :foo=>Time.utc(2011, 6, 5, 4, 3, 2)).to_s.must_match /<div foo="2011-06-05T04:03:02.000000"><\/div>/
627
+ @f.tag(:div, :foo=>Time.utc(2011, 6, 5, 4, 3, 2)).to_s.must_equal '<div foo="2011-06-05T04:03:02.000000"></div>'
610
628
  end
611
629
 
612
630
  it "should format bigdecimals in standard notation" do
@@ -854,9 +872,9 @@ describe "Forme built-in custom" do
854
872
  end
855
873
 
856
874
  it "wrapper: table should use a trtd wrapper and table inputs_wrapper" do
857
- Forme::Form.new(:wrapper=>:table).inputs([:textarea]).to_s.must_equal '<table><tr><td><textarea></textarea></td><td></td></tr></table>'
875
+ Forme::Form.new(:wrapper=>:table).inputs([:textarea]).to_s.must_equal '<table><tbody><tr><td><textarea></textarea></td><td></td></tr></tbody></table>'
858
876
  f = Forme::Form.new
859
- f.with_opts(:wrapper=>:table){f.inputs([:textarea])}.to_s.must_equal '<table><tr><td><textarea></textarea></td><td></td></tr></table>'
877
+ f.with_opts(:wrapper=>:table){f.inputs([:textarea])}.to_s.must_equal '<table><tbody><tr><td><textarea></textarea></td><td></td></tr></tbody></table>'
860
878
  end
861
879
 
862
880
  it "wrapper: ol should use an li wrapper and ol inputs_wrapper" do
@@ -902,24 +920,24 @@ describe "Forme built-in custom" do
902
920
  end
903
921
 
904
922
  it "inputs_wrapper: table wraps tags in an table" do
905
- Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea]).to_s.must_equal '<table><tr><td><textarea></textarea></td><td></td></tr></table>'
906
- Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :attr=>{:foo=>1}).to_s.must_equal '<table foo="1"><tr><td><textarea></textarea></td><td></td></tr></table>'
923
+ Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea]).to_s.must_equal '<table><tbody><tr><td><textarea></textarea></td><td></td></tr></tbody></table>'
924
+ Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :attr=>{:foo=>1}).to_s.must_equal '<table foo="1"><tbody><tr><td><textarea></textarea></td><td></td></tr></tbody></table>'
907
925
  end
908
926
 
909
927
  it "inputs_wrapper: table accepts a :legend option" do
910
- Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :legend=>'Inputs').to_s.must_equal '<table><caption>Inputs</caption><tr><td><textarea></textarea></td><td></td></tr></table>'
928
+ Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :legend=>'Inputs').to_s.must_equal '<table><caption>Inputs</caption><tbody><tr><td><textarea></textarea></td><td></td></tr></tbody></table>'
911
929
  end
912
930
 
913
931
  it "inputs_wrapper: table accepts a :legend_attr option" do
914
- Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :legend=>'Inputs', :legend_attr=>{:class=>'foo'}).to_s.must_equal '<table><caption class="foo">Inputs</caption><tr><td><textarea></textarea></td><td></td></tr></table>'
932
+ Forme::Form.new(:inputs_wrapper=>:table, :wrapper=>:trtd).inputs([:textarea], :legend=>'Inputs', :legend_attr=>{:class=>'foo'}).to_s.must_equal '<table><caption class="foo">Inputs</caption><tbody><tr><td><textarea></textarea></td><td></td></tr></tbody></table>'
915
933
  end
916
934
 
917
935
  it "inputs_wrapper: table accepts a :labels option" do
918
- Forme::Form.new(:inputs_wrapper=>:table).inputs(:labels=>%w'A B C').to_s.must_equal '<table><tr><th>A</th><th>B</th><th>C</th></tr></table>'
936
+ Forme::Form.new(:inputs_wrapper=>:table).inputs(:labels=>%w'A B C').to_s.must_equal '<table><thead><tr><th>A</th><th>B</th><th>C</th></tr></thead><tbody></tbody></table>'
919
937
  end
920
938
 
921
939
  it "inputs_wrapper: table doesn't add empty header row for :labels=>[]" do
922
- Forme::Form.new(:inputs_wrapper=>:table).inputs(:labels=>[]).to_s.must_equal '<table></table>'
940
+ Forme::Form.new(:inputs_wrapper=>:table).inputs(:labels=>[]).to_s.must_equal '<table><tbody></tbody></table>'
923
941
  end
924
942
 
925
943
  it "serializer: html_usa formats dates and datetimes in American format without timezones" do
@@ -7,14 +7,23 @@ require 'action_controller/railtie'
7
7
  rescue LoadError
8
8
  warn "unable to load rails, skipping rails spec"
9
9
  else
10
+ begin
11
+ require 'active_pack/gem_version'
12
+ rescue LoadError
13
+ end
10
14
  require 'forme/rails'
11
15
 
12
16
  class FormeRails < Rails::Application
13
- config.secret_token = routes.append { get ':action' , :controller=>'forme' }.inspect
17
+ routes.append do
18
+ %w'index inputs_block inputs_block_wrapper nest nest_sep nest_inputs nest_seq hash legend combined noblock noblock_post safe_buffer'.each do |action|
19
+ get action, :controller=>'forme', :action=>action
20
+ end
21
+ end
14
22
  config.active_support.deprecation = :stderr
15
23
  config.middleware.delete(ActionDispatch::ShowExceptions)
16
- config.middleware.delete("Rack::Lock")
17
- config.secret_key_base = 'foo'
24
+ config.middleware.delete(Rack::Lock)
25
+ config.secret_key_base = 'foo'*15
26
+ config.secret_token = 'secret token'*15
18
27
  config.eager_load = true
19
28
  initialize!
20
29
  end
@@ -217,8 +226,14 @@ describe "Forme Rails integration" do
217
226
  sin_get('/nest_inputs').must_equal "0 <form action=\"/baz\"> 1 <p>FBB</p> 2 n1 <fieldset class=\"inputs\"> n2 <input id=\"first\" name=\"first\" type=\"text\" value=\"foo\"/> <input id=\"last\" name=\"last\" type=\"text\" value=\"bar\"/> n3 </fieldset> n4 <fieldset class=\"inputs\"><legend>Foo</legend><input id=\"first\" name=\"first\" type=\"text\" value=\"foo\"/><input id=\"last\" name=\"last\" type=\"text\" value=\"bar\"/></fieldset> n5 3 </form>4"
218
227
  end
219
228
 
220
- it "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
221
- sin_get('/nest_seq').sub(%r{<input name=\"authenticity_token\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"authenticity_token\" type=\"hidden\" value=\"csrf\"/>").must_equal "0 <form action=\"/baz\" class=\"forme album\" method=\"post\"><input name=\"authenticity_token\" type=\"hidden\" value=\"csrf\"/> 1 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/><fieldset class=\"inputs\"><legend>Foo</legend><label>Name: <input id=\"album_artist_attributes_name\" name=\"album[artist_attributes][name]\" type=\"text\" value=\"A\"/></label></fieldset> 2 n1 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/><fieldset class=\"inputs\"><legend>Artist</legend> n2 <label>Name2: <input id=\"album_artist_attributes_name2\" name=\"album[artist_attributes][name2]\" type=\"text\" value=\"A2\"/></label> n3 </fieldset> n4 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/><fieldset class=\"inputs\"><legend>Bar</legend><label>Name3: <input id=\"album_artist_attributes_name3\" name=\"album[artist_attributes][name3]\" type=\"text\" value=\"A3\"/></label></fieldset> n5 3 </form>4"
229
+ unless defined?(JRUBY_VERSION) && JRUBY_VERSION =~ /\A9\.0/ && defined?(ActionPack::VERSION::STRING) && ActionPack::VERSION::STRING >= '5.1'
230
+ it "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
231
+ sin_get('/nest_seq').sub(%r{<input name=\"authenticity_token\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"authenticity_token\" type=\"hidden\" value=\"csrf\"/>").must_equal "0 <form action=\"/baz\" class=\"forme album\" method=\"post\"><input name=\"authenticity_token\" type=\"hidden\" value=\"csrf\"/> 1 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/><fieldset class=\"inputs\"><legend>Foo</legend><label>Name: <input id=\"album_artist_attributes_name\" name=\"album[artist_attributes][name]\" type=\"text\" value=\"A\"/></label></fieldset> 2 n1 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/><fieldset class=\"inputs\"><legend>Artist</legend> n2 <label>Name2: <input id=\"album_artist_attributes_name2\" name=\"album[artist_attributes][name2]\" type=\"text\" value=\"A2\"/></label> n3 </fieldset> n4 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/><fieldset class=\"inputs\"><legend>Bar</legend><label>Name3: <input id=\"album_artist_attributes_name3\" name=\"album[artist_attributes][name3]\" type=\"text\" value=\"A3\"/></label></fieldset> n5 3 </form>4"
232
+ end
233
+
234
+ it "#form should work without a block with hidden tags" do
235
+ sin_get('/noblock_post').sub(%r{<input name=\"authenticity_token\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"authenticity_token\" type=\"hidden\" value=\"csrf\"/>").must_equal '<form method="post"><input name="authenticity_token" type="hidden" value="csrf"/><input type="submit" value="xyz"/></form>'
236
+ end
222
237
  end
223
238
 
224
239
  it "#form should accept two hashes instead of requiring obj as first argument" do
@@ -237,10 +252,6 @@ describe "Forme Rails integration" do
237
252
  sin_get('/noblock').must_equal '<form action="/baz"><fieldset class="inputs"><legend>123</legend><input id="first" name="first" type="text" value="foo"/></fieldset><input type="submit" value="xyz"/></form>'
238
253
  end
239
254
 
240
- it "#form should work without a block with hidden tags" do
241
- sin_get('/noblock_post').sub(%r{<input name=\"authenticity_token\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"authenticity_token\" type=\"hidden\" value=\"csrf\"/>").must_equal '<form method="post"><input name="authenticity_token" type="hidden" value="csrf"/><input type="submit" value="xyz"/></form>'
242
- end
243
-
244
255
  it "#form should handle Rails SafeBuffers" do
245
256
  sin_get('/safe_buffer').must_equal '<form action="/baz"><fieldset class="inputs"><legend><b>foo</b></legend><input id="first" name="first" type="text" value="foo"/></fieldset><input type="submit" value="xyz"/></form>'
246
257
  end
@@ -1,8 +1,9 @@
1
1
  require 'rubygems'
2
- require 'sequel/no_core_ext'
2
+ require 'sequel'
3
3
 
4
4
  db_url = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' ? 'jdbc:sqlite::memory:' : 'sqlite:/'
5
- DB = Sequel.connect(db_url)
5
+ DB = Sequel.connect(db_url, :identifier_mangling=>false)
6
+ DB.extension(:freeze_datasets)
6
7
  Sequel.default_timezone = :utc
7
8
  DB.create_table(:artists) do
8
9
  primary_key :id
@@ -46,7 +47,7 @@ c = DB[:albums].insert(:name=>'c', :artist_id=>d, :gold=>true, :platinum=>true)
46
47
  DB[:tracks].insert(:name=>'o', :album_id=>c)
47
48
  s = DB[:tags].insert(:name=>'s')
48
49
  t = DB[:tags].insert(:name=>'t')
49
- u = DB[:tags].insert(:name=>'u')
50
+ DB[:tags].insert(:name=>'u')
50
51
  [[b, s], [b, t], [c, t]].each{|k, v| DB[:albums_tags].insert(k, v)}
51
52
 
52
53
  Sequel::Model.plugin :forme
@@ -21,7 +21,7 @@ DB.create_table(:clients) do
21
21
  end
22
22
 
23
23
  a = DB[:firms].insert(:name=>'a')
24
- b = DB[:invoices].insert(:name=>'b', :firm_id=>a, :summary=>'a brief summary')
24
+ DB[:invoices].insert(:name=>'b', :firm_id=>a, :summary=>'a brief summary')
25
25
  DB[:clients].insert(:name=>'a great client', :firm_id=>a)
26
26
 
27
27
  class Firm < Sequel::Model
@@ -426,23 +426,23 @@ describe "Forme Sequel::Model forms" do
426
426
  end
427
427
 
428
428
  it "should have #subform :grid option create a grid" do
429
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true)}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><tr><th>Name</th></tr><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
429
+ Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true)}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
430
430
  end
431
431
 
432
432
  it "should have #subform :grid option respect :inputs_opts option to pass options to inputs" do
433
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :inputs_opts=>{:attr=>{:class=>'foo'}})}.to_s.must_equal '<form class="forme album" method="post"><table class="foo"><caption>Artist</caption><tr><th>Name</th></tr><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
433
+ Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :inputs_opts=>{:attr=>{:class=>'foo'}})}.to_s.must_equal '<form class="forme album" method="post"><table class="foo"><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
434
434
  end
435
435
 
436
436
  it "should have #subform :grid option handle :legend and :labels options" do
437
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>'Foo', :labels=>%w'Bar')}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Foo</caption><tr><th>Bar</th></tr><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
437
+ Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>'Foo', :labels=>%w'Bar')}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Foo</caption><thead><tr><th>Bar</th></tr></thead><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
438
438
  end
439
439
 
440
440
  it "should have #subform :grid option handle :legend and :labels nil values" do
441
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>nil, :labels=>nil)}.to_s.must_equal '<form class="forme album" method="post"><table><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
441
+ Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>nil, :labels=>nil)}.to_s.must_equal '<form class="forme album" method="post"><table><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
442
442
  end
443
443
 
444
444
  it "should have #subform :grid option handle :skip_primary_key option" do
445
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :skip_primary_key=>true)}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><tr><th>Name</th></tr><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></table></form>'
445
+ Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :skip_primary_key=>true)}.to_s.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><tr><td class="string"><input id="album_artist_attributes_name" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
446
446
  end
447
447
 
448
448
  end
@@ -525,3 +525,52 @@ describe "Forme Sequel::Model validation parsing" do
525
525
 
526
526
  end
527
527
 
528
+ describe "Forme Sequel::Model default namespacing" do
529
+ before do
530
+ module Foo
531
+ class Album < ::Album
532
+ end
533
+ end
534
+
535
+ @ab = Foo::Album[1]
536
+ @b = Forme::Form.new(@ab)
537
+ end
538
+ after do
539
+ Object.send(:remove_const, :Foo)
540
+ end
541
+
542
+ it "namespaces the form class" do
543
+ @b.form.to_s.must_equal '<form class="forme foo/album" method="post"></form>'
544
+ end
545
+
546
+ it "namespaces the input id and name" do
547
+ @b.input(:name).to_s.must_equal '<label>Name: <input id="foo/album_name" name="foo/album[name]" type="text" value="b"/></label>'
548
+ end
549
+ end
550
+
551
+ describe "Forme Sequel::Model custom namespacing" do
552
+ before do
553
+ module Bar
554
+ class Album < ::Album
555
+ def forme_namespace
556
+ 'bar_album'
557
+ end
558
+ end
559
+ end
560
+
561
+ @ab = Bar::Album[1]
562
+ @b = Forme::Form.new(@ab)
563
+ end
564
+ after do
565
+ Object.send(:remove_const, :Bar)
566
+ end
567
+
568
+ it "namespaces the form class" do
569
+ @b.form.to_s.must_equal '<form class="forme bar_album" method="post"></form>'
570
+ end
571
+
572
+ it "namespaces the form input and name" do
573
+ @b.input(:name).to_s.must_equal '<label>Name: <input id="bar_album_name" name="bar_album[name]" type="text" value="b"/></label>'
574
+ end
575
+
576
+ end
@@ -9,15 +9,15 @@ describe "Sequel forme_set plugin" do
9
9
 
10
10
  it "#forme_set should only set values in the form" do
11
11
  @ab.forme_set(:name=>'Foo')
12
- @ab.name.must_equal nil
12
+ @ab.name.must_be_nil
13
13
 
14
14
  @f.input(:name)
15
15
  @ab.forme_set(:name=>'Foo')
16
16
  @ab.name.must_equal 'Foo'
17
17
 
18
18
  @ab.forme_set('copies_sold'=>'1')
19
- @ab.name.must_equal nil
20
- @ab.copies_sold.must_equal nil
19
+ @ab.name.must_be_nil
20
+ @ab.copies_sold.must_be_nil
21
21
 
22
22
  @f.input(:copies_sold)
23
23
  @ab.forme_set('name'=>'Bar', 'copies_sold'=>'1')
@@ -30,7 +30,7 @@ describe "Sequel forme_set plugin" do
30
30
  @f.input(:name, opts)
31
31
 
32
32
  @ab.forme_set(:name=>'Foo')
33
- @ab.name.must_equal nil
33
+ @ab.name.must_be_nil
34
34
 
35
35
  @ab.forme_set('foo'=>'Foo')
36
36
  @ab.name.must_equal 'Foo'
@@ -41,19 +41,19 @@ describe "Sequel forme_set plugin" do
41
41
  it "#forme_set should ignore values where key is explicitly set to nil" do
42
42
  @f.input(:name, :key=>nil)
43
43
  @ab.forme_set(:name=>'Foo')
44
- @ab.name.must_equal nil
44
+ @ab.name.must_be_nil
45
45
  @ab.forme_set(nil=>'Foo')
46
- @ab.name.must_equal nil
46
+ @ab.name.must_be_nil
47
47
  end
48
48
 
49
49
  it "#forme_set should skip inputs with disabled/readonly formatter" do
50
50
  @f.input(:name, :formatter=>:disabled)
51
51
  @ab.forme_set(:name=>'Foo')
52
- @ab.name.must_equal nil
52
+ @ab.name.must_be_nil
53
53
 
54
54
  @f.input(:name, :formatter=>:readonly)
55
55
  @ab.forme_set(:name=>'Foo')
56
- @ab.name.must_equal nil
56
+ @ab.name.must_be_nil
57
57
 
58
58
  @f.input(:name, :formatter=>:default)
59
59
  @ab.forme_set(:name=>'Foo')
@@ -64,12 +64,12 @@ describe "Sequel forme_set plugin" do
64
64
  @f = Forme::Form.new(@ab, :formatter=>:disabled)
65
65
  @f.input(:name)
66
66
  @ab.forme_set(:name=>'Foo')
67
- @ab.name.must_equal nil
67
+ @ab.name.must_be_nil
68
68
 
69
69
  @f = Forme::Form.new(@ab, :formatter=>:readonly)
70
70
  @f.input(:name)
71
71
  @ab.forme_set(:name=>'Foo')
72
- @ab.name.must_equal nil
72
+ @ab.name.must_be_nil
73
73
 
74
74
  @f.input(:name, :formatter=>:default)
75
75
  @ab.forme_set(:name=>'Foo')
@@ -78,14 +78,14 @@ describe "Sequel forme_set plugin" do
78
78
 
79
79
  it "#forme_set should handle setting values for associated objects" do
80
80
  @ab.forme_set(:artist_id=>1)
81
- @ab.artist_id.must_equal nil
81
+ @ab.artist_id.must_be_nil
82
82
 
83
83
  @f.input(:artist)
84
84
  @ab.forme_set(:artist_id=>'1')
85
85
  @ab.artist_id.must_equal 1
86
86
 
87
87
  @ab.forme_set('tag_pks'=>%w'1 2')
88
- @ab.artist_id.must_equal nil
88
+ @ab.artist_id.must_be_nil
89
89
  @ab.tag_pks.must_equal []
90
90
 
91
91
  @f.input(:tags)
@@ -120,7 +120,7 @@ describe "Sequel forme_set plugin" do
120
120
  @ab.forme_set('artist_id'=>'1', 'tag_pks'=>['2'])
121
121
  @ab.valid?.must_equal false
122
122
  @ab.errors[:artist_id].must_equal ['invalid value submitted']
123
- @ab.errors[:tag_pks].must_equal nil
123
+ @ab.errors[:tag_pks].must_be_nil
124
124
 
125
125
  @ab.forme_validations.clear
126
126
  @ab.forme_set('artist_id'=>'2', 'tag_pks'=>['2'])
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  $:.unshift(File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'lib'))
2
2
 
3
+ if ENV['WARNING']
4
+ require 'warning'
5
+ Warning.ignore(:missing_ivar)
6
+ end
7
+
3
8
  if ENV['COVERAGE']
4
9
  require File.join(File.dirname(File.expand_path(__FILE__)), "forme_coverage")
5
10
  SimpleCov.forme_coverage
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forme
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-09 00:00:00.000000000 Z
11
+ date: 2017-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -219,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
219
  version: '0'
220
220
  requirements: []
221
221
  rubyforge_project:
222
- rubygems_version: 2.5.1
222
+ rubygems_version: 2.6.11
223
223
  signing_key:
224
224
  specification_version: 4
225
225
  summary: HTML forms library