validates_timeliness 3.0.15 → 4.0.0
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 +4 -4
- data/.travis.yml +21 -0
- data/CHANGELOG.rdoc +0 -5
- data/README.rdoc +5 -5
- data/gemfiles/rails_4_0.gemfile +19 -0
- data/gemfiles/rails_4_1.gemfile +19 -0
- data/gemfiles/rails_4_2.gemfile +19 -0
- data/lib/generators/validates_timeliness/templates/validates_timeliness.rb +2 -2
- data/lib/validates_timeliness.rb +1 -1
- data/lib/validates_timeliness/attribute_methods.rb +36 -36
- data/lib/validates_timeliness/extensions.rb +3 -4
- data/lib/validates_timeliness/extensions/date_time_select.rb +2 -9
- data/lib/validates_timeliness/extensions/multiparameter_handler.rb +59 -65
- data/lib/validates_timeliness/helper_methods.rb +8 -2
- data/lib/validates_timeliness/orm/active_record.rb +59 -13
- data/lib/validates_timeliness/validator.rb +13 -5
- data/lib/validates_timeliness/version.rb +1 -1
- data/spec/spec_helper.rb +3 -2
- data/spec/support/model_helpers.rb +4 -4
- data/spec/support/tag_matcher.rb +35 -0
- data/spec/support/test_model.rb +0 -1
- data/spec/validates_timeliness/attribute_methods_spec.rb +10 -10
- data/spec/validates_timeliness/conversion_spec.rb +41 -41
- data/spec/validates_timeliness/extensions/date_time_select_spec.rb +5 -4
- data/spec/validates_timeliness/extensions/multiparameter_handler_spec.rb +8 -7
- data/spec/validates_timeliness/helper_methods_spec.rb +8 -8
- data/spec/validates_timeliness/orm/active_record_spec.rb +37 -37
- data/spec/validates_timeliness/validator/after_spec.rb +3 -3
- data/spec/validates_timeliness/validator/before_spec.rb +3 -3
- data/spec/validates_timeliness/validator/is_at_spec.rb +4 -4
- data/spec/validates_timeliness/validator/on_or_after_spec.rb +3 -3
- data/spec/validates_timeliness/validator/on_or_before_spec.rb +3 -3
- data/spec/validates_timeliness/validator_spec.rb +26 -26
- data/spec/validates_timeliness_spec.rb +8 -8
- metadata +7 -11
- data/gemfiles/mongoid_2_1.gemfile +0 -16
- data/gemfiles/mongoid_2_2.gemfile +0 -16
- data/gemfiles/mongoid_2_3.gemfile +0 -16
- data/gemfiles/mongoid_2_4.gemfile +0 -16
- data/gemfiles/rails_3_0.gemfile +0 -15
- data/gemfiles/rails_3_1.gemfile +0 -15
- data/gemfiles/rails_3_2.gemfile +0 -15
- data/lib/validates_timeliness/orm/mongoid.rb +0 -49
- data/spec/validates_timeliness/orm/mongoid_spec.rb +0 -223
| @@ -14,8 +14,14 @@ module ActiveModel | |
| 14 14 | 
             
                    timeliness_validation_for attr_names, :datetime
         | 
| 15 15 | 
             
                  end
         | 
| 16 16 |  | 
| 17 | 
            -
                  def  | 
| 18 | 
            -
                     | 
| 17 | 
            +
                  def validates_timeliness_of(*attr_names)
         | 
| 18 | 
            +
                    timeliness_validation_for attr_names
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  def timeliness_validation_for(attr_names, type=nil)
         | 
| 22 | 
            +
                    options = _merge_attributes(attr_names)
         | 
| 23 | 
            +
                    options.update(:type => type) if type
         | 
| 24 | 
            +
                    validates_with TimelinessValidator, options
         | 
| 19 25 | 
             
                  end
         | 
| 20 26 | 
             
                end
         | 
| 21 27 |  | 
| @@ -14,28 +14,74 @@ module ValidatesTimeliness | |
| 14 14 | 
             
                      timeliness_column_for_attribute(attr_name).type
         | 
| 15 15 | 
             
                    end
         | 
| 16 16 |  | 
| 17 | 
            -
                     | 
| 18 | 
            -
                       | 
| 19 | 
            -
                         | 
| 20 | 
            -
             | 
| 17 | 
            +
                    if ActiveModel.version >= Gem::Version.new('4.2')
         | 
| 18 | 
            +
                      def timeliness_column_for_attribute(attr_name)
         | 
| 19 | 
            +
                        columns_hash.fetch(attr_name.to_s) do |attr_name|
         | 
| 20 | 
            +
                          validation_type = _validators[attr_name.to_sym].find {|v| v.kind == :timeliness }.type.to_s
         | 
| 21 | 
            +
                          ::ActiveRecord::ConnectionAdapters::Column.new(attr_name, nil, lookup_cast_type(validation_type), validation_type)
         | 
| 22 | 
            +
                        end
         | 
| 23 | 
            +
                      end
         | 
| 24 | 
            +
                      
         | 
| 25 | 
            +
                      def lookup_cast_type(sql_type)
         | 
| 26 | 
            +
                        case sql_type
         | 
