punchcard 0.1.4 → 0.2.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/.gitignore +2 -1
- data/Gemfile +1 -2
- data/Gemfile.lock +23 -26
- data/README.rdoc +36 -22
- data/Rakefile +4 -3
- data/VERSION +1 -1
- data/lib/db/migrate/01_create_people.rb +13 -0
- data/lib/db/migrate/02_create_punches.rb +14 -0
- data/lib/punchcard/person.rb +4 -11
- data/lib/punchcard/punch.rb +14 -11
- data/lib/punchcard/tasks.rb +11 -0
- data/lib/punchcard.rb +8 -3
- data/punchcard.gemspec +13 -7
- data/test/helper.rb +7 -1
- data/test/test_database.rb +36 -11
- data/test/test_punchcard.rb +1 -0
- metadata +27 -9
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,63 +1,60 @@
|
|
1
|
-
GIT
|
2
|
-
remote: https://github.com/robertoles/sinatra-mongoid.git
|
3
|
-
revision: f0d04640b84306a5d1e08569c9d12e9841e908b1
|
4
|
-
specs:
|
5
|
-
sinatra-mongoid (0.0.2)
|
6
|
-
mongo_ext
|
7
|
-
mongoid
|
8
|
-
sinatra
|
9
|
-
|
10
1
|
PATH
|
11
2
|
remote: .
|
12
3
|
specs:
|
13
|
-
punchcard (0.1.
|
4
|
+
punchcard (0.1.4)
|
5
|
+
activerecord (~> 3.0.0)
|
14
6
|
bson_ext
|
15
7
|
gravtastic
|
16
8
|
haml (>= 3.0.24)
|
17
|
-
mongoid
|
18
9
|
sass (>= 3.0.0)
|
19
10
|
sinatra (>= 1.0.0)
|
20
11
|
|
21
12
|
GEM
|
22
13
|
remote: http://rubygems.org/
|
23
14
|
specs:
|
24
|
-
|
25
|
-
|
15
|
+
activemodel (3.0.3)
|
16
|
+
activesupport (= 3.0.3)
|
17
|
+
builder (~> 2.1.2)
|
18
|
+
i18n (~> 0.4)
|
19
|
+
activerecord (3.0.3)
|
20
|
+
activemodel (= 3.0.3)
|
21
|
+
activesupport (= 3.0.3)
|
22
|
+
arel (~> 2.0.2)
|
23
|
+
tzinfo (~> 0.3.23)
|
24
|
+
activesupport (3.0.3)
|
25
|
+
arel (2.0.6)
|
26
26
|
bson_ext (1.1.4)
|
27
|
-
|
27
|
+
builder (2.1.2)
|
28
|
+
ffi (1.0.1)
|
29
|
+
rake (>= 0.8.7)
|
28
30
|
gravtastic (3.1.0)
|
29
31
|
haml (3.0.24)
|
30
|
-
|
31
|
-
bson (>= 1.0.5)
|
32
|
-
mongo_ext (0.19.3)
|
33
|
-
mongoid (1.9.2)
|
34
|
-
activesupport (< 3.0.0)
|
35
|
-
bson (~> 1.0.1)
|
36
|
-
durran-validatable (>= 2.0.1)
|
37
|
-
mongo (~> 1.0.1)
|
38
|
-
will_paginate (< 2.9)
|
32
|
+
i18n (0.5.0)
|
39
33
|
rack (1.2.1)
|
40
34
|
rack-test (0.5.6)
|
41
35
|
rack (>= 1.0)
|
36
|
+
rake (0.8.7)
|
42
37
|
sass (3.1.0.alpha.200)
|
43
38
|
shoulda (2.10.3)
|
44
39
|
sinatra (1.1.0)
|
45
40
|
rack (~> 1.1)
|
46
41
|
tilt (~> 1.1)
|
42
|
+
sqlite3 (0.1.1)
|
43
|
+
ffi (>= 0.6.3)
|
47
44
|
tilt (1.1)
|
48
|
-
|
45
|
+
tzinfo (0.3.23)
|
49
46
|
|
50
47
|
PLATFORMS
|
51
48
|
ruby
|
52
49
|
|
53
50
|
DEPENDENCIES
|
51
|
+
activerecord (~> 3.0.0)
|
54
52
|
bson_ext
|
55
53
|
gravtastic
|
56
54
|
haml (>= 3.0.24)
|
57
|
-
mongoid
|
58
55
|
punchcard!
|
59
56
|
rack-test (>= 0.5.6)
|
60
57
|
sass (>= 3.0.0)
|
61
58
|
shoulda (= 2.10.3)
|
62
59
|
sinatra (>= 1.0.0)
|
63
|
-
|
60
|
+
sqlite3
|
data/README.rdoc
CHANGED
@@ -2,42 +2,56 @@
|
|
2
2
|
|
3
3
|
A simple Sinatra app that lets you track who is and has been in the office at what times.
|
4
4
|
|
5
|
-
==
|
6
|
-
|
7
|
-
Create a folder for your app, add a Gemfile:
|
5
|
+
== Bootstrap
|
8
6
|
|
7
|
+
Create a directory to hold your app, then create a Gemfile:
|
8
|
+
|
9
9
|
source :rubygems
|
10
|
-
gem '
|
10
|
+
gem 'pg'
|
11
|
+
# gem 'sqlite3' # if you want to run using sqlite or test locally
|
12
|
+
gem 'punchcard', ">= 0.1.3", :path => '../github/punchcard'
|
13
|
+
|
14
|
+
Create a Rakefile:
|
15
|
+
|
16
|
+
require 'bundler'
|
17
|
+
require 'rake'
|
18
|
+
Bundler.require
|
11
19
|
|
12
|
-
|
20
|
+
require 'punchcard/tasks'
|
21
|
+
|
22
|
+
Create a config.ru for rack:
|
13
23
|
|
14
24
|
require 'bundler'
|
15
25
|
Bundler.require
|
16
|
-
|
26
|
+
|
27
|
+
# You'll surely want to secure your punch card from general web access. The simplest way to do so is by
|
28
|
+
# using the rack auth middleware, defining it somewhere in your config.ru:
|
29
|
+
Punchcard.use Rack::Auth::Basic do |username, password|
|
30
|
+
[username, password] == ['someuser', 'secret']
|
31
|
+
end
|
32
|
+
|
17
33
|
run Punchcard
|
18
34
|
|
19
|
-
|
20
|
-
|
21
|
-
|
35
|
+
To run locally, make sure you have a proper ENV['DATABASE_URL'] configured or the sqlite3 gem installed
|
36
|
+
with your bundle. Then:
|
37
|
+
|
38
|
+
$ bundle install
|
39
|
+
$ rake db:migrate
|
40
|
+
$ rackup
|
41
|
+
|
42
|
+
Open http://localhost:9292
|
43
|
+
|
44
|
+
== Hosting on Heroku
|
22
45
|
|
23
|
-
|
46
|
+
Starting from the initial bootstrap above, make sure you have the pg gem in your bundle, then do the
|
47
|
+
following in the terminal:
|
24
48
|
|
25
49
|
$ git init
|
26
|
-
$ git commit -
|
50
|
+
$ git commit -am "Initial commit"
|
27
51
|
$ heroku create [APPNAME] --stack bamboo-mri-1.9.2
|
28
|
-
$ heroku addons:add mongohq:free
|
29
52
|
$ git push heroku master
|
30
53
|
|
31
|
-
Now head over to your app's url!
|
32
|
-
|
33
|
-
== Authentication
|
34
|
-
|
35
|
-
You'll surely want to secure your punch card from general web access. The simplest way to do so is by
|
36
|
-
using the rack auth middleware by defining it somewhere in your config.ru:
|
37
|
-
|
38
|
-
Punchcard.use Rack::Auth::Basic do |username, password|
|
39
|
-
[username, password] == ['admin', 'admin']
|
40
|
-
end
|
54
|
+
Now head over to your app's url! You'll still need to add users, see below.
|
41
55
|
|
42
56
|
== Adding people
|
43
57
|
|
data/Rakefile
CHANGED
@@ -5,8 +5,8 @@ begin
|
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "punchcard"
|
8
|
-
gem.summary = %Q{Simple sinatra/
|
9
|
-
gem.description = %Q{Simple sinatra/
|
8
|
+
gem.summary = %Q{Simple sinatra/activerecord based app for tracking time when people have been in the office}
|
9
|
+
gem.description = %Q{Simple sinatra/activerecord based app for tracking time when people have been in the office}
|
10
10
|
gem.email = "christoph at olszowka de"
|
11
11
|
gem.homepage = "http://github.com/colszowka/punchcard"
|
12
12
|
gem.authors = ["Christoph Olszowka"]
|
@@ -14,10 +14,11 @@ begin
|
|
14
14
|
gem.add_dependency 'bson_ext', '>= 0'
|
15
15
|
gem.add_dependency 'haml', '>= 3.0.24'
|
16
16
|
gem.add_dependency 'sass', '>= 3.0.0'
|
17
|
-
gem.add_dependency '
|
17
|
+
gem.add_dependency 'activerecord', '~> 3.0.0'
|
18
18
|
gem.add_dependency 'gravtastic', '>= 0'
|
19
19
|
gem.add_development_dependency "shoulda", "2.10.3"
|
20
20
|
gem.add_development_dependency "rack-test", ">= 0.5.6"
|
21
|
+
gem.add_development_dependency 'sqlite3', '>= 0'
|
21
22
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
22
23
|
end
|
23
24
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreatePunches < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :punches do |t|
|
4
|
+
t.integer :person_id, :null => false
|
5
|
+
t.datetime :checked_in_at, :null => false
|
6
|
+
t.datetime :checked_out_at, :default => nil
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
drop_table :people
|
13
|
+
end
|
14
|
+
end
|
data/lib/punchcard/person.rb
CHANGED
@@ -1,12 +1,5 @@
|
|
1
|
-
class Person
|
2
|
-
|
3
|
-
|
4
|
-
field :name
|
5
|
-
field :email
|
6
|
-
|
7
|
-
index :name, :unique => true
|
8
|
-
|
9
|
-
embeds_many :punches
|
1
|
+
class Person < ActiveRecord::Base
|
2
|
+
has_many :punches
|
10
3
|
|
11
4
|
validates_presence_of :name, :email
|
12
5
|
|
@@ -15,14 +8,14 @@ class Person
|
|
15
8
|
|
16
9
|
# Returns the currently pending punch when present, nil otherwise
|
17
10
|
def pending?
|
18
|
-
punches.pending.first
|
11
|
+
punches.pending.count > 0 ? punches.pending.first : nil
|
19
12
|
end
|
20
13
|
|
21
14
|
# Punches in when no punches pending, punches out when a pending punch exists!
|
22
15
|
# When punching in, checks whether a recently finished punch exists and reopens if so instead
|
23
16
|
# of creating a new punch
|
24
17
|
def punch!
|
25
|
-
if punch =
|
18
|
+
if punch = pending?
|
26
19
|
punch.punch_out!
|
27
20
|
else
|
28
21
|
if recently_finished = punches.recently_finished.first
|
data/lib/punchcard/punch.rb
CHANGED
@@ -1,16 +1,12 @@
|
|
1
|
-
class Punch
|
2
|
-
|
3
|
-
|
4
|
-
field :checked_out_at, :type => Time
|
5
|
-
|
6
|
-
embedded_in :person, :inverse_of => :punches
|
7
|
-
|
8
|
-
scope :pending, where(:checked_out_at.exists => false)
|
9
|
-
scope :finished, where(:checked_out_at.exists => true, :checked_in_at.exists => true)
|
10
|
-
scope :recently_finished, where(:checked_out_at.gt => 30.minutes.ago)
|
11
|
-
|
1
|
+
class Punch < ActiveRecord::Base
|
2
|
+
belongs_to :person
|
3
|
+
|
12
4
|
validates_presence_of :checked_in_at
|
13
5
|
|
6
|
+
scope :pending, where("checked_out_at IS NULL").order("checked_in_at ASC")
|
7
|
+
scope :finished, where("checked_in_at IS NOT NULL AND checked_out_at IS NOT NULL").order('checked_out_at DESC')
|
8
|
+
scope :recently_finished, where("checked_out_at > ?", 30.minutes.ago).order('checked_out_at DESC')
|
9
|
+
|
14
10
|
before_validation do |p|
|
15
11
|
p.checked_in_at ||= Time.now
|
16
12
|
end
|
@@ -19,6 +15,13 @@ class Punch
|
|
19
15
|
p.errors.add :person, "Person already has a pending punch!" if p.person.pending? and p.person.pending? != p
|
20
16
|
end
|
21
17
|
|
18
|
+
after_save do |p|
|
19
|
+
# Destroy punches shorter than 5 minutes
|
20
|
+
if p.checked_out_at.present? and (p.checked_out_at - p.checked_in_at) < 5.minutes
|
21
|
+
p.destroy
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
22
25
|
# Punches this punch out when pending
|
23
26
|
def punch_out!
|
24
27
|
return false if checked_out_at.present?
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Rake tasks for punchcard, import with require 'punchcard/tasks'
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
desc "Migrate the database"
|
5
|
+
task(:migrate) do
|
6
|
+
require 'logger'
|
7
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
8
|
+
ActiveRecord::Migration.verbose = false
|
9
|
+
ActiveRecord::Migrator.migrate(File.join(File.dirname(__FILE__), "../db/migrate"))
|
10
|
+
end
|
11
|
+
end
|
data/lib/punchcard.rb
CHANGED
@@ -2,9 +2,14 @@ require 'bundler'
|
|
2
2
|
Bundler.setup(:default)
|
3
3
|
|
4
4
|
require 'sinatra'
|
5
|
-
require 'sinatra/mongoid'
|
6
5
|
require 'gravtastic'
|
7
|
-
require '
|
6
|
+
require 'active_record'
|
7
|
+
|
8
|
+
require 'logger'
|
9
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
10
|
+
ActiveRecord::Base.logger.level = Logger::WARN
|
11
|
+
ActiveRecord::Migration.verbose = false
|
12
|
+
ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || {:adapter => 'sqlite3', :database => "punchcard_#{ENV['RACK_ENV'] || 'development'}.sqlite3"})
|
8
13
|
|
9
14
|
require 'punchcard/person'
|
10
15
|
require 'punchcard/punch'
|
@@ -18,7 +23,7 @@ class Punchcard < Sinatra::Base
|
|
18
23
|
end
|
19
24
|
|
20
25
|
get '/status.json' do
|
21
|
-
Person.
|
26
|
+
Person.order('name ASC').map(&:payload).to_json
|
22
27
|
end
|
23
28
|
|
24
29
|
post '/punch/:id' do
|
data/punchcard.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{punchcard}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Christoph Olszowka"]
|
12
|
-
s.date = %q{2010-12-
|
13
|
-
s.description = %q{Simple sinatra/
|
12
|
+
s.date = %q{2010-12-09}
|
13
|
+
s.description = %q{Simple sinatra/activerecord based app for tracking time when people have been in the office}
|
14
14
|
s.email = %q{christoph at olszowka de}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
@@ -26,12 +26,15 @@ Gem::Specification.new do |s|
|
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"config.ru",
|
29
|
+
"lib/db/migrate/01_create_people.rb",
|
30
|
+
"lib/db/migrate/02_create_punches.rb",
|
29
31
|
"lib/public/cardbg.png",
|
30
32
|
"lib/public/css/blueprint.css",
|
31
33
|
"lib/public/js/app.js",
|
32
34
|
"lib/punchcard.rb",
|
33
35
|
"lib/punchcard/person.rb",
|
34
36
|
"lib/punchcard/punch.rb",
|
37
|
+
"lib/punchcard/tasks.rb",
|
35
38
|
"lib/views/index.haml",
|
36
39
|
"lib/views/layout.haml",
|
37
40
|
"lib/views/screen.sass",
|
@@ -44,7 +47,7 @@ Gem::Specification.new do |s|
|
|
44
47
|
s.rdoc_options = ["--charset=UTF-8"]
|
45
48
|
s.require_paths = ["lib"]
|
46
49
|
s.rubygems_version = %q{1.3.7}
|
47
|
-
s.summary = %q{Simple sinatra/
|
50
|
+
s.summary = %q{Simple sinatra/activerecord based app for tracking time when people have been in the office}
|
48
51
|
s.test_files = [
|
49
52
|
"test/helper.rb",
|
50
53
|
"test/test_database.rb",
|
@@ -60,29 +63,32 @@ Gem::Specification.new do |s|
|
|
60
63
|
s.add_runtime_dependency(%q<bson_ext>, [">= 0"])
|
61
64
|
s.add_runtime_dependency(%q<haml>, [">= 3.0.24"])
|
62
65
|
s.add_runtime_dependency(%q<sass>, [">= 3.0.0"])
|
63
|
-
s.add_runtime_dependency(%q<
|
66
|
+
s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0"])
|
64
67
|
s.add_runtime_dependency(%q<gravtastic>, [">= 0"])
|
65
68
|
s.add_development_dependency(%q<shoulda>, ["= 2.10.3"])
|
66
69
|
s.add_development_dependency(%q<rack-test>, [">= 0.5.6"])
|
70
|
+
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
67
71
|
else
|
68
72
|
s.add_dependency(%q<sinatra>, [">= 1.0.0"])
|
69
73
|
s.add_dependency(%q<bson_ext>, [">= 0"])
|
70
74
|
s.add_dependency(%q<haml>, [">= 3.0.24"])
|
71
75
|
s.add_dependency(%q<sass>, [">= 3.0.0"])
|
72
|
-
s.add_dependency(%q<
|
76
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
|
73
77
|
s.add_dependency(%q<gravtastic>, [">= 0"])
|
74
78
|
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
75
79
|
s.add_dependency(%q<rack-test>, [">= 0.5.6"])
|
80
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
76
81
|
end
|
77
82
|
else
|
78
83
|
s.add_dependency(%q<sinatra>, [">= 1.0.0"])
|
79
84
|
s.add_dependency(%q<bson_ext>, [">= 0"])
|
80
85
|
s.add_dependency(%q<haml>, [">= 3.0.24"])
|
81
86
|
s.add_dependency(%q<sass>, [">= 3.0.0"])
|
82
|
-
s.add_dependency(%q<
|
87
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
|
83
88
|
s.add_dependency(%q<gravtastic>, [">= 0"])
|
84
89
|
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
85
90
|
s.add_dependency(%q<rack-test>, [">= 0.5.6"])
|
91
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
86
92
|
end
|
87
93
|
end
|
88
94
|
|
data/test/helper.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
1
2
|
require 'rubygems'
|
2
3
|
require 'bundler'
|
3
4
|
Bundler.require
|
4
5
|
require 'test/unit'
|
5
6
|
require 'shoulda'
|
7
|
+
require 'rack/test'
|
6
8
|
|
7
9
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
8
10
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
9
11
|
require 'punchcard'
|
10
12
|
|
11
|
-
|
13
|
+
# DB setup
|
14
|
+
require 'logger'
|
15
|
+
system 'rm ./punchcard_test.sqlite3'
|
16
|
+
ActiveRecord::Migrator.migrate(File.join(File.dirname(__FILE__), "../lib/db/migrate"))
|
12
17
|
|
13
18
|
class Test::Unit::TestCase
|
14
19
|
def setup
|
15
20
|
Person.delete_all
|
21
|
+
Punch.delete_all
|
16
22
|
end
|
17
23
|
end
|
data/test/test_database.rb
CHANGED
@@ -21,19 +21,22 @@ class TestDatabase < Test::Unit::TestCase
|
|
21
21
|
assert_nil @person.pending?
|
22
22
|
end
|
23
23
|
|
24
|
-
context "that
|
24
|
+
context "that got punched 2 hours ago" do
|
25
25
|
setup do
|
26
26
|
assert @person.punch!.instance_of?(Punch), "Should have been able to get punched and have returned a Punch"
|
27
|
+
punch = @person.pending?
|
28
|
+
punch.checked_in_at = 2.hours.ago
|
29
|
+
punch.save!
|
27
30
|
end
|
28
31
|
|
29
32
|
should "have one pending punch" do
|
30
33
|
assert_equal Punch, @person.pending?.class
|
31
|
-
assert_equal 1, @person.punches.pending.
|
32
|
-
assert_equal 0, @person.punches.finished.
|
34
|
+
assert_equal 1, @person.punches.pending.count
|
35
|
+
assert_equal 0, @person.punches.finished.count
|
33
36
|
end
|
34
37
|
|
35
38
|
should "not allow to create another pending punch" do
|
36
|
-
assert_raise
|
39
|
+
assert_raise ActiveRecord::RecordInvalid do
|
37
40
|
@person.punches.create!
|
38
41
|
end
|
39
42
|
end
|
@@ -53,8 +56,8 @@ class TestDatabase < Test::Unit::TestCase
|
|
53
56
|
|
54
57
|
should "have one punch and no pending punches" do
|
55
58
|
assert_equal 1, @person.punches.count
|
56
|
-
assert_equal 0, @person.punches.pending.
|
57
|
-
assert_equal 1, @person.punches.finished.
|
59
|
+
assert_equal 0, @person.punches.pending.count
|
60
|
+
assert_equal 1, @person.punches.finished.count
|
58
61
|
end
|
59
62
|
|
60
63
|
context "and gets punched yet again" do
|
@@ -68,17 +71,19 @@ class TestDatabase < Test::Unit::TestCase
|
|
68
71
|
|
69
72
|
should "have 1 punch by having reopened the old one" do
|
70
73
|
assert_equal 1, @person.punches.count
|
71
|
-
assert_equal 1, @person.punches.pending.
|
72
|
-
assert_equal 0, @person.punches.finished.
|
74
|
+
assert_equal 1, @person.punches.pending.count
|
75
|
+
assert_equal 0, @person.punches.finished.count
|
73
76
|
end
|
74
77
|
end
|
75
78
|
|
76
79
|
context "and gets punched yet again 2 hours later" do
|
77
80
|
setup do
|
78
81
|
# Fake the timestamp so reopening does not get triggered
|
79
|
-
punch = @person.punches.first
|
82
|
+
punch = @person.punches.finished.first
|
83
|
+
punch.checked_in_at = 3.hours.ago
|
80
84
|
punch.checked_out_at = 2.hours.ago
|
81
85
|
punch.save!
|
86
|
+
assert_nil @person.pending?
|
82
87
|
assert @person.punch!.instance_of?(Punch), "Should have been able to get punched and have returned a Punch"
|
83
88
|
end
|
84
89
|
|
@@ -88,13 +93,33 @@ class TestDatabase < Test::Unit::TestCase
|
|
88
93
|
|
89
94
|
should "have 2 punches and one pending punch" do
|
90
95
|
assert_equal 2, @person.punches.count
|
91
|
-
assert_equal 1, @person.punches.pending.
|
92
|
-
assert_equal 1, @person.punches.finished.
|
96
|
+
assert_equal 1, @person.punches.pending.count
|
97
|
+
assert_equal 1, @person.punches.finished.count
|
93
98
|
end
|
94
99
|
end
|
95
100
|
end
|
96
101
|
end
|
97
102
|
|
103
|
+
context "that punched in just now" do
|
104
|
+
setup do
|
105
|
+
@person.punch!
|
106
|
+
end
|
107
|
+
|
108
|
+
should "be punched in" do
|
109
|
+
assert @person.pending?
|
110
|
+
end
|
111
|
+
|
112
|
+
context "and punches out shortly after that" do
|
113
|
+
setup do
|
114
|
+
@person.punch!
|
115
|
+
end
|
116
|
+
|
117
|
+
should "not have any punches because of the automatic deletion of too-short punches" do
|
118
|
+
assert_equal 0, @person.punches.count
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
98
123
|
context "that punched in yesterday" do
|
99
124
|
setup do
|
100
125
|
@person.punch!
|
data/test/test_punchcard.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Christoph Olszowka
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-12-
|
17
|
+
date: 2010-12-09 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -76,16 +76,18 @@ dependencies:
|
|
76
76
|
type: :runtime
|
77
77
|
version_requirements: *id004
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
79
|
+
name: activerecord
|
80
80
|
prerelease: false
|
81
81
|
requirement: &id005 !ruby/object:Gem::Requirement
|
82
82
|
none: false
|
83
83
|
requirements:
|
84
|
-
- -
|
84
|
+
- - ~>
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
segments:
|
87
|
+
- 3
|
87
88
|
- 0
|
88
|
-
|
89
|
+
- 0
|
90
|
+
version: 3.0.0
|
89
91
|
type: :runtime
|
90
92
|
version_requirements: *id005
|
91
93
|
- !ruby/object:Gem::Dependency
|
@@ -131,7 +133,20 @@ dependencies:
|
|
131
133
|
version: 0.5.6
|
132
134
|
type: :development
|
133
135
|
version_requirements: *id008
|
134
|
-
|
136
|
+
- !ruby/object:Gem::Dependency
|
137
|
+
name: sqlite3
|
138
|
+
prerelease: false
|
139
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
segments:
|
145
|
+
- 0
|
146
|
+
version: "0"
|
147
|
+
type: :development
|
148
|
+
version_requirements: *id009
|
149
|
+
description: Simple sinatra/activerecord based app for tracking time when people have been in the office
|
135
150
|
email: christoph at olszowka de
|
136
151
|
executables: []
|
137
152
|
|
@@ -150,12 +165,15 @@ files:
|
|
150
165
|
- Rakefile
|
151
166
|
- VERSION
|
152
167
|
- config.ru
|
168
|
+
- lib/db/migrate/01_create_people.rb
|
169
|
+
- lib/db/migrate/02_create_punches.rb
|
153
170
|
- lib/public/cardbg.png
|
154
171
|
- lib/public/css/blueprint.css
|
155
172
|
- lib/public/js/app.js
|
156
173
|
- lib/punchcard.rb
|
157
174
|
- lib/punchcard/person.rb
|
158
175
|
- lib/punchcard/punch.rb
|
176
|
+
- lib/punchcard/tasks.rb
|
159
177
|
- lib/views/index.haml
|
160
178
|
- lib/views/layout.haml
|
161
179
|
- lib/views/screen.sass
|
@@ -194,7 +212,7 @@ rubyforge_project:
|
|
194
212
|
rubygems_version: 1.3.7
|
195
213
|
signing_key:
|
196
214
|
specification_version: 3
|
197
|
-
summary: Simple sinatra/
|
215
|
+
summary: Simple sinatra/activerecord based app for tracking time when people have been in the office
|
198
216
|
test_files:
|
199
217
|
- test/helper.rb
|
200
218
|
- test/test_database.rb
|