hungryform 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5a3eb50bf1ab74b3a5540384c4985bdaa0320666
4
+ data.tar.gz: 97110432dcc56453c65f81b1df816fc8a4dd1019
5
+ SHA512:
6
+ metadata.gz: bb6ca009dcf1d557b5485e76810dd2d3001debea174634e125de56ceccc797a3d84153b2fe51ade45082d3d79d393c5e23d82ad2c7b5f2876e696fcdbcfc79b6
7
+ data.tar.gz: b63768d3bca0af1a22b5c1845f80bd5fc770f77ced167cc4d42cf62f03f75cb972f9aaebd79a31ba8c72d50bd807b36bd425d17c8fc2b2a04cb5633b2c949669
data/.gitignore ADDED
File without changes
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hungryform.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,46 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hungryform (0.0.1)
5
+ activesupport
6
+ hashie
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (4.1.6)
12
+ i18n (~> 0.6, >= 0.6.9)
13
+ json (~> 1.7, >= 1.7.7)
14
+ minitest (~> 5.1)
15
+ thread_safe (~> 0.1)
16
+ tzinfo (~> 1.1)
17
+ diff-lcs (1.2.5)
18
+ hashie (3.3.1)
19
+ i18n (0.6.11)
20
+ json (1.8.1)
21
+ minitest (5.4.2)
22
+ rake (10.3.2)
23
+ rspec (3.1.0)
24
+ rspec-core (~> 3.1.0)
25
+ rspec-expectations (~> 3.1.0)
26
+ rspec-mocks (~> 3.1.0)
27
+ rspec-core (3.1.7)
28
+ rspec-support (~> 3.1.0)
29
+ rspec-expectations (3.1.2)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.1.0)
32
+ rspec-mocks (3.1.3)
33
+ rspec-support (~> 3.1.0)
34
+ rspec-support (3.1.2)
35
+ thread_safe (0.3.4)
36
+ tzinfo (1.2.2)
37
+ thread_safe (~> 0.1)
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ bundler (~> 1.6)
44
+ hungryform!
45
+ rake
46
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Andrey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # HungryForm
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'hungryform'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install hungryform
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/andrba/hungryform/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hungryform/version'
5
+ require 'json'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "hungryform"
9
+ spec.version = HungryForm::VERSION
10
+ spec.authors = ["Andrey Bazhutkin"]
11
+ spec.email = ["andrey.bazhutkin@gmail.com"]
12
+ spec.summary = "A Ruby Library for working with multi page forms"
13
+ spec.homepage = "https://github.com/andrba/hungryform"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+ spec.add_dependency "activesupport"
25
+ spec.add_dependency "hashie", "~> 3.3"
26
+ end
@@ -0,0 +1,38 @@
1
+ class HungryForm
2
+ class BaseActiveElement < BaseElement
3
+ attr_accessor :error
4
+
5
+ def initialize(name, parent, resolver, options = {}, &block)
6
+ super
7
+ self.error = ''
8
+
9
+ # Filter only the options that are present in the HungryForm::Validator singleton class
10
+ @validation_rules = options.select { |key, val| HungryForm::Validator.respond_to?(key) }
11
+
12
+ self.required = false unless parent.visible?
13
+
14
+ if options.has_key?(:params)
15
+ self.value = options[:params][self.name] || ''
16
+ else
17
+ self.value = ''
18
+ end
19
+ end
20
+
21
+ def valid?
22
+ self.error = ''
23
+
24
+ return true if !visible?
25
+
26
+ is_valid = true
27
+ @validation_rules.each do |key, rule|
28
+ error = HungryForm::Validator.send(key, self, rule) || ''
29
+ unless error.empty?
30
+ is_valid = false
31
+ break
32
+ end
33
+ end
34
+
35
+ is_valid
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ class HungryForm
2
+ class BaseElement < ::Hashie::Mash
3
+ attr_accessor :name, :placeholders, :resolver
4
+
5
+ def initialize(name, parent, resolver, options = {})
6
+ self.placeholders ||= {}
7
+ self.resolver = resolver
8
+
9
+ super(options)
10
+
11
+ self.visible = true unless self.key?(:visible)
12
+ self.visible &&= resolver.resolve_dependency(::JSON.parse(self.dependency)) if self.key?(:dependency)
13
+ self.name = (parent.nil?? "" : "#{parent.name}_") + resolver.get_value(name, self)
14
+
15
+ if self.key?(:label)
16
+ self.label = resolver.get_value(self.label, self)
17
+ else
18
+ self.label = resolver.get_value(name, self).humanize
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,81 @@
1
+ class HungryForm
2
+ # A base group object is used to handle nested elements.
3
+ # Nested element can be a regular BaseElement or BaseActiveElement, as well as a BaseGroup element.
4
+ #
5
+ # The following sample has three BaseGroup elements (page, group and nested group) that define a structure
6
+ # of a single form page
7
+ #
8
+ # page :about do
9
+ # group :about_yourself do
10
+ # html :about, value: "Tell us about yourself"
11
+ # group :address do
12
+ # text_field :street
13
+ # text_field :city
14
+ # end
15
+ # group :contact do
16
+ # text_field :phone
17
+ # end
18
+ # end
19
+ # end
20
+ #
21
+ # Every group element except for a nested group is
22
+ class BaseGroup < BaseElement
23
+ attr_accessor :elements, :errors
24
+
25
+ def initialize(name, parent, resolver, options = {}, &block)
26
+ raise HungryFormException, 'No group structure block given' unless block_given?
27
+
28
+ super
29
+
30
+ self.name = parent.nil?? name : "#{parent.name}_#{name}"
31
+ self.elements = []
32
+ self.errors = {}
33
+
34
+ instance_eval(&block)
35
+ end
36
+
37
+ def group(name, options = {}, &block)
38
+ elements << HungryForm::Group.new(name, self, @resolver, options, &block)
39
+ end
40
+
41
+ # Validates an entire group. If a group consists of nested groups
42
+ # they will be validated recursively
43
+ def valid?
44
+ errors.clear
45
+ is_valid = true
46
+
47
+ elements.each do |el|
48
+ if el.invalid?
49
+ is_valid = false
50
+ case el
51
+ when BaseActiveElement
52
+ errors[el.name] = el.error
53
+ when BaseGroupObject
54
+ errors.merge!(el.errors)
55
+ end
56
+ end
57
+ end
58
+
59
+ is_valid
60
+ end
61
+
62
+ def invalid?
63
+ !valid?
64
+ end
65
+
66
+ def method_missing(name, *args, &block)
67
+ #Find a matching class
68
+ klass = HungryForm.constants.find {|c| Class === HungryForm.const_get(c) && c.to_s.underscore.to_sym == name}
69
+ return super if klass.nil?
70
+
71
+ # Create a new element based on a symbol provided and push it into the group elements array
72
+ element = HungryForm::const_get(klass).send(:new, *([args[0], self, @resolver, args[1..-1]].flatten), &block)
73
+ elements << element
74
+
75
+ #Resolver keeps a hash of all elements of the form
76
+ @resolver.elements[element.name] = element
77
+
78
+ element
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,8 @@
1
+ class HungryForm
2
+ class Group < BaseGroup
3
+ def initialize(name, parent, resolver, options = {}, &block)
4
+ super
5
+ instance_eval(&block)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ class HungryForm
2
+ class Html < BaseElement
3
+ end
4
+ end
@@ -0,0 +1,27 @@
1
+ class HungryForm
2
+ # Page is a main element of a form.
3
+ # Each page can include a page structure, defined in the block
4
+ #
5
+ # A sample page could look like this:
6
+ # page :about do
7
+ # html :before, value: "Please fill out the following fields"
8
+ # text_field :first_name
9
+ # text_field :last_name
10
+ # end
11
+ #
12
+ # The only required argument of a page is its name.
13
+ # You can specify a title and a label in the options like this:
14
+ #
15
+ # page :about, title: "About me", label: "About"
16
+ #
17
+ # If there is no title or label specified, they will be created
18
+ # from the :name argument
19
+ class Page < BaseGroup
20
+ attr_accessor :title
21
+
22
+ def initialize(name, parent, resolver, options = {}, &block)
23
+ super
24
+ self.title = self.title || self.label
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ class HungryForm
2
+ class TextField < BaseActiveElement
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'elements/base_element'
2
+ require_relative 'elements/base_active_element'
3
+ require_relative 'elements/base_group'
4
+ require_relative 'elements/page'
5
+ require_relative 'elements/group'
6
+ require_relative 'elements/html'
7
+ require_relative 'elements/text_field'
@@ -0,0 +1,79 @@
1
+ class HungryForm
2
+ # The class is responsible for dependency resolving.
3
+ # It contains all form elements and params
4
+ class Resolver
5
+ attr_accessor :elements
6
+
7
+ def initialize(options = {})
8
+ @params = options[:params] || {}
9
+ @elements = {}
10
+ end
11
+
12
+ # Gets element value by element's name.
13
+ # If name is lambda - returns lambda's result
14
+ # If name is present in the resolvers' elements hash - returns element's value
15
+ # If name is present in the resolvers' params hash - returns params value
16
+ # Otherwise returns the argument without changes
17
+ def get_value(name, element = nil)
18
+ return name.call(element) if name.respond_to? :call
19
+
20
+ name = name.to_s.dup
21
+
22
+ # Apply placeholders to the name.
23
+ # A sample name string can look like this: page1_group[GROUP_NUMBER]_field
24
+ # where [GROUP_NUMBER] is a placeholder. When an element is present
25
+ # we get its placeholders and replace substrings in the name argument
26
+ if element
27
+ element.placeholders.each { |k, v| name[k] &&= v }
28
+ end
29
+
30
+ return @elements[name].value if @elements.has_key?(name)
31
+ return @params[name] if @params.has_key?(name)
32
+
33
+ name
34
+ end
35
+
36
+ # Gets dependency rules hash and returns true or false depending on
37
+ # the result of a recursive processing of the rules
38
+ def resolve_dependency(dependency)
39
+ dependency.each do |operator, arguments|
40
+ case operator
41
+ when 'AND'
42
+ raise HungryFormException, "No arguments for AND comparison: #{arguments}" if arguments.size == 0
43
+
44
+ arguments.each do |argument|
45
+ return false unless resolve_dependency(argument)
46
+ end
47
+
48
+ return true
49
+ when 'OR'
50
+ raise HungryFormException, "No arguments for OR comparison: #{arguments}" if arguments.size == 0
51
+
52
+ arguments.each do |argument|
53
+ return true if resolve_dependency(argument)
54
+ end
55
+
56
+ return false
57
+ when 'NOT'
58
+ return !resolve_dependency(arguments)
59
+ end
60
+
61
+ arguments = [arguments] unless arguments.is_a?(Array)
62
+
63
+ arguments = arguments[0..1].map {|name| get_value(name)}
64
+ return false if arguments.any?{ |arg| arg.nil? }
65
+
66
+ case operator
67
+ when 'EQ'
68
+ return arguments[0].to_s == arguments[1].to_s
69
+ when 'LT'
70
+ return arguments[0].to_f < arguments[1].to_f
71
+ when 'GT'
72
+ return arguments[0].to_f > arguments[1].to_f
73
+ when 'SET'
74
+ return !arguments[0].empty?
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,13 @@
1
+ class HungryForm
2
+ class Validator
3
+ class << self
4
+ def required(element, rule)
5
+ if rule.respond_to? :call
6
+ return rule.call(element)
7
+ else
8
+ return "is required" if element.value.to_s.empty? && rule
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ class HungryForm
2
+ VERSION = "0.0.1"
3
+ end
data/lib/hungryform.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/string/inflections'
3
+ require 'hashie'
4
+ require "hungryform/version"
5
+ require "hungryform/resolver"
6
+ require "hungryform/validator"
7
+ require "hungryform/elements"
8
+
9
+ # HungryForm is an object that manages form creation and validation.
10
+ # A sample object could look like this:
11
+ #
12
+ # form = HungryForm.new :params => params do
13
+ # page :about_yourself do
14
+ # text_field :first_name, :required => true
15
+ # text_field :last_name, :required => true
16
+ # checkbox :dog, label: "Do you have a dog?"
17
+ # end
18
+ # page :about_your_dog, visible: '{"SET": "about_yourself_dog"}' do
19
+ # text_field :name, :required
20
+ # text_area :what_can_it_do, label: "What can it do?"
21
+ # end
22
+ # end
23
+ #
24
+ # A form must contain only pages.
25
+ # Whenever a specific form error occurres inside the form it raises a HungryFormException
26
+ #
27
+ # When a new instance of a HungryForm is created, it uses options[:params] to
28
+ # build a structure of itself. The pages with dependencies, that resolve during this
29
+ # process will be included in the form.pages array. Pages without dependencies will be allways resolved.
30
+ # The rest of the pages will be ignored
31
+ class HungryForm
32
+ HungryFormException = Class.new(StandardError)
33
+
34
+ attr_reader :current_page, :pages
35
+
36
+ def initialize(options = {}, &block)
37
+ raise HungryFormException, 'No form structure block given' unless block_given?
38
+ @resolver = Resolver.new(options.slice(:params))
39
+ @pages = []
40
+ instance_eval(&block)
41
+ end
42
+
43
+ # Create a form page
44
+ def page(name, options = {}, &block)
45
+ page = Page.new(name, nil, @resolver, options, &block)
46
+ pages << page if page.visible?
47
+ end
48
+
49
+ # Entire form validation. Loops through the form pages and validates each page
50
+ def valid?
51
+ is_valid = true
52
+ pages.each do |page|
53
+ #Loop through pages to get all errors
54
+ is_valid = false if page.invalid?
55
+ end
56
+
57
+ is_valid
58
+ end
59
+
60
+ def invalid?
61
+ !valid?
62
+ end
63
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe HungryForm::Group do
4
+ it_behaves_like "a group"
5
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe HungryForm::Html do
4
+ it_behaves_like "an element"
5
+
6
+ describe ".new" do
7
+ let(:resolver) { HungryForm::Resolver.new() }
8
+ let(:options) { {value: "body text"} }
9
+ subject { HungryForm::Html.new(:html, nil, resolver, options) {} }
10
+
11
+ it "should have a value" do
12
+ expect(subject.value).to eq "body text"
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+
3
+ describe HungryForm::Page do
4
+ let(:resolver) { HungryForm::Resolver.new() }
5
+ let(:options) { {} }
6
+ let(:page) { HungryForm::Page.new(:pagename, nil, resolver, options) {} }
7
+
8
+ it_behaves_like "a group"
9
+
10
+ describe ".new" do
11
+ it "should have one element" do
12
+ page = HungryForm::Page.new(:pagename, nil, resolver, options) do
13
+ html :html_name, value: "<p>Test html block</p>"
14
+ end
15
+ expect(page.elements.size).to eq 1
16
+ end
17
+ end
18
+
19
+ describe "#group" do
20
+ it "should contain a group" do
21
+ page.group(:group_name, {}) {}
22
+ expect(page.elements.first.class).to eq HungryForm::Group
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe HungryForm::TextField do
4
+ it_behaves_like "an active element"
5
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe HungryForm do
4
+ describe ".new" do
5
+ subject(:form) { HungryForm.new {
6
+ page :first do
7
+ end
8
+ page :second, visible: false do
9
+ end
10
+ page :third do
11
+ end
12
+ } }
13
+
14
+ it "should contain 2 pages" do
15
+ expect(subject.pages.size).to eq 2
16
+ end
17
+ end
18
+
19
+ describe "#page" do
20
+ subject(:form) { HungryForm.new() {} }
21
+
22
+ it "should contain a page" do
23
+ form.page(:page_name, {}) {}
24
+ expect(form.pages.first.class).to eq HungryForm::Page
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,66 @@
1
+ require "spec_helper"
2
+
3
+ describe HungryForm::Resolver do
4
+ let(:resolver_params) { {:params => {}} }
5
+ subject(:resolver) { HungryForm::Resolver.new(resolver_params) }
6
+
7
+ describe ".get_value" do
8
+ let(:element) { HungryForm::Html.new(:html_name, nil, resolver, { value: "value" }) {} }
9
+
10
+ it "should get value from lambda param" do
11
+ value = subject.get_value( ->(el){ "value" } )
12
+ expect(value).to eq "value"
13
+ end
14
+
15
+ it "should get value from a form element" do
16
+ subject.elements[element.name] = element
17
+ expect(subject.get_value("html_name")).to eq "value"
18
+ end
19
+
20
+ it "should get value from a form params" do
21
+ resolver_params[:params] = { "param1" => "param_value" }
22
+ expect(subject.get_value("param1")).to eq "param_value"
23
+ end
24
+
25
+ it "should get value that equals the name" do
26
+ expect(subject.get_value("name that doesn't exist")).to eq "name that doesn't exist"
27
+ end
28
+ end
29
+
30
+ describe ".resolve_dependency" do
31
+ it "should resolve EQ dependency" do
32
+ dependency = { "EQ" => ["Text", "Text"] }
33
+ expect(subject.resolve_dependency(dependency)).to eq true
34
+ end
35
+
36
+ it "should resolve LT dependency" do
37
+ dependency = { "LT" => ["0", "1"] }
38
+ expect(subject.resolve_dependency(dependency)).to eq true
39
+ end
40
+
41
+ it "should resolve GT dependency" do
42
+ dependency = { "GT" => ["1", "0"] }
43
+ expect(subject.resolve_dependency(dependency)).to eq true
44
+ end
45
+
46
+ it "should resolve SET dependency" do
47
+ dependency = { "SET" => "1" }
48
+ expect(subject.resolve_dependency(dependency)).to eq true
49
+ end
50
+
51
+ it "should resolve AND dependency" do
52
+ dependency = { "AND" => [{"SET" => "1"}, {"SET" => "1"}] }
53
+ expect(subject.resolve_dependency(dependency)).to eq true
54
+ end
55
+
56
+ it "should resolve OR dependency" do
57
+ dependency = { "OR" => [{"SET" => ""}, {"SET" => "1"}] }
58
+ expect(subject.resolve_dependency(dependency)).to eq true
59
+ end
60
+
61
+ it "should resolve NOT dependency" do
62
+ dependency = { "NOT" => {"SET" => ""} }
63
+ expect(subject.resolve_dependency(dependency)).to eq true
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require "hungryform"
5
+
6
+ Dir["./spec/support/**/*.rb"].sort.each { |f| require f }
7
+
8
+ RSpec.configure do |config|
9
+ config.order = :random
10
+ end
@@ -0,0 +1,41 @@
1
+ RSpec.shared_examples "an active element" do
2
+ let(:resolver) { HungryForm::Resolver.new() }
3
+
4
+ let(:group_options) { {} }
5
+ let(:group) { HungryForm::Group.new(:group, nil, resolver, group_options) {} }
6
+
7
+ let(:element_options) { {} }
8
+ let(:element) { described_class.new(:element_name, group, resolver, element_options) {} }
9
+
10
+ it_behaves_like "an element"
11
+
12
+ describe ".new" do
13
+ it "should have empty error" do
14
+ expect(element.error).to eq ""
15
+ end
16
+
17
+ it "should not be required if its parent is not visible" do
18
+ group_options[:visible] = false
19
+ element_options[:required] = true
20
+ expect(element.required?).to eq false
21
+ end
22
+ end
23
+
24
+ describe "#valid?" do
25
+ describe "when required" do
26
+ before(:each) do
27
+ element_options[:required] = true
28
+ end
29
+
30
+ it "is valid" do
31
+ element.value = "value"
32
+ expect(element.valid?).to eq true
33
+ end
34
+
35
+ it "is invalid" do
36
+ element.value = ""
37
+ expect(element.valid?).to eq false
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,48 @@
1
+ RSpec.shared_examples "an element" do
2
+ let(:resolver) { HungryForm::Resolver.new() }
3
+
4
+ let(:group) { HungryForm::Group.new(:group, nil, resolver, {}) {} }
5
+
6
+ let(:element_options) { {} }
7
+ let(:element) { described_class.new(:element_name, group, resolver, element_options) {} }
8
+
9
+ describe "#visible?" do
10
+ it "should be visible" do
11
+ expect(element.visible?).to eq true
12
+ end
13
+
14
+ it "should not be visible" do
15
+ element_options[:visible] = false
16
+ expect(element.visible?).to eq false
17
+ end
18
+
19
+ context "when dependency is present" do
20
+ it "should not be visible" do
21
+ element_options[:dependency] = '{"EQ": ["0", "1"]}'
22
+ expect(element.visible?).to eq false
23
+ end
24
+
25
+ it "should never be visible" do
26
+ element_options[:visible] = false
27
+ element_options[:dependency] = '{"EQ": ["1", "1"]}'
28
+ expect(element.visible?).to eq false
29
+ end
30
+
31
+ it "should be visible" do
32
+ element_options[:dependency] = '{"EQ": ["1", "1"]}'
33
+ expect(element.visible?).to eq true
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#label" do
39
+ it "should have a humanized label based on element's name" do
40
+ expect(element.label).to eq "Element name"
41
+ end
42
+
43
+ it "should have a label defined in options" do
44
+ element_options[:label] = "Special Label"
45
+ expect(element.label).to eq "Special Label"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,34 @@
1
+ RSpec.shared_examples "a group" do
2
+ let(:resolver) { HungryForm::Resolver.new() }
3
+
4
+ let(:page) { described_class.new(:parent_name, nil, resolver, {}) {} }
5
+
6
+ let(:group_options) { {} }
7
+ let(:group) { described_class.new(:name, page, resolver, group_options) {} }
8
+
9
+ it_behaves_like "an element"
10
+
11
+ describe "#group" do
12
+ it "creates a nested group" do
13
+ group.group(:nested, {}) {}
14
+ expect(group.elements.first.class).to eq HungryForm::Group
15
+ end
16
+
17
+ it "concatenates nested element's name with the parent's one" do
18
+ group.group(:nested, {}) {}
19
+ expect(group.elements.first.name).to eq "parent_name_name_nested"
20
+ end
21
+ end
22
+
23
+ describe ".method_missing" do
24
+ it "creates a nested element" do
25
+ group.html(:name)
26
+ expect(group.elements.first.class).to eq HungryForm::Html
27
+ end
28
+
29
+ it "concatenates nested element's name with the parent's one" do
30
+ group.html(:html)
31
+ expect(group.elements.first.name).to eq "parent_name_name_html"
32
+ end
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hungryform
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrey Bazhutkin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: hashie
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.3'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.3'
83
+ description:
84
+ email:
85
+ - andrey.bazhutkin@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - Gemfile
93
+ - Gemfile.lock
94
+ - LICENSE
95
+ - README.md
96
+ - Rakefile
97
+ - hungryform.gemspec
98
+ - lib/hungryform.rb
99
+ - lib/hungryform/elements.rb
100
+ - lib/hungryform/elements/base_active_element.rb
101
+ - lib/hungryform/elements/base_element.rb
102
+ - lib/hungryform/elements/base_group.rb
103
+ - lib/hungryform/elements/group.rb
104
+ - lib/hungryform/elements/html.rb
105
+ - lib/hungryform/elements/page.rb
106
+ - lib/hungryform/elements/text_field.rb
107
+ - lib/hungryform/resolver.rb
108
+ - lib/hungryform/validator.rb
109
+ - lib/hungryform/version.rb
110
+ - spec/elements/group_spec.rb
111
+ - spec/elements/html_spec.rb
112
+ - spec/elements/page_spec.rb
113
+ - spec/elements/text_field_spec.rb
114
+ - spec/hungryform_spec.rb
115
+ - spec/resolver_spec.rb
116
+ - spec/spec_helper.rb
117
+ - spec/support/shared_active_element.rb
118
+ - spec/support/shared_element.rb
119
+ - spec/support/shared_group.rb
120
+ homepage: https://github.com/andrba/hungryform
121
+ licenses:
122
+ - MIT
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 2.4.4
141
+ signing_key:
142
+ specification_version: 4
143
+ summary: A Ruby Library for working with multi page forms
144
+ test_files:
145
+ - spec/elements/group_spec.rb
146
+ - spec/elements/html_spec.rb
147
+ - spec/elements/page_spec.rb
148
+ - spec/elements/text_field_spec.rb
149
+ - spec/hungryform_spec.rb
150
+ - spec/resolver_spec.rb
151
+ - spec/spec_helper.rb
152
+ - spec/support/shared_active_element.rb
153
+ - spec/support/shared_element.rb
154
+ - spec/support/shared_group.rb