validates_timeliness 4.1.1 → 5.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 942eb4506928d381dae7a7356206a045a57d8085cc9ef8ea6e96801186274bea
4
- data.tar.gz: 6991d619ce2c4872c16e1c757f6de78c8f1761c6b5194f10b0312158431aba15
3
+ metadata.gz: 66a4ad3b4dbb1cda9d19921e18b17bf30029679689d331aafa699a2a3bb447a5
4
+ data.tar.gz: 1877d86f268f923d7dd344f2fc6965fbf8d5a207d3d669e3255f094709520a72
5
5
  SHA512:
6
- metadata.gz: abf74b01270b55f495fd10ca1e5abcdfe899742499dcb8c7af17b11f68aa04143b843d3b65c9cbafbd6eae1f56a4a9d4959b9bd8af6ec42a1c7bcc65055689d1
7
- data.tar.gz: afb9c7e4657292e244749548a8669222da167410d7a28831c665f6a86fa88e0415e3daecbd4580f8c2eec24e754c59cfe7ba2a232256c7a769b0ff2805aea6a5
6
+ metadata.gz: a3df0f1b7817dbf16b3d9c502488974a2acbbe858d65641a186cf73afb2499d10de484918ff20097396cf2f9295dd88c083de64328510bed53b112e058439663
7
+ data.tar.gz: 1c9a48cdc41249bed2e75b9087b848e30dd5d9743489bac304aa4a255c374053437f397495b2447ceea1f2af1ae383e5e1b421055d68a86d0abbcde335c7fc46
@@ -1,18 +1,14 @@
1
1
  language: ruby
2
- before_install:
3
- - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
4
- - gem install bundler -v '< 2'
5
- before_script:
6
- - bundle install
2
+ before_install: gem install bundler
7
3
  cache: bundler
8
- bundler_args: --verbose
9
4
 
10
- matrix:
11
- include:
12
- - rvm: "2.4.6"
13
- gemfile: gemfiles/rails_4_2.gemfile
14
- - rvm: "2.5.5"
15
- gemfile: gemfiles/rails_4_2.gemfile
5
+ gemfile:
6
+ - gemfiles/rails_5_0.gemfile
7
+ - gemfiles/rails_5_1.gemfile
8
+ - gemfiles/rails_5_2.gemfile
9
+
10
+ rvm:
11
+ - "2.5.1"
16
12
 
17
13
  script: 'bundle exec rspec'
18
14
 
@@ -1,14 +1,10 @@
1
- = 4.1.1 [2019-08-06]
2
- * Add initializer to ensure Timeliness default ambigiuous date handling config
3
- in Timeliness v0.4.1+ is set correctly when using `use_us_formats` or
4
- `use_euro_formats` switcher to set default.
5
- * Removed build support for Ruby 2.3 and Rails 4.0 and 4.1 to EOL official
6
- support for those.
7
-
8
- = 4.1.0 [2019-06-11]
9
- * Relaxed Timeliness dependency version to >= 0.3.10 and < 1, which allows
10
- version 0.4 with threadsafety fix for use_us_formats and use_euro_formats
11
- hot switching in a request.
1
+ = [UNRELEASED]
2
+ * Fix DateTimeSelect extension support (AquisTech)
3
+
4
+ Breaking Changes
5
+ * Update Multiparameter extension to use ActiveRecord type classes with multiparameter handling
6
+ which stores a hash of multiparamter values as the value before type cast, no longer a mushed datetime string
7
+ * Removed all custom plugin attribute methods and method overrides in favour using ActiveModel type system
12
8
 
13
9
  = 4.0.2 [2016-01-07]
14
10
  * Fix undefine_generated_methods ivar guard setting to false
