time_of_day_attr 2.0.1 → 3.0.0.beta.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eaec6236cc4d2e7f298471e61ab3e58498dc416b
4
- data.tar.gz: b53b39ebbbac6c4dcaad3df6bc0dbe163853911c
3
+ metadata.gz: 1ebf5cc4b7319eee277b898f9b1640ad146cdc50
4
+ data.tar.gz: 722d500c30a81146b81aee9b355c3d066c3930ae
5
5
  SHA512:
6
- metadata.gz: 89de5c70a18f10db84f81ea5d40f4c0dbf8561194413b96b278184b37260d43f7ae02654b2a7f56374365fdc7c5f876cbfd063f516b2d5c96c9c5e43b13779bd
7
- data.tar.gz: 58309d82945193823b4c48861cb16544ef03bd75eebad4641304f8a53680c57dc6d0a7c0417392e71aad1ca33ba29ec8b40ab27ae5c663a3f7e9c3c65eda7615
6
+ metadata.gz: 4881e6b3f944773742c51b4b397cfe62e421394edec77ee1b1e54612c41b7dc76c54ad25153243d83425b07407672867e212e1eea5c8500db252b45cd34480dc
7
+ data.tar.gz: e4b02170e78bb124882bdea0ddf4cbe6b6ab4d15502cefdf34806bd1ca25771f35942256d6c6dc39f726fecfe9b84927e228786b0ad773bc847610094a33fbe0
data/Rakefile CHANGED
File without changes
@@ -0,0 +1,38 @@
1
+ module TimeOfDayAttr
2
+ module ActiveRecordExtension
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def time_of_day_attr(*attrs)
7
+ options = attrs.extract_options!
8
+
9
+ writers = AttrWriterModule.new(attrs, options)
10
+
11
+ if options[:prepend]
12
+ prepend writers
13
+ else
14
+ include writers
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ module AttrWriterModule
21
+ # rubocop:disable Metrics/MethodLength
22
+ def self.new(attrs, options)
23
+ Module.new do
24
+ attrs.each do |attr|
25
+ define_method("#{attr}=") do |value|
26
+ if value.is_a?(String)
27
+ delocalized_value = TimeOfDayAttr.delocalize(value, options)
28
+ super(delocalized_value)
29
+ else
30
+ super(value)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ # rubocop:enable Metrics/MethodLength
37
+ end
38
+ end
@@ -1,18 +1,14 @@
1
- require 'action_view'
2
-
3
1
  module TimeOfDayAttr
4
- module FormBuilderExt
2
+ module FormBuilderExtension
5
3
  extend ActiveSupport::Concern
6
4
 
7
5
  def time_of_day_field(method, options = {})
8
6
  options[:value] ||= begin
9
7
  value = object.public_send(method)
10
- TimeOfDayAttr.localize(value, options.extract!(:format, :omit_minutes_at_full_hour))
8
+ localize_options = options.extract!(:format, :omit_minutes_at_full_hour)
9
+ TimeOfDayAttr.localize(value, localize_options)
11
10
  end
12
11
  text_field(method, options)
13
12
  end
14
13
  end
15
14
  end
16
- ActiveSupport.on_load :action_view do
17
- ActionView::Helpers::FormBuilder.send(:include, TimeOfDayAttr::FormBuilderExt)
18
- end
@@ -0,0 +1,12 @@
1
+ module TimeOfDayAttr
2
+ class Railtie < ::Rails::Railtie
3
+ initializer 'time_of_day_attr.initialize' do
4
+ ActiveSupport.on_load(:active_record) do
5
+ include TimeOfDayAttr::ActiveRecordExtension
6
+ end
7
+ ActiveSupport.on_load(:action_view) do
8
+ ActionView::Helpers::FormBuilder.send(:include, TimeOfDayAttr::FormBuilderExtension)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,9 +1,20 @@
1
1
  module TimeOfDayAttr
