local_ci 0.0.5 → 0.0.6

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.
@@ -1,171 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe LocalCI::Job do
4
- before do
5
- @output = double(:output)
6
- allow(@output).to receive(:update)
7
-
8
- @flow = LocalCI::Flow.new(
9
- name: "flow",
10
- heading: "heading",
11
- parallel: true,
12
- block: -> {}
13
- )
14
- allow(@flow).to receive(:output).and_return(@output)
15
- end
16
-
17
- describe "#initialize" do
18
- it "creates a new job with the right arguments" do
19
- job = LocalCI::Job.new(
20
- flow: @flow,
21
- name: "The Job Name!",
22
- command: "command",
23
- block: "block"
24
- )
25
-
26
- expect(job.flow).to eq(@flow)
27
- expect(job.name).to eq("The Job Name!")
28
- expect(job.command).to eq("command")
29
- expect(job.block).to eq("block")
30
- expect(job.task).to eq("ci:flow:jobs:the_job_name")
31
- expect(job.state).to eq(:waiting)
32
- end
33
-
34
- context "when passed no block or command" do
35
- it "raises an error" do
36
- expect do
37
- LocalCI::Job.new(
38
- flow: @flow,
39
- name: "name",
40
- command: nil,
41
- block: nil
42
- )
43
- end.to raise_error(ArgumentError, "Must specify a block or command")
44
- end
45
- end
46
-
47
- it "defines a rake task" do
48
- LocalCI::Job.new(
49
- flow: @flow,
50
- name: "The Job Name!",
51
- command: "command",
52
- block: "block"
53
- )
54
-
55
- expect(Rake::Task.task_defined?("ci:flow:jobs:the_job_name")).to be(true)
56
- end
57
-
58
- it "gives the rake task the right prerequisite" do
59
- LocalCI::Job.new(
60
- flow: @flow,
61
- name: "The Job Name!",
62
- command: "command",
63
- block: "block"
64
- )
65
-
66
- expect(Rake::Task["ci:flow:jobs"].prerequisites).to include("ci:flow:jobs:the_job_name")
67
- end
68
- end
69
-
70
- describe "task" do
71
- context "when running a block" do
72
- it "runs all the commands from the block" do
73
- expect(LocalCI::Helper.runner).to receive(:run).with("command 1")
74
- expect(LocalCI::Helper.runner).to receive(:run).with("command", "2")
75
-
76
- LocalCI::Job.new(
77
- flow: @flow,
78
- name: "block task",
79
- command: nil,
80
- block: -> {
81
- run "command 1"
82
- run "command", "2"
83
- }
84
- )
85
-
86
- ::Rake::Task["ci:flow:jobs:block_task"].invoke
87
- end
88
-
89
- it "sets the state" do
90
- job = LocalCI::Job.new(
91
- flow: @flow,
92
- name: "block task",
93
- command: nil,
94
- block: -> {}
95
- )
96
-
97
- ::Rake::Task["ci:flow:jobs:block_task"].invoke
98
-
99
- expect(job.state).to eq(:success)
100
- end
101
-
102
- it "updates the output" do
103
- job = LocalCI::Job.new(
104
- flow: @flow,
105
- name: "block task",
106
- command: nil,
107
- block: -> {}
108
- )
109
- expect(@output).to receive(:update).with(job)
110
-
111
- ::Rake::Task["ci:flow:jobs:block_task"].invoke
112
- end
113
- end
114
-
115
- context "when running one command inline" do
116
- it "runs the commands" do
117
- expect(LocalCI::Helper.runner).to receive(:run).with("command", "by", "argument")
118
-
119
- LocalCI::Job.new(
120
- flow: @flow,
121
- name: "command task",
122
- command: ["command", "by", "argument"],
123
- block: nil
124
- )
125
- ::Rake::Task["ci:flow:jobs:command_task"].invoke
126
- end
127
- end
128
-
129
- context "when the job fails" do
130
- before do
131
- @job = LocalCI::Job.new(
132
- flow: @flow,
133
- name: "Raises an Error",
134
- command: "exit 1",
135
- block: nil
136
- )
137
- end
138
-
139
- it "is recorded against the flow" do
140
- expect(LocalCI::Helper.runner).to receive(:run).with("exit 1")
141
- .and_raise(
142
- TTY::Command::ExitError.new(
143
- "exit 1",
144
- double(
145
- exit_status: 1,
146
- err: "oops!",
147
- out: ""
148
- )
149
- )
150
- )
151
-
152
- ::Rake::Task["ci:flow:jobs:raises_an_error"].invoke
153
-
154
- expect(@flow.failures.size).to eq(1)
155
- expect(@flow.failures.first.job).to eq("Raises an Error")
156
- end
157
-
158
- it "sets the state" do
159
- ::Rake::Task["ci:flow:jobs:raises_an_error"].invoke
160
-
161
- expect(@job.state).to eq(:failed)
162
- end
163
-
164
- it "updates the output" do
165
- expect(@output).to receive(:update).with(@job)
166
-
167
- ::Rake::Task["ci:flow:jobs:raises_an_error"].invoke
168
- end
169
- end
170
- end
171
- end
@@ -1,413 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe LocalCI::Output do
4
- before do
5
- @job = double(:job)
6
- @flow = double(:flow, jobs: [])
7
- @thread = double(:thread, alive?: true)
8
- allow(@thread).to receive(:join)
9
-
10
- @output = LocalCI::Output.new(flow: @flow)
11
- @output.instance_variable_set(:@thread, @thread)
12
- end
13
-
14
- describe "#update" do
15
- before do
16
- allow(@output).to receive(:output)
17
- allow(@output).to receive(:json_output)
18
- end
19
-
20
- context "when we are not in a TTY" do
21
- before do
22
- expect(@output).to receive(:tty?).and_return(false)
23
- end
24
-
25
- it "sets the job" do
26
- @output.update(@job)
27
- expect(@output.job).to eq(@job)
28
- end
29
-
30
- it "calls json_output" do
31
- expect(@output).to receive(:json_output)
32
- @output.update(@job)
33
- end
34
- end
35
-
36
- context "when we are in a TTY" do
37
- before do
38
- allow(@output).to receive(:tty?).and_return(true)
39
- end
40
-
41
- context "when all jobs are done" do
42
- before do
43
- allow(@output).to receive(:done?).and_return(true)
44
- end
45
-
46
- it "calls finish" do
47
- expect(@output).to receive(:finish)
48
- @output.update(@job)
49
- end
50
-
51
- it "does not call start_thread" do
52
- expect(@output).not_to receive(:start_thread)
53
- @output.update(@job)
54
- end
55
- end
56
-
57
- context "the thread is alive" do
58
- before do
59
- allow(@output).to receive(:done?).and_return(false)
60
- end
61
-
62
- it "does not call finish" do
63
- expect(@output).not_to receive(:finish)
64
- @output.update(@job)
65
- end
66
-
67
- it "does not call start_thread" do
68
- expect(@output).not_to receive(:start_thread)
69
- @output.update(@job)
70
- end
71
- end
72
-
73
- context "the thread is not alive" do
74
- before do
75
- allow(@output).to receive(:done?).and_return(false)
76
- allow(@thread).to receive(:alive?).and_return(false)
77
- end
78
-
79
- it "starts the thread" do
80
- expect(@output).to receive(:start_thread)
81
-
82
- @output.update(@job)
83
- end
84
- end
85
- end
86
- end
87
-
88
- describe "#failures" do
89
- before do
90
- allow(@flow).to receive(:failures).and_return(
91
- [
92
- double(:failure, job: "job-1", message: "message-1"),
93
- double(:failure, job: "job-2", message: "message-2")
94
- ]
95
- )
96
- end
97
-
98
- context "when we are in a TTY" do
99
- it "displays the errors" do
100
- expect(@output).to receive(:tty?).and_return(true)
101
-
102
- expect(@output).to receive(:puts).with(/job-1\nmessage-1/)
103
- expect(@output).to receive(:puts).with(/job-2\nmessage-2/)
104
-
105
- @output.failures
106
- end
107
- end
108
-
109
- context "when we are not in a TTY" do
110
- it "does nothing" do
111
- expect(@output).to receive(:tty?).and_return(false)
112
-
113
- expect(@output).not_to receive(:puts)
114
-
115
- @output.failures
116
- end
117
- end
118
- end
119
-
120
- describe "#draw" do
121
- before do
122
- allow(@output).to receive(:print)
123
- allow(@output).to receive(:puts)
124
- allow(@output).to receive(:heading_line).and_return("heading-line")
125
- allow(@output).to receive(:job_line).and_return("job-line")
126
- allow(@output).to receive(:footer_line).and_return("footer-line")
127
-
128
- allow(@flow).to receive(:jobs).and_return(["job-1", "job-2"])
129
- end
130
-
131
- context "on first paint for the flow" do
132
- before do
133
- @output.instance_variable_set(:@first_paint, true)
134
- end
135
-
136
- it "does not clear lines" do
137
- expect(TTY::Cursor).not_to receive(:clear_line)
138
- expect(TTY::Cursor).not_to receive(:up)
139
-
140
- @output.draw
141
- end
142
-
143
- it "sets the start time" do
144
- expect(Time).to receive(:now).and_return("time")
145
-
146
- @output.draw
147
-
148
- expect(@output.instance_variable_get(:@start)).to eq("time")
149
- end
150
- end
151
-
152
- context "on subsequent paints" do
153
- before do
154
- @output.instance_variable_set(:@first_paint, false)
155
-
156
- allow(TTY::Cursor).to receive(:clear_line).and_return("")
157
- allow(TTY::Cursor).to receive(:up).and_return("")
158
- allow(@output).to receive(:print)
159
- end
160
-
161
- it "moves up and clears the line" do
162
- expect(TTY::Cursor).to receive(:clear_line).and_return("clear-line")
163
- expect(TTY::Cursor).to receive(:up).with(4).and_return("up")
164
-
165
- expect(@output).to receive(:print).with("clear-lineup")
166
-
167
- @output.draw
168
- end
169
- end
170
-
171
- it "paints the heading" do
172
- expect(@output).to receive(:heading_line).and_return("heading-line")
173
-
174
- expect(@output).to receive(:puts).with("heading-line")
175
-
176
- @output.draw
177
- end
178
-
179
- it "paints the jobs" do
180
- expect(@output).to receive(:job_line).with("job-1").and_return("job-line-1")
181
- expect(@output).to receive(:job_line).with("job-2").and_return("job-line-2")
182
-
183
- expect(@output).to receive(:puts).with("job-line-1")
184
- expect(@output).to receive(:puts).with("job-line-2")
185
-
186
- @output.draw
187
- end
188
-
189
- it "paints the footer" do
190
- expect(@output).to receive(:footer_line).and_return("footer-line")
191
-
192
- expect(@output).to receive(:puts).with("footer-line")
193
-
194
- @output.draw
195
- end
196
-
197
- context "when final is true" do
198
- it "draws an extra new line" do
199
- expect(@output).to receive(:puts).with(no_args)
200
-
201
- @output.draw(final: true)
202
- end
203
- end
204
- end
205
-
206
- describe "#color" do
207
- before do
208
- @pastel = double(:pastel)
209
- allow(@output).to receive(:pastel).and_return(@pastel)
210
- end
211
-
212
- context "when the flow is running" do
213
- it "returns blue" do
214
- expect(@output).to receive(:passed?).and_return(false)
215
- expect(@output).to receive(:failed?).and_return(false)
216
-
217
- expect(@pastel).to receive(:blue).with("message")
218
-
219
- @output.color("message")
220
- end
221
- end
222
-
223
- context "when the flow has passed" do
224
- it "returns blue" do
225
- expect(@output).to receive(:passed?).and_return(true)
226
-
227
- expect(@pastel).to receive(:green).with("message")
228
-
229
- @output.color("message")
230
- end
231
- end
232
-
233
- context "when the flow has failed" do
234
- it "returns blue" do
235
- expect(@output).to receive(:passed?).and_return(false)
236
- expect(@output).to receive(:failed?).and_return(true)
237
-
238
- expect(@pastel).to receive(:red).with("message")
239
-
240
- @output.color("message")
241
- end
242
- end
243
- end
244
-
245
- describe "#heading_line" do
246
- before do
247
- allow(@flow).to receive(:heading).and_return("flow-heading")
248
- allow(@output).to receive(:screen).and_return(double(width: 40))
249
- @pastel = Pastel.new
250
- end
251
-
252
- it "returns a heading the width of the terminal" do
253
- expect(@pastel.strip(@output.heading_line)).to eq(
254
- "===| flow-heading |====================="
255
- )
256
- end
257
-
258
- context "when the heading is too long" do
259
- it "truncates it with an ellipsis" do
260
- allow(@flow).to receive(:heading).and_return("Some really long heading that really probably shouldn't be this long but is I guess")
261
- expect(@pastel.strip(@output.heading_line)).to eq(
262
- "===| Some really long heading that… |==="
263
- )
264
- end
265
- end
266
-
267
- context "when the heading is just short enough" do
268
- it "does not truncate" do
269
- allow(@flow).to receive(:heading).and_return("Something long, but not silly!")
270
-
271
- expect(@pastel.strip(@output.heading_line)).to eq(
272
- "===| Something long, but not silly! |==="
273
- )
274
- end
275
- end
276
- end
277
-
278
- describe "#job_line" do
279
- before do
280
- @pastel = Pastel.new
281
-
282
- @job = double(:job, name: "job-name")
283
- allow(@job).to receive(:waiting?).and_return(false)
284
- allow(@job).to receive(:running?).and_return(false)
285
- allow(@job).to receive(:success?).and_return(false)
286
- allow(@job).to receive(:failed?).and_return(false)
287
-
288
- allow(@output).to receive_message_chain(:cursor, :clear_line).and_return("")
289
- allow(@output).to receive(:screen).and_return(double(width: 20))
290
- end
291
-
292
- context "when the job is waiting" do
293
- it "returns no indicator and the job name" do
294
- expect(@job).to receive(:waiting?).and_return(true)
295
- expect(@pastel.strip(@output.job_line(@job))).to eq("[ ] job-name")
296
- end
297
- end
298
-
299
- context "when the job is running" do
300
- it "returns an indicator and the job name" do
301
- expect(@job).to receive(:running?).and_return(true)
302
- expect(@pastel.strip(@output.job_line(@job))).to eq("[-] job-name")
303
- end
304
- end
305
-
306
- context "when the job was successful" do
307
- it "returns an indicator and the job name" do
308
- expect(@job).to receive(:success?).and_return(true)
309
- expect(@pastel.strip(@output.job_line(@job))).to eq("[✓] job-name")
310
- end
311
- end
312
-
313
- context "when the job failed" do
314
- it "returns an indicator and the job name" do
315
- expect(@job).to receive(:failed?).and_return(true)
316
- expect(@pastel.strip(@output.job_line(@job))).to eq("[✗] job-name")
317
- end
318
- end
319
-
320
- context "when the name is too long" do
321
- it "truncates it with an ellipsis" do
322
- allow(@job).to receive(:waiting?).and_return(true)
323
- allow(@job).to receive(:name).and_return("A really long job name, obviously just way too long, what are you even doing!")
324
-
325
- expect(@pastel.strip(@output.job_line(@job))).to eq(
326
- "[ ] A really long jo…"
327
- )
328
- end
329
- end
330
-
331
- context "when the name is just short enough" do
332
- it "does not truncate" do
333
- allow(@job).to receive(:waiting?).and_return(true)
334
- allow(@job).to receive(:name).and_return("A long job name!!")
335
-
336
- expect(@pastel.strip(@output.job_line(@job))).to eq(
337
- "[ ] A long job name!!"
338
- )
339
- end
340
- end
341
- end
342
-
343
- describe "#footer_line" do
344
- before do
345
- allow(@output).to receive(:screen).and_return(double(width: 20))
346
- allow(@output).to receive(:duration).and_return("duration")
347
- @pastel = Pastel.new
348
- end
349
-
350
- it "returns a footer the length of the terminal with the duration" do
351
- expect(@pastel.strip(@output.footer_line)).to eq(
352
- "-------(duration)---"
353
- )
354
- end
355
- end
356
-
357
- describe "#duration" do
358
- context "when less than 60 seconds" do
359
- it "shows seconds with two decimal places" do
360
- @output.instance_variable_set(:@start, 5.567)
361
- allow(Time).to receive(:now).and_return(45)
362
-
363
- expect(@output.duration).to eq("39.43s")
364
- end
365
-
366
- it "shows seconds with two decimal places even if it's exactly a second" do
367
- @output.instance_variable_set(:@start, 5.0)
368
- allow(Time).to receive(:now).and_return(45)
369
-
370
- expect(@output.duration).to eq("40.00s")
371
- end
372
- end
373
-
374
- context "when less than 60 minutes" do
375
- it "shows the minutes and seconds" do
376
- @output.instance_variable_set(:@start, 10)
377
- allow(Time).to receive(:now).and_return(1240.1)
378
-
379
- expect(@output.duration).to eq("20m 30s")
380
- end
381
- end
382
-
383
- context "when greater than 60 minutes" do
384
- it "shows the hours and minutes" do
385
- @output.instance_variable_set(:@start, 10)
386
- allow(Time).to receive(:now).and_return(3800.1)
387
-
388
- expect(@output.duration).to eq("1h 3m")
389
- end
390
- end
391
- end
392
-
393
- describe "#json_output" do
394
- it "returns the state as json" do
395
- allow(@flow).to receive(:heading).and_return("flow-heading")
396
- @output.instance_variable_set(:@job, double(
397
- :job,
398
- name: "job-name",
399
- duration: "job-duration",
400
- state: "job-state"
401
- ))
402
-
403
- expect(@output).to receive(:puts).with({
404
- flow: "flow-heading",
405
- job: "job-name",
406
- duration: "job-duration",
407
- state: "job-state"
408
- }.to_json)
409
-
410
- @output.json_output
411
- end
412
- end
413
- end
@@ -1,16 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe LocalCI::Rake do
4
- describe ".setup" do
5
- before do
6
- @klass = double(:klass)
7
- allow(@klass).to receive(:send)
8
- end
9
-
10
- it "includes the DSL" do
11
- expect(@klass).to receive(:send).with(:include, LocalCI::DSL)
12
-
13
- LocalCI::Rake.setup(@klass)
14
- end
15
- end
16
- end
@@ -1,114 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe LocalCI::Task do
4
- describe "#initialize" do
5
- context "with parallel preqresuites" do
6
- it "creates a MultiTask" do
7
- expect(::Rake::MultiTask).to receive(:[]).with("task")
8
-
9
- LocalCI::Task.new("task", parallel_prerequisites: true)
10
- end
11
-
12
- context "with a comment" do
13
- it "sets the comment" do
14
- task = double(:task)
15
- allow(::Rake::MultiTask).to receive(:[]).and_return(task)
16
- expect(task).to receive(:comment=).with("comment")
17
-
18
- LocalCI::Task.new("task", comment: "comment", parallel_prerequisites: true)
19
- end
20
- end
21
-
22
- context "without a comment" do
23
- it "does not set the comment" do
24
- task = double(:task)
25
- allow(::Rake::MultiTask).to receive(:[]).and_return(task)
26
- expect(task).not_to receive(:comment=)
27
-
28
- LocalCI::Task.new("task", parallel_prerequisites: true)
29
- end
30
- end
31
- end
32
-
33
- context "with sequential preqresuites" do
34
- it "creates a Task" do
35
- expect(::Rake::Task).to receive(:[]).with("task")
36
-
37
- LocalCI::Task.new("task", parallel_prerequisites: false)
38
- end
39
-
40
- context "with a comment" do
41
- it "sets the comment" do
42
- task = double(:task)
43
- allow(::Rake::Task).to receive(:[]).and_return(task)
44
- expect(task).to receive(:comment=).with("comment")
45
-
46
- LocalCI::Task.new("task", comment: "comment", parallel_prerequisites: false)
47
- end
48
- end
49
-
50
- context "without a comment" do
51
- it "does not set the comment" do
52
- task = double(:task)
53
- allow(::Rake::Task).to receive(:[]).and_return(task)
54
- expect(task).not_to receive(:comment=)
55
-
56
- LocalCI::Task.new("task", parallel_prerequisites: false)
57
- end
58
- end
59
- end
60
- end
61
-
62
- describe ".[]" do
63
- it "creates a LocalCI::Task" do
64
- expect(LocalCI::Task).to receive(:new).with(
65
- "task",
66
- comment: "comment"
67
- )
68
-
69
- LocalCI::Task["task", "comment"]
70
- end
71
- end
72
-
73
- describe "#add_prerequisite" do
74
- before do
75
- @task = LocalCI::Task.new("task", parallel_prerequisites: true)
76
- end
77
-
78
- it "adds the prerequisite" do
79
- expect(@task.prerequisites).to receive(:<<).with("prereq")
80
-
81
- @task.add_prerequisite("prereq")
82
- end
83
-
84
- context "When it already has that prerequisite" do
85
- it "doesn't add it again" do
86
- expect(@task.prerequisites).not_to receive(:<<)
87
- expect(@task).to receive(:prerequisites).and_return(["prereq"])
88
-
89
- @task.add_prerequisite("prereq")
90
- end
91
- end
92
- end
93
-
94
- describe "#define" do
95
- before do
96
- @task = LocalCI::Task.new("task", parallel_prerequisites: true)
97
- end
98
-
99
- it "calls define_task" do
100
- expect(::Rake::Task).to receive(:define_task).with("task")
101
-
102
- @task.define {}
103
- end
104
-
105
- it "uses the passed in block as the task body" do
106
- @block_run = false
107
-
108
- @task.define { @block_run = true }
109
-
110
- @task.invoke
111
- expect(@block_run).to be(true)
112
- end
113
- end
114
- end