fixman 0.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.
@@ -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'