seamusabshere-has_timestamps 1.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.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,59 @@
1
+ HasTimestamps
2
+ =================
3
+
4
+ Lets you timestamp models, like if you want to fake a CRM.
5
+
6
+ Note: it doesn't save objects automatically, so you have to run a "user.save" (etc.) when you're done timestamping.
7
+
8
+ Example
9
+ =======
10
+
11
+ class CreateTimestamps < ActiveRecord::Migration
12
+ def self.up
13
+ create_table(:timestamps) do |t|
14
+ t.integer :timestampable_id
15
+ t.string :timestampable_type
16
+ t.string :key
17
+ t.datetime :stamped_at
18
+ t.timestamps
19
+ end
20
+ end
21
+
22
+ def self.down
23
+ drop_table(:timestamps)
24
+ end
25
+ end
26
+
27
+ then...
28
+
29
+ class User < ActiveRecord::Base
30
+ has_timestamps
31
+ end
32
+
33
+ >> user.timestamps
34
+ => []
35
+ >> user.timestamp!(:hailed)
36
+ => Wed Dec 10 15:11:52 -0500 2008
37
+ >> user.timestamps
38
+ => [#<Timestamp id: nil, timestampable_id: 14, timestampable_type: "User", key: "hailed", stamped_at: "2008-12-10 15:11:52", created_at: nil, updated_at: nil>]
39
+ >> user.timestamped?(:hailed)
40
+ => true
41
+ >> user.save
42
+ => true
43
+ >> user.timestamped?(:saluted)
44
+ => false
45
+ >> user.timestamp!(:saluted)
46
+ => Wed Dec 10 15:12:28 -0500 2008
47
+ >> user.timestamped?(:saluted)
48
+ => true
49
+ >> user.timestamps[:saluted]
50
+ => Wed Dec 10 15:12:28 -0500 2008
51
+ >> user.timestamps[:hailed]
52
+ => Wed Dec 10 15:11:52 -0500 2008
53
+
54
+ Credits
55
+ =======
56
+
57
+ Thanks to Fingertips for inspiration.
58
+
59
+ Copyright (c) 2008 Seamus Abshere, released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the has_timestamps plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the has_timestamps plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'HasTimestamps'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
@@ -0,0 +1,27 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "has_timestamps"
3
+ s.version = "1.0"
4
+ s.date = "2008-12-29"
5
+ s.summary = "Rails plugin to add named timestamps to ActiveRecord models."
6
+ s.email = "seamus@abshere.net"
7
+ s.homepage = "http://github.com/seamusabshere/has_timestamps"
8
+ s.description = "has_timestamps is a Rails plugin that allows you to add named timestamps to ActiveRecord models without adding database columns."
9
+ s.has_rdoc = false
10
+ s.authors = "Seamus Abshere"
11
+ s.files = [
12
+ "has_timestamps.gemspec",
13
+ "init.rb",
14
+ "install.rb",
15
+ "lib/has_timestamps.rb",
16
+ "lib/timestamp.rb",
17
+ "MIT-LICENSE",
18
+ "Rakefile",
19
+ "README",
20
+ "tasks/has_timestamps_tasks.rake",
21
+ "uninstall.rb"
22
+ ]
23
+ s.test_files = [
24
+ "test/has_timestamps_test.rb",
25
+ "test/test_helper.rb"
26
+ ]
27
+ end
data/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'has_timestamps'
2
+ ActiveRecord::Base.send(:include, ActiveRecord::Acts::HasTimestamps)
3
+
4
+ require File.dirname(__FILE__) + '/lib/timestamp'
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,58 @@
1
+ module ActiveRecord #:nodoc:
2
+ module Acts #:nodoc:
3
+ module HasTimestamps
4
+ def self.included(base) #:nodoc:
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def has_timestamps(opts = {})
10
+ class_eval do
11
+ def save_or_destroy_timestamps
12
+ timestamps.each do |timestamp|
13
+ if timestamp.stamped_at.acts_like?(:time) or timestamp.stamped_at.is_a?(Date) or timestamp.stamped_at.is_a?(DateTime)
14
+ timestamp.save
15
+ elsif !timestamp.new_record?
16
+ timestamp.destroy
17
+ end
18
+ end
19
+ end
20
+ after_save :save_or_destroy_timestamps
21
+
22
+ def timestamp!(key)
23
+ timestamps[key.to_s] = Time.now
24
+ end
25
+
26
+ def timestamped?(key)
27
+ !timestamps[key.to_s].blank?
28
+ end
29
+ end
30
+
31
+ has_many :timestamps, opts.merge(:as => :timestampable) do
32
+ def [](key)
33
+ fetch_timestamp(key).stamped_at
34
+ end
35
+
36
+ def []=(key, stamped_at)
37
+ fetch_timestamp(key).stamped_at = stamped_at
38
+ end
39
+
40
+ def find_by_key(key)
41
+ proxy_owner.timestamps.to_a.find { |timestamp| timestamp.key == key.to_s }
42
+ end
43
+
44
+ private
45
+
46
+ def fetch_timestamp(key)
47
+ find_by_key(key) || build_timestamp(key)
48
+ end
49
+
50
+ def build_timestamp(key)
51
+ build(:key => key.to_s)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
data/lib/timestamp.rb ADDED
@@ -0,0 +1,26 @@
1
+ class Timestamp < ActiveRecord::Base
2
+ class << self
3
+ def create_table
4
+ self.connection.create_table(:timestamps) do |t|
5
+ t.integer :timestampable_id
6
+ t.string :timestampable_type
7
+ t.string :key
8
+ t.datetime :stamped_at
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ def drop_table
14
+ self.connection.drop_table(:timestamps)
15
+ end
16
+ end
17
+
18
+ belongs_to :timestampable, :polymorphic => true
19
+
20
+ validates_presence_of :key, :timestampable_id, :timestampable_type
21
+ validates_uniqueness_of :key, :scope => [ :timestampable_id, :timestampable_type ]
22
+
23
+ def to_param
24
+ self.key
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :has_timestamps do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,150 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module SharedTests
4
+ def self.included(klass)
5
+ klass.class_eval do
6
+ it "should test if two times are virtually simultaneous" do
7
+ t1 = Time.at(946702800)
8
+ t2 = Time.at(946702800 + DELTA_IN_SECONDS)
9
+ t3 = Time.at(946702800 + DELTA_IN_SECONDS + 1)
10
+ assert_simultaneous(t1, t2)
11
+ assert_not_simultaneous(t1, t3)
12
+ end
13
+
14
+ it "should get timestamp with brackets" do
15
+ assert_equal @timestamp.stamped_at, @person.timestamps[@timestamp.key.to_sym]
16
+ end
17
+
18
+ it "should get nil timestamp with brackets" do
19
+ assert_nil @person.timestamps[:gibberish]
20
+ end
21
+
22
+ it "should get timestamp as a Time" do
23
+ assert @person.timestamps[@timestamp.key.to_sym].acts_like?(:time)
24
+ end
25
+
26
+ it "should query timestamp with brackets" do
27
+ assert_equal @person.timestamped?(@timestamp.key.to_sym), true
28
+ assert_equal @person.timestamped?(:gibberish), false
29
+ end
30
+
31
+ it "should set timestamp" do
32
+ @person.timestamp!(:hailed)
33
+ @person.save
34
+ @person.reload
35
+ assert_simultaneous Time.now, @person.timestamps[:hailed]
36
+ end
37
+
38
+ it "should reset timestamp" do
39
+ old_time = @person.timestamps[:saluted]
40
+ @person.timestamp!(:saluted)
41
+ @person.save
42
+ @person.reload
43
+ assert_not_simultaneous(old_time, @person.timestamps[:saluted])
44
+ assert_simultaneous Time.now, @person.timestamps[:saluted]
45
+ end
46
+
47
+ it "should set timestamp manually" do
48
+ @person.timestamps[:hailed] = @another_time
49
+ @person.save
50
+ @person.reload
51
+ assert_simultaneous @another_time, @person.timestamps[:hailed]
52
+ end
53
+
54
+ it "should set timestamp manually to Date" do
55
+ @person.timestamps[:hailed] = @another_time.to_date
56
+ @person.save
57
+ @person.reload
58
+ assert_simultaneous @another_time, @person.timestamps[:hailed]
59
+ end
60
+
61
+ it "should set timestamp manually to DateTime" do
62
+ @person.timestamps[:hailed] = @another_time.to_datetime
63
+ @person.save
64
+ @person.reload
65
+ assert_simultaneous @another_time, @person.timestamps[:hailed]
66
+ end
67
+
68
+ it "should set timestamp to nil" do
69
+ @person.timestamps[:hailed] = nil
70
+ @person.save
71
+ @person.reload
72
+ assert_nil @person.timestamps[:hailed]
73
+ end
74
+
75
+ it "should reset timestamp manually" do
76
+ old_time = @person.timestamps[:saluted]
77
+ @person.timestamps[:saluted] = @another_time
78
+ @person.save
79
+ @person.reload
80
+ assert_not_simultaneous old_time, @person.timestamps[:saluted]
81
+ assert_simultaneous @another_time, @person.timestamps[:saluted]
82
+ end
83
+
84
+ it "should reset timestamp to nil" do
85
+ @person.timestamps[:saluted] = nil
86
+ @person.save
87
+ @person.reload
88
+ assert_nil @person.timestamps[:saluted]
89
+ end
90
+
91
+ it "should save timestamps" do
92
+ assert_difference('Timestamp.count', 1) do
93
+ @person.timestamp!(:hailed)
94
+ @person.save
95
+ end
96
+ end
97
+
98
+ it "should destroy nil timestamps" do
99
+ assert_difference('Timestamp.count', -1) do
100
+ @person.timestamps[:saluted] = nil
101
+ @person.save
102
+ end
103
+ end
104
+
105
+ it "should not save nil timestamps" do
106
+ assert_no_difference('Timestamp.count') do
107
+ @person.timestamps[:hailed] = nil
108
+ @person.save
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "HasTimestamps, when a timezone is not set" do
116
+ before do
117
+ HasTimestampsTest::Initializer.setup_database
118
+ @person = Person.first
119
+ @timestamp = Timestamp.first
120
+ @another_time = 3.days.ago.at_beginning_of_day
121
+ end
122
+ after do
123
+ HasTimestampsTest::Initializer.teardown_database
124
+ end
125
+
126
+ it "should not have a timezone" do
127
+ assert_nil Time.zone
128
+ end
129
+
130
+ include SharedTests
131
+ end
132
+
133
+ describe "HasTimestamps, when a timezone is set" do
134
+ before do
135
+ HasTimestampsTest::Initializer.setup_database
136
+ Time.zone = 'Pacific Time (US & Canada)'
137
+ @person = Person.first
138
+ @timestamp = Timestamp.first
139
+ @another_time = 3.days.ago.at_beginning_of_day
140
+ end
141
+ after do
142
+ HasTimestampsTest::Initializer.teardown_database
143
+ end
144
+
145
+ it "should have a timezone" do
146
+ assert_equal Time.zone.name, 'Pacific Time (US & Canada)'
147
+ end
148
+
149
+ include SharedTests
150
+ end
@@ -0,0 +1,85 @@
1
+ module HasTimestampsTest
2
+ module Initializer
3
+ VENDOR_RAILS = File.expand_path('../../../../rails', __FILE__)
4
+ OTHER_RAILS = File.expand_path('../../../rails', __FILE__)
5
+ PLUGIN_ROOT = File.expand_path('../../', __FILE__)
6
+
7
+ def self.rails_directory
8
+ if File.exist?(VENDOR_RAILS)
9
+ VENDOR_RAILS
10
+ elsif File.exist?(OTHER_RAILS)
11
+ OTHER_RAILS
12
+ end
13
+ end
14
+
15
+ def self.load_dependencies
16
+ if rails_directory
17
+ $:.unshift(File.join(rails_directory, 'activesupport', 'lib'))
18
+ $:.unshift(File.join(rails_directory, 'activerecord', 'lib'))
19
+ else
20
+ require 'rubygems' rescue LoadError
21
+ end
22
+
23
+ require 'activesupport'
24
+ require 'activerecord'
25
+ require 'active_support/testing/core_ext/test/unit/assertions'
26
+
27
+ require 'rubygems' rescue LoadError
28
+
29
+ require 'test/spec'
30
+ require File.join(PLUGIN_ROOT, 'init')
31
+ end
32
+
33
+ def self.configure_database
34
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
35
+ ActiveRecord::Migration.verbose = false
36
+ end
37
+
38
+ def self.setup_database
39
+ ActiveRecord::Schema.define do
40
+ create_table :people do |t|
41
+ t.string :name
42
+ end
43
+ create_table :timestamps do |t|
44
+ t.integer :timestampable_id
45
+ t.string :timestampable_type
46
+ t.string :key
47
+ t.datetime :stamped_at
48
+ t.timestamps
49
+ end
50
+ end
51
+ person_fixture = Person.create :name => 'Seamus'
52
+ person_fixture.timestamps[:saluted] = Time.now.years_ago(1).at_beginning_of_day
53
+ person_fixture.save
54
+ end
55
+
56
+ def self.teardown_database
57
+ ActiveRecord::Base.connection.tables.each do |table|
58
+ ActiveRecord::Base.connection.drop_table(table)
59
+ end
60
+ end
61
+
62
+ def self.start
63
+ load_dependencies
64
+ configure_database
65
+ end
66
+ end
67
+ end
68
+
69
+ HasTimestampsTest::Initializer.start
70
+
71
+ class Person < ActiveRecord::Base
72
+ has_timestamps
73
+ end
74
+
75
+ DELTA_IN_SECONDS = 5
76
+
77
+ def assert_simultaneous(t1, t2)
78
+ assert_in_delta t1, t2, DELTA_IN_SECONDS
79
+ end
80
+
81
+ def assert_not_simultaneous(t1, t2)
82
+ assert_raise(Test::Unit::AssertionFailedError) do
83
+ assert_simultaneous t1, t2
84
+ end
85
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: seamusabshere-has_timestamps
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.0"
5
+ platform: ruby
6
+ authors:
7
+ - Seamus Abshere
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-29 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: has_timestamps is a Rails plugin that allows you to add named timestamps to ActiveRecord models without adding database columns.
17
+ email: seamus@abshere.net
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - has_timestamps.gemspec
26
+ - init.rb
27
+ - install.rb
28
+ - lib/has_timestamps.rb
29
+ - lib/timestamp.rb
30
+ - MIT-LICENSE
31
+ - Rakefile
32
+ - README
33
+ - tasks/has_timestamps_tasks.rake
34
+ - uninstall.rb
35
+ has_rdoc: false
36
+ homepage: http://github.com/seamusabshere/has_timestamps
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.2.0
58
+ signing_key:
59
+ specification_version: 2
60
+ summary: Rails plugin to add named timestamps to ActiveRecord models.
61
+ test_files:
62
+ - test/has_timestamps_test.rb
63
+ - test/test_helper.rb