2
- Seconds = Struct.new(:value) do
3
- def to_time_of_day(time_format)
2
+ module Seconds
3
+ def self.convert_to_time_of_day(value, options = {})
4
+ return value unless value.respond_to?(:seconds)
5
+
6
+ format = options[:format] || DEFAULT_FORMATS.first
7
+ time_format = TimeFormat.translate_format(format)
8
+
9
+ time_of_day = seconds_to_time_of_day(value, time_format)
10
+
11
+ options[:omit_minutes_at_full_hour] ? TimeOfDay.omit_minutes_at_full_hour(time_of_day) : time_of_day
12
+ end
13
+
14
+ def self.seconds_to_time_of_day(value, time_format)
4
15
  # Switch to beginning of year to prevent wrong conversion on the day of time change
5
16
  # see https://en.wikipedia.org/wiki/Daylight_saving_time
6
- time = Time.now.beginning_of_year.at_midnight + value.seconds
17
+ time = Time.current.beginning_of_year.at_midnight + value.seconds
7
18
 
8
19
  time_of_day = time.strftime(time_format)
9
20
 
@@ -13,5 +24,6 @@ module TimeOfDayAttr
13
24
  time_of_day
14
25
  end
15
26
  end
27
+ private_class_method :seconds_to_time_of_day
16
28
  end
17
29
  end
@@ -0,0 +1,8 @@
1
+ module TimeOfDayAttr
2
+ module TimeFormat
3
+ def self.translate_format(format)
4
+ translate = format.is_a?(Symbol)
5
+ translate ? I18n.translate("time_of_day.formats.#{format}") : format
6
+ end
7
+ end
8
+ end
@@ -1,18 +1,48 @@
1
1
  module TimeOfDayAttr
2
- TimeOfDay = Struct.new(:value) do
3
- def to_seconds(time_format)
4
- time = Time.strptime(value, time_format)
5
- # Switch to beginning of year to prevent wrong conversion on the day of time change
6
- # see https://en.wikipedia.org/wiki/Daylight_saving_time
7
- time = time.change(month: 1, day: 1)
2
+ module TimeOfDay
3
+ def self.convert_to_seconds(time_of_day, options = {})
4
+ formats = options[:formats] || DEFAULT_FORMATS
5
+ catch(:out_of_range) do
6
+ formats.each do |format|
7
+ time_format = TimeFormat.translate_format(format)
8
+ seconds = time_of_day_to_seconds(time_of_day, time_format)
9
+ return seconds if seconds
10
+ end
11
+ end
12
+ nil
13
+ end
8
14
 
9
- seconds = time.seconds_since_midnight.to_i
15
+ def self.omit_minutes_at_full_hour(time_of_day)
16
+ time_of_day.end_with?('00') ? time_of_day[0...-3] : time_of_day
17
+ end
10
18
 
11
- if seconds.zero? && value.starts_with?('24')
12
- 24.hours.to_i
13
- else
14
- seconds
15
- end
19
+ def self.seconds_since_midnight(time_of_day, time)
20
+ seconds = time.seconds_since_midnight
21
+ seconds = 24.hours if time_of_day_24_00?(time_of_day, seconds)
22
+ seconds.to_i
23
+ end
24
+ private_class_method :seconds_since_midnight
25
+
26
+ def self.time_of_day_24_00?(time_of_day, seconds)
27
+ time_of_day.starts_with?('24') && seconds.zero?
28
+ end
29
+ private_class_method :time_of_day_24_00?
30
+
31
+ def self.time_of_day_to_seconds(time_of_day, time_format)
32
+ time = time_of_day_to_time(time_of_day, time_format)
33
+ return unless time
34
+ seconds_since_midnight(time_of_day, time)
35
+ end
36
+ private_class_method :time_of_day_to_seconds
37
+
38
+ def self.time_of_day_to_time(time_of_day, time_format)
39
+ time = Time.strptime(time_of_day, time_format)
40
+ # Switch to beginning of year to prevent wrong conversion on the day of time change
41
+ # see https://en.wikipedia.org/wiki/Daylight_saving_time
42
+ time.change(month: 1, day: 1)
43
+ rescue ArgumentError => e
44
+ throw(:out_of_range) if e.message.include?('out of range')
16
45
  end
46
+ private_class_method :time_of_day_to_time
17
47
  end
18
48
  end
