howzit 2.1.29 → 2.1.31
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +95 -0
- data/README.md +5 -1
- data/Rakefile +7 -1
- data/bin/howzit +5 -0
- data/lib/howzit/buildnote.rb +23 -1
- data/lib/howzit/config.rb +21 -0
- data/lib/howzit/console_logger.rb +62 -2
- data/lib/howzit/directive.rb +137 -0
- data/lib/howzit/script_support.rb +572 -0
- data/lib/howzit/stringutils.rb +47 -5
- data/lib/howzit/task.rb +57 -4
- data/lib/howzit/topic.rb +548 -5
- data/lib/howzit/version.rb +1 -1
- data/lib/howzit.rb +8 -1
- data/spec/buildnote_spec.rb +33 -4
- data/spec/log_level_spec.rb +247 -0
- data/spec/sequential_conditional_spec.rb +319 -0
- data/spec/set_var_spec.rb +603 -0
- data/spec/stringutils_spec.rb +41 -1
- data/spec/topic_spec.rb +8 -6
- data/src/_README.md +5 -1
- metadata +10 -2
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe '@set_var directive' do
|
|
6
|
+
before do
|
|
7
|
+
Howzit.options[:include_upstream] = false
|
|
8
|
+
Howzit.options[:default] = true
|
|
9
|
+
Howzit.options[:matching] = 'partial'
|
|
10
|
+
Howzit.options[:multiple_matches] = 'choose'
|
|
11
|
+
Howzit.options[:log_level] = 1
|
|
12
|
+
Howzit.options[:run] = true
|
|
13
|
+
Howzit.named_arguments = {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
after do
|
|
17
|
+
FileUtils.rm_f('builda.md')
|
|
18
|
+
Howzit.named_arguments = {}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe 'parsing @set_var directives' do
|
|
22
|
+
it 'parses @set_var directive with simple string value' do
|
|
23
|
+
note = <<~EONOTE
|
|
24
|
+
# Test
|
|
25
|
+
|
|
26
|
+
## Test Topic
|
|
27
|
+
|
|
28
|
+
@set_var(VERSION, "1.2.3")
|
|
29
|
+
EONOTE
|
|
30
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
31
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
32
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
33
|
+
|
|
34
|
+
expect(topic.directives).not_to be_nil
|
|
35
|
+
set_var_directive = topic.directives.find(&:set_var?)
|
|
36
|
+
expect(set_var_directive).not_to be_nil
|
|
37
|
+
expect(set_var_directive.var_name).to eq('VERSION')
|
|
38
|
+
expect(set_var_directive.var_value).to eq('1.2.3')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'parses @set_var directive with unquoted value' do
|
|
42
|
+
note = <<~EONOTE
|
|
43
|
+
# Test
|
|
44
|
+
|
|
45
|
+
## Test Topic
|
|
46
|
+
|
|
47
|
+
@set_var(STATUS, success)
|
|
48
|
+
EONOTE
|
|
49
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
50
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
51
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
52
|
+
|
|
53
|
+
set_var_directive = topic.directives.find(&:set_var?)
|
|
54
|
+
expect(set_var_directive).not_to be_nil
|
|
55
|
+
expect(set_var_directive.var_name).to eq('STATUS')
|
|
56
|
+
expect(set_var_directive.var_value).to eq('success')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'parses @set_var directive with value containing commas' do
|
|
60
|
+
note = <<~EONOTE
|
|
61
|
+
# Test
|
|
62
|
+
|
|
63
|
+
## Test Topic
|
|
64
|
+
|
|
65
|
+
@set_var(MESSAGE, Hello, world)
|
|
66
|
+
EONOTE
|
|
67
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
68
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
69
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
70
|
+
|
|
71
|
+
set_var_directive = topic.directives.find(&:set_var?)
|
|
72
|
+
expect(set_var_directive).not_to be_nil
|
|
73
|
+
expect(set_var_directive.var_name).to eq('MESSAGE')
|
|
74
|
+
expect(set_var_directive.var_value).to eq('Hello, world')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'parses @set_var directive with command substitution using backticks' do
|
|
78
|
+
note = <<~EONOTE
|
|
79
|
+
# Test
|
|
80
|
+
|
|
81
|
+
## Test Topic
|
|
82
|
+
|
|
83
|
+
@set_var(VERSION, `echo "1.2.3"`)
|
|
84
|
+
EONOTE
|
|
85
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
86
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
87
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
88
|
+
|
|
89
|
+
set_var_directive = topic.directives.find(&:set_var?)
|
|
90
|
+
expect(set_var_directive).not_to be_nil
|
|
91
|
+
expect(set_var_directive.var_name).to eq('VERSION')
|
|
92
|
+
expect(set_var_directive.var_value).to eq('`echo "1.2.3"`')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'parses @set_var directive with command substitution using $()' do
|
|
96
|
+
note = <<~EONOTE
|
|
97
|
+
# Test
|
|
98
|
+
|
|
99
|
+
## Test Topic
|
|
100
|
+
|
|
101
|
+
@set_var(DATE, $(date +%Y-%m-%d))
|
|
102
|
+
EONOTE
|
|
103
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
104
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
105
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
106
|
+
|
|
107
|
+
set_var_directive = topic.directives.find(&:set_var?)
|
|
108
|
+
expect(set_var_directive).not_to be_nil
|
|
109
|
+
expect(set_var_directive.var_name).to eq('DATE')
|
|
110
|
+
expect(set_var_directive.var_value).to eq('$(date +%Y-%m-%d)')
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'rejects invalid variable names with spaces' do
|
|
114
|
+
note = <<~EONOTE
|
|
115
|
+
# Test
|
|
116
|
+
|
|
117
|
+
## Test Topic
|
|
118
|
+
|
|
119
|
+
@set_var(INVALID NAME, value)
|
|
120
|
+
EONOTE
|
|
121
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
122
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
123
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
124
|
+
|
|
125
|
+
set_var_directive = topic.directives.find(&:set_var?)
|
|
126
|
+
expect(set_var_directive).to be_nil
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'accepts variable names with dashes and underscores' do
|
|
130
|
+
note = <<~EONOTE
|
|
131
|
+
# Test
|
|
132
|
+
|
|
133
|
+
## Test Topic
|
|
134
|
+
|
|
135
|
+
@set_var(MY-VAR_NAME, value)
|
|
136
|
+
EONOTE
|
|
137
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
138
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
139
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
140
|
+
|
|
141
|
+
set_var_directive = topic.directives.find(&:set_var?)
|
|
142
|
+
expect(set_var_directive).not_to be_nil
|
|
143
|
+
expect(set_var_directive.var_name).to eq('MY-VAR_NAME')
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
describe 'setting variables with @set_var' do
|
|
148
|
+
it 'sets a variable with a simple string value' do
|
|
149
|
+
note = <<~EONOTE
|
|
150
|
+
# Test
|
|
151
|
+
|
|
152
|
+
## Test Topic
|
|
153
|
+
|
|
154
|
+
@set_var(VERSION, "1.2.3")
|
|
155
|
+
@run(echo "Version is ${VERSION}")
|
|
156
|
+
EONOTE
|
|
157
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
158
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
159
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
160
|
+
|
|
161
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
162
|
+
|
|
163
|
+
output = []
|
|
164
|
+
allow_any_instance_of(Howzit::Task).to receive(:run).and_wrap_original do |method|
|
|
165
|
+
task = method.receiver
|
|
166
|
+
if task.action && task.action.include?('echo')
|
|
167
|
+
output << task.action
|
|
168
|
+
end
|
|
169
|
+
method.call
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
topic.run
|
|
173
|
+
|
|
174
|
+
expect(Howzit.named_arguments['VERSION']).to eq('1.2.3')
|
|
175
|
+
expect(output.any? { |o| o.include?('Version is 1.2.3') }).to be true
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it 'sets a variable with an unquoted value' do
|
|
179
|
+
note = <<~EONOTE
|
|
180
|
+
# Test
|
|
181
|
+
|
|
182
|
+
## Test Topic
|
|
183
|
+
|
|
184
|
+
@set_var(STATUS, success)
|
|
185
|
+
@run(echo "Status: ${STATUS}")
|
|
186
|
+
EONOTE
|
|
187
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
188
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
189
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
190
|
+
|
|
191
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
192
|
+
topic.run
|
|
193
|
+
|
|
194
|
+
expect(Howzit.named_arguments['STATUS']).to eq('success')
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it 'removes quotes from quoted values' do
|
|
198
|
+
note = <<~EONOTE
|
|
199
|
+
# Test
|
|
200
|
+
|
|
201
|
+
## Test Topic
|
|
202
|
+
|
|
203
|
+
@set_var(MESSAGE, "Hello, world")
|
|
204
|
+
@set_var(OTHER, 'Single quotes')
|
|
205
|
+
EONOTE
|
|
206
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
207
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
208
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
209
|
+
|
|
210
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
211
|
+
topic.run
|
|
212
|
+
|
|
213
|
+
expect(Howzit.named_arguments['MESSAGE']).to eq('Hello, world')
|
|
214
|
+
expect(Howzit.named_arguments['OTHER']).to eq('Single quotes')
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it 'sets multiple variables in sequence' do
|
|
218
|
+
note = <<~EONOTE
|
|
219
|
+
# Test
|
|
220
|
+
|
|
221
|
+
## Test Topic
|
|
222
|
+
|
|
223
|
+
@set_var(FIRST, "1")
|
|
224
|
+
@set_var(SECOND, "2")
|
|
225
|
+
@set_var(THIRD, "3")
|
|
226
|
+
EONOTE
|
|
227
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
228
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
229
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
230
|
+
|
|
231
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
232
|
+
topic.run
|
|
233
|
+
|
|
234
|
+
expect(Howzit.named_arguments['FIRST']).to eq('1')
|
|
235
|
+
expect(Howzit.named_arguments['SECOND']).to eq('2')
|
|
236
|
+
expect(Howzit.named_arguments['THIRD']).to eq('3')
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it 'allows variable substitution in values' do
|
|
240
|
+
note = <<~EONOTE
|
|
241
|
+
# Test
|
|
242
|
+
|
|
243
|
+
## Test Topic
|
|
244
|
+
|
|
245
|
+
@set_var(BASE, "1.2")
|
|
246
|
+
@set_var(VERSION, "${BASE}.3")
|
|
247
|
+
EONOTE
|
|
248
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
249
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
250
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
251
|
+
|
|
252
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
253
|
+
topic.run
|
|
254
|
+
|
|
255
|
+
expect(Howzit.named_arguments['BASE']).to eq('1.2')
|
|
256
|
+
expect(Howzit.named_arguments['VERSION']).to eq('1.2.3')
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
describe 'command substitution in @set_var' do
|
|
261
|
+
it 'executes command with backticks and uses output as value' do
|
|
262
|
+
note = <<~EONOTE
|
|
263
|
+
# Test
|
|
264
|
+
|
|
265
|
+
## Test Topic
|
|
266
|
+
|
|
267
|
+
@set_var(VERSION, `echo "1.2.3"`)
|
|
268
|
+
EONOTE
|
|
269
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
270
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
271
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
272
|
+
|
|
273
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
274
|
+
topic.run
|
|
275
|
+
|
|
276
|
+
expect(Howzit.named_arguments['VERSION']).to eq('1.2.3')
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
it 'executes command with $() syntax and uses output as value' do
|
|
280
|
+
note = <<~EONOTE
|
|
281
|
+
# Test
|
|
282
|
+
|
|
283
|
+
## Test Topic
|
|
284
|
+
|
|
285
|
+
@set_var(VERSION, $(echo "1.2.3"))
|
|
286
|
+
EONOTE
|
|
287
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
288
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
289
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
290
|
+
|
|
291
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
292
|
+
topic.run
|
|
293
|
+
|
|
294
|
+
expect(Howzit.named_arguments['VERSION']).to eq('1.2.3')
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it 'strips whitespace from command output' do
|
|
298
|
+
note = <<~EONOTE
|
|
299
|
+
# Test
|
|
300
|
+
|
|
301
|
+
## Test Topic
|
|
302
|
+
|
|
303
|
+
@set_var(VERSION, `echo " 1.2.3 "`)
|
|
304
|
+
EONOTE
|
|
305
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
306
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
307
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
308
|
+
|
|
309
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
310
|
+
topic.run
|
|
311
|
+
|
|
312
|
+
expect(Howzit.named_arguments['VERSION']).to eq('1.2.3')
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
it 'allows variable substitution in command' do
|
|
316
|
+
note = <<~EONOTE
|
|
317
|
+
# Test
|
|
318
|
+
|
|
319
|
+
## Test Topic
|
|
320
|
+
|
|
321
|
+
@set_var(BASE, "1.2")
|
|
322
|
+
@set_var(VERSION, `echo "${BASE}.3"`)
|
|
323
|
+
EONOTE
|
|
324
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
325
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
326
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
327
|
+
|
|
328
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
329
|
+
topic.run
|
|
330
|
+
|
|
331
|
+
expect(Howzit.named_arguments['VERSION']).to eq('1.2.3')
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it 'handles command execution errors gracefully' do
|
|
335
|
+
note = <<~EONOTE
|
|
336
|
+
# Test
|
|
337
|
+
|
|
338
|
+
## Test Topic
|
|
339
|
+
|
|
340
|
+
@set_var(VERSION, `nonexistent-command-that-fails`)
|
|
341
|
+
@run(echo "test")
|
|
342
|
+
EONOTE
|
|
343
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
344
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
345
|
+
|
|
346
|
+
# Set up console mock before topic is created (since gather_tasks runs during initialization)
|
|
347
|
+
console_warnings = []
|
|
348
|
+
allow(Howzit.console).to receive(:warn) do |message|
|
|
349
|
+
console_warnings << message
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
353
|
+
|
|
354
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
355
|
+
topic.run
|
|
356
|
+
|
|
357
|
+
expect(Howzit.named_arguments['VERSION']).to eq('')
|
|
358
|
+
expect(console_warnings.any? { |w| w =~ /Error executing command in @set_var/ }).to be true
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
describe 'using @set_var variables in conditionals' do
|
|
363
|
+
it 'allows @if blocks to use variables set with @set_var' do
|
|
364
|
+
note = <<~EONOTE
|
|
365
|
+
# Test
|
|
366
|
+
|
|
367
|
+
## Test Topic
|
|
368
|
+
|
|
369
|
+
@set_var(STATUS, "success")
|
|
370
|
+
@if ${STATUS} == "success"
|
|
371
|
+
@run(echo "Conditional executed") Conditional Task
|
|
372
|
+
@end
|
|
373
|
+
EONOTE
|
|
374
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
375
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
376
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
377
|
+
|
|
378
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
379
|
+
|
|
380
|
+
task_titles = []
|
|
381
|
+
allow_any_instance_of(Howzit::Task).to receive(:run).and_wrap_original do |method|
|
|
382
|
+
task = method.receiver
|
|
383
|
+
task_titles << task.title if task.respond_to?(:title) && task.title
|
|
384
|
+
method.call
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
topic.run
|
|
388
|
+
|
|
389
|
+
# Variable should be set during execution and task should run
|
|
390
|
+
# Note: Variable may not persist after run completes in sequential path
|
|
391
|
+
# but it should be available during execution
|
|
392
|
+
expect(task_titles).to include('Conditional Task')
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
it 'does not execute @if blocks when variable condition is false' do
|
|
396
|
+
note = <<~EONOTE
|
|
397
|
+
# Test
|
|
398
|
+
|
|
399
|
+
## Test Topic
|
|
400
|
+
|
|
401
|
+
@set_var(STATUS, "failure")
|
|
402
|
+
@if ${STATUS} == "success"
|
|
403
|
+
@run(echo "This should not run") Hidden Task
|
|
404
|
+
@end
|
|
405
|
+
EONOTE
|
|
406
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
407
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
408
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
409
|
+
|
|
410
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
411
|
+
|
|
412
|
+
task_titles = []
|
|
413
|
+
allow_any_instance_of(Howzit::Task).to receive(:run).and_wrap_original do |method|
|
|
414
|
+
task = method.receiver
|
|
415
|
+
task_titles << task.title if task.respond_to?(:title) && task.title
|
|
416
|
+
method.call
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
topic.run
|
|
420
|
+
|
|
421
|
+
expect(task_titles).not_to include('Hidden Task')
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
it 'allows @elsif and @else blocks to use @set_var variables' do
|
|
425
|
+
note = <<~EONOTE
|
|
426
|
+
# Test
|
|
427
|
+
|
|
428
|
+
## Test Topic
|
|
429
|
+
|
|
430
|
+
@set_var(STATUS, "warning")
|
|
431
|
+
@if ${STATUS} == "success"
|
|
432
|
+
@run(echo "Success") Success Task
|
|
433
|
+
@elsif ${STATUS} == "warning"
|
|
434
|
+
@run(echo "Warning") Warning Task
|
|
435
|
+
@else
|
|
436
|
+
@run(echo "Other") Other Task
|
|
437
|
+
@end
|
|
438
|
+
EONOTE
|
|
439
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
440
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
441
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
442
|
+
|
|
443
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
444
|
+
|
|
445
|
+
task_titles = []
|
|
446
|
+
allow_any_instance_of(Howzit::Task).to receive(:run).and_wrap_original do |method|
|
|
447
|
+
task = method.receiver
|
|
448
|
+
task_titles << task.title if task.respond_to?(:title) && task.title
|
|
449
|
+
method.call
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
topic.run
|
|
453
|
+
|
|
454
|
+
expect(task_titles).to include('Warning Task')
|
|
455
|
+
expect(task_titles).not_to include('Success Task')
|
|
456
|
+
expect(task_titles).not_to include('Other Task')
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
it 're-evaluates conditionals after @set_var changes variables' do
|
|
460
|
+
note = <<~EONOTE
|
|
461
|
+
# Test
|
|
462
|
+
|
|
463
|
+
## Test Topic
|
|
464
|
+
|
|
465
|
+
@set_var(STATUS, "initial")
|
|
466
|
+
@if ${STATUS} == "initial"
|
|
467
|
+
@run(echo "Initial state") Initial Task
|
|
468
|
+
@set_var(STATUS, "updated")
|
|
469
|
+
@end
|
|
470
|
+
@if ${STATUS} == "updated"
|
|
471
|
+
@run(echo "Updated state") Updated Task
|
|
472
|
+
@end
|
|
473
|
+
EONOTE
|
|
474
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
475
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
476
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
477
|
+
|
|
478
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
479
|
+
|
|
480
|
+
task_titles = []
|
|
481
|
+
allow_any_instance_of(Howzit::Task).to receive(:run).and_wrap_original do |method|
|
|
482
|
+
task = method.receiver
|
|
483
|
+
task_titles << task.title if task.respond_to?(:title) && task.title
|
|
484
|
+
method.call
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
topic.run
|
|
488
|
+
|
|
489
|
+
expect(task_titles).to include('Initial Task')
|
|
490
|
+
expect(task_titles).to include('Updated Task')
|
|
491
|
+
expect(Howzit.named_arguments['STATUS']).to eq('updated')
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
describe 'using @set_var variables in @run directives' do
|
|
496
|
+
it 'substitutes variables in @run command' do
|
|
497
|
+
note = <<~EONOTE
|
|
498
|
+
# Test
|
|
499
|
+
|
|
500
|
+
## Test Topic
|
|
501
|
+
|
|
502
|
+
@set_var(VERSION, "1.2.3")
|
|
503
|
+
@set_var(FILE, "test.txt")
|
|
504
|
+
@run(echo "Version ${VERSION} in ${FILE}")
|
|
505
|
+
EONOTE
|
|
506
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
507
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
508
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
509
|
+
|
|
510
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
511
|
+
|
|
512
|
+
output = []
|
|
513
|
+
allow_any_instance_of(Howzit::Task).to receive(:run).and_wrap_original do |method|
|
|
514
|
+
task = method.receiver
|
|
515
|
+
output << task.action if task.action
|
|
516
|
+
method.call
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
topic.run
|
|
520
|
+
|
|
521
|
+
expect(output.any? { |o| o.include?('Version 1.2.3 in test.txt') }).to be true
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
it 'substitutes variables from command substitution in @run' do
|
|
525
|
+
note = <<~EONOTE
|
|
526
|
+
# Test
|
|
527
|
+
|
|
528
|
+
## Test Topic
|
|
529
|
+
|
|
530
|
+
@set_var(VERSION, `echo "1.2.3"`)
|
|
531
|
+
@run(echo "Built version ${VERSION}")
|
|
532
|
+
EONOTE
|
|
533
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
534
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
535
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
536
|
+
|
|
537
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
538
|
+
|
|
539
|
+
output = []
|
|
540
|
+
allow_any_instance_of(Howzit::Task).to receive(:run).and_wrap_original do |method|
|
|
541
|
+
task = method.receiver
|
|
542
|
+
output << task.action if task.action
|
|
543
|
+
method.call
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
topic.run
|
|
547
|
+
|
|
548
|
+
expect(Howzit.named_arguments['VERSION']).to eq('1.2.3')
|
|
549
|
+
expect(output.any? { |o| o.include?('Built version 1.2.3') }).to be true
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
describe 'non-sequential execution path' do
|
|
554
|
+
it 'processes @set_var directives before tasks when no conditionals present' do
|
|
555
|
+
note = <<~EONOTE
|
|
556
|
+
# Test
|
|
557
|
+
|
|
558
|
+
## Test Topic
|
|
559
|
+
|
|
560
|
+
@set_var(VERSION, "1.2.3")
|
|
561
|
+
@run(echo "Version ${VERSION}")
|
|
562
|
+
EONOTE
|
|
563
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
564
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
565
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
566
|
+
|
|
567
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
568
|
+
|
|
569
|
+
output = []
|
|
570
|
+
allow_any_instance_of(Howzit::Task).to receive(:run).and_wrap_original do |method|
|
|
571
|
+
task = method.receiver
|
|
572
|
+
output << task.action if task.action
|
|
573
|
+
method.call
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
topic.run
|
|
577
|
+
|
|
578
|
+
expect(Howzit.named_arguments['VERSION']).to eq('1.2.3')
|
|
579
|
+
expect(output.any? { |o| o.include?('Version 1.2.3') }).to be true
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
it 'processes multiple @set_var directives in non-sequential path' do
|
|
583
|
+
note = <<~EONOTE
|
|
584
|
+
# Test
|
|
585
|
+
|
|
586
|
+
## Test Topic
|
|
587
|
+
|
|
588
|
+
@set_var(FIRST, "1")
|
|
589
|
+
@set_var(SECOND, "2")
|
|
590
|
+
@run(echo "${FIRST} and ${SECOND}")
|
|
591
|
+
EONOTE
|
|
592
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
593
|
+
Howzit.instance_variable_set(:@buildnote, nil)
|
|
594
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
595
|
+
|
|
596
|
+
allow(Howzit::Prompt).to receive(:yn).and_return(true)
|
|
597
|
+
topic.run
|
|
598
|
+
|
|
599
|
+
expect(Howzit.named_arguments['FIRST']).to eq('1')
|
|
600
|
+
expect(Howzit.named_arguments['SECOND']).to eq('2')
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
end
|
data/spec/stringutils_spec.rb
CHANGED
|
@@ -78,5 +78,45 @@ describe 'StringUtils' do
|
|
|
78
78
|
expect(result).to eq('echo ${BASH_VAR}')
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
|
-
end
|
|
82
81
|
|
|
82
|
+
describe '#metadata' do
|
|
83
|
+
before do
|
|
84
|
+
Howzit.named_arguments = {}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'parses MultiMarkdown-style metadata up to first blank line' do
|
|
88
|
+
text = <<~META
|
|
89
|
+
author: Note Author
|
|
90
|
+
license: MIT
|
|
91
|
+
|
|
92
|
+
This is the rest of the file.
|
|
93
|
+
author: Should not override
|
|
94
|
+
META
|
|
95
|
+
|
|
96
|
+
meta = text.metadata
|
|
97
|
+
expect(meta['author']).to eq('Note Author')
|
|
98
|
+
expect(meta['license']).to eq('MIT')
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'parses YAML front matter when starting with ---' do
|
|
102
|
+
text = <<~META
|
|
103
|
+
---
|
|
104
|
+
author: Brett Terpstra
|
|
105
|
+
license: MIT
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
# Title
|
|
109
|
+
META
|
|
110
|
+
|
|
111
|
+
meta = text.metadata
|
|
112
|
+
expect(meta['author']).to eq('Brett Terpstra')
|
|
113
|
+
expect(meta['license']).to eq('MIT')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'returns empty hash when there is no metadata' do
|
|
117
|
+
text = "Just some content\nWithout metadata\n"
|
|
118
|
+
meta = text.metadata
|
|
119
|
+
expect(meta).to eq({})
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
data/spec/topic_spec.rb
CHANGED
|
@@ -11,9 +11,11 @@ describe Howzit::Topic do
|
|
|
11
11
|
it 'makes a new topic instance' do
|
|
12
12
|
expect(topic).to be_a described_class
|
|
13
13
|
end
|
|
14
|
+
|
|
14
15
|
it 'has the correct title' do
|
|
15
16
|
expect(topic.title).to eq title
|
|
16
17
|
end
|
|
18
|
+
|
|
17
19
|
it 'has the correct content' do
|
|
18
20
|
expect(topic.content).to eq content
|
|
19
21
|
end
|
|
@@ -21,10 +23,10 @@ describe Howzit::Topic do
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
describe Howzit::Topic do
|
|
24
|
-
subject(:topic)
|
|
26
|
+
subject(:topic) do
|
|
25
27
|
bn = Howzit.buildnote
|
|
26
28
|
bn.find_topic('Topic Balogna')[0]
|
|
27
|
-
|
|
29
|
+
end
|
|
28
30
|
|
|
29
31
|
describe '.title' do
|
|
30
32
|
it 'has the correct title' do
|
|
@@ -60,7 +62,7 @@ describe Howzit::Topic do
|
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
it 'fails on bad pattern' do
|
|
63
|
-
expect(topic.grep('xxx+')).
|
|
65
|
+
expect(topic.grep('xxx+')).not_to be_truthy
|
|
64
66
|
end
|
|
65
67
|
end
|
|
66
68
|
|
|
@@ -73,11 +75,12 @@ describe Howzit::Topic do
|
|
|
73
75
|
end
|
|
74
76
|
|
|
75
77
|
it 'Copies to clipboard' do
|
|
76
|
-
expect
|
|
78
|
+
expect do
|
|
77
79
|
ENV['RUBYOPT'] = '-W1'
|
|
78
80
|
Howzit.options[:log_level] = 0
|
|
81
|
+
Howzit.instance_variable_set(:@console, nil) # Reset console to pick up new log level
|
|
79
82
|
topic.run
|
|
80
|
-
|
|
83
|
+
end.to output(/Copied/).to_stderr
|
|
81
84
|
end
|
|
82
85
|
end
|
|
83
86
|
|
|
@@ -102,7 +105,6 @@ describe Howzit::Topic do
|
|
|
102
105
|
end
|
|
103
106
|
end
|
|
104
107
|
|
|
105
|
-
|
|
106
108
|
describe '.arguments' do
|
|
107
109
|
before do
|
|
108
110
|
Howzit.arguments = []
|