forme 1.5.0 → 1.6.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 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