@@ -1,51 +1,23 @@
1
- require 'time_of_day_attr/time_of_day'
2
- require 'time_of_day_attr/seconds'
3
- require 'time_of_day_attr/active_record_ext'
4
- require 'time_of_day_attr/form_builder_ext'
5
-
6
- formats = Dir[File.join(File.dirname(__FILE__), '../config/locales/*.yml')]
7
- I18n.load_path.concat(formats)
8
-
9
1
  module TimeOfDayAttr
10
- DEFAULT_FORMATS = [:default, :hour].freeze
11
-
12
- class << self
13
- def delocalize(value, options = {})
14
- time_of_day = TimeOfDay.new(value)
15
-
16
- formats = options[:formats] || DEFAULT_FORMATS
17
-
18
- delocalized_values = formats.map do |format|
19
- begin
20
- time_of_day.to_seconds(time_format(format))
21
- rescue ArgumentError => e
22
- return nil if e.message.include?('out of range')
23
- next
24
- end
25
- end
26
-
27
- delocalized_values.compact.first
28
- end
2
+ DEFAULT_FORMATS = %i[default hour].freeze
29
3
 
30
- def localize(value, options = {})
31
- return value unless value.respond_to?(:seconds)
4
+ autoload :ActiveRecordExtension, 'time_of_day_attr/active_record_extension'
5
+ autoload :FormBuilderExtension, 'time_of_day_attr/form_builder_extension'
6
+ autoload :Seconds, 'time_of_day_attr/seconds'
7
+ autoload :TimeFormat, 'time_of_day_attr/time_format'
8
+ autoload :TimeOfDay, 'time_of_day_attr/time_of_day'
32
9
 
33
- format = options[:format] || DEFAULT_FORMATS.first
10
+ require 'i18n'
11
+ I18n.load_path << File.expand_path('../config/locales/time_of_day.en.yml', __dir__)
12
+ I18n.load_path << File.expand_path('../config/locales/time_of_day.de.yml', __dir__)
34
13
 
35
- time_of_day = Seconds.new(value).to_time_of_day(time_format(format))
36
-
37
- omit_minutes = options[:omit_minutes_at_full_hour] && time_of_day.end_with?('00')
38
-
39
- omit_minutes ? time_of_day[0...-3] : time_of_day
40
- end
41
- alias l localize
42
-
43
- private
44
-
45
- def time_format(format)
46
- translate = format.is_a?(Symbol)
14
+ def self.delocalize(time_of_day, options = {})
15
+ TimeOfDay.convert_to_seconds(time_of_day, options)
16
+ end
47
17
 
48
- translate ? I18n.translate("time_of_day.formats.#{format}") : format
49
- end
18
+ def self.localize(seconds, options = {})
19
+ Seconds.convert_to_time_of_day(seconds, options)
50
20
  end
51
21
  end
22
+
23
+ require 'time_of_day_attr/railtie' if defined?(Rails)
@@ -4,7 +4,7 @@ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:'
4
4
  require_relative 'schema'
5
5
  require_relative 'models/business_hour'
6
6
 
7
- class ActiveRecordExtTest < ActiveSupport::TestCase
7
+ class ActiveRecordExtensionTest < ActiveSupport::TestCase
8
8
  context 'time of day value' do
9
9
  setup do
10
10
  @business_hour = BusinessHour.new(opening: '9:00', closing: '17:00')
@@ -1,4 +1,8 @@
1
+ # rubocop:disable Rails/ApplicationRecord
1
2
  class BusinessHour < ActiveRecord::Base
3
+ # rubocop:enable Rails/ApplicationRecord
4
+ include TimeOfDayAttr::ActiveRecordExtension
5
+
2
6
  attr_reader :tracked_opening, :tracked_closing
3
7
 
