howzit 2.1.28 → 2.1.30
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 +121 -0
- data/README.md +5 -1
- data/Rakefile +11 -4
- data/bin/howzit +65 -65
- data/howzit.gemspec +1 -1
- data/lib/howzit/buildnote.rb +4 -8
- data/lib/howzit/colors.rb +50 -22
- data/lib/howzit/condition_evaluator.rb +307 -0
- data/lib/howzit/conditional_content.rb +96 -0
- data/lib/howzit/config.rb +28 -3
- data/lib/howzit/console_logger.rb +74 -2
- data/lib/howzit/directive.rb +137 -0
- data/lib/howzit/prompt.rb +20 -12
- data/lib/howzit/run_report.rb +1 -1
- data/lib/howzit/script_comm.rb +105 -0
- data/lib/howzit/script_support.rb +479 -0
- data/lib/howzit/stringutils.rb +4 -4
- data/lib/howzit/task.rb +68 -6
- data/lib/howzit/topic.rb +576 -13
- data/lib/howzit/util.rb +11 -3
- data/lib/howzit/version.rb +1 -1
- data/lib/howzit.rb +5 -0
- data/spec/condition_evaluator_spec.rb +261 -0
- data/spec/conditional_blocks_integration_spec.rb +159 -0
- data/spec/conditional_content_spec.rb +296 -0
- data/spec/log_level_spec.rb +247 -0
- data/spec/script_comm_spec.rb +303 -0
- data/spec/sequential_conditional_spec.rb +319 -0
- data/spec/set_var_spec.rb +603 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/topic_spec.rb +8 -6
- data/src/_README.md +5 -1
- metadata +23 -4
data/lib/howzit/util.rb
CHANGED
|
@@ -118,7 +118,11 @@ module Howzit
|
|
|
118
118
|
# Paginate the output
|
|
119
119
|
def page(text)
|
|
120
120
|
unless $stdout.isatty
|
|
121
|
-
|
|
121
|
+
begin
|
|
122
|
+
puts text
|
|
123
|
+
rescue Errno::EPIPE
|
|
124
|
+
# Pipe closed, ignore
|
|
125
|
+
end
|
|
122
126
|
return
|
|
123
127
|
end
|
|
124
128
|
|
|
@@ -181,7 +185,11 @@ module Howzit
|
|
|
181
185
|
if options[:paginate] && Howzit.options[:paginate]
|
|
182
186
|
page(output)
|
|
183
187
|
else
|
|
184
|
-
|
|
188
|
+
begin
|
|
189
|
+
puts output
|
|
190
|
+
rescue Errno::EPIPE
|
|
191
|
+
# Pipe closed, ignore
|
|
192
|
+
end
|
|
185
193
|
end
|
|
186
194
|
end
|
|
187
195
|
|
|
@@ -219,7 +227,7 @@ module Howzit
|
|
|
219
227
|
##
|
|
220
228
|
def os_paste
|
|
221
229
|
os = RbConfig::CONFIG['target_os']
|
|
222
|
-
out =
|
|
230
|
+
out = '{bg}Pasting from clipboard'.c
|
|
223
231
|
case os
|
|
224
232
|
when /darwin.*/i
|
|
225
233
|
Howzit.console.debug("#{out} (macOS){x}".c)
|
data/lib/howzit/version.rb
CHANGED
data/lib/howzit.rb
CHANGED
|
@@ -38,6 +38,11 @@ require_relative 'howzit/stringutils'
|
|
|
38
38
|
|
|
39
39
|
require_relative 'howzit/console_logger'
|
|
40
40
|
require_relative 'howzit/config'
|
|
41
|
+
require_relative 'howzit/script_comm'
|
|
42
|
+
require_relative 'howzit/script_support'
|
|
43
|
+
require_relative 'howzit/condition_evaluator'
|
|
44
|
+
require_relative 'howzit/conditional_content'
|
|
45
|
+
require_relative 'howzit/directive'
|
|
41
46
|
require_relative 'howzit/task'
|
|
42
47
|
require_relative 'howzit/topic'
|
|
43
48
|
require_relative 'howzit/buildnote'
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Howzit::ConditionEvaluator do
|
|
6
|
+
describe '.evaluate' do
|
|
7
|
+
context 'with string comparisons' do
|
|
8
|
+
it 'evaluates == correctly' do
|
|
9
|
+
expect(described_class.evaluate('"test" == "test"', {})).to be true
|
|
10
|
+
expect(described_class.evaluate('"test" == "other"', {})).to be false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'evaluates =~ regex correctly' do
|
|
14
|
+
expect(described_class.evaluate('"test" =~ /es/', {})).to be true
|
|
15
|
+
expect(described_class.evaluate('"test" =~ /xyz/', {})).to be false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'evaluates *= (contains) correctly' do
|
|
19
|
+
expect(described_class.evaluate('"testing" *= "est"', {})).to be true
|
|
20
|
+
expect(described_class.evaluate('"testing" *= "xyz"', {})).to be false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'evaluates ^= (starts with) correctly' do
|
|
24
|
+
expect(described_class.evaluate('"testing" ^= "test"', {})).to be true
|
|
25
|
+
expect(described_class.evaluate('"testing" ^= "ing"', {})).to be false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'evaluates $= (ends with) correctly' do
|
|
29
|
+
expect(described_class.evaluate('"testing" $= "ing"', {})).to be true
|
|
30
|
+
expect(described_class.evaluate('"testing" $= "test"', {})).to be false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'evaluates **= (fuzzy match) correctly' do
|
|
34
|
+
expect(described_class.evaluate('"fluffy" **= "ffy"', {})).to be true
|
|
35
|
+
expect(described_class.evaluate('"fluffy" **= "fly"', {})).to be true
|
|
36
|
+
expect(described_class.evaluate('"fluffy" **= "fuf"', {})).to be true
|
|
37
|
+
expect(described_class.evaluate('"fluffy" **= "xyz"', {})).to be false
|
|
38
|
+
expect(described_class.evaluate('"fluffy" **= "fxy"', {})).to be false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'with numeric comparisons' do
|
|
43
|
+
it 'evaluates == correctly' do
|
|
44
|
+
expect(described_class.evaluate('5 == 5', {})).to be true
|
|
45
|
+
expect(described_class.evaluate('5 == 3', {})).to be false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'evaluates != correctly' do
|
|
49
|
+
expect(described_class.evaluate('5 != 3', {})).to be true
|
|
50
|
+
expect(described_class.evaluate('5 != 5', {})).to be false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'evaluates > correctly' do
|
|
54
|
+
expect(described_class.evaluate('5 > 3', {})).to be true
|
|
55
|
+
expect(described_class.evaluate('3 > 5', {})).to be false
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'evaluates >= correctly' do
|
|
59
|
+
expect(described_class.evaluate('5 >= 5', {})).to be true
|
|
60
|
+
expect(described_class.evaluate('5 >= 3', {})).to be true
|
|
61
|
+
expect(described_class.evaluate('3 >= 5', {})).to be false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'evaluates < correctly' do
|
|
65
|
+
expect(described_class.evaluate('3 < 5', {})).to be true
|
|
66
|
+
expect(described_class.evaluate('5 < 3', {})).to be false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'evaluates <= correctly' do
|
|
70
|
+
expect(described_class.evaluate('3 <= 3', {})).to be true
|
|
71
|
+
expect(described_class.evaluate('3 <= 5', {})).to be true
|
|
72
|
+
expect(described_class.evaluate('5 <= 3', {})).to be false
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'with negation' do
|
|
77
|
+
it 'handles not prefix' do
|
|
78
|
+
expect(described_class.evaluate('not "test" == "other"', {})).to be true
|
|
79
|
+
expect(described_class.evaluate('not "test" == "test"', {})).to be false
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'handles ! prefix' do
|
|
83
|
+
expect(described_class.evaluate('! "test" == "other"', {})).to be true
|
|
84
|
+
expect(described_class.evaluate('! "test" == "test"', {})).to be false
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context 'with positional arguments' do
|
|
89
|
+
before do
|
|
90
|
+
Howzit.arguments = %w[arg1 arg2 arg3]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
after do
|
|
94
|
+
Howzit.arguments = nil
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it 'evaluates $1, $2, etc.' do
|
|
98
|
+
expect(described_class.evaluate('$1 == "arg1"', {})).to be true
|
|
99
|
+
expect(described_class.evaluate('$2 == "arg2"', {})).to be true
|
|
100
|
+
expect(described_class.evaluate('$1 == "other"', {})).to be false
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
context 'with named arguments' do
|
|
105
|
+
before do
|
|
106
|
+
Howzit.named_arguments = { test: 'value', other: 'thing' }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
after do
|
|
110
|
+
Howzit.named_arguments = nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'evaluates named arguments' do
|
|
114
|
+
expect(described_class.evaluate('test == "value"', {})).to be true
|
|
115
|
+
expect(described_class.evaluate('other == "thing"', {})).to be true
|
|
116
|
+
expect(described_class.evaluate('test == "other"', {})).to be false
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'evaluates named arguments with ${} syntax' do
|
|
120
|
+
Howzit.named_arguments = { var: 'val', env: 'production' }
|
|
121
|
+
expect(described_class.evaluate('${var} == "val"', {})).to be true
|
|
122
|
+
expect(described_class.evaluate('${env} == "production"', {})).to be true
|
|
123
|
+
expect(described_class.evaluate('${var} == "other"', {})).to be false
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context 'with metadata' do
|
|
128
|
+
it 'evaluates metadata keys' do
|
|
129
|
+
context = { metadata: { 'key1' => 'value1', 'key2' => 'value2' } }
|
|
130
|
+
expect(described_class.evaluate('key1 == "value1"', context)).to be true
|
|
131
|
+
expect(described_class.evaluate('key2 == "value2"', context)).to be true
|
|
132
|
+
expect(described_class.evaluate('key1 == "other"', context)).to be false
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context 'with environment variables' do
|
|
137
|
+
it 'evaluates environment variables' do
|
|
138
|
+
ENV['TEST_VAR'] = 'test_value'
|
|
139
|
+
expect(described_class.evaluate('TEST_VAR == "test_value"', {})).to be true
|
|
140
|
+
ENV.delete('TEST_VAR')
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
context 'with special conditions' do
|
|
145
|
+
it 'evaluates git dirty' do
|
|
146
|
+
# Just test that it doesn't crash
|
|
147
|
+
result = described_class.evaluate('git dirty', {})
|
|
148
|
+
expect([true, false]).to include(result)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'evaluates git clean' do
|
|
152
|
+
result = described_class.evaluate('git clean', {})
|
|
153
|
+
expect([true, false]).to include(result)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it 'evaluates file exists' do
|
|
157
|
+
expect(described_class.evaluate('file exists /dev/null', {})).to be true
|
|
158
|
+
expect(described_class.evaluate('file exists /nonexistent/file', {})).to be false
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'evaluates dir exists' do
|
|
162
|
+
expect(described_class.evaluate('dir exists /tmp', {})).to be true
|
|
163
|
+
expect(described_class.evaluate('dir exists /nonexistent/dir', {})).to be false
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it 'evaluates cwd' do
|
|
167
|
+
result = described_class.evaluate('cwd', {})
|
|
168
|
+
expect(result).to be true
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'evaluates working directory' do
|
|
172
|
+
result = described_class.evaluate('working directory', {})
|
|
173
|
+
expect(result).to be true
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it 'evaluates cwd with string comparisons' do
|
|
177
|
+
cwd = Dir.pwd
|
|
178
|
+
expect(described_class.evaluate("cwd == \"#{cwd}\"", {})).to be true
|
|
179
|
+
expect(described_class.evaluate("cwd =~ /#{Regexp.escape(File.basename(cwd))}/", {})).to be true
|
|
180
|
+
expect(described_class.evaluate("cwd *= \"#{File.basename(cwd)}\"", {})).to be true
|
|
181
|
+
expect(described_class.evaluate("cwd ^= \"#{cwd[0..10]}\"", {})).to be true
|
|
182
|
+
expect(described_class.evaluate("cwd $= \"#{cwd[-10..-1]}\"", {})).to be true
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
context 'with file contents conditions' do
|
|
187
|
+
let(:test_file) { 'test_version.txt' }
|
|
188
|
+
|
|
189
|
+
before do
|
|
190
|
+
File.write(test_file, '0.1.2')
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
after do
|
|
194
|
+
File.delete(test_file) if File.exist?(test_file)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it 'evaluates file contents ^= (starts with) correctly' do
|
|
198
|
+
expect(described_class.evaluate("file contents #{test_file} ^= 0.", {})).to be true
|
|
199
|
+
expect(described_class.evaluate("file contents #{test_file} ^= 1.", {})).to be false
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it 'evaluates file contents *= (contains) correctly' do
|
|
203
|
+
expect(described_class.evaluate("file contents #{test_file} *= 1.2", {})).to be true
|
|
204
|
+
expect(described_class.evaluate("file contents #{test_file} *= 2.3", {})).to be false
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it 'evaluates file contents $= (ends with) correctly' do
|
|
208
|
+
expect(described_class.evaluate("file contents #{test_file} $= .2", {})).to be true
|
|
209
|
+
expect(described_class.evaluate("file contents #{test_file} $= .3", {})).to be false
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it 'evaluates file contents == correctly' do
|
|
213
|
+
expect(described_class.evaluate("file contents #{test_file} == 0.1.2", {})).to be true
|
|
214
|
+
expect(described_class.evaluate("file contents #{test_file} == 1.0.0", {})).to be false
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it 'evaluates file contents != correctly' do
|
|
218
|
+
expect(described_class.evaluate("file contents #{test_file} != 1.0.0", {})).to be true
|
|
219
|
+
expect(described_class.evaluate("file contents #{test_file} != 0.1.2", {})).to be false
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it 'evaluates file contents **= (fuzzy match) correctly' do
|
|
223
|
+
expect(described_class.evaluate("file contents #{test_file} **= 012", {})).to be true
|
|
224
|
+
expect(described_class.evaluate("file contents #{test_file} **= 021", {})).to be false
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
it 'evaluates file contents =~ (regex) correctly' do
|
|
228
|
+
expect(described_class.evaluate("file contents #{test_file} =~ /0\\.\\d+\\.\\d+/", {})).to be true
|
|
229
|
+
expect(described_class.evaluate("file contents #{test_file} =~ /1\\.\\d+\\.\\d+/", {})).to be false
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it 'returns false for non-existent file' do
|
|
233
|
+
expect(described_class.evaluate('file contents nonexistent.txt ^= 0.', {})).to be false
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it 'handles file path as variable' do
|
|
237
|
+
context = { metadata: { 'version_file' => test_file } }
|
|
238
|
+
expect(described_class.evaluate('file contents version_file ^= 0.', context)).to be true
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
context 'with simple existence checks' do
|
|
243
|
+
before do
|
|
244
|
+
Howzit.named_arguments = { defined_var: 'value' }
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
after do
|
|
248
|
+
Howzit.named_arguments = nil
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it 'returns true for defined variables' do
|
|
252
|
+
expect(described_class.evaluate('defined_var', {})).to be true
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
it 'returns false for undefined variables' do
|
|
256
|
+
expect(described_class.evaluate('undefined_var', {})).to be false
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'Conditional Blocks Integration' 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
|
+
end
|
|
12
|
+
|
|
13
|
+
after do
|
|
14
|
+
FileUtils.rm_f('builda.md')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe 'with conditional blocks in topics' do
|
|
18
|
+
it 'includes content when @if condition is true' do
|
|
19
|
+
note = <<~EONOTE
|
|
20
|
+
# Test
|
|
21
|
+
|
|
22
|
+
## Test Topic
|
|
23
|
+
|
|
24
|
+
@if "test" == "test"
|
|
25
|
+
This should be included
|
|
26
|
+
@end
|
|
27
|
+
EONOTE
|
|
28
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
29
|
+
Howzit.instance_variable_set(:@buildnote, nil) # Force reload
|
|
30
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
31
|
+
expect(topic).not_to be_nil
|
|
32
|
+
output = topic.print_out
|
|
33
|
+
expect(output.join("\n")).to include('This should be included')
|
|
34
|
+
expect(output.join("\n")).not_to include('@if')
|
|
35
|
+
expect(output.join("\n")).not_to include('@end')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'excludes content when @if condition is false' do
|
|
39
|
+
note = <<~EONOTE
|
|
40
|
+
# Test
|
|
41
|
+
|
|
42
|
+
## Test Topic
|
|
43
|
+
|
|
44
|
+
@if "test" == "other"
|
|
45
|
+
This should NOT be included
|
|
46
|
+
@end
|
|
47
|
+
EONOTE
|
|
48
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
49
|
+
Howzit.instance_variable_set(:@buildnote, nil) # Force reload
|
|
50
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
51
|
+
expect(topic).not_to be_nil
|
|
52
|
+
output = topic.print_out
|
|
53
|
+
expect(output.join("\n")).not_to include('This should NOT be included')
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'includes tasks when condition is true' do
|
|
57
|
+
note = <<~EONOTE
|
|
58
|
+
# Test
|
|
59
|
+
|
|
60
|
+
## Test Topic
|
|
61
|
+
|
|
62
|
+
@if 1 == 1
|
|
63
|
+
@run(echo "test") Test Command
|
|
64
|
+
@end
|
|
65
|
+
EONOTE
|
|
66
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
67
|
+
Howzit.instance_variable_set(:@buildnote, nil) # Force reload
|
|
68
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
69
|
+
expect(topic).not_to be_nil
|
|
70
|
+
expect(topic.tasks.count).to eq(1)
|
|
71
|
+
expect(topic.tasks[0].action).to include('echo "test"')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'excludes tasks when condition is false' do
|
|
75
|
+
note = <<~EONOTE
|
|
76
|
+
# Test
|
|
77
|
+
|
|
78
|
+
## Test Topic
|
|
79
|
+
|
|
80
|
+
@if 1 == 2
|
|
81
|
+
@run(echo "hidden") Hidden Command
|
|
82
|
+
@end
|
|
83
|
+
EONOTE
|
|
84
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
85
|
+
Howzit.instance_variable_set(:@buildnote, nil) # Force reload
|
|
86
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
87
|
+
expect(topic).not_to be_nil
|
|
88
|
+
expect(topic.tasks.count).to eq(0)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'handles nested conditional blocks' do
|
|
92
|
+
note = <<~EONOTE
|
|
93
|
+
# Test
|
|
94
|
+
|
|
95
|
+
## Test Topic
|
|
96
|
+
|
|
97
|
+
@if "outer" == "outer"
|
|
98
|
+
Outer content
|
|
99
|
+
@if "inner" == "inner"
|
|
100
|
+
Inner content
|
|
101
|
+
@end
|
|
102
|
+
More outer content
|
|
103
|
+
@end
|
|
104
|
+
EONOTE
|
|
105
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
106
|
+
Howzit.instance_variable_set(:@buildnote, nil) # Force reload
|
|
107
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
108
|
+
expect(topic).not_to be_nil
|
|
109
|
+
output = topic.print_out
|
|
110
|
+
expect(output.join("\n")).to include('Outer content')
|
|
111
|
+
expect(output.join("\n")).to include('Inner content')
|
|
112
|
+
expect(output.join("\n")).to include('More outer content')
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'handles metadata in conditions' do
|
|
116
|
+
note = <<~EONOTE
|
|
117
|
+
env: production
|
|
118
|
+
|
|
119
|
+
# Test
|
|
120
|
+
|
|
121
|
+
## Test Topic
|
|
122
|
+
|
|
123
|
+
@if env == "production"
|
|
124
|
+
Production content
|
|
125
|
+
@end
|
|
126
|
+
EONOTE
|
|
127
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
128
|
+
Howzit.instance_variable_set(:@buildnote, nil) # Force reload
|
|
129
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
130
|
+
expect(topic).not_to be_nil
|
|
131
|
+
output = topic.print_out
|
|
132
|
+
expect(output.join("\n")).to include('Production content')
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it 'handles @unless blocks correctly' do
|
|
136
|
+
note = <<~EONOTE
|
|
137
|
+
# Test
|
|
138
|
+
|
|
139
|
+
## Test Topic
|
|
140
|
+
|
|
141
|
+
@unless "test" == "other"
|
|
142
|
+
This should be included
|
|
143
|
+
@end
|
|
144
|
+
|
|
145
|
+
@unless "test" == "test"
|
|
146
|
+
This should NOT be included
|
|
147
|
+
@end
|
|
148
|
+
EONOTE
|
|
149
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
150
|
+
Howzit.instance_variable_set(:@buildnote, nil) # Force reload
|
|
151
|
+
topic = Howzit.buildnote.find_topic('Test Topic')[0]
|
|
152
|
+
expect(topic).not_to be_nil
|
|
153
|
+
output = topic.print_out
|
|
154
|
+
expect(output.join("\n")).to include('This should be included')
|
|
155
|
+
expect(output.join("\n")).not_to include('This should NOT be included')
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|