balboa 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -14
- data/Gemfile +12 -10
- data/bin/balboa +12 -9
- data/lib/balboa.rb +0 -1
- data/lib/balboa/cli/command/last_command.rb +1 -1
- data/lib/balboa/cli/command/punch_command.rb +19 -12
- data/lib/balboa/cli/command/reset_command.rb +4 -2
- data/lib/balboa/cli/defaults.rb +2 -2
- data/lib/balboa/cli/parser.rb +4 -3
- data/lib/balboa/config_file.rb +1 -1
- data/lib/balboa/interactor/command/fill_punch_command.rb +6 -5
- data/lib/balboa/interactor/command/login_command.rb +5 -4
- data/lib/balboa/interactor/interactor_builder.rb +12 -4
- data/lib/balboa/punch_date.rb +4 -0
- data/lib/balboa/schedule.rb +14 -0
- data/lib/balboa/version.rb +1 -1
- data/spec/balboa/cli/command/last_command_spec.rb +2 -2
- data/spec/balboa/cli/command/punch_command_spec.rb +144 -0
- data/spec/balboa/cli/command/reset_command_spec.rb +3 -5
- data/spec/balboa/cli/defaults_spec.rb +180 -0
- data/spec/balboa/cli/parser_spec.rb +32 -60
- data/spec/balboa/{capybara_interactor_spec.rb → interactor/capybara_interactor_spec.rb} +0 -0
- data/spec/balboa/punch_date_spec.rb +20 -0
- data/spec/balboa/schedule_spec.rb +35 -0
- data/spec/spec_helper.rb +5 -0
- metadata +6 -5
- data/lib/balboa/interactor/interactor_wrapper.rb +0 -23
- data/spec/balboa/interactor/interactor_wrapper_spec.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bae7fa2a0ed778439952c80e904bfc4d1b20bb86
|
4
|
+
data.tar.gz: cf581ff2e9e518d84fddbb4a68ce3b719c3cff7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c479bc46f03d0bdbfec9e4bd451bc14f9b438632828a020272900c295d7f1c9afe0c78379584abae4a9f42b02ef6efa3f971bddb740f7b10368510c703903ec9
|
7
|
+
data.tar.gz: b15e044b0c286edad6da3c934b7b1e9298ff067bbbfef26286871bd45b63d5fc345f248f33277a43b54a852bf0ba646480ef14f341b1f842527ee77248f76c9a
|
data/.travis.yml
CHANGED
@@ -6,21 +6,7 @@ rvm:
|
|
6
6
|
- 2.3.0
|
7
7
|
- 2.2
|
8
8
|
- 2.1
|
9
|
-
- 2.0
|
10
9
|
matrix:
|
11
|
-
include:
|
12
|
-
- rvm: jruby
|
13
|
-
env: JRUBY_OPTS='--2.0 --server -Xcompile.invokedynamic=false'
|
14
|
-
- rvm: jruby-head
|
15
|
-
env: JRUBY_OPTS='--server -Xcompile.invokedynamic=false'
|
16
|
-
allow_failures:
|
17
|
-
- rvm: jruby
|
18
|
-
- rvm: jruby-head
|
19
|
-
- rvm: rbx-2
|
20
|
-
- rvm: ruby-head
|
21
|
-
- rvm: 1.9.3
|
22
|
-
- rvm: 1.9.2
|
23
|
-
- rvm: 1.8.7
|
24
10
|
fast_finish: true
|
25
11
|
branches:
|
26
12
|
only:
|
data/Gemfile
CHANGED
@@ -4,14 +4,16 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
gemspec
|
6
6
|
|
7
|
-
|
8
|
-
gem '
|
9
|
-
gem '
|
10
|
-
gem '
|
11
|
-
gem '
|
7
|
+
group :development do
|
8
|
+
gem 'reek', '~> 4.2.0'
|
9
|
+
gem 'rspec', '~> 3.0'
|
10
|
+
gem 'cucumber', '~> 2.0'
|
11
|
+
gem 'rubocop', '~> 0.41.1'
|
12
|
+
gem 'mutant-rspec', '~> 0.8.8'
|
13
|
+
gem 'rake', '~> 11.2.2'
|
14
|
+
gem 'rack', '~> 1.0.0'
|
12
15
|
|
13
|
-
gem '
|
14
|
-
|
15
|
-
gem '
|
16
|
-
|
17
|
-
gem 'phantomjs', '~> 2.1.1.0', require: 'phantomjs/poltergeist'
|
16
|
+
gem 'capybara', '~> 2.7.1'
|
17
|
+
gem 'poltergeist', '~> 1.10.0'
|
18
|
+
gem 'phantomjs', '~> 2.1.1.0', require: 'phantomjs/poltergeist'
|
19
|
+
end
|
data/bin/balboa
CHANGED
@@ -7,16 +7,19 @@ require_relative '../lib/balboa/interactor/interactor_builder'
|
|
7
7
|
|
8
8
|
require 'highline/import'
|
9
9
|
|
10
|
-
options =
|
11
|
-
YAML.load_file(Balboa::CONFIG_FILE)
|
12
|
-
else
|
13
|
-
Balboa::CLI::Defaults.prompt(HighLine)
|
14
|
-
end
|
10
|
+
options = Balboa::CLI::Parser.parse(ARGV)
|
15
11
|
|
16
|
-
|
12
|
+
defaults = if options['skip_defaults']
|
13
|
+
{}
|
14
|
+
elsif File.exist?(Balboa::CONFIG_FILE)
|
15
|
+
YAML.load_file(Balboa::CONFIG_FILE)
|
16
|
+
else
|
17
|
+
Balboa::CLI::Defaults.prompt(HighLine)
|
18
|
+
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
options = defaults.merge(options)
|
21
|
+
|
22
|
+
interactor = Balboa::Interactor::InteractorBuilder.create(options)
|
20
23
|
|
21
24
|
app_last = Balboa::CLI::Command::LastCommand.new(interactor)
|
22
25
|
app_punch = Balboa::CLI::Command::PunchCommand.new(interactor, HighLine)
|
@@ -31,7 +34,7 @@ app.add_command(:reset, app_reset)
|
|
31
34
|
app.add_command(:star_wars, app_star_wars)
|
32
35
|
|
33
36
|
begin
|
34
|
-
app.execute
|
37
|
+
$stdout.puts(app.execute)
|
35
38
|
rescue Balboa::CLI::Application::CommandNotFound
|
36
39
|
$stdout.puts("\nCommand Not Found!")
|
37
40
|
$stdout.puts("\nRun `balboa -h' to check available commands and options.")
|
data/lib/balboa.rb
CHANGED
@@ -5,7 +5,6 @@ require_relative 'balboa/config_file'
|
|
5
5
|
require_relative 'balboa/host'
|
6
6
|
|
7
7
|
require_relative 'balboa/interactor/capybara_interactor'
|
8
|
-
require_relative 'balboa/interactor/interactor_wrapper'
|
9
8
|
require_relative 'balboa/interactor/command/fetch_last_punch_command'
|
10
9
|
require_relative 'balboa/interactor/command/fill_punch_command'
|
11
10
|
require_relative 'balboa/interactor/command/login_command'
|
@@ -14,28 +14,35 @@ module Balboa
|
|
14
14
|
def execute
|
15
15
|
punch_dates.reject! { |date| skip_date?(date) }
|
16
16
|
|
17
|
-
punch_dates.each
|
18
|
-
|
19
|
-
|
20
|
-
end
|
17
|
+
punch_dates.each { |date| @interactor.punch(date) }
|
18
|
+
|
19
|
+
command_output
|
21
20
|
end
|
22
21
|
|
23
22
|
private
|
24
23
|
|
25
24
|
def punch_dates
|
26
|
-
|
27
|
-
|
28
|
-
(last_punch_date..yesterday).map do |date|
|
29
|
-
PunchDate.new(date, @cli)
|
25
|
+
@punch_dates ||= (last_punch_date..(Date.today - 1)).map do |date|
|
26
|
+
Balboa::PunchDate.new(date, @cli)
|
30
27
|
end
|
31
28
|
end
|
32
29
|
|
33
|
-
def
|
34
|
-
|
30
|
+
def command_output
|
31
|
+
punch_dates.map do |date|
|
32
|
+
"\n#{date.strftime('%d/%m/%Y')}"
|
33
|
+
end.join
|
34
|
+
end
|
35
|
+
|
36
|
+
def skip_date?(punch_date)
|
37
|
+
!punch_date.punchable? || skips_include?(punch_date)
|
38
|
+
end
|
39
|
+
|
40
|
+
def skips_include?(punch_date)
|
41
|
+
skipped_dates.include?(punch_date.to_date)
|
35
42
|
end
|
36
43
|
|
37
|
-
def
|
38
|
-
@interactor.options['skips']
|
44
|
+
def skipped_dates
|
45
|
+
@interactor.options['skips']
|
39
46
|
end
|
40
47
|
|
41
48
|
def last_punch_date
|
data/lib/balboa/cli/defaults.rb
CHANGED
data/lib/balboa/cli/parser.rb
CHANGED
@@ -10,16 +10,16 @@ module Balboa
|
|
10
10
|
new(*args).parse
|
11
11
|
end
|
12
12
|
|
13
|
-
def initialize(argv
|
14
|
-
@config =
|
13
|
+
def initialize(argv)
|
14
|
+
@config = {}
|
15
15
|
@argv = argv
|
16
16
|
@parser = OptionParser.new
|
17
17
|
end
|
18
18
|
|
19
19
|
def parse
|
20
20
|
configure_parser
|
21
|
-
|
22
21
|
@parser.parse!(@argv)
|
22
|
+
@config
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
@@ -60,6 +60,7 @@ module Balboa
|
|
60
60
|
|
61
61
|
@parser.on('-c', '--config \'FILE\'', message) do |file|
|
62
62
|
@config.merge!(YAML.load_file(file))
|
63
|
+
@config['skip_defaults'] = true
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
data/lib/balboa/config_file.rb
CHANGED
@@ -13,8 +13,9 @@ module Balboa
|
|
13
13
|
|
14
14
|
PunchCreationError = Class.new(RuntimeError)
|
15
15
|
|
16
|
-
def initialize(
|
17
|
-
@
|
16
|
+
def initialize(schedule, project)
|
17
|
+
@schedule = schedule
|
18
|
+
@project = project
|
18
19
|
end
|
19
20
|
|
20
21
|
def execute(date)
|
@@ -34,18 +35,18 @@ module Balboa
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def fill_first_shift(date)
|
37
|
-
fill_form(date, @
|
38
|
+
fill_form(date, @schedule.start_at, @schedule.lunch_at)
|
38
39
|
end
|
39
40
|
|
40
41
|
def fill_second_shift(date)
|
41
|
-
fill_form(date, @
|
42
|
+
fill_form(date, @schedule.restart_at, @schedule.leave_at)
|
42
43
|
end
|
43
44
|
|
44
45
|
def fill_form(date, start_time, finish_time)
|
45
46
|
fill_in 'punch[from_time]', with: TIME_TEMPLATE % start_time
|
46
47
|
fill_in 'punch[to_time]', with: TIME_TEMPLATE % finish_time
|
47
48
|
fill_in 'punch[when_day]', with: date.to_s
|
48
|
-
select @
|
49
|
+
select @project, from: 'punch[project_id]'
|
49
50
|
|
50
51
|
confirm
|
51
52
|
end
|
@@ -12,8 +12,9 @@ module Balboa
|
|
12
12
|
|
13
13
|
LoginFailure = Class.new(RuntimeError)
|
14
14
|
|
15
|
-
def initialize(
|
16
|
-
@
|
15
|
+
def initialize(email, password)
|
16
|
+
@email = email
|
17
|
+
@password = password
|
17
18
|
end
|
18
19
|
|
19
20
|
def execute
|
@@ -31,8 +32,8 @@ module Balboa
|
|
31
32
|
end
|
32
33
|
|
33
34
|
def fill_form
|
34
|
-
fill_in 'E-mail', with: @
|
35
|
-
fill_in 'Password', with: @
|
35
|
+
fill_in 'E-mail', with: @email
|
36
|
+
fill_in 'Password', with: @password
|
36
37
|
end
|
37
38
|
|
38
39
|
def confirm
|
@@ -4,6 +4,7 @@ require_relative 'capybara_interactor'
|
|
4
4
|
require_relative 'command/fetch_last_punch_command'
|
5
5
|
require_relative 'command/fill_punch_command'
|
6
6
|
require_relative 'command/login_command'
|
7
|
+
require_relative '../schedule'
|
7
8
|
|
8
9
|
module Balboa
|
9
10
|
module Interactor
|
@@ -14,11 +15,11 @@ module Balboa
|
|
14
15
|
|
15
16
|
def initialize(options)
|
16
17
|
@options = options
|
17
|
-
@interactor =
|
18
|
+
@interactor = CapybaraInteractor.new(options)
|
18
19
|
end
|
19
20
|
|
20
21
|
def create
|
21
|
-
last_punch =
|
22
|
+
last_punch = Command::FetchLastPunchCommand.new
|
22
23
|
|
23
24
|
@interactor.tap do |itr|
|
24
25
|
itr.add_command(:punch, fill_punch)
|
@@ -29,12 +30,19 @@ module Balboa
|
|
29
30
|
|
30
31
|
private
|
31
32
|
|
33
|
+
def schedule
|
34
|
+
Balboa::Schedule.new(@options['start_at'],
|
35
|
+
@options['lunch_at'],
|
36
|
+
@options['restart_at'],
|
37
|
+
@options['leave_at'])
|
38
|
+
end
|
39
|
+
|
32
40
|
def fill_punch
|
33
|
-
|
41
|
+
Command::FillPunchCommand.new(schedule, @options['project'])
|
34
42
|
end
|
35
43
|
|
36
44
|
def login
|
37
|
-
|
45
|
+
Command::LoginCommand.new(@options['email'], @options['password'])
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
data/lib/balboa/punch_date.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Balboa
|
4
|
+
class Schedule
|
5
|
+
attr_reader :start_at, :lunch_at, :restart_at, :leave_at
|
6
|
+
|
7
|
+
def initialize(start_at, lunch_at, restart_at, leave_at)
|
8
|
+
@start_at = start_at
|
9
|
+
@lunch_at = lunch_at
|
10
|
+
@restart_at = restart_at
|
11
|
+
@leave_at = leave_at
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/balboa/version.rb
CHANGED
@@ -6,8 +6,8 @@ describe Balboa::CLI::Command::LastCommand do
|
|
6
6
|
it 'prints out the result of interactor last method' do
|
7
7
|
interactor = double('itr', last: 42)
|
8
8
|
|
9
|
-
|
9
|
+
output = described_class.new(interactor).execute
|
10
10
|
|
11
|
-
|
11
|
+
expect(output).to eq("\n42")
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'highline'
|
5
|
+
|
6
|
+
require_relative '../../../../lib/balboa/punch_date'
|
7
|
+
|
8
|
+
describe Balboa::CLI::Command::PunchCommand do
|
9
|
+
class InteractorFaker
|
10
|
+
def initialize(last, skips = [])
|
11
|
+
@last = last
|
12
|
+
|
13
|
+
@options = {
|
14
|
+
'skips' => skips
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :last, :options
|
19
|
+
|
20
|
+
def punch(date)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'raises when skips is not an array' do
|
25
|
+
interactor = InteractorFaker.new('bad date')
|
26
|
+
|
27
|
+
command = described_class.new(interactor, nil)
|
28
|
+
|
29
|
+
expect { command.execute }.to raise_error(ArgumentError)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns all punched dates' do
|
33
|
+
today = Date.new(2015, 8, 15)
|
34
|
+
last_punch_date = today - 7
|
35
|
+
|
36
|
+
allow(Date).to receive(:today).and_return(today)
|
37
|
+
interactor = InteractorFaker.new(last_punch_date.to_s)
|
38
|
+
|
39
|
+
command = described_class.new(interactor, nil)
|
40
|
+
|
41
|
+
punched_dates = [
|
42
|
+
"\n10/08/2015",
|
43
|
+
'11/08/2015',
|
44
|
+
'12/08/2015',
|
45
|
+
'13/08/2015',
|
46
|
+
'14/08/2015'
|
47
|
+
]
|
48
|
+
expect(command.execute).to eq(punched_dates.join("\n"))
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns all punched dates except for the skipped ones' do
|
52
|
+
today = Date.new(2015, 8, 15)
|
53
|
+
last_punch_date = today - 7
|
54
|
+
skips = [Date.new(2015, 8, 12), Date.new(2015, 8, 14)]
|
55
|
+
|
56
|
+
allow(Date).to receive(:today).and_return(today)
|
57
|
+
interactor = InteractorFaker.new(last_punch_date.to_s, skips)
|
58
|
+
|
59
|
+
command = described_class.new(interactor, nil)
|
60
|
+
|
61
|
+
punched_dates = [
|
62
|
+
"\n10/08/2015",
|
63
|
+
'11/08/2015',
|
64
|
+
'13/08/2015'
|
65
|
+
]
|
66
|
+
expect(command.execute).to eq(punched_dates.join("\n"))
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns all punched dates except for the skipped ones' do
|
70
|
+
today = Date.new(2015, 8, 15)
|
71
|
+
last_punch_date = today - 7
|
72
|
+
skips = [Date.new(2015, 8, 12), Date.new(2015, 8, 14)]
|
73
|
+
|
74
|
+
allow(Date).to receive(:today).and_return(today)
|
75
|
+
interactor = InteractorFaker.new(last_punch_date.to_s, skips)
|
76
|
+
|
77
|
+
command = described_class.new(interactor, nil)
|
78
|
+
|
79
|
+
punched_dates = [
|
80
|
+
"\n10/08/2015",
|
81
|
+
'11/08/2015',
|
82
|
+
'13/08/2015'
|
83
|
+
]
|
84
|
+
expect(command.execute).to eq(punched_dates.join("\n"))
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns nothing when last punch date is recent' do
|
88
|
+
today = Date.new(2015, 8, 15)
|
89
|
+
last_punch_date = today
|
90
|
+
skips = [Date.new(2015, 8, 12), Date.new(2015, 8, 14)]
|
91
|
+
|
92
|
+
allow(Date).to receive(:today).and_return(today)
|
93
|
+
interactor = InteractorFaker.new(last_punch_date.to_s, skips)
|
94
|
+
|
95
|
+
command = described_class.new(interactor, nil)
|
96
|
+
|
97
|
+
expect(command.execute).to eq('')
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'on holidays' do
|
101
|
+
it 'skips date when user input no' do
|
102
|
+
today = Date.new(2015, 9, 10)
|
103
|
+
last_punch_date = today - 7
|
104
|
+
|
105
|
+
input = StringIO.new('no\n')
|
106
|
+
output = StringIO.new
|
107
|
+
cli = HighLine.new(input, output)
|
108
|
+
|
109
|
+
allow(Date).to receive(:today).and_return(today)
|
110
|
+
interactor = InteractorFaker.new(last_punch_date.to_s)
|
111
|
+
|
112
|
+
command = described_class.new(interactor, cli)
|
113
|
+
|
114
|
+
punched_dates = [
|
115
|
+
"\n04/09/2015",
|
116
|
+
'08/09/2015',
|
117
|
+
'09/09/2015'
|
118
|
+
]
|
119
|
+
expect(command.execute).to eq(punched_dates.join("\n"))
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'returns date when user input yes' do
|
123
|
+
today = Date.new(2015, 9, 10)
|
124
|
+
last_punch_date = today - 7
|
125
|
+
|
126
|
+
input = StringIO.new('yes\n')
|
127
|
+
output = StringIO.new
|
128
|
+
cli = HighLine.new(input, output)
|
129
|
+
|
130
|
+
allow(Date).to receive(:today).and_return(today)
|
131
|
+
interactor = InteractorFaker.new(last_punch_date.to_s)
|
132
|
+
|
133
|
+
command = described_class.new(interactor, cli)
|
134
|
+
|
135
|
+
punched_dates = [
|
136
|
+
"\n04/09/2015",
|
137
|
+
'07/09/2015',
|
138
|
+
'08/09/2015',
|
139
|
+
'09/09/2015'
|
140
|
+
]
|
141
|
+
expect(command.execute).to eq(punched_dates.join("\n"))
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Balboa::CLI::Command::ResetCommand do
|
6
6
|
it 'deletes the .balboa.yml file' do
|
7
|
-
expect(File).to receive(:delete).with(
|
7
|
+
expect(File).to receive(:delete).with(Balboa::CONFIG_FILE)
|
8
8
|
|
9
9
|
described_class.new.execute
|
10
10
|
end
|
@@ -12,10 +12,8 @@ describe Balboa::CLI::Command::ResetCommand do
|
|
12
12
|
it 'prints out a success message' do
|
13
13
|
success_message = "\nBalboa restored to initial settings!"
|
14
14
|
|
15
|
-
allow(File).to receive(:delete).with(
|
15
|
+
allow(File).to receive(:delete).with(Balboa::CONFIG_FILE)
|
16
16
|
|
17
|
-
expect(
|
18
|
-
|
19
|
-
described_class.new.execute
|
17
|
+
expect(described_class.new.execute).to eq(success_message)
|
20
18
|
end
|
21
19
|
end
|
@@ -4,4 +4,184 @@ require 'spec_helper'
|
|
4
4
|
require 'highline'
|
5
5
|
|
6
6
|
describe Balboa::CLI::Defaults do
|
7
|
+
it 'welcomes the user' do
|
8
|
+
input = StringIO.new
|
9
|
+
output = StringIO.new
|
10
|
+
cli = HighLine.new(input, output)
|
11
|
+
|
12
|
+
input << "john@doe.com\n"
|
13
|
+
input << "john@doe.com\n"
|
14
|
+
input << "Doe Company\n"
|
15
|
+
input << "\n"
|
16
|
+
input << "\n"
|
17
|
+
input << "\n"
|
18
|
+
input << "\n"
|
19
|
+
input.rewind
|
20
|
+
|
21
|
+
described_class.prompt(cli)
|
22
|
+
|
23
|
+
expect(output.string).to include('First run. Please type your settings!')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not show input password' do
|
27
|
+
input = StringIO.new
|
28
|
+
output = StringIO.new
|
29
|
+
cli = HighLine.new(input, output)
|
30
|
+
|
31
|
+
password = 'motherlode'
|
32
|
+
|
33
|
+
input << "john@doe.com\n"
|
34
|
+
input << "#{password}\n"
|
35
|
+
input << "Doe Company\n"
|
36
|
+
input << "\n"
|
37
|
+
input << "\n"
|
38
|
+
input << "\n"
|
39
|
+
input << "\n"
|
40
|
+
input.rewind
|
41
|
+
|
42
|
+
described_class.prompt(cli)
|
43
|
+
|
44
|
+
expect(output.string).not_to include(password)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'prompts for attributes and fill some with default value' do
|
48
|
+
input = StringIO.new
|
49
|
+
output = StringIO.new
|
50
|
+
cli = HighLine.new(input, output)
|
51
|
+
|
52
|
+
input << "john@doe.com\n"
|
53
|
+
input << "john@doe.com\n"
|
54
|
+
input << "Doe Company\n"
|
55
|
+
input << "\n"
|
56
|
+
input << "\n"
|
57
|
+
input << "\n"
|
58
|
+
input << "\n"
|
59
|
+
input.rewind
|
60
|
+
|
61
|
+
config = described_class.prompt(cli)
|
62
|
+
|
63
|
+
expect(config).to eq(
|
64
|
+
'email' => 'john@doe.com',
|
65
|
+
'password' => 'john@doe.com',
|
66
|
+
'project' => 'Doe Company',
|
67
|
+
'start_at' => '8',
|
68
|
+
'lunch_at' => '12',
|
69
|
+
'restart_at' => '13',
|
70
|
+
'leave_at' => '17',
|
71
|
+
'skips' => []
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'prompts for password but removes if empty' do
|
76
|
+
input = StringIO.new
|
77
|
+
output = StringIO.new
|
78
|
+
cli = HighLine.new(input, output)
|
79
|
+
|
80
|
+
input << "john@doe.com\n"
|
81
|
+
input << "\n"
|
82
|
+
input << "Doe Company\n"
|
83
|
+
input << "\n"
|
84
|
+
input << "\n"
|
85
|
+
input << "\n"
|
86
|
+
input << "\n"
|
87
|
+
input.rewind
|
88
|
+
|
89
|
+
config = described_class.prompt(cli)
|
90
|
+
|
91
|
+
expect(config).to eq(
|
92
|
+
'email' => 'john@doe.com',
|
93
|
+
'project' => 'Doe Company',
|
94
|
+
'start_at' => '8',
|
95
|
+
'lunch_at' => '12',
|
96
|
+
'restart_at' => '13',
|
97
|
+
'leave_at' => '17',
|
98
|
+
'skips' => []
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'prompts for attributes and place them in the right spot' do
|
103
|
+
input = StringIO.new
|
104
|
+
output = StringIO.new
|
105
|
+
cli = HighLine.new(input, output)
|
106
|
+
|
107
|
+
input << "john@doe.com\n"
|
108
|
+
input << "john@doe.com\n"
|
109
|
+
input << "Doe Company\n"
|
110
|
+
input << "13\n"
|
111
|
+
input << "14\n"
|
112
|
+
input << "15\n"
|
113
|
+
input << "16\n"
|
114
|
+
input.rewind
|
115
|
+
|
116
|
+
config = described_class.prompt(cli)
|
117
|
+
|
118
|
+
expect(config).to eq(
|
119
|
+
'email' => 'john@doe.com',
|
120
|
+
'password' => 'john@doe.com',
|
121
|
+
'project' => 'Doe Company',
|
122
|
+
'start_at' => '13',
|
123
|
+
'lunch_at' => '14',
|
124
|
+
'restart_at' => '15',
|
125
|
+
'leave_at' => '16',
|
126
|
+
'skips' => []
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'prompts for attributes and place them in the right spot' do
|
131
|
+
input = StringIO.new
|
132
|
+
output = StringIO.new
|
133
|
+
cli = HighLine.new(input, output)
|
134
|
+
|
135
|
+
input << "john@doe.com\n"
|
136
|
+
input << "john@doe.com\n"
|
137
|
+
input << "Doe Company\n"
|
138
|
+
input << "13\n"
|
139
|
+
input << "14\n"
|
140
|
+
input << "15\n"
|
141
|
+
input << "16\n"
|
142
|
+
input.rewind
|
143
|
+
|
144
|
+
file = double('file')
|
145
|
+
open_args = [Balboa::CONFIG_FILE, 'w']
|
146
|
+
config = {
|
147
|
+
'email' => 'john@doe.com',
|
148
|
+
'password' => 'john@doe.com',
|
149
|
+
'project' => 'Doe Company',
|
150
|
+
'start_at' => '13',
|
151
|
+
'lunch_at' => '14',
|
152
|
+
'restart_at' => '15',
|
153
|
+
'leave_at' => '16',
|
154
|
+
'skips' => []
|
155
|
+
}
|
156
|
+
|
157
|
+
expect(File).to receive(:open).with(*open_args).and_yield(file)
|
158
|
+
expect(file).to receive(:write).with(config.to_yaml)
|
159
|
+
|
160
|
+
described_class.prompt(cli)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'prompts for schedule and adapt on each input' do
|
164
|
+
input = StringIO.new
|
165
|
+
output = StringIO.new
|
166
|
+
cli = HighLine.new(input, output)
|
167
|
+
|
168
|
+
input << "john@doe.com\n"
|
169
|
+
input << "john@doe.com\n"
|
170
|
+
input << "Doe Company\n"
|
171
|
+
input << "1\n"
|
172
|
+
input << "2\n"
|
173
|
+
input << "4\n"
|
174
|
+
input << "8\n"
|
175
|
+
input.rewind
|
176
|
+
|
177
|
+
described_class.prompt(cli)
|
178
|
+
|
179
|
+
expectations = [
|
180
|
+
'First shift: |8|',
|
181
|
+
'Lunch: |5|',
|
182
|
+
'Second shift: |3|',
|
183
|
+
'Leave: |11|'
|
184
|
+
]
|
185
|
+
expect(output.string).to include(*expectations)
|
186
|
+
end
|
7
187
|
end
|
@@ -6,111 +6,94 @@ require_relative '../../../lib/balboa/cli/parser'
|
|
6
6
|
|
7
7
|
describe Balboa::CLI::Parser do
|
8
8
|
it 'parses a password option into a hash of configurations' do
|
9
|
-
config = {}
|
10
9
|
argv = ['-p', 'test']
|
11
|
-
|
12
|
-
described_class.parse(argv, config)
|
10
|
+
config = described_class.parse(argv)
|
13
11
|
|
14
12
|
expect(config).to eq('password' => 'test')
|
15
13
|
end
|
16
14
|
|
17
15
|
it 'parses a password full option into a hash of configurations' do
|
18
|
-
config = {}
|
19
16
|
argv = ['--password', 'test']
|
20
|
-
|
21
|
-
described_class.parse(argv, config)
|
17
|
+
config = described_class.parse(argv)
|
22
18
|
|
23
19
|
expect(config).to eq('password' => 'test')
|
24
20
|
end
|
25
21
|
|
26
22
|
it 'parses a project option into a hash of configurations' do
|
27
|
-
config = {}
|
28
23
|
argv = ['-w', 'test']
|
29
|
-
|
30
|
-
described_class.parse(argv, config)
|
24
|
+
config = described_class.parse(argv)
|
31
25
|
|
32
26
|
expect(config).to eq('project' => 'test')
|
33
27
|
end
|
34
28
|
|
35
29
|
it 'parses a project full option into a hash of configurations' do
|
36
|
-
config = {}
|
37
30
|
argv = ['--project', 'test']
|
38
|
-
|
39
|
-
described_class.parse(argv, config)
|
31
|
+
config = described_class.parse(argv)
|
40
32
|
|
41
33
|
expect(config).to eq('project' => 'test')
|
42
34
|
end
|
43
35
|
|
44
36
|
it 'parses a email option into a hash of configurations' do
|
45
|
-
config = {}
|
46
37
|
argv = ['-e', 'test']
|
47
|
-
|
48
|
-
described_class.parse(argv, config)
|
38
|
+
config = described_class.parse(argv)
|
49
39
|
|
50
40
|
expect(config).to eq('email' => 'test')
|
51
41
|
end
|
52
42
|
|
53
43
|
it 'parses a email full option into a hash of configurations' do
|
54
|
-
config = {}
|
55
44
|
argv = ['--email', 'test']
|
56
|
-
|
57
|
-
described_class.parse(argv, config)
|
45
|
+
config = described_class.parse(argv)
|
58
46
|
|
59
47
|
expect(config).to eq('email' => 'test')
|
60
48
|
end
|
61
49
|
|
62
50
|
it 'parses a config option into a hash of configurations' do
|
63
|
-
config = {}
|
64
51
|
argv = ['-c', 'spec/fixtures/file.yml']
|
65
|
-
|
66
|
-
described_class.parse(argv, config)
|
52
|
+
config = described_class.parse(argv)
|
67
53
|
|
68
54
|
expectation = {
|
69
|
-
'email'
|
70
|
-
'password'
|
71
|
-
'project'
|
72
|
-
'start_at'
|
73
|
-
'lunch_at'
|
74
|
-
'restart_at'
|
75
|
-
'
|
76
|
-
'
|
55
|
+
'email' => 'email',
|
56
|
+
'password' => 'password',
|
57
|
+
'project' => 'project',
|
58
|
+
'start_at' => '8',
|
59
|
+
'lunch_at' => '12',
|
60
|
+
'restart_at' => '13',
|
61
|
+
'skip_defaults' => true,
|
62
|
+
'leave_at' => '17',
|
63
|
+
'skips' => []
|
77
64
|
}
|
78
65
|
expect(config).to eq(expectation)
|
79
66
|
end
|
80
67
|
|
81
68
|
it 'parses a config full option into a hash of configurations' do
|
82
|
-
config = {}
|
83
69
|
argv = ['--config', 'spec/fixtures/file.yml']
|
84
|
-
|
85
|
-
described_class.parse(argv, config)
|
70
|
+
config = described_class.parse(argv)
|
86
71
|
|
87
72
|
expectation = {
|
88
|
-
'email'
|
89
|
-
'password'
|
90
|
-
'project'
|
91
|
-
'start_at'
|
92
|
-
'lunch_at'
|
93
|
-
'restart_at'
|
94
|
-
'
|
95
|
-
'
|
73
|
+
'email' => 'email',
|
74
|
+
'password' => 'password',
|
75
|
+
'project' => 'project',
|
76
|
+
'start_at' => '8',
|
77
|
+
'lunch_at' => '12',
|
78
|
+
'restart_at' => '13',
|
79
|
+
'skip_defaults' => true,
|
80
|
+
'leave_at' => '17',
|
81
|
+
'skips' => []
|
96
82
|
}
|
97
83
|
expect(config).to eq(expectation)
|
98
84
|
end
|
99
85
|
|
100
86
|
it 'raises ENOENT on invalid path to file' do
|
101
|
-
config = {}
|
102
87
|
argv = ['-c', 'wrong path to file']
|
103
88
|
|
104
|
-
parser = described_class.new(argv
|
89
|
+
parser = described_class.new(argv)
|
105
90
|
|
106
91
|
expect { parser.parse }.to raise_error(Errno::ENOENT)
|
107
92
|
end
|
108
93
|
|
109
94
|
it 'parses a skipped date option into a hash of configurations' do
|
110
|
-
config = {}
|
111
95
|
argv = ['-s', '13/06/1992,15/06/2002']
|
112
|
-
|
113
|
-
described_class.parse(argv, config)
|
96
|
+
config = described_class.parse(argv)
|
114
97
|
|
115
98
|
expectation = {
|
116
99
|
'skips' => [
|
@@ -121,19 +104,15 @@ describe Balboa::CLI::Parser do
|
|
121
104
|
end
|
122
105
|
|
123
106
|
it 'raises argument error in case of a wrong date format' do
|
124
|
-
config = {}
|
125
107
|
argv = ['-s', 'test']
|
126
|
-
|
127
|
-
parser = described_class.new(argv, config)
|
108
|
+
parser = described_class.new(argv)
|
128
109
|
|
129
110
|
expect { parser.parse }.to raise_error(ArgumentError)
|
130
111
|
end
|
131
112
|
|
132
113
|
it 'parses a skipped date full option into a hash of configurations' do
|
133
|
-
config = {}
|
134
114
|
argv = ['--skip', '12/06/1992,12/06/1992']
|
135
|
-
|
136
|
-
described_class.parse(argv, config)
|
115
|
+
config = described_class.parse(argv)
|
137
116
|
|
138
117
|
expectation = {
|
139
118
|
'skips' => [
|
@@ -144,27 +123,20 @@ describe Balboa::CLI::Parser do
|
|
144
123
|
end
|
145
124
|
|
146
125
|
it 'parses options that override or fulfill config' do
|
147
|
-
config = {
|
148
|
-
'password' => '1',
|
149
|
-
'project' => '3'
|
150
|
-
}
|
151
126
|
argv = ['-p', '3', '-e', '2', '-w', '1']
|
152
|
-
|
153
|
-
described_class.parse(argv, config)
|
127
|
+
config = described_class.parse(argv)
|
154
128
|
|
155
129
|
expectation = {
|
156
130
|
'password' => '3',
|
157
131
|
'email' => '2',
|
158
132
|
'project' => '1'
|
159
133
|
}
|
160
|
-
|
161
134
|
expect(config).to eq(expectation)
|
162
135
|
end
|
163
136
|
|
164
137
|
it 'raises on invalid arguments' do
|
165
|
-
config = {}
|
166
138
|
argv = ['-z']
|
167
|
-
parser = described_class.new(argv
|
139
|
+
parser = described_class.new(argv)
|
168
140
|
|
169
141
|
expect { parser.parse }.to raise_error(OptionParser::InvalidOption)
|
170
142
|
end
|
File without changes
|
@@ -11,6 +11,13 @@ describe Balboa::PunchDate do
|
|
11
11
|
expect(punch_date.to_s).to eq('2011-01-01')
|
12
12
|
end
|
13
13
|
|
14
|
+
it 'responds to to_date' do
|
15
|
+
date = Date.new(2011, 1, 1)
|
16
|
+
punch_date = described_class.new(date, nil)
|
17
|
+
|
18
|
+
expect(punch_date.to_date).to eq(date)
|
19
|
+
end
|
20
|
+
|
14
21
|
it 'responds to strftime' do
|
15
22
|
date = Date.new(2011, 1, 1)
|
16
23
|
punch_date = described_class.new(date, nil)
|
@@ -61,5 +68,18 @@ describe Balboa::PunchDate do
|
|
61
68
|
|
62
69
|
expect(punch_date.punchable?).to be true
|
63
70
|
end
|
71
|
+
|
72
|
+
it 'displays the holiday name' do
|
73
|
+
input = StringIO.new("yes\n")
|
74
|
+
output = StringIO.new
|
75
|
+
cli = HighLine.new(input, output)
|
76
|
+
|
77
|
+
date = Date.new(2011, 4, 21)
|
78
|
+
punch_date = described_class.new(date, cli)
|
79
|
+
|
80
|
+
punch_date.punchable?
|
81
|
+
|
82
|
+
expect(output.string).to match(/Tiradentes/)
|
83
|
+
end
|
64
84
|
end
|
65
85
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Balboa::Schedule do
|
6
|
+
it 'saves all shift attributes' do
|
7
|
+
schedule = described_class.new(8, 12, 13, 17)
|
8
|
+
|
9
|
+
expect(schedule).not_to be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'responds to start_at' do
|
13
|
+
schedule = described_class.new(8, 12, 13, 17)
|
14
|
+
|
15
|
+
expect(schedule.start_at).to eq(8)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'responds to lunch_at' do
|
19
|
+
schedule = described_class.new(8, 12, 13, 17)
|
20
|
+
|
21
|
+
expect(schedule.lunch_at).to eq(12)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'responds to restart_at' do
|
25
|
+
schedule = described_class.new(8, 12, 13, 17)
|
26
|
+
|
27
|
+
expect(schedule.restart_at).to eq(13)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'responds to leave_at' do
|
31
|
+
schedule = described_class.new(8, 12, 13, 17)
|
32
|
+
|
33
|
+
expect(schedule.leave_at).to eq(17)
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: balboa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Waldyr de Souza
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
@@ -104,19 +104,20 @@ files:
|
|
104
104
|
- lib/balboa/interactor/command/fill_punch_command.rb
|
105
105
|
- lib/balboa/interactor/command/login_command.rb
|
106
106
|
- lib/balboa/interactor/interactor_builder.rb
|
107
|
-
- lib/balboa/interactor/interactor_wrapper.rb
|
108
107
|
- lib/balboa/punch_date.rb
|
108
|
+
- lib/balboa/schedule.rb
|
109
109
|
- lib/balboa/version.rb
|
110
|
-
- spec/balboa/capybara_interactor_spec.rb
|
111
110
|
- spec/balboa/cli/application_spec.rb
|
112
111
|
- spec/balboa/cli/command/last_command_spec.rb
|
112
|
+
- spec/balboa/cli/command/punch_command_spec.rb
|
113
113
|
- spec/balboa/cli/command/reset_command_spec.rb
|
114
114
|
- spec/balboa/cli/command/star_wars_command_spec.rb
|
115
115
|
- spec/balboa/cli/defaults_spec.rb
|
116
116
|
- spec/balboa/cli/parser_spec.rb
|
117
|
+
- spec/balboa/interactor/capybara_interactor_spec.rb
|
117
118
|
- spec/balboa/interactor/interactor_builder_spec.rb
|
118
|
-
- spec/balboa/interactor/interactor_wrapper_spec.rb
|
119
119
|
- spec/balboa/punch_date_spec.rb
|
120
|
+
- spec/balboa/schedule_spec.rb
|
120
121
|
- spec/balboa_spec.rb
|
121
122
|
- spec/fixtures/file.yml
|
122
123
|
- spec/spec_helper.rb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Balboa
|
4
|
-
module Interactor
|
5
|
-
class InteractorWrapper
|
6
|
-
def initialize(interactor)
|
7
|
-
@interactor = interactor
|
8
|
-
end
|
9
|
-
|
10
|
-
def punch(date)
|
11
|
-
@interactor.punch(date)
|
12
|
-
end
|
13
|
-
|
14
|
-
def last
|
15
|
-
@interactor.last
|
16
|
-
end
|
17
|
-
|
18
|
-
def options
|
19
|
-
@interactor.options
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Balboa::Interactor::InteractorWrapper do
|
6
|
-
it 'forwards punch call to its dependency' do
|
7
|
-
today = Date.today
|
8
|
-
|
9
|
-
interactor = double
|
10
|
-
allow(interactor).to receive(:punch).with(today)
|
11
|
-
|
12
|
-
described_class.new(interactor).punch(today)
|
13
|
-
|
14
|
-
expect(interactor).to have_received(:punch).with(today).once
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'forwards last call to its dependency' do
|
18
|
-
interactor = double
|
19
|
-
allow(interactor).to receive(:last)
|
20
|
-
|
21
|
-
described_class.new(interactor).last
|
22
|
-
|
23
|
-
expect(interactor).to have_received(:last).once
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'forwards options call to its dependency' do
|
27
|
-
interactor = double
|
28
|
-
allow(interactor).to receive(:options)
|
29
|
-
|
30
|
-
described_class.new(interactor).options
|
31
|
-
|
32
|
-
expect(interactor).to have_received(:options).once
|
33
|
-
end
|
34
|
-
end
|