@@ -1,14 +1,13 @@
1
- = ValidatesTimeliness
1
+ = ValidatesTimeliness {<img src="https://travis-ci.org/adzap/validates_timeliness.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/adzap/validates_timeliness]
2
2
 
3
3
  * Source: http://github.com/adzap/validates_timeliness
4
4
  * Issues: http://github.com/adzap/validates_timeliness/issues
5
5
 
6
6
  == Description
7
7
 
8
- Complete validation of dates, times and datetimes for Rails 4.2.x and ActiveModel. Rails 4.0.x and 4.1.x may
9
- still work but official support has ended.
8
+ Complete validation of dates, times and datetimes for Rails 5.0.x and ActiveModel.
10
9
 
11
- If you a looking for the old version for Rails 3.x go here[http://github.com/adzap/validates_timeliness/tree/v3.x].
10
+ If you a looking for the old version for Rails 4.x go here [https://github.com/adzap/validates_timeliness/tree/4-0-stable].
12
11
 
13
12
 
14
13
  == Features
@@ -31,7 +30,7 @@ If you a looking for the old version for Rails 3.x go here[http://github.com/adz
31
30
  == Installation
32
31
 
33
32
  # in Gemfile
34
- gem 'validates_timeliness', '~> 4.1'
33
+ gem 'validates_timeliness', '~> 5.0.0.pre'
35
34
 
36
35
  # Run bundler
37
36
  $ bundle install
@@ -0,0 +1,18 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.0.0"
6
+ gem "rspec"
7
+ gem "rspec-rails", "~> 3.7"
8
+ gem "timecop"
9
+ gem "byebug"
10
+ gem "appraisal"
11
+ gem "sqlite3"
12
+ gem "nokogiri", "~> 1.8"
13
+
14
+ group :active_record do
15
+ gem "sqlite3-ruby", require: "sqlite3"
16
+ end
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,18 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.1.0"
6
+ gem "rspec"
7
+ gem "rspec-rails", "~> 3.7"
8
+ gem "timecop"
9
+ gem "byebug"
10
+ gem "appraisal"
11
+ gem "sqlite3"
12
+ gem "nokogiri", "~> 1.8"
13
+
14
+ group :active_record do
15
+ gem "sqlite3-ruby", require: "sqlite3"
16
+ end
17
+
18
+ gemspec path: "../"
@@ -0,0 +1,18 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.2.0"
6
+ gem "rspec"
7
+ gem "rspec-rails", "~> 3.7"
8
+ gem "timecop"
9
+ gem "byebug"
10
+ gem "appraisal"
11
+ gem "sqlite3"
12
+ gem "nokogiri", "~> 1.8"
13
+
14
+ group :active_record do
15
+ gem "sqlite3-ruby", require: "sqlite3"
16
+ end
17
+
18
+ gemspec path: "../"
@@ -62,7 +62,7 @@ module ValidatesTimeliness
62
62
  def self.parser; Timeliness end
63
63
  end
64
64
 
65
- require 'validates_timeliness/conversion'
65
+ require 'validates_timeliness/converter'
66
66
  require 'validates_timeliness/validator'
67
67
  require 'validates_timeliness/helper_methods'
68
68
  require 'validates_timeliness/attribute_methods'
@@ -6,83 +6,44 @@ module ValidatesTimeliness
6
6
  class_attribute :timeliness_validated_attributes
7
7
  self.timeliness_validated_attributes = []
8
8
  end
9
+ end
10
+ end
9
11
 
10
- module ClassMethods
11
-
12
- public
13
- # Override in ORM shim
14
- def timeliness_attribute_timezone_aware?(attr_name)
15
- false
16
- end
17
-
18
- # Override in ORM shim
19
- def timeliness_attribute_type(attr_name)
20
- :datetime
21
- end
22
-
23
- def define_timeliness_methods(before_type_cast=false)
24
- return if timeliness_validated_attributes.blank?
25
- timeliness_validated_attributes.each do |attr_name|
26
- define_attribute_timeliness_methods(attr_name, before_type_cast)
27
- end
28
- end
29
-
30
- def generated_timeliness_methods
31
- @generated_timeliness_methods ||= Module.new { |m|
32
- extend Mutex_m
33
- }.tap { |mod| include mod }
34
- end
35
-
36
- def undefine_timeliness_attribute_methods
37
- generated_timeliness_methods.module_eval do
38
- instance_methods.each { |m| undef_method(m) }
39
- end
40
- end
41
-
42
- protected
43
-
44
- def define_attribute_timeliness_methods(attr_name, before_type_cast=false)
45
- define_timeliness_write_method(attr_name)
46
- define_timeliness_before_type_cast_method(attr_name) if before_type_cast
47
- end
48
-
49
- def define_timeliness_write_method(attr_name)
50
- generated_timeliness_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
51
- def #{attr_name}=(value)
52
- write_timeliness_attribute('#{attr_name}', value)
53
- end
54
- STR
55
- end
56
-
57
- def define_timeliness_before_type_cast_method(attr_name)
58
- generated_timeliness_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
59
- def #{attr_name}_before_type_cast
60
- read_timeliness_attribute_before_type_cast('#{attr_name}')
61
- end
62
- STR
63
- end
64
- end
65
-
66
- def write_timeliness_attribute(attr_name, value)
67
- @timeliness_cache ||= {}
68
- @timeliness_cache[attr_name] = value
12
+ ActiveModel::Type::Date.class_eval do
13
+ # Module.new do |m|
14
+ def cast_value(value)
15
+ return super unless ValidatesTimeliness.use_plugin_parser
69
16
 
70
- if ValidatesTimeliness.use_plugin_parser
71
- type = self.class.timeliness_attribute_type(attr_name)
72
- timezone = :current if self.class.timeliness_attribute_timezone_aware?(attr_name)
73
- value = Timeliness::Parser.parse(value, type, :zone => timezone)
74
- value = value.to_date if value && type == :date
17
+ if value.is_a?(::String)
18
+ return if value.empty?
19
+ value = Timeliness::Parser.parse(value, :date)
20
+ value.to_date if value
21
+ elsif value.respond_to?(:to_date)
22
+ value.to_date
23
+ else
24
+ value
75
25
  end
76
-
77
- @attributes[attr_name] = value
78
26
  end
27
+ # end.tap { |mod| include mod }
28
+ end
79
29
 
80
- def read_timeliness_attribute_before_type_cast(attr_name)
81
- @timeliness_cache && @timeliness_cache[attr_name] || @attributes[attr_name]
30
+ ActiveModel::Type::Time.class_eval do
31
+ def user_input_in_time_zone(value)
32
+ if value.is_a?(String) && ValidatesTimeliness.use_plugin_parser
33
+ dummy_time_value = value.sub(/\A(\d\d\d\d-\d\d-\d\d |)/, Date.current.to_s + ' ')
34
+ Timeliness::Parser.parse(dummy_time_value, :datetime, zone: :current)
35
+ else
36
+ value.in_time_zone
82
37
  end
38
+ end
39
+ end
83
40
 
84
- def _clear_timeliness_cache
85
- @timeliness_cache = {}
41
+ ActiveModel::Type::DateTime.class_eval do
42
+ def user_input_in_time_zone(value)
43
+ if value.is_a?(String) && ValidatesTimeliness.use_plugin_parser
44
+ Timeliness::Parser.parse(value, :datetime, zone: :current)
45
+ else
46
+ value.in_time_zone
86
47
  end
87
48
  end
88
- end
49
+ end
@@ -1,10 +1,18 @@
1
1
  module ValidatesTimeliness
2
- module Conversion
2
+ class Converter
3
+ attr_reader :type, :format, :ignore_usec
3
4
 
4
- def type_cast_value(value, type)
5
+ def initialize(type:, format: nil, ignore_usec: false, time_zone_aware: false)
6
+ @type = type
7
+ @format = format
8
+ @ignore_usec = ignore_usec
9
+ @time_zone_aware = time_zone_aware
10
+ end
11
+
12
+ def type_cast_value(value)
5
13
  return nil if value.nil? || !value.respond_to?(:to_time)
6
14
 
7
- value = value.in_time_zone if value.acts_like?(:time) && @timezone_aware
15
+ value = value.in_time_zone if value.acts_like?(:time) && time_zone_aware?
8
16
  value = case type
9
17
  when :time
10
18
  dummy_time(value)
@@ -15,8 +23,8 @@ module ValidatesTimeliness
15
23
  else
16
24
  value
17
25
  end
18
- if options[:ignore_usec] && value.is_a?(Time)
19
- Timeliness::Parser.make_time(Array(value).reverse[4..9], (:current if @timezone_aware))
26
+ if ignore_usec && value.is_a?(Time)
27
+ Timeliness::Parser.make_time(Array(value).reverse[4..9], (:current if time_zone_aware?))
20
28
  else
21
29
  value
22
30
  end
@@ -24,30 +32,30 @@ module ValidatesTimeliness
24
32
 
25
33
  def dummy_time(value)
26
34
  time = if value.acts_like?(:time)
27
- value = value.in_time_zone if @timezone_aware
35
+ value = value.in_time_zone if time_zone_aware?
28
36
  [value.hour, value.min, value.sec]
29
37
  else
30
38
  [0,0,0]
31
39
  end
32
40
  values = ValidatesTimeliness.dummy_date_for_time_type + time
33
- Timeliness::Parser.make_time(values, (:current if @timezone_aware))
41
+ Timeliness::Parser.make_time(values, (:current if time_zone_aware?))
34
42
  end
35
43
 
36
- def evaluate_option_value(value, record)
44
+ def evaluate(value, scope=nil)
37
45
  case value
38
46
  when Time, Date
39
47
  value
40
48
  when String
41
49
  parse(value)
42
50
  when Symbol
43
- if !record.respond_to?(value) && restriction_shorthand?(value)
51
+ if !scope.respond_to?(value) && restriction_shorthand?(value)
44
52
  ValidatesTimeliness.restriction_shorthand_symbols[value].call
45
53
  else
46
- evaluate_option_value(record.send(value), record)
54
+ evaluate(scope.send(value))
47
55
  end
48
56
  when Proc
49
- result = value.arity > 0 ? value.call(record) : value.call
50
- evaluate_option_value(result, record)
57
+ result = value.arity > 0 ? value.call(scope) : value.call
58
+ evaluate(result, scope)
51
59
  else
52
60
  value
53
61
  end
@@ -59,14 +67,18 @@ module ValidatesTimeliness
59
67
 
60
68
  def parse(value)
61
69
  return nil if value.nil?
70
+
62
71
  if ValidatesTimeliness.use_plugin_parser
63
- Timeliness::Parser.parse(value, @type, :zone => (:current if @timezone_aware), :format => options[:format], :strict => false)
72
+ Timeliness::Parser.parse(value, type, zone: (:current if time_zone_aware?), format: format, strict: false)
64
73
  else
65
- @timezone_aware ? Time.zone.parse(value) : value.to_time(ValidatesTimeliness.default_timezone)
74
+ time_zone_aware? ? Time.zone.parse(value) : value.to_time(ValidatesTimeliness.default_timezone)
66
75
  end
67
76
  rescue ArgumentError, TypeError
68
77
  nil
69
78
  end
70
79
 
80
+ def time_zone_aware?
81
+ @time_zone_aware
82
+ end
71
83
  end
72
84
  end
@@ -1,10 +1,10 @@
1
1
  module ValidatesTimeliness
2
2
  module Extensions
3
- autoload :DateTimeSelect, 'validates_timeliness/extensions/date_time_select'
3
+ autoload :TimelinessDateTimeSelect, 'validates_timeliness/extensions/date_time_select'
4
4
  end
5
5
 
6
6
  def self.enable_date_time_select_extension!
7
- ::ActionView::Helpers::Tags::DateSelect.send(:include, ValidatesTimeliness::Extensions::DateTimeSelect)
7
+ ::ActionView::Helpers::Tags::DateSelect.send(:prepend, ValidatesTimeliness::Extensions::TimelinessDateTimeSelect)
8
8
  end
9
9
 
10
10
  def self.enable_multiparameter_extension!
@@ -1,54 +1,50 @@
1
1
  module ValidatesTimeliness
2
2
  module Extensions
3
- module DateTimeSelect
4
- extend ActiveSupport::Concern
5
-
3
+ module TimelinessDateTimeSelect
6
4
  # Intercepts the date and time select helpers to reuse the values from
7
5
  # the params rather than the parsed value. This allows invalid date/time
8
6
  # values to be redisplayed instead of blanks to aid correction by the user.
9
7
  # It's a minor usability improvement which is rarely an issue for the user.
8
+ attr_accessor :object_name, :method_name, :template_object, :options, :html_options
10
9
 
11
- included do
12
- alias_method_chain :value, :timeliness
13
- end
10
+ POSITION = {
11
+ :year => 1, :month => 2, :day => 3, :hour => 4, :min => 5, :sec => 6
12
+ }.freeze
14
13
 
15
- class TimelinessDateTime
14
+ class DateTimeValue
16
15
  attr_accessor :year, :month, :day, :hour, :min, :sec
17
16
 
18
- def initialize(year, month, day, hour, min, sec)
17
+ def initialize(year:, month:, day: nil, hour: nil, min: nil, sec: nil)
19
18
  @year, @month, @day, @hour, @min, @sec = year, month, day, hour, min, sec
20
19
  end
21
20
 
22
- # adapted from activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 36 (3.0.7)
23
21
  def change(options)
24
- TimelinessDateTime.new(
25
- options[:year] || year,
26
- options[:month] || month,
27
- options[:day] || day,
28
- options[:hour] || hour,
29
- options[:min] || (options[:hour] ? 0 : min),
30
- options[:sec] || ((options[:hour] || options[:min]) ? 0 : sec)
22
+ self.class.new(
23
+ year: options.fetch(:year, year),
24
+ month: options.fetch(:month, month),
25
+ day: options.fetch(:day, day),
26
+ hour: options.fetch(:hour, hour),
27
+ min: options.fetch(:min) { options[:hour] ? 0 : min },
28
+ sec: options.fetch(:sec) { options[:hour] || options[:min] ? 0 : sec }
31
29
  )
32
30
  end
33
31
  end
34
32
 
35
- def value_with_timeliness(object)
36
- return value_without_timeliness(object) unless @template_object.params[@object_name]
37
-
38
- @template_object.params[@object_name]
33
+ # Splat args to support Rails 5.0 which expects object, and 5.2 which doesn't
34
+ def value(*object)
35
+ return super unless @template_object.params[@object_name]
39
36
 
40
37
  pairs = @template_object.params[@object_name].select {|k,v| k =~ /^#{@method_name}\(/ }
41
- return value_without_timeliness(object) if pairs.empty?
38
+ return super if pairs.empty?
42
39
 
43
- values = [nil] * 6
44
- pairs.map do |(param, value)|
45
- position = param.scan(/\((\d+)\w+\)/).first.first
46
- values[position.to_i-1] = value.to_i
40
+ values = {}
41
+ pairs.each_pair do |key, value|
42
+ position = key[/\((\d+)\w+\)/, 1]
43
+ values[POSITION.key(position.to_i)] = value.to_i
47
44
  end
48
45
 
49
- TimelinessDateTime.new(*values)
46
+ DateTimeValue.new(values)
50
47
  end
51
-
52
48
  end
53
49
  end
54
50
  end