padrino-validation-html5 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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