| 27 | 
            +
                        when 'datetime' then ::ActiveRecord::Type::DateTime.new 
         | 
| 28 | 
            +
                        when 'date' then ::ActiveRecord::Type::Date.new 
         | 
| 29 | 
            +
                        when 'time' then ::ActiveRecord::Type::Time.new 
         | 
| 30 | 
            +
                        end
         | 
| 31 | 
            +
                      end
         | 
| 32 | 
            +
                    else
         | 
| 33 | 
            +
                      def timeliness_column_for_attribute(attr_name)
         | 
| 34 | 
            +
                        columns_hash.fetch(attr_name.to_s) do |attr_name|
         | 
| 35 | 
            +
                          validation_type = _validators[attr_name.to_sym].find {|v| v.kind == :timeliness }.type.to_s
         | 
| 36 | 
            +
                          ::ActiveRecord::ConnectionAdapters::Column.new(attr_name, nil, validation_type)
         | 
| 37 | 
            +
                        end
         | 
| 21 38 | 
             
                      end
         | 
| 22 39 | 
             
                    end
         | 
| 23 40 |  | 
| 24 41 | 
             
                    def define_attribute_methods
         | 
| 25 | 
            -
                      super.tap  | 
| 26 | 
            -
                         | 
| 27 | 
            -
             | 
| 42 | 
            +
                      super.tap { 
         | 
| 43 | 
            +
                        generated_timeliness_methods.synchronize do
         | 
| 44 | 
            +
                          return if @timeliness_methods_generated
         | 
| 45 | 
            +
                          define_timeliness_methods true
         | 
| 46 | 
            +
                          @timeliness_methods_generated = true
         | 
| 47 | 
            +
                        end
         | 
| 48 | 
            +
                      }
         | 
| 28 49 | 
             
                    end
         | 
| 29 50 |  | 
| 30 | 
            -
                     | 
| 51 | 
            +
                    def undefine_attribute_methods
         | 
| 52 | 
            +
                      super.tap { 
         | 
| 53 | 
            +
                        generated_timeliness_methods.synchronize do
         | 
| 54 | 
            +
                          return unless @timeliness_methods_generated
         | 
| 55 | 
            +
                          undefine_timeliness_attribute_methods 
         | 
| 56 | 
            +
                          @timeliness_methods_generated = true
         | 
| 57 | 
            +
                        end
         | 
| 58 | 
            +
                      }
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
                    # Override to overwrite methods in ActiveRecord attribute method module because in AR 4+
         | 
| 61 | 
            +
                    # there is curious code which calls the method directly from the generated methods module
         | 
| 62 | 
            +
                    # via bind inside method_missing. This means our method in the formerly custom timeliness
         | 
| 63 | 
            +
                    # methods module was never reached.
         | 
| 64 | 
            +
                    def generated_timeliness_methods
         | 
| 65 | 
            +
                      generated_attribute_methods
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 31 68 |  | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 69 | 
            +
                  def write_timeliness_attribute(attr_name, value)
         | 
| 70 | 
            +
                    @timeliness_cache ||= {}
         | 
| 71 | 
            +
                    @timeliness_cache[attr_name] = value
         | 
| 34 72 |  | 
| 35 | 
            -
             | 
| 36 | 
            -
                       | 
| 37 | 
            -
                       | 
| 73 | 
            +
                    if ValidatesTimeliness.use_plugin_parser
         | 
| 74 | 
            +
                      type = self.class.timeliness_attribute_type(attr_name)
         | 
| 75 | 
            +
                      timezone = :current if self.class.timeliness_attribute_timezone_aware?(attr_name)
         | 
| 76 | 
            +
                      value = Timeliness::Parser.parse(value, type, :zone => timezone)
         | 
| 77 | 
            +
                      value = value.to_date if value && type == :date
         | 
| 38 78 | 
             
                    end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    write_attribute(attr_name, value)
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
                  
         | 
| 83 | 
            +
                  def read_timeliness_attribute_before_type_cast(attr_name)
         | 
| 84 | 
            +
                    @timeliness_cache && @timeliness_cache[attr_name] || read_attribute_before_type_cast(attr_name)
         | 
| 39 85 | 
             
                  end
         | 
| 40 86 |  | 
| 41 87 | 
             
                  def reload(*args)
         | 
| @@ -5,7 +5,7 @@ module ValidatesTimeliness | |
| 5 5 | 
             
              class Validator < ActiveModel::EachValidator
         | 
| 6 6 | 
             
                include Conversion
         | 
| 7 7 |  | 
| 8 | 
            -
                attr_reader :type
         | 
| 8 | 
            +
                attr_reader :type, :attributes
         | 
