forme 0.7.0 → 0.8.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 +7 -0
- data/CHANGELOG +12 -0
- data/README.rdoc +1 -1
- data/lib/forme.rb +59 -10
- data/lib/forme/rails.rb +24 -3
- data/lib/forme/sinatra.rb +21 -4
- data/lib/forme/version.rb +1 -1
- data/lib/sequel/plugins/forme.rb +1 -1
- data/spec/forme_spec.rb +44 -0
- data/spec/rails_integration_spec.rb +13 -3
- data/spec/sequel_plugin_spec.rb +12 -1
- data/spec/sinatra_integration_spec.rb +19 -10
- metadata +10 -17
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 06d7e50cfae657572071affb86ef307636c65345
         | 
| 4 | 
            +
              data.tar.gz: 5eef25b91f833f3a57caef3903d25886cb48f00d
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: a19e5579fc8f0bfe11c5136f2ecc69db057a23f76d08bc01aad4680c1ebeb9fbd27476a04d60265efe5de1d1e5ab0b16dd615f8bc0081c7b733ef9f188e31581
         | 
| 7 | 
            +
              data.tar.gz: ba0fe6ba4e18fe182c0a93eb9b33f28e0d0f30729ec537f2a3b468d8b9db56a75d657aadb17b4c164a3128d901017d7460a7ce8ecd9bd8a923d5017bc1e4d051
         | 
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,3 +1,15 @@ | |
| 1 | 
            +
            === 0.8.0 (2013-10-30)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * form calls without block or :inputs or :button options are now handled correctly in the Sinatra integration (jeremyevans)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * CSRF token tags are now automatically added to forms in Rails and Sinatra if using rack_csrf (jeremyevans) (#5)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Form objects now support a :hidden_tags option for automatically adding hidden tags (jeremyevans)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * Sequel many_to_one associations with existing and required values no longer have a blank option added by default (jeremyevans)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            * ActiveSupport::SafeBuffer objects are now automatically treated as raw in the Rails integration (jeremyevans)
         | 
| 12 | 
            +
             | 
| 1 13 | 
             
            === 0.7.0 (2012-05-02)
         | 
| 2 14 |  | 
| 3 15 | 
             
            * Support :label_position option in both of the labelers, can be set to :before or :after to override the default (jeremyevans)
         | 
    
        data/README.rdoc
    CHANGED
    
    | @@ -76,7 +76,7 @@ You can even do everything in a single method call: | |
| 76 76 |  | 
| 77 77 | 
             
            = Basic Design
         | 
| 78 78 |  | 
| 79 | 
            -
             | 
| 79 | 
            +
            Internally, Forme builds an abstract syntax tree of objects that
         | 
| 80 80 | 
             
            represent the form.  The abstract syntax tree goes through a
         | 
| 81 81 | 
             
            series of transformations that convert it from high level
         | 
| 82 82 | 
             
            abstract forms to low level abstract forms and finally to
         | 
    
        data/lib/forme.rb
    CHANGED
    
    | @@ -99,7 +99,7 @@ module Forme | |
| 99 99 | 
             
              #                       +obj+ or +block+, but not both.  If +obj+ is given, should be
         | 
| 100 100 | 
             
              #                       either a +Class+ instance or it should respond to +call+.  If a
         | 
| 101 101 | 
             
              #                       +Class+ instance is given, instances of that class should respond
         | 
| 102 | 
            -
              #                       to +call+, and  | 
| 102 | 
            +
              #                       to +call+, and a new instance of that class should be used
         | 
| 103 103 | 
             
              #                       for each transformation.
         | 
| 104 104 | 
             
              def self.register_transformer(type, sym, obj=nil, &block)
         | 
| 105 105 | 
             
                raise Error, "Not a valid transformer type" unless TRANSFORMERS.has_key?(type)
         | 
| @@ -145,6 +145,7 @@ module Forme | |
| 145 145 | 
             
                # :obj :: Sets the +obj+ attribute
         | 
| 146 146 | 
             
                # :error_handler :: Sets the +error_handler+ for the form
         | 
| 147 147 | 
             
                # :formatter :: Sets the +formatter+ for the form
         | 
| 148 | 
            +
                # :hidden_tags :: Sets the hidden tags to automatically add to this form.
         | 
| 148 149 | 
             
                # :inputs_wrapper :: Sets the +inputs_wrapper+ for the form
         | 
| 149 150 | 
             
                # :labeler :: Sets the +labeler+ for the form
         | 
| 150 151 | 
             
                # :wrapper :: Sets the +wrapper+ for the form
         | 
| @@ -175,6 +176,15 @@ module Forme | |
| 175 176 | 
             
                # Must respond to +call+ or be a registered symbol.
         | 
| 176 177 | 
             
                attr_reader :serializer
         | 
| 177 178 |  | 
| 179 | 
            +
                # The hidden tags to automatically add to the form.  If set, this should be an
         | 
| 180 | 
            +
                # array, where elements are one of the following types:
         | 
| 181 | 
            +
                # String, Array, Forme::Tag :: Added directly as a child of the form tag.
         | 
| 182 | 
            +
                # Hash :: Adds a hidden tag for each entry, with keys as the name of the hidden
         | 
| 183 | 
            +
                #         tag and values as the value of the hidden tag.
         | 
| 184 | 
            +
                # Proc :: Will be called with the form tag object, and should return an instance
         | 
| 185 | 
            +
                #         of one of the handled types (or nil to not add a tag).
         | 
| 186 | 
            +
                attr_reader :hidden_tags
         | 
| 187 | 
            +
             | 
| 178 188 | 
             
                # Create a +Form+ instance and yield it to the block,
         | 
| 179 189 | 
             
                # injecting the opening form tag before yielding and
         | 
| 180 190 | 
             
                # the closing form tag after yielding.
         | 
| @@ -232,6 +242,7 @@ module Forme | |
| 232 242 | 
             
                  end
         | 
| 233 243 | 
             
                  config = CONFIGURATIONS[@opts[:config]||Forme.default_config]
         | 
| 234 244 | 
             
                  TRANSFORMER_TYPES.each{|k| instance_variable_set(:"@#{k}", transformer(k, @opts.fetch(k, config[k])))}
         | 
| 245 | 
            +
                  @hidden_tags = @opts[:hidden_tags]
         | 
| 235 246 | 
             
                  @nesting = []
         | 
| 236 247 | 
             
                end
         | 
| 237 248 |  | 
| @@ -285,7 +296,7 @@ module Forme | |
| 285 296 |  | 
| 286 297 | 
             
                # Create a form tag with the given attributes.
         | 
| 287 298 | 
             
                def form(attr={}, &block)
         | 
| 288 | 
            -
                  tag(:form, attr, &block)
         | 
| 299 | 
            +
                  tag(:form, attr, method(:hidden_form_tags), &block)
         | 
| 289 300 | 
             
                end
         | 
| 290 301 |  | 
| 291 302 | 
             
                # Formats the +input+ using the +formatter+.
         | 
| @@ -429,6 +440,35 @@ module Forme | |
| 429 440 |  | 
| 430 441 | 
             
                private
         | 
| 431 442 |  | 
| 443 | 
            +
                # Return array of hidden tags to use for this form,
         | 
| 444 | 
            +
                # or nil if the form does not have hidden tags added automatically.
         | 
| 445 | 
            +
                def hidden_form_tags(form_tag)
         | 
| 446 | 
            +
                  if hidden_tags
         | 
| 447 | 
            +
                    tags = []
         | 
| 448 | 
            +
                    hidden_tags.each do |hidden_tag|
         | 
| 449 | 
            +
                      hidden_tag = hidden_tag.call(form_tag) if hidden_tag.respond_to?(:call)
         | 
| 450 | 
            +
                      tags.concat(parse_hidden_tags(hidden_tag))
         | 
| 451 | 
            +
                    end
         | 
| 452 | 
            +
                    tags
         | 
| 453 | 
            +
                  end
         | 
| 454 | 
            +
                end
         | 
| 455 | 
            +
             | 
| 456 | 
            +
                # Handle various types of hidden tags for the form.
         | 
| 457 | 
            +
                def parse_hidden_tags(hidden_tag)
         | 
| 458 | 
            +
                  case hidden_tag
         | 
| 459 | 
            +
                  when Array
         | 
| 460 | 
            +
                    hidden_tag
         | 
| 461 | 
            +
                  when Tag, String
         | 
| 462 | 
            +
                    [hidden_tag]
         | 
| 463 | 
            +
                  when Hash
         | 
| 464 | 
            +
                    hidden_tag.map{|k,v| _tag(:input, :type=>:hidden, :name=>k, :value=>v)}
         | 
| 465 | 
            +
                  when nil
         | 
| 466 | 
            +
                    []
         | 
| 467 | 
            +
                  else
         | 
| 468 | 
            +
                    raise Error, "unhandled hidden_tag response: #{hidden_tag.inspect}"
         | 
| 469 | 
            +
                  end
         | 
| 470 | 
            +
                end
         | 
| 471 | 
            +
             | 
| 432 472 | 
             
                # Extend +obj+ with +Serialized+ and associate it with the receiver, such
         | 
| 433 473 | 
             
                # that calling +to_s+ on the object will use the receiver's serializer
         | 
| 434 474 | 
             
                # to generate the resulting string.
         | 
| @@ -530,15 +570,8 @@ module Forme | |
| 530 570 |  | 
| 531 571 | 
             
                # Set the +form+, +type+, +attr+, and +children+.
         | 
| 532 572 | 
             
                def initialize(form, type, attr={}, children=nil)
         | 
| 533 | 
            -
                  case children
         | 
| 534 | 
            -
                  when Array
         | 
| 535 | 
            -
                    @children = children
         | 
| 536 | 
            -
                  when nil
         | 
| 537 | 
            -
                    @children = nil
         | 
| 538 | 
            -
                  else
         | 
| 539 | 
            -
                    @children = [children]
         | 
| 540 | 
            -
                  end
         | 
| 541 573 | 
             
                  @form, @type, @attr = form, type, (attr||{})
         | 
| 574 | 
            +
                  @children = parse_children(children)
         | 
| 542 575 | 
             
                end
         | 
| 543 576 |  | 
| 544 577 | 
             
                # Adds a child to the array of receiver's children.
         | 
| @@ -560,6 +593,22 @@ module Forme | |
| 560 593 | 
             
                def to_s
         | 
| 561 594 | 
             
                  form.serialize(self)
         | 
| 562 595 | 
             
                end
         | 
| 596 | 
            +
             | 
| 597 | 
            +
                private
         | 
| 598 | 
            +
             | 
| 599 | 
            +
                # Convert children constructor argument into the children to use for the tag.
         | 
| 600 | 
            +
                def parse_children(children)
         | 
| 601 | 
            +
                  case children
         | 
| 602 | 
            +
                  when Array
         | 
| 603 | 
            +
                    children
         | 
| 604 | 
            +
                  when Proc, Method
         | 
| 605 | 
            +
                    parse_children(children.call(self))
         | 
| 606 | 
            +
                  when nil
         | 
| 607 | 
            +
                    nil
         | 
| 608 | 
            +
                  else
         | 
| 609 | 
            +
                    [children]
         | 
| 610 | 
            +
                  end
         | 
| 611 | 
            +
                end
         | 
| 563 612 | 
             
              end
         | 
| 564 613 |  | 
| 565 614 | 
             
              # Module that can extend objects associating them with a specific
         | 
    
        data/lib/forme/rails.rb
    CHANGED
    
    | @@ -1,7 +1,28 @@ | |
| 1 1 | 
             
            require 'forme'
         | 
| 2 2 |  | 
| 3 | 
            +
            class ActiveSupport::SafeBuffer
         | 
| 4 | 
            +
              include Forme::Raw
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 3 7 | 
             
            module Forme
         | 
| 4 | 
            -
              module Rails | 
| 8 | 
            +
              module Rails
         | 
| 9 | 
            +
                HIDDEN_TAGS = []
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                # Add a hidden tag proc that will be used for all forms created via Forme::Rails::ERB#form.
         | 
| 12 | 
            +
                # The block is yielded the Forme::Tag object for the form tag.
         | 
| 13 | 
            +
                # The block should return either nil if hidden tag should be added, or a Forme::Tag object (or an array of them),
         | 
| 14 | 
            +
                # or a hash with keys specifying the name of the tags and the values specifying the values of the tags .
         | 
| 15 | 
            +
                def self.add_hidden_tag(&block)
         | 
| 16 | 
            +
                  HIDDEN_TAGS << block
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # Add CSRF token tag by default for POST forms
         | 
| 20 | 
            +
                add_hidden_tag do |tag|
         | 
| 21 | 
            +
                  if (form = tag.form) && (template = form.template) && template.protect_against_forgery? && tag.attr[:method].to_s.upcase == 'POST'
         | 
| 22 | 
            +
                    {template.request_forgery_protection_token=>template.form_authenticity_token}
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 5 26 | 
             
                # Subclass used when using Forme/Rails ERB integration,
         | 
| 6 27 | 
             
                # handling integration with the view template.
         | 
| 7 28 | 
             
                class Form < ::Forme::Form
         | 
| @@ -66,7 +87,7 @@ module Forme | |
| 66 87 | 
             
                  def tag_(type, attr={}, children=[])
         | 
| 67 88 | 
             
                    tag = _tag(type, attr, children)
         | 
| 68 89 | 
             
                    emit(serializer.serialize_open(tag)) if serializer.respond_to?(:serialize_open)
         | 
| 69 | 
            -
                    Array(children).each{|c| emit(c)}
         | 
| 90 | 
            +
                    Array(tag.children).each{|c| emit(c)}
         | 
| 70 91 | 
             
                    yield self if block_given?
         | 
| 71 92 | 
             
                    emit(serializer.serialize_close(tag)) if serializer.respond_to?(:serialize_close)
         | 
| 72 93 | 
             
                  end
         | 
| @@ -90,7 +111,7 @@ module Forme | |
| 90 111 | 
             
                  #                                  opening attributes, third if provided is
         | 
| 91 112 | 
             
                  #                                  +Form+'s options.
         | 
| 92 113 | 
             
                  def forme(obj=nil, attr={}, opts={}, &block)
         | 
| 93 | 
            -
                    h = {:template=>self}
         | 
| 114 | 
            +
                    h = {:template=>self, :hidden_tags=>Forme::Rails::HIDDEN_TAGS}
         | 
| 94 115 | 
             
                    (obj.is_a?(Hash) ? attr = attr.merge(h) : opts = opts.merge(h))
         | 
| 95 116 | 
             
                    Form.form(obj, attr, opts, &block)
         | 
| 96 117 | 
             
                  end
         | 
    
        data/lib/forme/sinatra.rb
    CHANGED
    
    | @@ -1,7 +1,24 @@ | |
| 1 1 | 
             
            require 'forme'
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Forme
         | 
| 4 | 
            -
              module Sinatra | 
| 4 | 
            +
              module Sinatra
         | 
| 5 | 
            +
                HIDDEN_TAGS = []
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                # Add a hidden tag proc that will be used for all forms created via Forme::Sinatra::ERB#form.
         | 
| 8 | 
            +
                # The block is yielded the Forme::Tag object for the form tag.
         | 
| 9 | 
            +
                # The block should return either nil if hidden tag should be added, or a Forme::Tag object (or an array of them),
         | 
| 10 | 
            +
                # or a hash with keys specifying the name of the tags and the values specifying the values of the tags .
         | 
| 11 | 
            +
                def self.add_hidden_tag(&block)
         | 
| 12 | 
            +
                  HIDDEN_TAGS << block
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                # Add CSRF token tag by default for POST forms
         | 
| 16 | 
            +
                add_hidden_tag do |tag|
         | 
| 17 | 
            +
                  if defined?(::Rack::Csrf) && (form = tag.form) && (env = form.opts[:env]) && tag.attr[:method].to_s.upcase == 'POST'
         | 
| 18 | 
            +
                    {::Rack::Csrf.field=>::Rack::Csrf.token(env)}
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 5 22 | 
             
                # Subclass used when using Forme/Sinatra ERB integration.
         | 
| 6 23 | 
             
                # Handles integrating into the view template so that
         | 
| 7 24 | 
             
                # methods with blocks can inject strings into the output.
         | 
| @@ -37,7 +54,7 @@ module Forme | |
| 37 54 | 
             
                    if block
         | 
| 38 55 | 
             
                      capture(block){super}
         | 
| 39 56 | 
             
                    else
         | 
| 40 | 
            -
                       | 
| 57 | 
            +
                      super
         | 
| 41 58 | 
             
                    end
         | 
| 42 59 | 
             
                  end
         | 
| 43 60 |  | 
| @@ -50,7 +67,7 @@ module Forme | |
| 50 67 | 
             
                    if block
         | 
| 51 68 | 
             
                      capture(block) do
         | 
| 52 69 | 
             
                        emit(serializer.serialize_open(tag)) if serializer.respond_to?(:serialize_open)
         | 
| 53 | 
            -
                        children.each{|c| emit(c)}
         | 
| 70 | 
            +
                        Array(tag.children).each{|c| emit(c)}
         | 
| 54 71 | 
             
                        yield self
         | 
| 55 72 | 
             
                        emit(serializer.serialize_close(tag)) if serializer.respond_to?(:serialize_close)
         | 
| 56 73 | 
             
                      end
         | 
| @@ -92,7 +109,7 @@ module Forme | |
| 92 109 | 
             
                  #                                  +Form+'s options.
         | 
| 93 110 | 
             
                  def form(obj=nil, attr={}, opts={}, &block)
         | 
| 94 111 | 
             
                    if block
         | 
| 95 | 
            -
                      h = {:output=>@_out_buf}
         | 
| 112 | 
            +
                      h = {:output=>@_out_buf, :hidden_tags=>Forme::Sinatra::HIDDEN_TAGS, :env=>env}
         | 
| 96 113 | 
             
                      (obj.is_a?(Hash) ? attr = attr.merge(h) : opts = opts.merge(h))
         | 
| 97 114 | 
             
                      Form.form(obj, attr, opts, &block)
         | 
| 98 115 | 
             
                    else
         | 
    
        data/lib/forme/version.rb
    CHANGED
    
    
    
        data/lib/sequel/plugins/forme.rb
    CHANGED
    
    | @@ -309,8 +309,8 @@ module Sequel # :nodoc: | |
| 309 309 | 
             
                        wrapper ? wrapper.call(radios, _input(:radio, opts)) : radios
         | 
| 310 310 | 
             
                      else
         | 
| 311 311 | 
             
                        opts[:id] = form.namespaced_id(key) unless opts.has_key?(:id)
         | 
| 312 | 
            -
                        opts[:add_blank] = true if !opts.has_key?(:add_blank)
         | 
| 313 312 | 
             
                        opts[:required] = true if !opts.has_key?(:required) && (sch = obj.model.db_schema[key]) && !sch[:allow_null]
         | 
| 313 | 
            +
                        opts[:add_blank] = true if !opts.has_key?(:add_blank) && !(opts[:required] && opts[:value])
         | 
| 314 314 | 
             
                        handle_label(field)
         | 
| 315 315 | 
             
                        ::Forme.attr_classes(opts[:wrapper_attr], "required") if opts[:required]
         | 
| 316 316 | 
             
                        _input(:select, opts)
         | 
    
        data/spec/forme_spec.rb
    CHANGED
    
    | @@ -246,6 +246,16 @@ describe "Forme plain forms" do | |
| 246 246 | 
             
                @f.tag(:textarea, {:name=>:foo}, :bar).to_s.should == '<textarea name="foo">bar</textarea>'
         | 
| 247 247 | 
             
              end
         | 
| 248 248 |  | 
| 249 | 
            +
              specify "#tag should accept children as procs" do
         | 
| 250 | 
            +
                @f.tag(:div, {:class=>"foo"}, lambda{|t| t.form.tag(:input, :class=>t.attr[:class])}).to_s.should == '<div class="foo"><input class="foo"/></div>'
         | 
| 251 | 
            +
              end
         | 
| 252 | 
            +
             | 
| 253 | 
            +
              specify "#tag should accept children as methods" do
         | 
| 254 | 
            +
                o = Object.new
         | 
| 255 | 
            +
                def o.foo(t) t.form.tag(:input, :class=>t.attr[:class]) end
         | 
| 256 | 
            +
                @f.tag(:div, {:class=>"foo"}, o.method(:foo)).to_s.should == '<div class="foo"><input class="foo"/></div>'
         | 
| 257 | 
            +
              end
         | 
| 258 | 
            +
             | 
| 249 259 | 
             
              specify "should have an #inputs method for multiple inputs wrapped in a fieldset" do
         | 
| 250 260 | 
             
                @f.inputs([:textarea, :text]).to_s.should == '<fieldset class="inputs"><textarea></textarea><input type="text"/></fieldset>'
         | 
| 251 261 | 
             
              end
         | 
| @@ -325,6 +335,10 @@ describe "Forme plain forms" do | |
| 325 335 | 
             
                @f.input(:checkbox, :labeler=>:explicit, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar', :label_position=>:before).to_s.should == '<label for="bar">Foo</label><input id="bar_hidden" name="a" type="hidden" value="0"/><input id="bar" name="a" type="checkbox" value="foo"/>'
         | 
| 326 336 | 
             
              end
         | 
| 327 337 |  | 
| 338 | 
            +
              specify "inputs handle implicit labels or checkboxes without hidden fields with :label_position=>:before" do
         | 
| 339 | 
            +
                @f.input(:checkbox, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar', :label_position=>:before, :no_hidden=>true).to_s.should == '<label>Foo <input id="bar" name="a" type="checkbox" value="foo"/></label>'
         | 
| 340 | 
            +
              end
         | 
| 341 | 
            +
             | 
| 328 342 | 
             
              specify "inputs should accept a :error_handler option to use a custom error_handler" do
         | 
| 329 343 | 
             
                @f.input(:textarea, :error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}, :error=>'bar', :id=>:foo).to_s.should == '<textarea class="error" id="foo"></textarea>!!! bar'
         | 
| 330 344 | 
             
              end
         | 
| @@ -360,6 +374,36 @@ describe "Forme plain forms" do | |
| 360 374 | 
             
              end
         | 
| 361 375 | 
             
            end
         | 
| 362 376 |  | 
| 377 | 
            +
            describe "Forme::Form :hidden_tags option " do
         | 
| 378 | 
            +
              before do
         | 
| 379 | 
            +
                @f = Forme::Form.new
         | 
| 380 | 
            +
              end
         | 
| 381 | 
            +
             | 
| 382 | 
            +
              specify "should handle hash" do
         | 
| 383 | 
            +
                Forme.form({}, :hidden_tags=>[{:a=>'b'}]).to_s.should == '<form><input name="a" type="hidden" value="b"/></form>'
         | 
| 384 | 
            +
              end
         | 
| 385 | 
            +
             | 
| 386 | 
            +
              specify "should handle array" do
         | 
| 387 | 
            +
                Forme.form({}, :hidden_tags=>[["a ", "b"]]).to_s.should == '<form>a b</form>'
         | 
| 388 | 
            +
              end
         | 
| 389 | 
            +
             | 
| 390 | 
            +
              specify "should handle string" do
         | 
| 391 | 
            +
                Forme.form({}, :hidden_tags=>["a "]).to_s.should == '<form>a </form>'
         | 
| 392 | 
            +
              end
         | 
| 393 | 
            +
             | 
| 394 | 
            +
              specify "should handle proc return hash" do
         | 
| 395 | 
            +
                Forme.form({}, :hidden_tags=>[lambda{|tag| {:a=>'b'}}]).to_s.should == '<form><input name="a" type="hidden" value="b"/></form>'
         | 
| 396 | 
            +
              end
         | 
| 397 | 
            +
             | 
| 398 | 
            +
              specify "should handle proc return tag" do
         | 
| 399 | 
            +
                Forme.form({:method=>'post'}, :hidden_tags=>[lambda{|tag| tag.form._tag(tag.attr[:method])}]).to_s.should == '<form method="post"><post></post></form>'
         | 
| 400 | 
            +
              end
         | 
| 401 | 
            +
             | 
| 402 | 
            +
              specify "should raise error for unhandled object" do
         | 
| 403 | 
            +
                proc{Forme.form({}, :hidden_tags=>[Object.new])}.should raise_error
         | 
| 404 | 
            +
              end
         | 
| 405 | 
            +
            end
         | 
| 406 | 
            +
             | 
| 363 407 | 
             
            describe "Forme custom" do
         | 
| 364 408 | 
             
              specify "formatters can be specified as a proc" do
         | 
| 365 409 | 
             
                Forme::Form.new(:formatter=>proc{|i| i.form._tag(:textarea, i.opts.map{|k,v| [v.upcase, k.to_s.downcase]})}).input(:text, :name=>'foo').to_s.should == '<textarea FOO="name"></textarea>'
         | 
| @@ -6,10 +6,12 @@ require 'action_controller/railtie' | |
| 6 6 | 
             
            require 'forme/rails'
         | 
| 7 7 |  | 
| 8 8 | 
             
            class FormeRails < Rails::Application
         | 
| 9 | 
            -
              config.secret_token = routes.append {  | 
| 9 | 
            +
              config.secret_token = routes.append { get ':action' , :controller=>'forme' }.inspect
         | 
| 10 10 | 
             
              config.active_support.deprecation = :stderr
         | 
| 11 11 | 
             
              config.middleware.delete(ActionDispatch::ShowExceptions)
         | 
| 12 | 
            -
              config. | 
| 12 | 
            +
              config.middleware.delete("Rack::Lock")
         | 
| 13 | 
            +
              config.secret_key_base = 'foo'
         | 
| 14 | 
            +
              config.eager_load = true
         | 
| 13 15 | 
             
              initialize!
         | 
| 14 16 | 
             
            end
         | 
| 15 17 |  | 
| @@ -139,6 +141,10 @@ END | |
| 139 141 | 
             
              def noblock
         | 
| 140 142 | 
             
                render :inline => "<%= forme([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
         | 
| 141 143 | 
             
              end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
              def safe_buffer
         | 
| 146 | 
            +
                render :inline => "<%= forme([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'<b>foo</b>'.html_safe) %>"
         | 
| 147 | 
            +
              end
         | 
| 142 148 | 
             
            end
         | 
| 143 149 |  | 
| 144 150 | 
             
            describe "Forme Rails integration" do
         | 
| @@ -174,7 +180,7 @@ describe "Forme Rails integration" do | |
| 174 180 | 
             
              end
         | 
| 175 181 |  | 
| 176 182 | 
             
              specify "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
         | 
| 177 | 
            -
                sin_get('/nest_seq').should == "0 <form action=\"/baz\" class=\"forme album\" method=\"post\" | 
| 183 | 
            +
                sin_get('/nest_seq').sub(%r{<input name=\"authenticity_token\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"authenticity_token\" type=\"hidden\" value=\"csrf\"/>").should == "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\"/> n2 <label>Name2: <input id=\"album_artist_attributes_name2\" name=\"album[artist_attributes][name2]\" type=\"text\" value=\"A2\"/></label> n3 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"
         | 
| 178 184 | 
             
              end
         | 
| 179 185 |  | 
| 180 186 | 
             
              specify "#form should accept two hashes instead of requiring obj as first argument" do
         | 
| @@ -192,4 +198,8 @@ describe "Forme Rails integration" do | |
| 192 198 | 
             
              specify "#form should work without a block" do
         | 
| 193 199 | 
             
                sin_get('/noblock').should == '<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>'
         | 
| 194 200 | 
             
              end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
              specify "#form should handle Rails SafeBuffers" do
         | 
| 203 | 
            +
                sin_get('/safe_buffer').should == '<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>'
         | 
| 204 | 
            +
              end
         | 
| 195 205 | 
             
            end
         | 
    
        data/spec/sequel_plugin_spec.rb
    CHANGED
    
    | @@ -17,6 +17,13 @@ describe "Forme Sequel::Model forms" do | |
| 17 17 | 
             
                @b.form(:class=>:foo, :method=>:get).to_s.should == '<form class="foo forme album" method="get"></form>'
         | 
| 18 18 | 
             
              end
         | 
| 19 19 |  | 
| 20 | 
            +
              specify "should handle invalid methods" do
         | 
| 21 | 
            +
                def @ab.db_schema
         | 
| 22 | 
            +
                  super.merge(:foo=>{:type=>:bar})
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
                @b.input(:foo, :value=>'baz').to_s.should == '<label>Foo: <input id="album_foo" name="album[foo]" type="text" value="baz"/></label>'
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 20 27 | 
             
              specify "should allow an array of classes" do
         | 
| 21 28 | 
             
                @b.form(:class=>[:foo, :bar]).to_s.should == '<form class="foo bar forme album" method="post"></form>'
         | 
| 22 29 | 
             
                @b.form(:class=>[:foo, [:bar, :baz]]).to_s.should == '<form class="foo bar baz forme album" method="post"></form>'
         | 
| @@ -122,12 +129,16 @@ describe "Forme Sequel::Model forms" do | |
| 122 129 | 
             
                @c.input(:artist).to_s.should == '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a</option><option selected="selected" value="2">d</option></select></label>'
         | 
| 123 130 | 
             
              end
         | 
| 124 131 |  | 
| 132 | 
            +
              specify "should not add a blank option by default if there is a default value and it is required" do
         | 
| 133 | 
            +
                @b.input(:artist, :required=>true).to_s.should == '<label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option selected="selected" value="1">a</option><option value="2">d</option></select></label>'
         | 
| 134 | 
            +
              end
         | 
| 135 | 
            +
             | 
| 125 136 | 
             
              specify "should allow overriding default input type using a :type option" do
         | 
| 126 137 | 
             
                @b.input(:artist, :type=>:string, :value=>nil).to_s.should == '<label>Artist: <input id="album_artist" name="album[artist]" type="text"/></label>'
         | 
| 127 138 | 
             
              end
         | 
| 128 139 |  | 
| 129 140 | 
             
              specify "should use a required wrapper tag for many_to_one required associations" do
         | 
| 130 | 
            -
                @b.input(:artist, :required=>true, :wrapper=>:li).to_s.should == '<li class="many_to_one required"><label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option  | 
| 141 | 
            +
                @b.input(:artist, :required=>true, :wrapper=>:li).to_s.should == '<li class="many_to_one required"><label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option selected="selected" value="1">a</option><option value="2">d</option></select></label></li>'
         | 
| 131 142 | 
             
              end
         | 
| 132 143 |  | 
| 133 144 | 
             
              specify "should use a set of radio buttons for many_to_one associations with :as=>:radio option" do
         | 
| @@ -5,11 +5,14 @@ require 'rubygems' | |
| 5 5 | 
             
            require 'sinatra/base'
         | 
| 6 6 | 
             
            require 'forme/sinatra'
         | 
| 7 7 | 
             
            require(ENV['ERUBIS'] ? 'erubis' : 'erb')
         | 
| 8 | 
            +
            require 'rack/csrf'
         | 
| 8 9 |  | 
| 9 10 | 
             
            class FormeSinatraTest < Sinatra::Base
         | 
| 10 11 | 
             
              helpers(Forme::Sinatra::ERB)
         | 
| 11 12 | 
             
              disable :show_exceptions
         | 
| 12 13 | 
             
              enable :raise_errors
         | 
| 14 | 
            +
              enable :sessions
         | 
| 15 | 
            +
              use Rack::Csrf
         | 
| 13 16 |  | 
| 14 17 | 
             
              get '/' do
         | 
| 15 18 | 
             
                erb <<END
         | 
| @@ -24,21 +27,17 @@ END | |
| 24 27 |  | 
| 25 28 | 
             
              get '/inputs_block' do
         | 
| 26 29 | 
             
                erb <<END
         | 
| 27 | 
            -
            <% form([:foo, :bar], :action=>'/baz') do |f| %>
         | 
| 28 | 
            -
              <% f.inputs(:legend=>'FBB') do %>
         | 
| 30 | 
            +
            <% form([:foo, :bar], :action=>'/baz') do |f| %><% f.inputs(:legend=>'FBB') do %>
         | 
| 29 31 | 
             
                <%= f.input(:last) %>
         | 
| 30 | 
            -
              <% end %>
         | 
| 31 | 
            -
            <% end %>
         | 
| 32 | 
            +
              <% end %><% end %>
         | 
| 32 33 | 
             
            END
         | 
| 33 34 | 
             
              end
         | 
| 34 35 |  | 
| 35 36 | 
             
              get '/inputs_block_wrapper' do
         | 
| 36 37 | 
             
                erb <<END
         | 
| 37 | 
            -
            <% form([:foo, :bar], {:action=>'/baz'}, :inputs_wrapper=>:fieldset_ol) do |f| %>
         | 
| 38 | 
            -
              <% f.inputs(:legend=>'FBB') do %>
         | 
| 38 | 
            +
            <% form([:foo, :bar], {:action=>'/baz'}, :inputs_wrapper=>:fieldset_ol) do |f| %><% f.inputs(:legend=>'FBB') do %>
         | 
| 39 39 | 
             
                <%= f.input(:last) %>
         | 
| 40 | 
            -
              <% end %>
         | 
| 41 | 
            -
            <% end %>
         | 
| 40 | 
            +
              <% end %><% end %>
         | 
| 42 41 | 
             
            END
         | 
| 43 42 | 
             
              end
         | 
| 44 43 |  | 
| @@ -134,11 +133,17 @@ END | |
| 134 133 | 
             
              get '/noblock' do
         | 
| 135 134 | 
             
                erb "<%= form([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
         | 
| 136 135 | 
             
              end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
              get '/noblock_empty' do
         | 
| 138 | 
            +
                erb "<%= form(:action=>'/baz') %>"
         | 
| 139 | 
            +
              end
         | 
| 137 140 | 
             
            end
         | 
| 138 141 |  | 
| 139 142 | 
             
            describe "Forme Sinatra ERB integration" do
         | 
| 140 143 | 
             
              def sin_get(path)
         | 
| 141 | 
            -
                 | 
| 144 | 
            +
                s = ''
         | 
| 145 | 
            +
                FormeSinatraTest.new.call(@rack.merge('PATH_INFO'=>path))[2].each{|str| s << str}
         | 
| 146 | 
            +
                s.gsub(/\s+/, ' ').strip
         | 
| 142 147 | 
             
              end
         | 
| 143 148 | 
             
              before do
         | 
| 144 149 | 
             
                o = Object.new
         | 
| @@ -167,7 +172,7 @@ describe "Forme Sinatra ERB integration" do | |
| 167 172 | 
             
              end
         | 
| 168 173 |  | 
| 169 174 | 
             
              specify "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
         | 
| 170 | 
            -
                sin_get('/nest_seq').should == "0 <form action=\"/baz\" class=\"forme album\" method=\"post\" | 
| 175 | 
            +
                sin_get('/nest_seq').sub(%r{<input name=\"_csrf\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"_csrf\" type=\"hidden\" value=\"csrf\"/>").should == "0 <form action=\"/baz\" class=\"forme album\" method=\"post\"><input name=\"_csrf\" 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\"/> n2 <label>Name2: <input id=\"album_artist_attributes_name2\" name=\"album[artist_attributes][name2]\" type=\"text\" value=\"A2\"/></label> n3 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"
         | 
| 171 176 | 
             
              end
         | 
| 172 177 |  | 
| 173 178 | 
             
              specify "#form should accept two hashes instead of requiring obj as first argument" do
         | 
| @@ -185,4 +190,8 @@ describe "Forme Sinatra ERB integration" do | |
| 185 190 | 
             
              specify "#form should work without a block" do
         | 
| 186 191 | 
             
                sin_get('/noblock').should == '<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>'
         | 
| 187 192 | 
             
              end
         | 
| 193 | 
            +
             | 
| 194 | 
            +
              specify "#form with an empty form should work" do
         | 
| 195 | 
            +
                sin_get('/noblock_empty').should == '<form action="/baz"></form>'
         | 
| 196 | 
            +
              end
         | 
| 188 197 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,28 +1,22 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: forme
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 5 | 
            -
              prerelease: 
         | 
| 4 | 
            +
              version: 0.8.0
         | 
| 6 5 | 
             
            platform: ruby
         | 
| 7 6 | 
             
            authors:
         | 
| 8 7 | 
             
            - Jeremy Evans
         | 
| 9 8 | 
             
            autorequire: 
         | 
| 10 9 | 
             
            bindir: bin
         | 
| 11 10 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date:  | 
| 11 | 
            +
            date: 2013-10-30 00:00:00.000000000 Z
         | 
| 13 12 | 
             
            dependencies: []
         | 
| 14 | 
            -
            description:  | 
| 15 | 
            -
             | 
| 13 | 
            +
            description: |
         | 
| 14 | 
            +
              Forme is a forms library with the following goals:
         | 
| 16 15 |  | 
| 17 16 | 
             
              1) Have no external dependencies
         | 
| 18 | 
            -
             | 
| 19 17 | 
             
              2) Have a simple API
         | 
| 20 | 
            -
             | 
| 21 18 | 
             
              3) Support forms both with and without related objects
         | 
| 22 | 
            -
             | 
| 23 19 | 
             
              4) Allow compiling down to different types of output
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            '
         | 
| 26 20 | 
             
            email: code@jeremyevans.net
         | 
| 27 21 | 
             
            executables: []
         | 
| 28 22 | 
             
            extensions: []
         | 
| @@ -48,33 +42,32 @@ files: | |
| 48 42 | 
             
            - lib/sequel/plugins/forme.rb
         | 
| 49 43 | 
             
            homepage: http://gihub.com/jeremyevans/forme
         | 
| 50 44 | 
             
            licenses: []
         | 
| 45 | 
            +
            metadata: {}
         | 
| 51 46 | 
             
            post_install_message: 
         | 
| 52 47 | 
             
            rdoc_options:
         | 
| 53 48 | 
             
            - --quiet
         | 
| 54 49 | 
             
            - --line-numbers
         | 
| 55 50 | 
             
            - --inline-source
         | 
| 56 51 | 
             
            - --title
         | 
| 57 | 
            -
            -  | 
| 52 | 
            +
            - 'Forme: HTML forms library'
         | 
| 58 53 | 
             
            - --main
         | 
| 59 54 | 
             
            - README.rdoc
         | 
| 60 55 | 
             
            require_paths:
         | 
| 61 56 | 
             
            - lib
         | 
| 62 57 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 63 | 
            -
              none: false
         | 
| 64 58 | 
             
              requirements:
         | 
| 65 | 
            -
              - -  | 
| 59 | 
            +
              - - '>='
         | 
| 66 60 | 
             
                - !ruby/object:Gem::Version
         | 
| 67 61 | 
             
                  version: '0'
         | 
| 68 62 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 69 | 
            -
              none: false
         | 
| 70 63 | 
             
              requirements:
         | 
| 71 | 
            -
              - -  | 
| 64 | 
            +
              - - '>='
         | 
| 72 65 | 
             
                - !ruby/object:Gem::Version
         | 
| 73 66 | 
             
                  version: '0'
         | 
| 74 67 | 
             
            requirements: []
         | 
| 75 68 | 
             
            rubyforge_project: 
         | 
| 76 | 
            -
            rubygems_version:  | 
| 69 | 
            +
            rubygems_version: 2.0.3
         | 
| 77 70 | 
             
            signing_key: 
         | 
| 78 | 
            -
            specification_version:  | 
| 71 | 
            +
            specification_version: 4
         | 
| 79 72 | 
             
            summary: HTML forms library
         | 
| 80 73 | 
             
            test_files: []
         |