fixman 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/History.txt +6 -0
- data/Manifest.txt +23 -0
- data/README.md +176 -0
- data/Rakefile +19 -0
- data/bin/fixman +50 -0
- data/lib/fixman.rb +13 -0
- data/lib/fixman/command_line.rb +184 -0
- data/lib/fixman/configuration.rb +161 -0
- data/lib/fixman/controller.rb +121 -0
- data/lib/fixman/raw_task.rb +103 -0
- data/lib/fixman/repository.rb +99 -0
- data/lib/fixman/task.rb +19 -0
- data/lib/fixman/task_parse_error.rb +12 -0
- data/lib/fixman/tester.rb +69 -0
- data/lib/fixman/utilities.rb +8 -0
- data/test/test_command_line.rb +250 -0
- data/test/test_configuration.rb +58 -0
- data/test/test_controller.rb +16 -0
- data/test/test_fixman.rb +7 -0
- data/test/test_raw_task.rb +97 -0
- data/test/test_repository.rb +21 -0
- data/test/test_task.rb +28 -0
- data/test/test_tester.rb +89 -0
- metadata +163 -0
data/lib/fixman/task.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fixman
|
2
|
+
class Task
|
3
|
+
attr_reader :name, :condition
|
4
|
+
|
5
|
+
def initialize(name, condition, command, cleanup)
|
6
|
+
@name = name
|
7
|
+
@condition = condition
|
8
|
+
@command = command
|
9
|
+
@cleanup = cleanup
|
10
|
+
end
|
11
|
+
|
12
|
+
def run target
|
13
|
+
success = @command.call(target)
|
14
|
+
@cleanup.call(target)
|
15
|
+
|
16
|
+
success
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'English'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Fixman
|
5
|
+
class Tester
|
6
|
+
TERMINAL_WIDTH = 80
|
7
|
+
|
8
|
+
def initialize(configuration)
|
9
|
+
@conf = configuration
|
10
|
+
@target_cache = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def test
|
14
|
+
@conf.raw_tasks.each do |raw_task|
|
15
|
+
raw_task.refine.each do |task|
|
16
|
+
puts(test_task task)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def test_task task
|
24
|
+
puts "Collecting targets for #{task.name}..."
|
25
|
+
targets = collect task.condition
|
26
|
+
failures = []
|
27
|
+
puts "Running the #{task.name} on targets..."
|
28
|
+
targets.each do |target|
|
29
|
+
failures << target unless task.run target
|
30
|
+
end
|
31
|
+
report task.name, targets, failures
|
32
|
+
end
|
33
|
+
|
34
|
+
def collect(condition)
|
35
|
+
if @target_cache[condition]
|
36
|
+
@target_cache[condition]
|
37
|
+
else
|
38
|
+
targets = []
|
39
|
+
places_to_search = [@conf.fixtures_base]
|
40
|
+
places_to_search.each do |place|
|
41
|
+
# exclude symbolic links to avoid cycles
|
42
|
+
place.each_child do |child|
|
43
|
+
next if child.symlink?
|
44
|
+
targets << child if condition.call(child)
|
45
|
+
places_to_search << child if child.directory?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
@target_cache[condition] = targets
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def report(name, targets, failures)
|
53
|
+
n_of_targets = targets.size
|
54
|
+
n_of_successes = n_of_targets - failures.size
|
55
|
+
|
56
|
+
sio = StringIO.new
|
57
|
+
sio.puts "#{name} (#{n_of_successes}/#{n_of_targets})"
|
58
|
+
sio.puts '-' * TERMINAL_WIDTH
|
59
|
+
if n_of_successes == n_of_targets
|
60
|
+
sio.puts 'All targets ran as expected.'
|
61
|
+
else
|
62
|
+
sio.puts "Failing targets:"
|
63
|
+
sio.puts failures.sort
|
64
|
+
end
|
65
|
+
sio.puts
|
66
|
+
sio.string
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
require 'fixman'
|
2
|
+
require 'minitest'
|
3
|
+
|
4
|
+
class TestCommandLine < Minitest::Test
|
5
|
+
extend Fixman::CommandLine
|
6
|
+
|
7
|
+
@@desired_input_index = 0
|
8
|
+
|
9
|
+
def test_parse_normal_options
|
10
|
+
options = TestCommandLine.parse_options! ['-c', 'my_conf.yaml']
|
11
|
+
assert_equal Pathname.new('my_conf.yaml'), options[:conf_path]
|
12
|
+
|
13
|
+
options = TestCommandLine.parse_options! []
|
14
|
+
assert_equal Pathname.new(Fixman::Configuration::DEFAULT_CONF_FILE),
|
15
|
+
options[:conf_path]
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_parse_option_leaves_positional
|
19
|
+
args = %w(hey -c mey yey -c key)
|
20
|
+
TestCommandLine.parse_options! args
|
21
|
+
assert_equal %w(hey yey), args
|
22
|
+
|
23
|
+
args = %w(hey)
|
24
|
+
TestCommandLine.parse_options! args
|
25
|
+
assert_equal %w(hey), args
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_parse_normal_potisional
|
29
|
+
args = %w(add)
|
30
|
+
command, other_args = TestCommandLine.parse_positional_arguments!(args)
|
31
|
+
assert_equal [], args
|
32
|
+
assert_equal :add, command
|
33
|
+
assert_equal({}, other_args)
|
34
|
+
|
35
|
+
args = %w(update user/name)
|
36
|
+
command, other_args = TestCommandLine.parse_positional_arguments!(args)
|
37
|
+
assert_equal [], args
|
38
|
+
assert_equal :update, command
|
39
|
+
assert_equal({canonical_name: 'user/name', sha: nil}, other_args)
|
40
|
+
|
41
|
+
args = %w(uPdaTe uSEr/name someSHA)
|
42
|
+
command, other_args = TestCommandLine.parse_positional_arguments!(args)
|
43
|
+
assert_equal [], args
|
44
|
+
assert_equal :update, command
|
45
|
+
assert_equal({canonical_name: 'uSEr/name', sha: 'someSHA'}, other_args)
|
46
|
+
|
47
|
+
args = %w(fetch groupA groupB groupC)
|
48
|
+
command, other_args = TestCommandLine.parse_positional_arguments!(args)
|
49
|
+
assert_equal [], args
|
50
|
+
assert_equal :fetch, command
|
51
|
+
assert_equal({groups: [:groupa, :groupb, :groupc]}, other_args)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_start_session_optional
|
55
|
+
input = {}
|
56
|
+
template = { symbol: :test, prompt: 'Test prompt', label: '', type: :optional }
|
57
|
+
change_get_input "test value" do
|
58
|
+
assert_output(template[:prompt]) do
|
59
|
+
TestCommandLine.send(:start_session, input, template)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
expected_input = { test: 'test value' }
|
63
|
+
assert_equal(expected_input, input)
|
64
|
+
|
65
|
+
template = { symbol: :test2, prompt: 'Another prompt', label: ''}
|
66
|
+
change_get_input "test value2" do
|
67
|
+
assert_output(template[:prompt]) do
|
68
|
+
TestCommandLine.send(:start_session, input, template)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
expected_input[:test2] = 'test value2'
|
72
|
+
assert_equal(expected_input, input)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_start_session_mandatory
|
76
|
+
input = {}
|
77
|
+
template = {
|
78
|
+
symbol: :test,
|
79
|
+
prompt: 'Test prompt',
|
80
|
+
label: '',
|
81
|
+
type: :mandatory
|
82
|
+
}
|
83
|
+
change_get_input "TEST value" do
|
84
|
+
assert_output(template[:prompt]) do
|
85
|
+
TestCommandLine.send(:start_session, input, template)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
expected_input = { test: 'TEST value' }
|
89
|
+
assert_equal(expected_input, input)
|
90
|
+
|
91
|
+
input = {}
|
92
|
+
change_get_input [' ', '', 'TEST value'] do
|
93
|
+
assert_output(template[:prompt] * 3) do
|
94
|
+
TestCommandLine.send(:start_session, input, template)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
expected_input = { test: 'TEST value' }
|
98
|
+
assert_equal(expected_input, input)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_start_session_single_choice
|
102
|
+
input = {}
|
103
|
+
template = {
|
104
|
+
symbol: :test,
|
105
|
+
prompt: 'Test prompt',
|
106
|
+
label: '',
|
107
|
+
type: :single_choice,
|
108
|
+
choices: %w(1 2 3 4)
|
109
|
+
}
|
110
|
+
change_get_input "2" do
|
111
|
+
assert_output(%r|1/2/3|) do
|
112
|
+
TestCommandLine.send(:start_session, input, template)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
expected_input = { test: '2' }
|
116
|
+
assert_equal(expected_input, input)
|
117
|
+
|
118
|
+
input = {}
|
119
|
+
change_get_input [' ', '5', '3'] do
|
120
|
+
assert_output(%r|1/2/3/4.*1/2/3/4|m) do
|
121
|
+
TestCommandLine.send(:start_session, input, template)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
expected_input = { test: '3' }
|
125
|
+
assert_equal(expected_input, input)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_start_session_multiple_choice
|
129
|
+
input = {}
|
130
|
+
template = {
|
131
|
+
symbol: :test,
|
132
|
+
prompt: 'Test prompt',
|
133
|
+
label: '',
|
134
|
+
type: :multiple_choice,
|
135
|
+
choices: %w(RUby pytHOn elixir)
|
136
|
+
}
|
137
|
+
change_get_input "pytHOn" do
|
138
|
+
assert_output(%r|RUby/pytHOn/elixir|) do
|
139
|
+
TestCommandLine.send(:start_session, input, template)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
expected_input = { test: ['pytHOn'] }
|
143
|
+
assert_equal(expected_input, input)
|
144
|
+
|
145
|
+
input = {}
|
146
|
+
change_get_input [' ', '5,RUby', 'elixir,pytHOn'] do
|
147
|
+
assert_output(%r|RUby.*RUby|m) do
|
148
|
+
TestCommandLine.send(:start_session, input, template)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
expected_input = { test: ['elixir', 'pytHOn'] }
|
152
|
+
assert_equal(expected_input, input)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_get_params
|
156
|
+
extra_templates = [
|
157
|
+
{
|
158
|
+
symbol: :notes,
|
159
|
+
prompt: 'Notes',
|
160
|
+
label: 'Notes',
|
161
|
+
type: :optional
|
162
|
+
},
|
163
|
+
{
|
164
|
+
symbol: :licence,
|
165
|
+
prompt: 'Licence',
|
166
|
+
label: 'Licence',
|
167
|
+
type: :single_choice,
|
168
|
+
choices: ['MIT', 'Apache']
|
169
|
+
}
|
170
|
+
]
|
171
|
+
|
172
|
+
inputs = [
|
173
|
+
'https://github.com/madgen/fixman',
|
174
|
+
'a , b, c',
|
175
|
+
'It is good to take notes',
|
176
|
+
'apache'
|
177
|
+
]
|
178
|
+
params = []
|
179
|
+
expected_sha = 'fake SHA'
|
180
|
+
assert_output(/URL.*Notes.*Licence.*Apache/m) do
|
181
|
+
params =
|
182
|
+
change_get_input inputs do
|
183
|
+
Fixman::Repository.stub(:retrieve_head_sha, expected_sha) do
|
184
|
+
TestCommandLine.get_params extra_templates, %w(d a e b c)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
assert_equal 'fixman', params[:name]
|
190
|
+
assert_equal 'madgen', params[:owner]
|
191
|
+
assert_equal inputs[0], params[:url]
|
192
|
+
assert_equal %w(a b c), params[:groups]
|
193
|
+
assert_equal inputs[2], params[:notes]
|
194
|
+
assert_equal 'Apache', params[:licence]
|
195
|
+
assert_equal expected_sha, params[:sha]
|
196
|
+
|
197
|
+
inputs = [
|
198
|
+
'https://bithub.com/madgen/fixman',
|
199
|
+
'fixman',
|
200
|
+
'madgen',
|
201
|
+
'a',
|
202
|
+
'It is good to take notes',
|
203
|
+
'mit'
|
204
|
+
]
|
205
|
+
assert_output(/URL.*Notes.*Licence.*Apache/m) do
|
206
|
+
params =
|
207
|
+
change_get_input inputs do
|
208
|
+
Fixman::Repository.stub(:retrieve_head_sha, expected_sha) do
|
209
|
+
TestCommandLine.get_params extra_templates, %w(d a e b c)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
assert_equal inputs[0], params[:url]
|
215
|
+
assert_equal inputs[1], params[:name]
|
216
|
+
assert_equal inputs[2], params[:owner]
|
217
|
+
assert_equal ['a'], params[:groups]
|
218
|
+
assert_equal inputs[4], params[:notes]
|
219
|
+
assert_equal 'MIT', params[:licence]
|
220
|
+
assert_equal expected_sha, params[:sha]
|
221
|
+
end
|
222
|
+
|
223
|
+
private
|
224
|
+
|
225
|
+
def change_get_input(desired_input)
|
226
|
+
TestCommandLine.instance_eval { undef :get_input }
|
227
|
+
TestCommandLine.define_singleton_method :get_input do
|
228
|
+
result =
|
229
|
+
if desired_input.is_a? String
|
230
|
+
desired_input
|
231
|
+
elsif desired_input.is_a? Array
|
232
|
+
desired_input[@@desired_input_index]
|
233
|
+
end
|
234
|
+
@@desired_input_index += 1
|
235
|
+
result
|
236
|
+
end
|
237
|
+
|
238
|
+
result = yield
|
239
|
+
|
240
|
+
TestCommandLine.instance_eval do
|
241
|
+
undef :get_input
|
242
|
+
@@desired_input_index = 0
|
243
|
+
end
|
244
|
+
TestCommandLine.define_singleton_method :get_input do
|
245
|
+
gets.chomp
|
246
|
+
end
|
247
|
+
|
248
|
+
result
|
249
|
+
end
|
250
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'fixman'
|
2
|
+
require 'minitest'
|
3
|
+
require 'classy_hash'
|
4
|
+
|
5
|
+
class TestConfiguration < Minitest::Test
|
6
|
+
def test_validate_minimal_conf
|
7
|
+
conf_params = {
|
8
|
+
fixtures_base: 'hello',
|
9
|
+
tasks: [
|
10
|
+
{
|
11
|
+
name: 'test_task',
|
12
|
+
command: {
|
13
|
+
action: 'wc',
|
14
|
+
}
|
15
|
+
}
|
16
|
+
],
|
17
|
+
}
|
18
|
+
|
19
|
+
assert_nil CH.validate(conf_params, Fixman::Configuration::CONF_SCHEMA)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_condition_schema_validation
|
23
|
+
schema = { condition: Fixman::Configuration::CONDITION_OR_CLEANUP_SCHEMA }
|
24
|
+
|
25
|
+
valid = {
|
26
|
+
condition: {
|
27
|
+
type: :ruby,
|
28
|
+
action: 'proc {}'
|
29
|
+
}
|
30
|
+
}
|
31
|
+
cond = valid[:condition]
|
32
|
+
assert_nil(CH.validate valid, schema)
|
33
|
+
|
34
|
+
cond[:type] = :shell
|
35
|
+
cond[:action] = 'wc'
|
36
|
+
assert_nil(CH.validate valid, schema)
|
37
|
+
|
38
|
+
cond.delete :type
|
39
|
+
assert_raises(RuntimeError) { CH.validate valid, schema }
|
40
|
+
|
41
|
+
cond[:type] = :something_else
|
42
|
+
assert_raises(RuntimeError) { CH.validate valid, schema }
|
43
|
+
|
44
|
+
cond[:type] = :ruby
|
45
|
+
cond[:action] = 'not a proc'
|
46
|
+
assert_raises(RuntimeError) { CH.validate valid, schema }
|
47
|
+
|
48
|
+
cond[:type] = :ruby
|
49
|
+
cond[:action] = 'proc {}'
|
50
|
+
cond[:exit_status] = 300
|
51
|
+
assert_nil CH.validate valid, schema
|
52
|
+
|
53
|
+
cond[:type] = :shell
|
54
|
+
cond[:action] = 'wc'
|
55
|
+
cond[:exit_status] = 300
|
56
|
+
assert_raises(RuntimeError) { CH.validate valid, schema }
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fixman'
|
2
|
+
require 'minitest'
|
3
|
+
require 'minitest/mock'
|
4
|
+
|
5
|
+
class TestController < Minitest::Test
|
6
|
+
|
7
|
+
def test_write_ledger
|
8
|
+
original_ledger = ""
|
9
|
+
repos = Minitest::Mock.new.expect(:map, ['abc','def'])
|
10
|
+
Tempfile.open 'location' do |t|
|
11
|
+
Fixman::Controller.send :write_ledger, repos, original_ledger, t.path
|
12
|
+
t.rewind
|
13
|
+
assert_equal "---\n- abc\n- def\n", t.read
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|