hungryform 0.0.1

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 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