| 9 9 |  | 
| 10 10 | 
             
                RESTRICTIONS = {
         | 
| 11 11 | 
             
                  :is_at        => :==,
         | 
| @@ -42,16 +42,24 @@ module ValidatesTimeliness | |
| 42 42 | 
             
                  end
         | 
| 43 43 |  | 
| 44 44 | 
             
                  @restrictions_to_check = RESTRICTIONS.keys & options.keys
         | 
| 45 | 
            +
             | 
| 45 46 | 
             
                  super
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  setup_timeliness_validated_attributes(options[:class]) if options[:class]
         | 
| 46 49 | 
             
                end
         | 
| 47 50 |  | 
| 48 | 
            -
                def  | 
| 51 | 
            +
                def setup_timeliness_validated_attributes(model)
         | 
| 49 52 | 
             
                  if model.respond_to?(:timeliness_validated_attributes)
         | 
| 50 53 | 
             
                    model.timeliness_validated_attributes ||= []
         | 
| 51 | 
            -
                    model.timeliness_validated_attributes |=  | 
| 54 | 
            +
                    model.timeliness_validated_attributes |= attributes
         | 
| 52 55 | 
             
                  end
         | 
| 53 56 | 
             
                end
         | 
| 54 57 |  | 
| 58 | 
            +
                # Rails 4.0 compatibility for old #setup method with class as arg
         | 
| 59 | 
            +
                if ActiveModel.version <= Gem::Version.new('4.1')
         | 
| 60 | 
            +
                  alias_method(:setup, :setup_timeliness_validated_attributes) 
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 55 63 | 
             
                def validate_each(record, attr_name, value)
         | 
| 56 64 | 
             
                  raw_value = attribute_raw_value(record, attr_name) || value
         | 
| 57 65 | 
             
                  return if (@allow_nil && raw_value.nil?) || (@allow_blank && raw_value.blank?)
         | 
| @@ -93,8 +101,8 @@ module ValidatesTimeliness | |
| 93 101 | 
             
                end
         | 
| 94 102 |  | 
| 95 103 | 
             
                def attribute_raw_value(record, attr_name)
         | 
| 96 | 
            -
                  record.respond_to?(: | 
| 97 | 
            -
                    record. | 
| 104 | 
            +
                  record.respond_to?(:read_timeliness_attribute_before_type_cast) &&
         | 
| 105 | 
            +
                    record.read_timeliness_attribute_before_type_cast(attr_name.to_s)
         | 
| 98 106 | 
             
                end
         | 
| 99 107 |  | 
| 100 108 | 
             
                def timezone_aware?(record, attr_name)
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -5,13 +5,13 @@ require 'active_model/validations' | |
| 5 5 | 
             
            require 'active_record'
         | 
| 6 6 | 
             
            require 'action_view'
         | 
| 7 7 | 
             
            require 'timecop'
         | 
| 8 | 
            -
            require 'rspec_tag_matchers'
         | 
| 9 8 |  | 
| 10 9 | 
             
            require 'validates_timeliness'
         | 
| 11 10 |  | 
| 12 11 | 
             
            require 'support/test_model'
         | 
| 13 12 | 
             
            require 'support/model_helpers'
         | 
| 14 13 | 
             
            require 'support/config_helper'
         | 
| 14 | 
            +
            require 'support/tag_matcher'
         | 
| 15 15 |  | 
| 16 16 | 
             
            ValidatesTimeliness.setup do |c|
         | 
| 17 17 | 
             
              c.extend_orms = [ :active_record ]
         | 
| @@ -24,6 +24,7 @@ Time.zone = 'Australia/Melbourne' | |
| 24 24 |  | 
| 25 25 | 
             
            LOCALE_PATH = File.expand_path(File.dirname(__FILE__) + '/../lib/generators/validates_timeliness/templates/en.yml')
         | 
| 26 26 | 
             
            I18n.load_path.unshift(LOCALE_PATH)
         | 
| 27 | 
            +
            I18n.available_locales = ['en', 'es']
         | 
| 27 28 |  | 
| 28 29 | 
             
            # Extend TestModel as you would another ORM/ODM module
         | 
| 29 30 | 
             
            module TestModelShim
         | 
| @@ -85,7 +86,7 @@ end | |
| 85 86 |  | 
| 86 87 | 
             
            RSpec.configure do |c|
         | 
| 87 88 | 
             
              c.mock_with :rspec
         | 
| 88 | 
            -
              c.include( | 
| 89 | 
            +
              c.include(TagMatcher)
         | 
| 89 90 | 
             
              c.include(ModelHelpers)
         | 
| 90 91 | 
             
              c.include(ConfigHelper)
         | 
| 91 92 | 
             
              c.before do
         | 
| @@ -3,15 +3,15 @@ module ModelHelpers | |
| 3 3 | 
             
              # Some test helpers from Rails source 
         | 
| 4 4 | 
             
              def invalid!(attr_name, values, error = nil)
         | 
| 5 5 | 
             
                with_each_person_value(attr_name, values) do |record, value|
         | 
| 6 | 
            -
                  record. | 
| 7 | 
            -
                  record.errors[attr_name].size. | 
| 8 | 
            -
                  record.errors[attr_name].first. | 
| 6 | 
            +
                  expect(record).to be_invalid
         | 
| 7 | 
            +
                  expect(record.errors[attr_name].size).to be >= 1
         | 
| 8 | 
            +
                  expect(record.errors[attr_name].first).to eq(error) if error
         | 
| 9 9 | 
             
                end
         | 
| 10 10 | 
             
              end
         | 
| 11 11 |  | 
| 12 12 | 
             
              def valid!(attr_name, values)
         | 
| 13 13 | 
             
                with_each_person_value(attr_name, values) do |record, value|
         | 
| 14 | 
            -
                  record. | 
| 14 | 
            +
                  expect(record).to be_valid
         | 
| 15 15 | 
             
                end
         | 
| 16 16 | 
             
              end
         | 
| 17 17 |  | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            require 'nokogiri'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TagMatcher
         | 
| 4 | 
            +
              extend RSpec::Matchers::DSL
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              matcher :have_tag do |selector|
         | 
| 7 | 
            +
                match do |subject|
         | 
| 8 | 
            +
                  matches = doc(subject).search(selector)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  if @inner_text
         | 
| 11 | 
            +
                    matches = matches.select { |element| element.inner_text == @inner_text }
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  matches.any?
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                chain :with_inner_text do |inner_text|
         | 
| 18 | 
            +
                  @inner_text = inner_text
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                private
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def body(subject)
         | 
| 24 | 
            +
                  if subject.respond_to?(:body)
         | 
| 25 | 
            +
                    subject.body
         | 
| 26 | 
            +
                  else
         | 
| 27 | 
            +
                    subject.to_s
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def doc(subject)
         | 
| 32 | 
            +
                  @doc ||= Nokogiri::HTML(body(subject))
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
    
        data/spec/support/test_model.rb
    CHANGED
    
    
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 3 | 
             
            describe ValidatesTimeliness::AttributeMethods do
         | 
| 4 | 
            -
              it 'should define  | 
| 5 | 
            -
                PersonWithShim.new. | 
| 4 | 
            +
              it 'should define read_timeliness_attribute_before_type_cast instance method' do
         | 
| 5 | 
            +
                expect(PersonWithShim.new).to respond_to(:read_timeliness_attribute_before_type_cast)
         | 
| 6 6 | 
             
              end
         | 
| 7 7 |  | 
| 8 8 | 
             
              describe ".timeliness_validated_attributes" do
         | 
| @@ -12,7 +12,7 @@ describe ValidatesTimeliness::AttributeMethods do | |
| 12 12 | 
             
                  PersonWithShim.validates_time :birth_time
         | 
| 13 13 | 
             
                  PersonWithShim.validates_datetime :birth_datetime
         | 
| 14 14 |  | 
| 15 | 
            -
                  PersonWithShim.timeliness_validated_attributes. | 
| 15 | 
            +
                  expect(PersonWithShim.timeliness_validated_attributes).to eq([ :birth_date, :birth_time, :birth_datetime ])
         | 
| 16 16 | 
             
                end
         | 
| 17 17 | 
             
              end
         | 
| 18 18 |  | 
| @@ -31,13 +31,13 @@ describe ValidatesTimeliness::AttributeMethods do | |
| 31 31 | 
             
                it 'should cache attribute raw value' do
         | 
| 32 32 | 
             
                  r = PersonWithCache.new
         | 
| 33 33 | 
             
                  r.birth_datetime = date_string = '2010-01-01'
         | 
| 34 | 
            -
                  r. | 
| 34 | 
            +
                  expect(r.read_timeliness_attribute_before_type_cast('birth_datetime')).to eq(date_string)
         | 
| 35 35 | 
             
                end
         | 
| 36 36 |  | 
| 37 37 | 
             
                it 'should not overwrite user defined methods' do
         | 
| 38 38 | 
             
                  e = Employee.new
         | 
| 39 39 | 
             
                  e.birth_date = '2010-01-01'
         | 
| 40 | 
            -
                  e.redefined_birth_date_called. | 
| 40 | 
            +
                  expect(e.redefined_birth_date_called).to be_truthy
         | 
| 41 41 | 
             
                end
         | 
| 42 42 |  | 
| 43 43 | 
             
                it 'should be undefined if model class has dynamic attribute methods reset' do
         | 
| @@ -46,13 +46,13 @@ describe ValidatesTimeliness::AttributeMethods do | |
| 46 46 | 
             
                  r = PersonWithShim.new
         | 
| 47 47 | 
             
                  r.birth_date = Time.now
         | 
| 48 48 |  | 
| 49 | 
            -
                  write_method =  | 
| 49 | 
            +
                  write_method = :birth_date=
         | 
| 50 50 |  | 
| 51 | 
            -
                  PersonWithShim.send(:generated_timeliness_methods).instance_methods. | 
| 51 | 
            +
                  expect(PersonWithShim.send(:generated_timeliness_methods).instance_methods).to include(write_method)
         | 
| 52 52 |  | 
| 53 53 | 
             
                  PersonWithShim.undefine_attribute_methods 
         | 
| 54 54 |  | 
| 55 | 
            -
                  PersonWithShim.send(:generated_timeliness_methods).instance_methods. | 
| 55 | 
            +
                  expect(PersonWithShim.send(:generated_timeliness_methods).instance_methods).not_to include(write_method)
         | 
| 56 56 | 
             
                end
         | 
| 57 57 |  | 
| 58 58 | 
             
                context "with plugin parser" do
         | 
| @@ -70,7 +70,7 @@ describe ValidatesTimeliness::AttributeMethods do | |
| 70 70 | 
             
                  end
         | 
| 71 71 |  | 
| 72 72 | 
             
                  it 'should parse a string value' do
         | 
| 73 | 
            -
                    Timeliness::Parser. | 
| 73 | 
            +
                    expect(Timeliness::Parser).to receive(:parse)
         | 
| 74 74 | 
             
                    r = PersonWithParser.new
         | 
| 75 75 | 
             
                    r.birth_date = '2010-01-01'
         | 
| 76 76 | 
             
                  end
         | 
| @@ -80,7 +80,7 @@ describe ValidatesTimeliness::AttributeMethods do | |
| 80 80 |  | 
| 81 81 | 
             
              context "before_type_cast method" do
         | 
| 82 82 | 
             
                it 'should not be defined if ORM does not support it' do
         | 
| 83 | 
            -
                  PersonWithShim.new. | 
| 83 | 
            +
                  expect(PersonWithShim.new).not_to respond_to(:birth_datetime_before_type_cast)
         | 
| 84 84 | 
             
                end
         | 
| 85 85 | 
             
              end
         | 
| 86 86 | 
             
            end
         | 
| @@ -12,68 +12,68 @@ describe ValidatesTimeliness::Conversion do | |
| 12 12 | 
             
              describe "#type_cast_value" do
         | 
| 13 13 | 
             
                describe "for date type" do
         | 
| 14 14 | 
             
                  it "should return same value for date value" do
         | 
| 15 | 
            -
                    type_cast_value(Date.new(2010, 1, 1), :date). | 
| 15 | 
            +
                    expect(type_cast_value(Date.new(2010, 1, 1), :date)).to eq(Date.new(2010, 1, 1))
         | 
| 16 16 | 
             
                  end
         | 
| 17 17 |  | 
| 18 18 | 
             
                  it "should return date part of time value" do
         | 
| 19 | 
            -
                    type_cast_value(Time.mktime(2010, 1, 1, 0, 0, 0), :date). | 
| 19 | 
            +
                    expect(type_cast_value(Time.mktime(2010, 1, 1, 0, 0, 0), :date)).to eq(Date.new(2010, 1, 1))
         | 
| 20 20 | 
             
                  end
         | 
| 21 21 |  | 
| 22 22 | 
             
                  it "should return date part of datetime value" do
         | 
| 23 | 
            -
                    type_cast_value(DateTime.new(2010, 1, 1, 0, 0, 0), :date). | 
| 23 | 
            +
                    expect(type_cast_value(DateTime.new(2010, 1, 1, 0, 0, 0), :date)).to eq(Date.new(2010, 1, 1))
         | 
| 24 24 | 
             
                  end
         | 
| 25 25 |  | 
| 26 26 | 
             
                  it 'should return nil for invalid value types' do
         | 
| 27 | 
            -
                    type_cast_value(12, :date). | 
| 27 | 
            +
                    expect(type_cast_value(12, :date)).to eq(nil)
         | 
| 28 28 | 
             
                  end
         | 
| 29 29 | 
             
                end
         | 
| 30 30 |  | 
| 31 31 | 
             
                describe "for time type" do
         | 
| 32 32 | 
             
                  it "should return same value for time value matching dummy date part" do
         | 
| 33 | 
            -
                    type_cast_value(Time.utc(2000, 1, 1, 0, 0, 0), :time). | 
| 33 | 
            +
                    expect(type_cast_value(Time.utc(2000, 1, 1, 0, 0, 0), :time)).to eq(Time.utc(2000, 1, 1, 0, 0, 0))
         | 
| 34 34 | 
             
                  end
         | 
| 35 35 |  | 
| 36 36 | 
             
                  it "should return dummy time value with same time part for time value with different date" do
         | 
| 37 | 
            -
                    type_cast_value(Time.utc(2010, 1, 1, 0, 0, 0), :time). | 
| 37 | 
            +
                    expect(type_cast_value(Time.utc(2010, 1, 1, 0, 0, 0), :time)).to eq(Time.utc(2000, 1, 1, 0, 0, 0))
         | 
| 38 38 | 
             
                  end
         | 
| 39 39 |  | 
| 40 40 | 
             
                  it "should return dummy time only for date value" do
         | 
| 41 | 
            -
                    type_cast_value(Date.new(2010, 1, 1), :time). | 
| 41 | 
            +
                    expect(type_cast_value(Date.new(2010, 1, 1), :time)).to eq(Time.utc(2000, 1, 1, 0, 0, 0))
         | 
| 42 42 | 
             
                  end
         | 
| 43 43 |  | 
| 44 44 | 
             
                  it "should return dummy date with time part for datetime value" do
         | 
| 45 | 
            -
                    type_cast_value(DateTime.civil_from_format(:utc, 2010, 1, 1, 12, 34, 56), :time). | 
| 45 | 
            +
                    expect(type_cast_value(DateTime.civil_from_format(:utc, 2010, 1, 1, 12, 34, 56), :time)).to eq(Time.utc(2000, 1, 1, 12, 34, 56))
         | 
| 46 46 | 
             
                  end
         | 
| 47 47 |  | 
| 48 48 | 
             
                  it 'should return nil for invalid value types' do
         | 
| 49 | 
            -
                    type_cast_value(12, :time). | 
| 49 | 
            +
                    expect(type_cast_value(12, :time)).to eq(nil)
         | 
| 50 50 | 
             
                  end
         | 
| 51 51 | 
             
                end
         | 
| 52 52 |  | 
| 53 53 | 
             
                describe "for datetime type" do
         | 
| 54 54 | 
             
                  it "should return Date as Time value" do
         | 
| 55 | 
            -
                    type_cast_value(Date.new(2010, 1, 1), :datetime). | 
| 55 | 
            +
                    expect(type_cast_value(Date.new(2010, 1, 1), :datetime)).to eq(Time.local(2010, 1, 1, 0, 0, 0))
         | 
| 56 56 | 
             
                  end
         | 
| 57 57 |  | 
| 58 58 | 
             
                  it "should return same Time value" do
         | 
| 59 59 | 
             
                    value = Time.utc(2010, 1, 1, 12, 34, 56)
         | 
| 60 | 
            -
                    type_cast_value(Time.utc(2010, 1, 1, 12, 34, 56), :datetime). | 
| 60 | 
            +
                    expect(type_cast_value(Time.utc(2010, 1, 1, 12, 34, 56), :datetime)).to eq(value)
         | 
| 61 61 | 
             
                  end
         | 
| 62 62 |  | 
| 63 63 | 
             
                  it "should return as Time with same component values" do
         | 
| 64 | 
            -
                    type_cast_value(DateTime.civil_from_format(:utc, 2010, 1, 1, 12, 34, 56), :datetime). | 
| 64 | 
            +
                    expect(type_cast_value(DateTime.civil_from_format(:utc, 2010, 1, 1, 12, 34, 56), :datetime)).to eq(Time.utc(2010, 1, 1, 12, 34, 56))
         | 
| 65 65 | 
             
                  end
         | 
| 66 66 |  | 
| 67 67 | 
             
                  it "should return same Time in correct zone if timezone aware" do
         | 
| 68 68 | 
             
                    @timezone_aware = true
         | 
| 69 69 | 
             
                    value = Time.utc(2010, 1, 1, 12, 34, 56)
         | 
| 70 70 | 
             
                    result = type_cast_value(value, :datetime)
         | 
| 71 | 
            -
                    result. | 
| 72 | 
            -
                    result.zone. | 
| 71 | 
            +
                    expect(result).to eq(Time.zone.local(2010, 1, 1, 23, 34, 56))
         | 
| 72 | 
            +
                    expect(result.zone).to eq('AEDT')
         | 
| 73 73 | 
             
                  end
         | 
| 74 74 |  | 
| 75 75 | 
             
                  it 'should return nil for invalid value types' do
         | 
| 76 | 
            -
                    type_cast_value(12, :datetime). | 
| 76 | 
            +
                    expect(type_cast_value(12, :datetime)).to eq(nil)
         | 
| 77 77 | 
             
                  end
         | 
| 78 78 | 
             
                end
         | 
| 79 79 |  | 
| @@ -82,41 +82,41 @@ describe ValidatesTimeliness::Conversion do | |
| 82 82 |  | 
| 83 83 | 
             
                  it "should ignore usec on time values when evaluated" do
         | 
| 84 84 | 
             
                    value = Time.utc(2010, 1, 1, 12, 34, 56, 10000)
         | 
| 85 | 
            -
                    type_cast_value(value, :datetime). | 
| 85 | 
            +
                    expect(type_cast_value(value, :datetime)).to eq(Time.utc(2010, 1, 1, 12, 34, 56))
         | 
| 86 86 | 
             
                  end
         | 
| 87 87 |  | 
| 88 88 | 
             
                  it "should ignore usec and return time in correct zone if timezone aware" do
         | 
| 89 89 | 
             
                    @timezone_aware = true
         | 
| 90 90 | 
             
                    value = Time.utc(2010, 1, 1, 12, 34, 56, 10000)
         | 
| 91 91 | 
             
                    result = type_cast_value(value, :datetime)
         | 
| 92 | 
            -
                    result. | 
| 93 | 
            -
                    result.zone. | 
| 92 | 
            +
                    expect(result).to eq(Time.zone.local(2010, 1, 1, 23, 34, 56))
         | 
| 93 | 
            +
                    expect(result.zone).to eq('AEDT')
         | 
| 94 94 | 
             
                  end
         | 
| 95 95 | 
             
                end
         | 
| 96 96 | 
             
              end
         | 
| 97 97 |  | 
| 98 98 | 
             
              describe "#dummy_time" do
         | 
| 99 99 | 
             
                it 'should return Time with dummy date values but same time components' do
         | 
| 100 | 
            -
                  dummy_time(Time.utc(2010, 11, 22, 12, 34, 56)). | 
| 100 | 
            +
                  expect(dummy_time(Time.utc(2010, 11, 22, 12, 34, 56))).to eq(Time.utc(2000, 1, 1, 12, 34, 56))
         | 
| 101 101 | 
             
                end
         | 
| 102 102 |  | 
| 103 103 | 
             
                it 'should return same value for Time which already has dummy date values' do
         | 
| 104 | 
            -
                  dummy_time(Time.utc(2000, 1, 1, 12, 34, 56)). | 
| 104 | 
            +
                  expect(dummy_time(Time.utc(2000, 1, 1, 12, 34, 56))).to eq(Time.utc(2000, 1, 1, 12, 34, 56))
         | 
| 105 105 | 
             
                end
         | 
| 106 106 |  | 
| 107 107 | 
             
                it 'should return time component values shifted to current zone if timezone aware' do
         | 
| 108 108 | 
             
                  @timezone_aware = true
         | 
| 109 | 
            -
                  dummy_time(Time.utc(2000, 1, 1, 12, 34, 56)). | 
| 109 | 
            +
                  expect(dummy_time(Time.utc(2000, 1, 1, 12, 34, 56))).to eq(Time.zone.local(2000, 1, 1, 23, 34, 56))
         | 
| 110 110 | 
             
                end
         | 
| 111 111 |  | 
| 112 112 | 
             
                it 'should return base dummy time value for Date value' do
         | 
| 113 | 
            -
                  dummy_time(Date.new(2010, 11, 22)). | 
| 113 | 
            +
                  expect(dummy_time(Date.new(2010, 11, 22))).to eq(Time.utc(2000, 1, 1, 0, 0, 0))
         | 
| 114 114 | 
             
                end
         | 
| 115 115 |  | 
| 116 116 | 
             
                describe "with custom dummy date" do
         | 
| 117 117 | 
             
                  it 'should return dummy time with custom dummy date' do
         | 
| 118 118 | 
             
                    with_config(:dummy_date_for_time_type, [2010, 1, 1] ) do
         | 
| 119 | 
            -
                      dummy_time(Time.utc(1999, 11, 22, 12, 34, 56)). | 
| 119 | 
            +
                      expect(dummy_time(Time.utc(1999, 11, 22, 12, 34, 56))).to eq(Time.utc(2010, 1, 1, 12, 34, 56))
         | 
| 120 120 | 
             
                    end
         | 
| 121 121 | 
             
                  end
         | 
| 122 122 | 
             
                end
         | 
| @@ -127,56 +127,56 @@ describe ValidatesTimeliness::Conversion do | |
| 127 127 |  | 
| 128 128 | 
             
                it 'should return Date object as is' do
         | 
| 129 129 | 
             
                  value = Date.new(2010,1,1)
         | 
| 130 | 
            -
                  evaluate_option_value(value, person). | 
| 130 | 
            +
                  expect(evaluate_option_value(value, person)).to eq(value)
         | 
| 131 131 | 
             
                end
         | 
| 132 132 |  | 
| 133 133 | 
             
                it 'should return Time object as is' do
         | 
| 134 134 | 
             
                  value = Time.mktime(2010,1,1)
         | 
| 135 | 
            -
                  evaluate_option_value(value, person). | 
| 135 | 
            +
                  expect(evaluate_option_value(value, person)).to eq(value)
         | 
| 136 136 | 
             
                end
         | 
| 137 137 |  | 
| 138 138 | 
             
                it 'should return DateTime object as is' do
         | 
| 139 139 | 
             
                  value = DateTime.new(2010,1,1,0,0,0)
         | 
| 140 | 
            -
                  evaluate_option_value(value, person). | 
| 140 | 
            +
                  expect(evaluate_option_value(value, person)).to eq(value)
         | 
| 141 141 | 
             
                end
         | 
| 142 142 |  | 
| 143 143 | 
             
                it 'should return Time value returned from proc with 0 arity' do
         | 
| 144 144 | 
             
                  value = Time.mktime(2010,1,1)
         | 
| 145 | 
            -
                  evaluate_option_value(lambda { value }, person). | 
| 145 | 
            +
                  expect(evaluate_option_value(lambda { value }, person)).to eq(value)
         | 
| 146 146 | 
             
                end
         | 
| 147 147 |  | 
| 148 148 | 
             
                it 'should return Time value returned by record attribute call in proc arity of 1' do
         | 
| 149 149 | 
             
                  value = Time.mktime(2010,1,1)
         | 
| 150 150 | 
             
                  person.birth_time = value
         | 
| 151 | 
            -
                  evaluate_option_value(lambda {|r| r.birth_time }, person). | 
| 151 | 
            +
                  expect(evaluate_option_value(lambda {|r| r.birth_time }, person)).to eq(value)
         | 
| 152 152 | 
             
                end
         | 
| 153 153 |  | 
| 154 154 | 
             
                it 'should return Time value for attribute method symbol which returns Time' do
         | 
| 155 155 | 
             
                  value = Time.mktime(2010,1,1)
         | 
| 156 156 | 
             
                  person.birth_time = value
         | 
| 157 | 
            -
                  evaluate_option_value(:birth_time, person). | 
| 157 | 
            +
                  expect(evaluate_option_value(:birth_time, person)).to eq(value)
         | 
| 158 158 | 
             
                end
         | 
| 159 159 |  | 
| 160 160 | 
             
                it 'should return Time value is default zone from string time value' do
         | 
| 161 161 | 
             
                  value = '2010-01-01 12:00:00'
         | 
| 162 | 
            -
                  evaluate_option_value(value, person). | 
| 162 | 
            +
                  expect(evaluate_option_value(value, person)).to eq(Time.utc(2010,1,1,12,0,0))
         | 
| 163 163 | 
             
                end
         | 
| 164 164 |  | 
| 165 165 | 
             
                it 'should return Time value is current zone from string time value if timezone aware' do
         | 
| 166 166 | 
             
                  @timezone_aware = true
         | 
| 167 167 | 
             
                  value = '2010-01-01 12:00:00'
         | 
| 168 | 
            -
                  evaluate_option_value(value, person). | 
| 168 | 
            +
                  expect(evaluate_option_value(value, person)).to eq(Time.zone.local(2010,1,1,12,0,0))
         | 
| 169 169 | 
             
                end
         | 
| 170 170 |  | 
| 171 171 | 
             
                it 'should return Time value in default zone from proc which returns string time' do
         | 
| 172 172 | 
             
                  value = '2010-01-01 12:00:00'
         | 
| 173 | 
            -
                  evaluate_option_value(lambda { value }, person). | 
| 173 | 
            +
                  expect(evaluate_option_value(lambda { value }, person)).to eq(Time.utc(2010,1,1,12,0,0))
         | 
| 174 174 | 
             
                end
         | 
| 175 175 |  | 
| 176 176 | 
             
                it 'should return Time value for attribute method symbol which returns string time value' do
         | 
| 177 177 | 
             
                  value = '2010-01-01 12:00:00'
         | 
| 178 178 | 
             
                  person.birth_time = value
         | 
| 179 | 
            -
                  evaluate_option_value(:birth_time, person). | 
| 179 | 
            +
                  expect(evaluate_option_value(:birth_time, person)).to eq(Time.zone.local(2010,1,1,12,0,0))
         | 
| 180 180 | 
             
                end
         | 
| 181 181 |  | 
| 182 182 | 
             
                context "restriction shorthand" do
         | 
| @@ -185,17 +185,17 @@ describe ValidatesTimeliness::Conversion do | |
| 185 185 | 
             
                  end
         | 
| 186 186 |  | 
| 187 187 | 
             
                  it 'should evaluate :now as current time' do
         | 
| 188 | 
            -
                    evaluate_option_value(:now, person). | 
| 188 | 
            +
                    expect(evaluate_option_value(:now, person)).to eq(Time.now)
         | 
| 189 189 | 
             
                  end
         | 
| 190 190 |  | 
| 191 191 | 
             
                  it 'should evaluate :today as current time' do
         | 
| 192 | 
            -
                    evaluate_option_value(:today, person). | 
| 192 | 
            +
                    expect(evaluate_option_value(:today, person)).to eq(Date.today)
         | 
| 193 193 | 
             
                  end
         | 
| 194 194 |  | 
| 195 195 | 
             
                  it 'should not use shorthand if symbol if is record method' do
         | 
| 196 196 | 
             
                    time = 1.day.from_now
         | 
| 197 | 
            -
                    person. | 
| 198 | 
            -
                    evaluate_option_value(:now, person). | 
| 197 | 
            +
                    allow(person).to receive(:now).and_return(time)
         | 
| 198 | 
            +
                    expect(evaluate_option_value(:now, person)).to eq(time)
         | 
| 199 199 | 
             
                  end
         | 
| 200 200 | 
             
                end
         | 
| 201 201 | 
             
              end
         | 
| @@ -205,7 +205,7 @@ describe ValidatesTimeliness::Conversion do | |
| 205 205 | 
             
                  with_config(:use_plugin_parser, true)
         | 
| 206 206 |  | 
| 207 207 | 
             
                  it 'should use timeliness' do
         | 
| 208 | 
            -
                    Timeliness::Parser. | 
| 208 | 
            +
                    expect(Timeliness::Parser).to receive(:parse)
         | 
| 209 209 | 
             
                    parse('2000-01-01')
         | 
| 210 210 | 
             
                  end
         | 
| 211 211 | 
             
                end
         | 
| @@ -215,20 +215,20 @@ describe ValidatesTimeliness::Conversion do | |
| 215 215 |  | 
| 216 216 | 
             
                  it 'should use Time.zone.parse attribute is timezone aware' do
         | 
| 217 217 | 
             
                    @timezone_aware = true
         | 
| 218 | 
            -
                    Time.zone. | 
| 218 | 
            +
                    expect(Time.zone).to receive(:parse)
         | 
| 219 219 | 
             
                    parse('2000-01-01')
         | 
| 220 220 | 
             
                  end
         | 
| 221 221 |  | 
| 222 222 | 
             
                  it 'should use value#to_time if use_plugin_parser setting is false and attribute is not timezone aware' do
         | 
| 223 223 | 
             
                    @timezone_aware = false
         | 
| 224 224 | 
             
                    value = '2000-01-01'
         | 
| 225 | 
            -
                    value. | 
| 225 | 
            +
                    expect(value).to receive(:to_time)
         | 
| 226 226 | 
             
                    parse(value)
         | 
| 227 227 | 
             
                  end
         | 
| 228 228 | 
             
                end
         | 
| 229 229 |  | 
| 230 230 | 
             
                it 'should return nil if value is nil' do
         | 
| 231 | 
            -
                  parse(nil). | 
| 231 | 
            +
                  expect(parse(nil)).to be_nil
         | 
| 232 232 | 
             
                end
         | 
| 233 233 | 
             
              end
         | 
| 234 234 | 
             
            end
         |