4
8
  time_of_day_attr :opening
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+
3
+ module TimeOfDayAttr
4
+ class TimeOfDayTest < ActiveSupport::TestCase
5
+ context '::convert_to_time_of_day' do
6
+ should 'convert seconds to time of day' do
7
+ assert_equal ' 9:00', Seconds.convert_to_time_of_day(32_400)
8
+ assert_equal '14:45', Seconds.convert_to_time_of_day(53_100)
9
+ end
10
+
11
+ should 'omit minutes at full hour' do
12
+ assert_equal ' 9', Seconds.convert_to_time_of_day(32_400, omit_minutes_at_full_hour: true)
13
+ assert_equal '14', Seconds.convert_to_time_of_day(50_400, omit_minutes_at_full_hour: true)
14
+ assert_equal '14:45', Seconds.convert_to_time_of_day(53_100, omit_minutes_at_full_hour: true)
15
+ end
16
+
17
+ should 'convert nil to nil' do
18
+ assert_nil Seconds.convert_to_time_of_day(nil)
19
+ end
20
+
21
+ should 'support 24 hours' do
22
+ assert_equal ' 0:00', Seconds.convert_to_time_of_day(0)
23
+ assert_equal '24:00', Seconds.convert_to_time_of_day(86_400)
24
+ assert_equal ' 0', Seconds.convert_to_time_of_day(0, omit_minutes_at_full_hour: true)
25
+ assert_equal '24', Seconds.convert_to_time_of_day(86_400, omit_minutes_at_full_hour: true)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ module TimeOfDayAttr
4
+ class TimeOfDayTest < ActiveSupport::TestCase
5
+ context '::convert_to_seconds' do
6
+ should 'convert time of day to seconds' do
7
+ assert_equal 36_000, TimeOfDay.convert_to_seconds('10:00')
8
+ assert_equal 55_800, TimeOfDay.convert_to_seconds('15:30')
9
+ assert_equal 61_140, TimeOfDay.convert_to_seconds('16:59')
10
+ assert_equal 32_400, TimeOfDay.convert_to_seconds('9:00')
11
+ assert_equal 32_400, TimeOfDay.convert_to_seconds('09:00')
12
+ assert_equal 32_400, TimeOfDay.convert_to_seconds('9', formats: [:hour])
13
+ end
14
+
15
+ should 'convert out of range time of day to nil' do
16
+ assert_nil TimeOfDay.convert_to_seconds('25:00')
17
+ assert_nil TimeOfDay.convert_to_seconds('24:30')
18
+ end
19
+ end
20
+ end
21
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: time_of_day_attr
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clemens Teichmann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-01 00:00:00.000000000 Z
11
+ date: 2018-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: i18n
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.2.14
19
+ version: '0.7'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.2.14
26
+ version: '0.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sqlite3
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,8 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  description: This ruby gem converts time of day to seconds since midnight and back.
42
- The seconds value is stored in the database and can be used for calculations and
43
- validations.
42
+ The value in seconds can be used for calculations and validations.
44
43
  email:
45
44
  - clemens_t@web.de
46
45
  executables: []
@@ -52,16 +51,18 @@ files:
52
51
  - config/locales/time_of_day.de.yml
53
52
  - config/locales/time_of_day.en.yml
54
53
  - lib/time_of_day_attr.rb
55
- - lib/time_of_day_attr/active_record_ext.rb
54
+ - lib/time_of_day_attr/active_record_extension.rb
56
55
  - lib/time_of_day_attr/form_builder_ext.rb
56
+ - lib/time_of_day_attr/railtie.rb
57
57
  - lib/time_of_day_attr/seconds.rb
58
+ - lib/time_of_day_attr/time_format.rb
58
59
  - lib/time_of_day_attr/time_of_day.rb
59
- - lib/time_of_day_attr/version.rb
60
- - test/active_record_ext_test.rb
60
+ - test/active_record_extension_test.rb
61
61
  - test/models/business_hour.rb
62
62
  - test/schema.rb
63
63
  - test/test_helper.rb
64
- - test/time_of_day_attr_test.rb
64
+ - test/time_of_day_attr/seconds_test.rb
65
+ - test/time_of_day_attr/time_of_day_test.rb
65
66
  homepage: https://github.com/clemenst/time_of_day_attr
66
67
  licenses:
67
68
  - MIT
@@ -77,18 +78,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
78
  version: '0'
78
79
  required_rubygems_version: !ruby/object:Gem::Requirement
79
80
  requirements:
80
- - - ">="
81
+ - - ">"
81
82
  - !ruby/object:Gem::Version
