fixman 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,12 @@
1
+ module Fixman
2
+ class TaskParseError < Exception
3
+ def initialize message, task_index
4
+ @message = message
5
+ @task_index = task_index
6
+ end
7
+
8
+ def message
9
+ "Task##{@task_index + 1}: #{@message}"
10
+ end
11
+ end
12
+ 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,8 @@
1
+ module Fixman
2
+ module Utilities
3
+ def error message, exit_code = 1
4
+ STDERR.puts message
5
+ exit exit_code
6
+ end
7
+ end
8
+ 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
@@ -0,0 +1,7 @@
1
+ require 'test_configuration'
2
+ require 'test_command_line'
3
+ require 'test_controller'
4
+ require 'test_raw_task'
5
+ require 'test_repository'
6
+ require 'test_task'
7
+ require 'test_tester'