activerecord-time 0.0.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.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .idea
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in activerecord-time.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Uwe Kubosch
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # activerecord-time
2
+
3
+ A handler for storing TimeOfDay objects in ActiveRecord objects as sql time values.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'activerecord-time'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install activerecord-time
18
+
19
+ ## Usage
20
+
21
+ Create your tables with fields with type :time and you will be able to access them as
22
+ TimeOfDay objects.
23
+
24
+ ```Ruby
25
+ create_table :schedules do |t|
26
+ ...
27
+ t.column :start_at, :time
28
+ ...
29
+ end
30
+ ```
31
+
32
+ or
33
+
34
+ ```Ruby
35
+ create_table :schedules do |table|
36
+ ...
37
+ t.time :start_at
38
+ ...
39
+ end
40
+ ```
41
+
42
+ or
43
+
44
+ ```Ruby
45
+ add_column :schedule, :start_time, :time
46
+ ```
47
+
48
+ The value of the column will be a TimeOfDay object:
49
+
50
+ ```Ruby
51
+ schedule = Schedule.new
52
+ schedule.start_time = TimeOfDay.parse('08:34')
53
+ ```
54
+
55
+ or
56
+
57
+ ```Ruby
58
+ schedule = Schedule.new
59
+ schedule.start_time = '08:34'
60
+ ```
61
+
62
+
63
+
64
+ ## Contributing
65
+
66
+ 1. Fork it
67
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
68
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
69
+ 4. Push to the branch (`git push origin my-new-feature`)
70
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'rubygems'
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'activerecord-time/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "activerecord-time"
8
+ gem.version = Activerecord::Time::VERSION
9
+ gem.authors = ["Uwe Kubosch"]
10
+ gem.email = ["uwe@kubosch.no"]
11
+ gem.description = %q{A handler for storing TimeOfDay objects in ActiveRecord objects as sql time values.}
12
+ gem.summary = %q{A handler for storing TimeOfDay objects in ActiveRecord objects as sql time values.}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,3 @@
1
+ require 'activerecord-time/version'
2
+ require 'time_of_day'
3
+ require 'activerecord-time/extension'
@@ -0,0 +1,28 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class Column
4
+ def klass_with_time_of_day
5
+ return TimeOfDay if :time === type
6
+ klass_without_time_of_day
7
+ end
8
+ alias_method_chain :klass, :time_of_day
9
+
10
+ def self.string_to_dummy_time(string)
11
+ return string if string.is_a? TimeOfDay
12
+ return nil if string.empty?
13
+ TimeOfDay.parse(string)
14
+ end
15
+ end
16
+ module Quoting
17
+ def quote_with_time_of_day(value, column = nil)
18
+ return "'#{quoted_time(value)}'" if TimeOfDay === value
19
+ quote_without_time_of_day(value, column)
20
+ end
21
+ alias_method_chain :quote, :time_of_day
22
+
23
+ def quoted_time(value)
24
+ value.to_s
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module Activerecord
2
+ module Time
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,117 @@
1
+ class TimeOfDay
2
+ yaml_as "tag:yaml.org,2002:timestamp#hms"
3
+ yaml_as "tag:yaml.org,2002:time"
4
+ yaml_as "tag:ruby.yaml.org,2002:time"
5
+
6
+ attr_accessor :hour # 0 - 23
7
+ attr_accessor :minute # 0 - 59
8
+ attr_accessor :second # 0 - 59
9
+
10
+ def initialize(hour, minute, second = 0)
11
+ raise "Invalid hour: #{hour}" unless hour >= 0 && hour <= 23
12
+ raise "Invalid minute: #{minute}" unless minute >= 0 && minute <= 59
13
+ raise "Invalid second: #{second}" unless second >= 0 && hour <= 59
14
+ @hour, @minute, @second = hour, minute, second
15
+ end
16
+
17
+ def init_with(coder)
18
+ parts = self.class.parse_parts(coder.scalar)
19
+ initialize(*parts)
20
+ end
21
+
22
+ def self.now
23
+ Time.now.time_of_day
24
+ end
25
+
26
+ def self.parse(string)
27
+ return nil if string.blank?
28
+ self.new(*parse_parts(string))
29
+ end
30
+
31
+ def self.parse_parts(string)
32
+ string.strip!
33
+ raise "Illegal time format: '#{string}'" unless string =~ /^(\d{1,2}):?(\d{2})?(?::(\d{1,2}))?$/
34
+ [$1.to_i, $2.to_i, $3.to_i]
35
+ end
36
+
37
+ def on(date)
38
+ Time.local(date.year, date.month, date.day, hour, minute, second)
39
+ end
40
+
41
+ def -(seconds)
42
+ raise "Illegal argument: #{seconds.inspect}" unless seconds.is_a? Numeric
43
+ t = Time.local(0, 1, 1, hour, minute, second)
44
+ t -= seconds
45
+ self.class.new(t.hour, t.min, t.sec)
46
+ end
47
+
48
+ def <=>(other)
49
+ [@hour, @minute, @second] <=> [other.hour, other.minute, other.second]
50
+ end
51
+
52
+ def ==(other)
53
+ return false unless other.is_a? TimeOfDay
54
+ (self <=> other) == 0
55
+ end
56
+
57
+ def <(other)
58
+ return false unless other.is_a? TimeOfDay
59
+ (self <=> other) < 0
60
+ end
61
+
62
+ def <=(other)
63
+ return false unless other.is_a? TimeOfDay
64
+ (self <=> other) <= 0
65
+ end
66
+
67
+ def >(other)
68
+ return false unless other.is_a? TimeOfDay
69
+ (self <=> other) > 0
70
+ end
71
+
72
+ def >=(other)
73
+ return false unless other.is_a? TimeOfDay
74
+ (self <=> other) >= 0
75
+ end
76
+
77
+ def strftime(format)
78
+ on(Date.today).strftime(format)
79
+ end
80
+
81
+ def to_s(with_seconds = true)
82
+ if with_seconds
83
+ "%02d:%02d:%02d" % [@hour, @minute, @second]
84
+ else
85
+ "%02d:%02d" % [@hour, @minute]
86
+ end
87
+ end
88
+
89
+ def self.yaml_new(klass, tag, val)
90
+ if String === val
91
+ self.parse val
92
+ else
93
+ raise YAML::TypeError, "Invalid Time: " + val.inspect
94
+ end
95
+ end
96
+
97
+ def to_yaml(opts = {})
98
+ YAML::quick_emit(nil, opts) do |out|
99
+ out.scalar('tag:yaml.org,2002:time', self.to_s, :plain)
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ class Time
106
+ def time_of_day
107
+ TimeOfDay.new(hour, min, sec)
108
+ end
109
+
110
+ end
111
+
112
+ class Date
113
+ def at(time_of_day)
114
+ Time.local(year, month, day, time_of_day.hour, time_of_day.minute, time_of_day.second)
115
+ end
116
+
117
+ end
data/test/database.yml ADDED
@@ -0,0 +1,18 @@
1
+ sqlite:
2
+ :adapter: sqlite
3
+ :dbfile: plugin.sqlite.db
4
+ sqlite3:
5
+ :adapter: sqlite3
6
+ :dbfile: ":memory:"
7
+ postgresql:
8
+ :adapter: postgresql
9
+ :username: postgres
10
+ :password: postgres
11
+ :database: plugin_test
12
+ :min_messages: ERROR
13
+ mysql:
14
+ :adapter: mysql
15
+ :host: localhost
16
+ :username: rails
17
+ :password:
18
+ :database: plugin_test
@@ -0,0 +1,122 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Thing < ActiveRecord::Base
4
+ end
5
+
6
+ def thing
7
+ Thing.new(:name => "Thing One",:price_in_cents=> 125)
8
+ end
9
+
10
+ class RailsMoneyTest < Test::Unit::TestCase
11
+
12
+ def test_should_return_price_as_money_object
13
+ price = thing.price
14
+ assert_kind_of Money, price
15
+ assert_equal "$1.25", thing.price.to_s
16
+ end
17
+
18
+ def test_should_set_price_from_money_object
19
+ thing1 = thing
20
+ thing1.price = Money.new(1095)
21
+ assert_equal 109500, thing1.price_in_cents
22
+ assert_equal "$1,095.00", thing1.price.to_s
23
+ end
24
+
25
+ def test_should_set_price_from_fixnum
26
+ thing1 = thing
27
+ thing1.price = 1095
28
+ assert_equal 109500, thing1.price_in_cents
29
+ end
30
+
31
+ def test_should_set_price_from_float
32
+ thing1 = thing
33
+ thing1.price = 10.95
34
+ assert_equal 1095, thing1.price_in_cents
35
+ end
36
+
37
+ def test_should_set_price_from_string
38
+ thing1 = thing
39
+ thing1.price = "$10.95"
40
+ assert_equal 1095, thing1.price_in_cents
41
+ thing1.price = "10"
42
+ assert_equal 1000, thing1.price_in_cents
43
+ end
44
+
45
+ def test_should_format_correctly
46
+ assert_equal "$12.40", Money.new(12.40).to_s
47
+ end
48
+
49
+ def test_should_raise_exception_setting_invalid_price
50
+ assert_raise(MoneyError) { thing.price = [] }
51
+ end
52
+ end
53
+
54
+ class MoneyTest < Test::Unit::TestCase
55
+
56
+ def test_should_create_money_object
57
+ assert cash_money = Money.new(1290)
58
+ assert_equal 129000, cash_money.cents
59
+ assert_equal 1290, cash_money.dollars
60
+ assert_equal "$1,290.00", cash_money.to_s
61
+ assert_equal false, cash_money.free?
62
+ assert_equal 0, Money.new(nil).cents
63
+ end
64
+
65
+ def test_should_create_money_object_from_float_with_proper_rounding
66
+ money = Money.new(12.196)
67
+ assert_equal 1220, money.cents
68
+ assert_instance_of Fixnum, money.cents
69
+ end
70
+
71
+ def test_should_raise_exception_if_invalid_type_passed_to_initialize
72
+ assert_raise(MoneyError) { Money.new([]) }
73
+ end
74
+
75
+ def test_should_return_free_on_to_s_if_cents_is_zero
76
+ cash_money = Money.new(0)
77
+ assert_equal 'free', cash_money.to_s
78
+ assert_equal true, cash_money.free?
79
+ assert_equal true, cash_money.zero?
80
+ end
81
+
82
+ def test_should_be_comparable
83
+ assert Money.include?(Comparable)
84
+ assert Money.new(0) == Money.new(0)
85
+ end
86
+
87
+ def test_should_add_money
88
+ assert_equal Money.new(20.95), Money.new(10) + Money.new(10.95)
89
+ assert_equal Money.new(2000), Money.new(1000) + 1000
90
+ assert_equal Money.new(20.06), Money.new(10.00) + 10.056
91
+ end
92
+
93
+ def test_should_subtract_money
94
+ assert_equal Money.new(500), Money.new(1000) - Money.new(500)
95
+ assert_equal Money.new(500), Money.new(1000) - 500
96
+ assert_equal Money.new(4.60), Money.new(10) - 5.40
97
+ end
98
+
99
+ def test_should_multiply_money
100
+ assert_equal Money.new(500), Money.new(100) * 5
101
+ assert_equal Money.new(9.99), Money.new(3.33) * 3
102
+ assert_equal Money.new(11.99), Money.new(3.33) * 3.6 # 1198.9
103
+ end
104
+
105
+ def test_should_divide_money_and_retur_array_of_monies
106
+ money_array = [Money.new(3.34), Money.new(3.33), Money.new(3.33)]
107
+ assert_equal money_array, Money.new(10.00) / 3
108
+ assert_equal [Money.new(2.00), Money.new(2.00)], Money.new(4.00) / 2
109
+ assert_raises(MoneyError) { Money.new(4.00) / 2.2 }
110
+ end
111
+
112
+ def test_should_implement_to_money
113
+ assert_equal Money.new(10), Money.new(10).to_money
114
+ assert_equal Money.new(100.00), 100.00.to_money
115
+ assert_equal Money.new(100.96), 100.956.to_money
116
+ end
117
+
118
+ def test_should_create_from_cents
119
+ assert_equal Money.new(1.50), Money.create_from_cents(150)
120
+ end
121
+
122
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,10 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+
3
+ # Create tables for testing your plugin
4
+
5
+ create_table :things do |t|
6
+ t.column :name, :string
7
+ t.column :price_in_cents, :integer
8
+ end
9
+
10
+ end
@@ -0,0 +1,17 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ RAILS_ROOT = File.dirname(__FILE__)
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'active_record'
7
+ require "#{File.dirname(__FILE__)}/../init"
8
+
9
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
10
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
11
+ ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite3'])
12
+
13
+ load(File.dirname(__FILE__) + "/schema.rb") if File.exist?(File.dirname(__FILE__) + "/schema.rb")
14
+
15
+
16
+
17
+
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-time
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Uwe Kubosch
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-01-04 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: A handler for storing TimeOfDay objects in ActiveRecord objects as sql time values.
22
+ email:
23
+ - uwe@kubosch.no
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .gitignore
32
+ - Gemfile
33
+ - LICENSE.txt
34
+ - README.md
35
+ - Rakefile
36
+ - activerecord-time.gemspec
37
+ - lib/activerecord-time.rb
38
+ - lib/activerecord-time/extension.rb
39
+ - lib/activerecord-time/version.rb
40
+ - lib/time_of_day.rb
41
+ - test/database.yml
42
+ - test/rails_time_test.rb
43
+ - test/schema.rb
44
+ - test/test_helper.rb
45
+ homepage: ""
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.24
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: A handler for storing TimeOfDay objects in ActiveRecord objects as sql time values.
78
+ test_files:
79
+ - test/database.yml
80
+ - test/rails_time_test.rb
81
+ - test/schema.rb
82
+ - test/test_helper.rb