pluginaweek-smart_field_constraints 0.1.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,25 @@
1
+ == master
2
+
3
+ == 0.1.1 / 2009-03-15
4
+
5
+ * Fix limits for integer columns being interpreted incorrectly [Michael Grosser]
6
+
7
+ == 0.1.0 / 2008-12-14
8
+
9
+ * Remove the PluginAWeek namespace
10
+ * Update tests to use ActionView::TestCase
11
+
12
+ == 0.0.2 / 2008-06-22
13
+
14
+ * Remove log files from gems
15
+ * Don't check length validation constraints if models were loaded prior to the plugin being loaded [Michael Grosser]
16
+ * Refactor FormHelper extension to allow for others to easily extend the plugin for things like textarea lengths [Michael Grosser]
17
+ * Add support for tracking validates_size_of validations
18
+
19
+ == 0.0.1 / 2008-05-05
20
+
21
+ * Initial public release
22
+ * Add documentation
23
+ * Remove maxlength attribute for textare tags since it's not valid html
24
+ * Don't set the size based on the smart maxlength
25
+ * Don't expect columns to exist for every attribute
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007-2009 Aaron Pfeifer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,92 @@
1
+ = smart_field_constraints
2
+
3
+ +smart_field_constraints+ intelligently applies a maxlength attribute for text
4
+ fields based on column constraints and validations.
5
+
6
+ == Resources
7
+
8
+ API
9
+
10
+ * http://api.pluginaweek.org/smart_field_constraints
11
+
12
+ Bugs
13
+
14
+ * http://pluginaweek.lighthouseapp.com/projects/13287-smart_field_constraints
15
+
16
+ Development
17
+
18
+ * http://github.com/pluginaweek/smart_field_constraints
19
+
20
+ Source
21
+
22
+ * git://github.com/pluginaweek/smart_field_constraints.git
23
+
24
+ == Description
25
+
26
+ HTML input field restrictions within forms can often help with both validation
27
+ and improving the user experience. Normally, adding the +maxlength+ configuration
28
+ option for input fields is not DRY and duplicates data already available in the
29
+ model or database. This plugin helps make this automatic.
30
+
31
+ +smart_field_constraints+ looks in two places for determining the maxlength value
32
+ for an input field:
33
+ * Model validates_length_of/validates_size_of validations
34
+ * Database column definitions (limits specifically)
35
+
36
+ Model validations will always take preference over database column definitions.
37
+
38
+ == Usage
39
+
40
+ There's nothing that you need to change to be able to use this plugin. It'll
41
+ just start automatically adding the +maxlength+ values it finds based on the
42
+ information described above (unless you define that option yourself).
43
+
44
+ === Example
45
+
46
+ Model:
47
+ class User < ActiveRecord::Base
48
+ validates_length_of :login, :maximum => 12
49
+ end
50
+
51
+ View:
52
+ text_field(:user, :login)
53
+
54
+ HTML:
55
+ <input id="user_login" maxlength="12" name="user[login]" size="30" type="text" />
56
+
57
+ === Textarea maxlengths
58
+
59
+ Since the +maxlength+ attribute is not W3C-compliant for textareas, it is not
60
+ included in the types of fields that will be automatically assigned length
61
+ constraints. However, you can easily add this yourself by extending the plugin
62
+ yourself. For an example of this see smart_field_constraints_textarea[http://github.com/grosser/smart_field_constraints_textarea].
63
+
64
+ == Caveats
65
+
66
+ === Plugin load order
67
+
68
+ If you have plugins with models that are loaded *before* smart_field_constraints
69
+ is loaded, then any length validations defined in those models will *not* be
70
+ tracked and automatically used in form fields. To fix this, you can adjust your
71
+ application's plugin load order to ensure that smart_field_constraints is loaded
72
+ first:
73
+
74
+ config/environment.rb:
75
+ Rails::Initializer.run do |config|
76
+ ...
77
+ config.plugins = [:smart_field_constraints, :all]
78
+ ...
79
+ end
80
+
81
+ == Testing
82
+
83
+ Before you can run any tests, the following gem must be installed:
84
+ * plugin_test_helper[http://github.com/pluginaweek/plugin_test_helper]
85
+
86
+ To run against a specific version of Rails:
87
+
88
+ rake test RAILS_FRAMEWORK_ROOT=/path/to/rails
89
+
90
+ == Dependencies
91
+
92
+ * Rails 2.0 or later
@@ -0,0 +1,96 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/contrib/sshpublisher'
5
+
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = 'smart_field_constraints'
8
+ s.version = '0.1.1'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'Intelligently applies a maxlength attribute for text fields based on column constraints and validations'
11
+ s.description = s.summary
12
+
13
+ s.files = FileList['{lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
14
+ s.require_path = 'lib'
15
+ s.has_rdoc = true
16
+ s.test_files = Dir['test/**/*_test.rb']
17
+
18
+ s.author = 'Aaron Pfeifer'
19
+ s.email = 'aaron@pluginaweek.org'
20
+ s.homepage = 'http://www.pluginaweek.org'
21
+ s.rubyforge_project = 'pluginaweek'
22
+ end
23
+
24
+ desc 'Default: run all tests.'
25
+ task :default => :test
26
+
27
+ desc "Test the #{spec.name} plugin."
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << 'lib'
30
+ t.test_files = spec.test_files
31
+ t.verbose = true
32
+ end
33
+
34
+ begin
35
+ require 'rcov/rcovtask'
36
+ namespace :test do
37
+ desc "Test the #{spec.name} plugin with Rcov."
38
+ Rcov::RcovTask.new(:rcov) do |t|
39
+ t.libs << 'lib'
40
+ t.test_files = spec.test_files
41
+ t.rcov_opts << '--exclude="^(?!lib/)"'
42
+ t.verbose = true
43
+ end
44
+ end
45
+ rescue LoadError
46
+ end
47
+
48
+ desc "Generate documentation for the #{spec.name} plugin."
49
+ Rake::RDocTask.new(:rdoc) do |rdoc|
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = spec.name
52
+ rdoc.template = '../rdoc_template.rb'
53
+ rdoc.options << '--line-numbers' << '--inline-source'
54
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
55
+ end
56
+
57
+ desc 'Generate a gemspec file.'
58
+ task :gemspec do
59
+ File.open("#{spec.name}.gemspec", 'w') do |f|
60
+ f.write spec.to_ruby
61
+ end
62
+ end
63
+
64
+ Rake::GemPackageTask.new(spec) do |p|
65
+ p.gem_spec = spec
66
+ p.need_tar = true
67
+ p.need_zip = true
68
+ end
69
+
70
+ desc 'Publish the beta gem.'
71
+ task :pgem => [:package] do
72
+ Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
73
+ end
74
+
75
+ desc 'Publish the API documentation.'
76
+ task :pdoc => [:rdoc] do
77
+ Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
78
+ end
79
+
80
+ desc 'Publish the API docs and gem'
81
+ task :publish => [:pgem, :pdoc, :release]
82
+
83
+ desc 'Publish the release files to RubyForge.'
84
+ task :release => [:gem, :package] do
85
+ require 'rubyforge'
86
+
87
+ ruby_forge = RubyForge.new.configure
88
+ ruby_forge.login
89
+
90
+ %w(gem tgz zip).each do |ext|
91
+ file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
92
+ puts "Releasing #{File.basename(file)}..."
93
+
94
+ ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
95
+ end
96
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'smart_field_constraints'
@@ -0,0 +1,2 @@
1
+ require 'smart_field_constraints/extensions/form_helper'
2
+ require 'smart_field_constraints/extensions/validations'
@@ -0,0 +1,62 @@
1
+ module SmartFieldConstraints
2
+ module Extensions #:nodoc:
3
+ # Automatically applies the maximum length for an input field if it can be
4
+ # determined
5
+ module InstanceTag
6
+ def self.included(base) #:nodoc:
7
+ base.class_eval do
8
+ alias_method_chain :to_input_field_tag, :smart_constraints
9
+ end
10
+ end
11
+
12
+ # Apply constraints for the given field
13
+ def to_input_field_tag_with_smart_constraints(field_type, options = {})
14
+ # Only check password and text fields
15
+ add_max_length_constraints(options) if %w(password text).include?(field_type)
16
+
17
+ to_input_field_tag_without_smart_constraints(field_type, options)
18
+ end
19
+
20
+ private
21
+ def add_max_length_constraints(options)
22
+ options.stringify_keys!
23
+ return if options['maxlength'] || !object
24
+
25
+ # Look for the attribute's maximum length from tracked validations or
26
+ # the column's definition
27
+ if max_length = validation_length || column_limit
28
+ # If the size isn't specified, use the caller's maxlength of the default value.
29
+ # This must be done here, otherwise it'll use the maxlength value that
30
+ # we apply here
31
+ options['size'] ||= options['maxlength'] || ActionView::Helpers::InstanceTag::DEFAULT_FIELD_OPTIONS['size']
32
+ options['maxlength'] = max_length
33
+ end
34
+ end
35
+
36
+ # Finds the maximum length according to validations
37
+ def validation_length
38
+ if constraints = object.class.smart_length_constraints
39
+ constraints[method_name]
40
+ end
41
+ end
42
+
43
+ # Finds the maximum length according to column limits
44
+ def column_limit
45
+ column = object.class.columns_hash[method_name]
46
+
47
+ if column && limit = column.limit
48
+ if column.text?
49
+ limit
50
+ elsif column.number?
51
+ # Length is bound by the upper limit of the number + 1 (for negatives)
52
+ Math.log10(2 ** (limit * 8 - 1)).ceil + 1
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ ActionView::Helpers::InstanceTag.class_eval do
61
+ include SmartFieldConstraints::Extensions::InstanceTag
62
+ end
@@ -0,0 +1,74 @@
1
+ module SmartFieldConstraints
2
+ module Extensions #:nodoc:
3
+ # Tracks validations on the length of fields so that they can be used when
4
+ # generating form tags for those fields
5
+ module Validations
6
+ def self.included(base) #:nodoc:
7
+ base.class_eval do
8
+ extend SmartFieldConstraints::Extensions::Validations::ClassMethods
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+ def self.extended(base) #:nodoc:
14
+ base.class_eval do
15
+ class_inheritable_hash :smart_length_constraints
16
+ self.smart_length_constraints = {}
17
+ end
18
+
19
+ class << base
20
+ alias_method_chain :validates_length_of, :smart_constraints
21
+ alias_method_chain :validates_size_of, :smart_constraints
22
+ end
23
+ end
24
+
25
+ # Tracks what the maximum value is that's allowed for all of the
26
+ # attributes being validated
27
+ def validates_length_of_with_smart_constraints(*attrs)
28
+ track_length_constraints(attrs)
29
+ validates_length_of_without_smart_constraints(*attrs)
30
+ end
31
+
32
+ # Tracks what the maximum value is that's allowed for all of the
33
+ # attributes being validated
34
+ def validates_size_of_with_smart_constraints(*attrs)
35
+ track_length_constraints(attrs)
36
+ validates_size_of_without_smart_constraints(*attrs)
37
+ end
38
+
39
+ private
40
+ def track_length_constraints(attrs)
41
+ options = attrs.last
42
+ if options.is_a?(Hash)
43
+ # Extract the option restricting the length
44
+ options = options.symbolize_keys
45
+ range_options = ActiveRecord::Validations::ClassMethods::ALL_RANGE_OPTIONS & options.keys
46
+ option = range_options.first
47
+ option_value = options[range_options.first]
48
+
49
+ # Find the max value from ranges or specific maximums
50
+ max_length = nil
51
+ case option
52
+ when :within, :in
53
+ max_length = option_value.end
54
+ when :maximum, :is
55
+ max_length = option_value
56
+ end
57
+
58
+ if max_length
59
+ # Store the maximum value for each attribute so that it can be referenced later
60
+ attrs.each do |attr|
61
+ self.smart_length_constraints ||= {}
62
+ self.smart_length_constraints[attr.to_s] = max_length
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ ActiveRecord::Base.class_eval do
73
+ include SmartFieldConstraints::Extensions::Validations
74
+ end
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,8 @@
1
+ require 'config/boot'
2
+
3
+ Rails::Initializer.run do |config|
4
+ config.plugins = %w(tags smart_field_constraints)
5
+ config.cache_classes = false
6
+ config.whiny_nils = true
7
+ config.action_controller.session = {:key => 'rails_session', :secret => 'd229e4d22437432705ab3985d4d246'}
8
+ end
@@ -0,0 +1,14 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users, :id => false do |t|
4
+ t.integer :id, :limit => 4, :null => false # For limit for testing purposes
5
+ t.string :login, :limit => 12
6
+ t.string :password, :limit => 16
7
+ t.text :biography
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ drop_table :users
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ class CreateTags < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :tags do |t|
4
+ t.string :name, :limit => 100
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :tags
10
+ end
11
+ end
@@ -0,0 +1 @@
1
+ require 'tag'
@@ -0,0 +1,3 @@
1
+ class Tag < ActiveRecord::Base
2
+ validates_length_of :name, :maximum => 30
3
+ end
@@ -0,0 +1,110 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class FormHelperWithoutConstraintsTest < ActionView::TestCase
4
+ tests ActionView::Helpers::FormHelper
5
+
6
+ def setup
7
+ @user = User.new
8
+ end
9
+
10
+ def test_should_not_add_maxlength_for_text_field
11
+ assert_equal '<input id="user_biography" name="user[biography]" size="30" type="text" />', text_field(:user, :biography)
12
+ end
13
+
14
+ def test_should_not_add_maxlength_for_password_field
15
+ assert_equal '<input id="user_biography" name="user[biography]" size="30" type="password" />', password_field(:user, :biography)
16
+ end
17
+ end
18
+
19
+ class FormHelperWithValidationConstraintsTest < ActionView::TestCase
20
+ tests ActionView::Helpers::FormHelper
21
+
22
+ def setup
23
+ User.validates_length_of :biography, :maximum => 120
24
+ User.validates_length_of :password, :maximum => 14
25
+
26
+ @user = User.new
27
+ end
28
+
29
+ def test_should_not_add_maxlength_for_text_area
30
+ assert_equal '<textarea cols="40" id="user_biography" name="user[biography]" rows="20"></textarea>', text_area(:user, :biography)
31
+ end
32
+
33
+ def test_should_not_add_maxlength_for_hidden_field
34
+ assert_equal '<input id="user_password" name="user[password]" type="hidden" />', hidden_field(:user, :password)
35
+ end
36
+
37
+ def test_should_add_maxlength_for_password_field
38
+ assert_equal '<input id="user_password" maxlength="14" name="user[password]" size="30" type="password" />', password_field(:user, :password)
39
+ end
40
+
41
+ def test_should_add_maxlength_for_text_field
42
+ assert_equal '<input id="user_biography" maxlength="120" name="user[biography]" size="30" type="text" />', text_field(:user, :biography)
43
+ end
44
+
45
+ def test_should_allow_maxlength_to_be_overridden
46
+ assert_equal '<input id="user_biography" maxlength="100" name="user[biography]" size="100" type="text" />', text_field(:user, :biography, :maxlength => 100)
47
+ end
48
+
49
+ def teardown
50
+ User.class_eval do
51
+ ActiveRecord::Validations::VALIDATIONS.each do |validation|
52
+ instance_variable_set("@#{validation}_callbacks", nil)
53
+ end
54
+ end
55
+
56
+ User.smart_length_constraints.clear
57
+ end
58
+ end
59
+
60
+ class FormHelperWithStringColumnConstraintsTest < ActionView::TestCase
61
+ tests ActionView::Helpers::FormHelper
62
+
63
+ def setup
64
+ @user = User.new
65
+ end
66
+
67
+ def test_should_not_add_maxlength_for_text_area
68
+ assert_equal '<textarea cols="40" id="user_login" name="user[login]" rows="20"></textarea>', text_area(:user, :login)
69
+ end
70
+
71
+ def test_should_not_add_maxlength_for_hidden_field
72
+ assert_equal '<input id="user_password" name="user[password]" type="hidden" />', hidden_field(:user, :password)
73
+ end
74
+
75
+ def test_should_add_maxlength_for_password_field
76
+ assert_equal '<input id="user_password" maxlength="16" name="user[password]" size="30" type="password" />', password_field(:user, :password)
77
+ end
78
+
79
+ def test_should_add_maxlength_for_text_field
80
+ assert_equal '<input id="user_login" maxlength="12" name="user[login]" size="30" type="text" />', text_field(:user, :login)
81
+ end
82
+
83
+ def test_should_allow_maxlength_to_be_overridden
84
+ assert_equal '<input id="user_login" maxlength="100" name="user[login]" size="100" type="text" />', text_field(:user, :login, :maxlength => 100)
85
+ end
86
+ end
87
+
88
+ class FormHelperWithNumberColumnConstraintsTest < ActionView::TestCase
89
+ tests ActionView::Helpers::FormHelper
90
+
91
+ def setup
92
+ @user = User.new
93
+ end
94
+
95
+ def test_should_add_maxlength
96
+ assert_equal '<input id="user_id" maxlength="11" name="user[id]" size="30" type="text" />', text_field(:user, :id)
97
+ end
98
+ end
99
+
100
+ class FormHelperForModelNotTrackedTest < ActionView::TestCase
101
+ tests ActionView::Helpers::FormHelper
102
+
103
+ def setup
104
+ @tag = Tag.new
105
+ end
106
+
107
+ def test_should_add_maxlength_based_on_column_constraints
108
+ assert_equal '<input id="tag_name" maxlength="100" name="tag[name]" size="30" type="text" />', text_field(:tag, :name)
109
+ end
110
+ end
@@ -0,0 +1,7 @@
1
+ # Load the plugin testing framework
2
+ $:.unshift("#{File.dirname(__FILE__)}/../../plugin_test_helper/lib")
3
+ require 'rubygems'
4
+ require 'plugin_test_helper'
5
+
6
+ # Run the migrations
7
+ ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate")
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class ModelWithoutLengthValidationsTest < ActiveSupport::TestCase
4
+ def test_should_not_have_any_constraints
5
+ assert User.smart_length_constraints.empty?
6
+ end
7
+ end
8
+
9
+ class ModelWithLengthValidationsTest < ActiveSupport::TestCase
10
+ def test_should_not_track_constraint_for_minimum
11
+ User.validates_length_of :name, :minimum => 1
12
+ assert_nil User.smart_length_constraints['name']
13
+ end
14
+
15
+ def test_should_track_constraint_for_within
16
+ User.validates_length_of :name, :within => 1..10
17
+ assert_equal 10, User.smart_length_constraints['name']
18
+ end
19
+
20
+ def test_should_track_constraint_for_in
21
+ User.validates_length_of :name, :in => 1..10
22
+ assert_equal 10, User.smart_length_constraints['name']
23
+ end
24
+
25
+ def test_should_track_constraint_for_maximum
26
+ User.validates_length_of :name, :maximum => 10
27
+ assert_equal 10, User.smart_length_constraints['name']
28
+ end
29
+
30
+ def test_should_track_validation_for_is
31
+ User.validates_length_of :name, :is => 10
32
+ assert_equal 10, User.smart_length_constraints['name']
33
+ end
34
+
35
+ def teardown
36
+ User.class_eval do
37
+ ActiveRecord::Validations::VALIDATIONS.each do |validation|
38
+ instance_variable_set("@#{validation}_callbacks", nil)
39
+ end
40
+ end
41
+
42
+ User.smart_length_constraints.clear
43
+ end
44
+ end
45
+
46
+ class ModelWithSizeValidationsTest < ActiveSupport::TestCase
47
+ def test_should_track_constraints
48
+ User.validates_size_of :name, :maximum => 10
49
+ assert_equal 10, User.smart_length_constraints['name']
50
+ end
51
+
52
+ def teardown
53
+ User.class_eval do
54
+ ActiveRecord::Validations::VALIDATIONS.each do |validation|
55
+ instance_variable_set("@#{validation}_callbacks", nil)
56
+ end
57
+ end
58
+
59
+ User.smart_length_constraints.clear
60
+ end
61
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pluginaweek-smart_field_constraints
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Pfeifer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-08 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Intelligently applies a maxlength attribute for text fields based on column constraints and validations
17
+ email: aaron@pluginaweek.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/smart_field_constraints
26
+ - lib/smart_field_constraints/extensions
27
+ - lib/smart_field_constraints/extensions/validations.rb
28
+ - lib/smart_field_constraints/extensions/form_helper.rb
29
+ - lib/smart_field_constraints.rb
30
+ - test/unit
31
+ - test/unit/validations_test.rb
32
+ - test/helpers
33
+ - test/helpers/form_helper_test.rb
34
+ - test/app_root
35
+ - test/app_root/app
36
+ - test/app_root/app/models
37
+ - test/app_root/app/models/user.rb
38
+ - test/app_root/vendor
39
+ - test/app_root/vendor/plugins
40
+ - test/app_root/vendor/plugins/tags
41
+ - test/app_root/vendor/plugins/tags/lib
42
+ - test/app_root/vendor/plugins/tags/lib/tag.rb
43
+ - test/app_root/vendor/plugins/tags/init.rb
44
+ - test/app_root/db
45
+ - test/app_root/db/migrate
46
+ - test/app_root/db/migrate/001_create_users.rb
47
+ - test/app_root/db/migrate/002_create_tags.rb
48
+ - test/app_root/config
49
+ - test/app_root/config/environment.rb
50
+ - test/test_helper.rb
51
+ - CHANGELOG.rdoc
52
+ - init.rb
53
+ - LICENSE
54
+ - Rakefile
55
+ - README.rdoc
56
+ has_rdoc: true
57
+ homepage: http://www.pluginaweek.org
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ requirements: []
76
+
77
+ rubyforge_project: pluginaweek
78
+ rubygems_version: 1.2.0
79
+ signing_key:
80
+ specification_version: 2
81
+ summary: Intelligently applies a maxlength attribute for text fields based on column constraints and validations
82
+ test_files:
83
+ - test/unit/validations_test.rb
84
+ - test/helpers/form_helper_test.rb