padrino-validation-html5 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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --drb
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ group :automated do
7
+ gem 'spork', '>= 0.9.0.rc9'
8
+ gem 'guard-spork'
9
+ gem 'guard-rspec'
10
+
11
+ if /darwin/ === RUBY_PLATFORM
12
+ gem 'rb-fsevent'
13
+ gem 'ruby_gntp'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'spork' do
5
+ watch('Gemfile')
6
+ watch('Gemfile.lock')
7
+ watch('spec/spec_helper.rb')
8
+ end
9
+
10
+ guard 'rspec', :version => 2 do
11
+ watch(%r{^spec/.+_spec\.rb$})
12
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('spec/spec_helper.rb') { "spec" }
15
+ end
16
+
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ load "spec/spec.rake"
@@ -0,0 +1,2 @@
1
+ require "padrino/validation/html5"
2
+ require "padrino/validation/html5/version"
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+
3
+ require "padrino-helpers/tag_helpers"
4
+ require "padrino-helpers/form_helpers"
5
+ require "padrino-helpers/form_builder/abstract_form_builder"
6
+
7
+ module Padrino
8
+ module Validation; end
9
+ end
10
+
11
+ module Padrino::Validation::HTML5
12
+ module ExtendedHelpers
13
+ private
14
+ def identity_tag_attributes
15
+ super + [:readonly, :required, :autofocus, :novalidate, :formnovalidate, :multiple]
16
+ end
17
+ end
18
+
19
+ class << self
20
+ def registered(app)
21
+ builder = Padrino::Helpers::FormBuilder.const_get(app.settings.default_builder)
22
+ builder.send :include, self
23
+ Padrino::Helpers::TagHelpers.instance_eval do
24
+ alias_method :__identity_tag_attributes, :identity_tag_attributes
25
+ def identity_tag_attributes
26
+ __identity_tag_attributes + [:readonly, :required, :autofocus, :novalidate, :formnovalidate, :multiple]
27
+ end
28
+ end
29
+ end
30
+
31
+ def included(subj)
32
+ subj.field_types.each {|field|
33
+ define_method(field) {|field, options={}| options = inject_validations(field, options); super(field, options) }
34
+ }
35
+ end
36
+ end
37
+
38
+ def inject_validations(field, options={})
39
+ validators = object.class.validators_on(field).
40
+ group_by(&:kind).
41
+ map {|kind, validators| [kind, validators.map(&:options).inject(&:merge)] }
42
+ validators.each do |kind, opts|
43
+ case kind
44
+ when :presence
45
+ options.reverse_merge!(required: true)
46
+ when :length
47
+ attrs = {}
48
+ if opts[:is]
49
+ attrs[:minlength] = attrs[:maxlength] = opts[:is]
50
+ else
51
+ attrs[:minlength] = [opts[:minimum], opts[:within].try(:first)].compact.max
52
+ attrs[:maxlength] = [opts[:maximum], opts[:within].try(:last)].compact.min
53
+ end
54
+ options.reverse_merge!(attrs.reject {|_, v| v.blank? })
55
+ when :inclusion
56
+ if opts[:in].respond_to?(:first) && opts[:in].respond_to?(:last)
57
+ attrs = {
58
+ min: opts[:in].first,
59
+ max: opts[:in].last
60
+ }
61
+ options.reverse_merge!(attrs.reject {|_, v| v.blank? })
62
+ end
63
+ end
64
+ end
65
+ options
66
+ end
67
+ end
68
+
@@ -0,0 +1,7 @@
1
+ module Padrino
2
+ module Validation
3
+ module HTML5
4
+ VERSION = "0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "padrino/validation/html5/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "padrino-validation-html5"
7
+ s.version = Padrino::Validation::HTML5::VERSION
8
+ s.authors = ["AOKI Hanae"]
9
+ s.email = ["aereal@kerare.org"]
10
+ s.homepage = "https://github.com/aereal/padrino-validation-html5"
11
+ s.summary = %q{automatically add client-side validations}
12
+ s.description = %q{automatically add client-side validations}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_runtime_dependency "padrino-helpers"
19
+ s.add_development_dependency "rake"
20
+ s.add_development_dependency "rspec"
21
+ s.add_development_dependency "activemodel"
22
+ s.add_development_dependency "nokogiri"
23
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ describe Padrino::Validation::HTML5 do
4
+ include Padrino::Helpers::OutputHelpers
5
+ include Padrino::Helpers::TagHelpers
6
+ include Padrino::Helpers::AssetTagHelpers
7
+ include Padrino::Helpers::FormHelpers
8
+ include Padrino::Validation::HTML5::ExtendedHelpers
9
+
10
+ before do
11
+ Padrino::Helpers::FormBuilder::StandardFormBuilder.send :include, Padrino::Validation::HTML5
12
+ class Model < ActiveModel::Base
13
+ @attrs = [:name, :age]
14
+ define_attribute_methods @attrs
15
+ attr_accessor *@attrs
16
+ end
17
+ end
18
+
19
+ context "when model has field which should be present" do
20
+ before do
21
+ Model.validates_presence_of :name
22
+ end
23
+
24
+ it "injects `required' attribute to `input' element" do
25
+ form_for(Model.new, '/register') {|f| f.text_field :name }.
26
+ should have_tag('input', required: 'required')
27
+ end
28
+ end
29
+
30
+ context "when model has field which restricted max length" do
31
+ before do
32
+ Model.validates_length_of :name, maximum: 255
33
+ end
34
+
35
+ it "injects `maxlength' attribute to `input' element" do
36
+ form_for(Model.new, '/register') {|f| f.text_field :name }.
37
+ should have_tag('input', maxlength: '255')
38
+ end
39
+ end
40
+
41
+ context "when model has field which is inclusive of any range" do
42
+ before do
43
+ Model.validates_inclusion_of :age, in: 20..30
44
+ end
45
+
46
+ it "injects `max' attribute to element" do
47
+ form_for(Model.new, '/register') {|f| f.text_field :age }.
48
+ should have_tag('input', max: '30', min: '20')
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,13 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ spec_tasks = Dir['spec/*/'].map { |d| File.basename(d) }
4
+
5
+ spec_tasks.each do |folder|
6
+ RSpec::Core::RakeTask.new("spec:#{folder}") do |t|
7
+ t.pattern = "./spec/#{folder}/**/*_spec.rb"
8
+ t.rspec_opts = %w(-fs --color)
9
+ end
10
+ end
11
+
12
+ desc "Run complete application spec suite"
13
+ task 'spec' => spec_tasks.map { |f| "spec:#{f}" }
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'spork'
5
+
6
+ Spork.prefork do
7
+ require "bundler/setup"
8
+ Bundler.setup(:default)
9
+ require "rspec"
10
+ require "nokogiri"
11
+ require "active_model"
12
+ require "padrino-helpers"
13
+ require "padrino/validation/html5"
14
+
15
+ pwd = File.dirname(__FILE__)
16
+ $: << File.expand_path(pwd + '/../lib')
17
+
18
+ Dir["#{pwd}/support/**/*.rb"].each {|_| require File.expand_path(_) }
19
+ end
20
+
21
+ Spork.each_run do
22
+ end
23
+
@@ -0,0 +1,10 @@
1
+ require "active_model"
2
+
3
+ class ActiveModel::Base
4
+ include ActiveModel::AttributeMethods
5
+ include ActiveModel::Validations
6
+
7
+ def initialize(attrs={})
8
+ attrs.each {|k, v| send("#{k}=", v) }
9
+ end
10
+ end
@@ -0,0 +1,93 @@
1
+ require "nokogiri"
2
+
3
+ RSpec::Matchers.define :have_tag do |expected_tag, options={}|
4
+ match do |actual|
5
+ @expected_tag = expected_tag
6
+ @options = options
7
+ matched = nokogiri(actual)
8
+
9
+ if options[:count]
10
+ matched.size == options[:count].to_i
11
+ else
12
+ matched.any?
13
+ end
14
+ end
15
+
16
+ failure_message_for_should do |actual|
17
+ "expected following output to contain a #{tag_inspect} tag:\n#{@document}"
18
+ end
19
+
20
+ failure_message_for_should_not do |actual|
21
+ "expected following output to omit a #{tag_inspect}:\n#{@document}"
22
+ end
23
+
24
+ def nokogiri(str)
25
+ q = Nokogiri::CSS.parse(@expected_tag.to_s).map(&:to_xpath).first
26
+ @query = Nokogiri::XML::NodeSet === str ? q.gsub(%r|^//|, './/') : q
27
+
28
+ add_options_conditions_to!(@query)
29
+
30
+ @document =
31
+ case str
32
+ when Nokogiri::HTML::Document, Nokogiri::XML::NodeSet
33
+ str
34
+ when str.respond_to?(:body)
35
+ Nokogiri::HTML(str.body.to_s)
36
+ else
37
+ Nokogiri::HTML(str.to_s)
38
+ end
39
+ @document.xpath(*@query)
40
+ end
41
+
42
+ def xpath_escape(str)
43
+ if str.include?("'")
44
+ if str.include?('"')
45
+ parts = str.split("'").map {|part| "'#{part}'" }
46
+ "concat(#{parts.join(%|, "'", |)})"
47
+ else
48
+ %|"#{str}"|
49
+ end
50
+ else
51
+ "'#{str}'"
52
+ end
53
+ end
54
+
55
+ def tag_inspect
56
+ html = "<#{@expected_tag}"
57
+
58
+ @options.reject {|k, v| [:content, :count].include? k }.each do |k, v|
59
+ html << %| #{k}="#{v}"|
60
+ end
61
+
62
+ if @options[:content]
63
+ html << ">#{@options[:content]}</#{@expected_tag}>"
64
+ else
65
+ html << "/>"
66
+ end
67
+
68
+ html
69
+ end
70
+
71
+ def add_attributes_conditions_to!(query)
72
+ attribute_conditions = []
73
+
74
+ @options.reject {|k, v| [:content, :count].include? k }.each do |k, v|
75
+ attribute_conditions << "@#{k} = #{xpath_escape(v)}"
76
+ end
77
+
78
+ unless attribute_conditions.none?
79
+ query << "[#{attribute_conditions.join(' and ')}]"
80
+ end
81
+ end
82
+
83
+ def add_content_condition_to!(query)
84
+ if @options[:content]
85
+ query << "[contains(., #{xpath_escape(@options[:content])})]"
86
+ end
87
+ end
88
+
89
+ def add_options_conditions_to!(query)
90
+ add_attributes_conditions_to!(query)
91
+ add_content_condition_to!(query)
92
+ end
93
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: padrino-validation-html5
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - AOKI Hanae
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-10 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: padrino-helpers
16
+ requirement: &70152662705860 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70152662705860
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70152662705400 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70152662705400
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70152662704840 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70152662704840
47
+ - !ruby/object:Gem::Dependency
48
+ name: activemodel
49
+ requirement: &70152662704400 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70152662704400
58
+ - !ruby/object:Gem::Dependency
59
+ name: nokogiri
60
+ requirement: &70152662703940 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70152662703940
69
+ description: automatically add client-side validations
70
+ email:
71
+ - aereal@kerare.org
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - Gemfile
79
+ - Guardfile
80
+ - Rakefile
81
+ - lib/padrino-validation-html5.rb
82
+ - lib/padrino/validation/html5.rb
83
+ - lib/padrino/validation/html5/version.rb
84
+ - padrino-validation-html5.gemspec
85
+ - spec/padrino/validation/html5_spec.rb
86
+ - spec/spec.rake
87
+ - spec/spec_helper.rb
88
+ - spec/support/activemodel_base.rb
89
+ - spec/support/matchers/have_tag.rb
90
+ homepage: https://github.com/aereal/padrino-validation-html5
91
+ licenses: []
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ segments:
103
+ - 0
104
+ hash: 3227414695813390310
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ segments:
112
+ - 0
113
+ hash: 3227414695813390310
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 1.8.11
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: automatically add client-side validations
120
+ test_files:
121
+ - spec/padrino/validation/html5_spec.rb
122
+ - spec/spec.rake
123
+ - spec/spec_helper.rb
124
+ - spec/support/activemodel_base.rb
125
+ - spec/support/matchers/have_tag.rb