82
- version: '0'
83
+ version: 1.3.1
83
84
  requirements: []
84
85
  rubyforge_project:
85
- rubygems_version: 2.6.8
86
+ rubygems_version: 2.5.2.1
86
87
  signing_key:
87
88
  specification_version: 4
88
89
  summary: Time of day attributes for your Rails model
89
90
  test_files:
90
- - test/schema.rb
91
- - test/models/business_hour.rb
92
- - test/active_record_ext_test.rb
93
- - test/time_of_day_attr_test.rb
94
91
  - test/test_helper.rb
92
+ - test/time_of_day_attr/seconds_test.rb
93
+ - test/time_of_day_attr/time_of_day_test.rb
94
+ - test/models/business_hour.rb
95
+ - test/schema.rb
96
+ - test/active_record_extension_test.rb
@@ -1,35 +0,0 @@
1
- require 'active_record'
2
-
3
- module TimeOfDayAttr
4
- module ActiveRecordExt
5
- extend ActiveSupport::Concern
6
-
7
- module ClassMethods
8
- def time_of_day_attr(*attrs)
9
- options = attrs.extract_options!
10
-
11
- writers = Module.new do
12
- attrs.each do |attr|
13
- define_method("#{attr}=") do |value|
14
- if value.is_a?(String)
15
- delocalized_value = TimeOfDayAttr.delocalize(value, options)
16
- super(delocalized_value)
17
- else
18
- super(value)
19
- end
20
- end
21
- end
22
- end
23
-
24
- if options[:prepend]
25
- prepend writers
26
- else
27
- include writers
28
- end
29
- end
30
- end
31
- end
32
- end
33
- ActiveSupport.on_load(:active_record) do
34
- include TimeOfDayAttr::ActiveRecordExt
35
- end
@@ -1,3 +0,0 @@
1
- module TimeOfDayAttr
2
- VERSION = '2.0.1'.freeze
3
- end
@@ -1,43 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TimeOfDayAttrTest < ActiveSupport::TestCase
4
- context '::localize' do
5
- should 'convert seconds to time of day' do
6
- assert_equal ' 9:00', TimeOfDayAttr.localize(32_400)
7
- assert_equal '14:45', TimeOfDayAttr.localize(53_100)
8
- end
9
-
10
- should 'omit minutes at full hour' do
11
- assert_equal ' 9', TimeOfDayAttr.localize(32_400, omit_minutes_at_full_hour: true)
12
- assert_equal '14', TimeOfDayAttr.localize(50_400, omit_minutes_at_full_hour: true)
13
- assert_equal '14:45', TimeOfDayAttr.localize(53_100, omit_minutes_at_full_hour: true)
14
- end
15
-
16
- should 'convert nil to nil' do
17
- assert_nil TimeOfDayAttr.localize(nil)
18
- end
19
-
20
- should 'support 24 hours' do
21
- assert_equal ' 0:00', TimeOfDayAttr.localize(0)
22
- assert_equal '24:00', TimeOfDayAttr.localize(86_400)
23
- assert_equal ' 0', TimeOfDayAttr.localize(0, omit_minutes_at_full_hour: true)
24
- assert_equal '24', TimeOfDayAttr.localize(86_400, omit_minutes_at_full_hour: true)
25
- end
26
- end
27
-
28
- context '::delocaize' do
29
- should 'convert time of day to seconds' do
30
- assert_equal 36_000, TimeOfDayAttr.delocalize('10:00')
31
- assert_equal 55_800, TimeOfDayAttr.delocalize('15:30')
32
- assert_equal 61_140, TimeOfDayAttr.delocalize('16:59')
33
- assert_equal 32_400, TimeOfDayAttr.delocalize('9:00')
34
- assert_equal 32_400, TimeOfDayAttr.delocalize('09:00')
35
- assert_equal 32_400, TimeOfDayAttr.delocalize('9', formats: [:hour])
36
- end
37
-
38
- should 'convert out of range time of day to nil' do
39
- assert_nil TimeOfDayAttr.delocalize('25:00')
40
- assert_nil TimeOfDayAttr.delocalize('24:30')
41
- end
42
- end
43
- end