validates_timeliness 4.1.1 → 5.0.0.alpha1

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