rundoc 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -7
  3. data/CHANGELOG.md +15 -0
  4. data/CONTRIBUTING.md +25 -0
  5. data/README.md +35 -48
  6. data/Rakefile +5 -1
  7. data/bin/rundoc +4 -17
  8. data/lib/rundoc/cli.rb +207 -49
  9. data/lib/rundoc/cli_argument_parser.rb +140 -0
  10. data/lib/rundoc/code_command/bash.rb +8 -1
  11. data/lib/rundoc/code_command/rundoc/depend_on.rb +1 -24
  12. data/lib/rundoc/code_command/rundoc/require.rb +13 -7
  13. data/lib/rundoc/code_command/website/driver.rb +7 -5
  14. data/lib/rundoc/code_command/website/navigate.rb +1 -1
  15. data/lib/rundoc/code_command/website/screenshot.rb +7 -2
  16. data/lib/rundoc/code_command/website/visit.rb +1 -1
  17. data/lib/rundoc/code_section.rb +4 -6
  18. data/lib/rundoc/context/after_build.rb +14 -0
  19. data/lib/rundoc/context/execution.rb +22 -0
  20. data/lib/rundoc/parser.rb +9 -5
  21. data/lib/rundoc/version.rb +1 -1
  22. data/lib/rundoc.rb +13 -5
  23. data/rundoc.gemspec +1 -0
  24. data/test/fixtures/cnb/ruby/download.md +22 -0
  25. data/test/fixtures/cnb/ruby/image_structure.md +34 -0
  26. data/test/fixtures/cnb/ruby/intro.md +5 -0
  27. data/test/fixtures/cnb/ruby/multiple_langs.md +43 -0
  28. data/test/fixtures/cnb/ruby/rundoc.md +48 -0
  29. data/test/fixtures/cnb/ruby/what_is_pack_build.md +18 -0
  30. data/test/fixtures/cnb/shared/call_to_action.md +11 -0
  31. data/test/fixtures/cnb/shared/configure_builder.md +23 -0
  32. data/test/fixtures/cnb/shared/install_pack.md +14 -0
  33. data/test/fixtures/cnb/shared/pack_build.md +20 -0
  34. data/test/fixtures/cnb/shared/procfile.md +13 -0
  35. data/test/fixtures/cnb/shared/use_the_image.md +52 -0
  36. data/test/fixtures/cnb/shared/what_is_a_builder.md +18 -0
  37. data/test/fixtures/rails_4/rundoc.md +5 -7
  38. data/test/fixtures/rails_5/rundoc.md +1 -1
  39. data/test/fixtures/rails_6/rundoc.md +2 -2
  40. data/test/fixtures/rails_7/rundoc.md +2 -3
  41. data/test/fixtures/simple_git/rundoc.md +13 -0
  42. data/test/integration/after_build_test.rb +62 -0
  43. data/test/integration/print_test.rb +9 -9
  44. data/test/integration/require_test.rb +63 -0
  45. data/test/integration/website_test.rb +35 -0
  46. data/test/rundoc/cli_argument_parser_test.rb +118 -0
  47. data/test/rundoc/code_section_test.rb +40 -8
  48. data/test/rundoc/parser_test.rb +3 -3
  49. data/test/rundoc/peg_parser_test.rb +6 -6
  50. data/test/rundoc/regex_test.rb +22 -0
  51. data/test/system/exe_cli_test.rb +231 -0
  52. data/test/test_helper.rb +74 -1
  53. metadata +40 -3
@@ -16,7 +16,7 @@ class ParserTest < Minitest::Test
16
16
  Dir.mktmpdir do |dir|
17
17
  Dir.chdir(dir) do
18
18
  expected = "sup\n\n```\n$ mkdir foo\n$ ls\nfoo\n```\n\nyo\n"
19
- parsed = Rundoc::Parser.new(contents)
19
+ parsed = parse_contents(contents)
20
20
  actual = parsed.to_md.gsub(Rundoc::CodeSection::AUTOGEN_WARNING, "")
21
21
  assert_equal expected, actual
22
22
  end
@@ -38,7 +38,7 @@ class ParserTest < Minitest::Test
38
38
  Dir.mktmpdir do |dir|
39
39
  Dir.chdir(dir) do
40
40
  expected = "sup\n\nIn file `foo/code.rb` write:\n\n```\na = 1 + 1\nb = a * 2\n```\nyo\n"
41
- parsed = Rundoc::Parser.new(contents)
41
+ parsed = parse_contents(contents)
42
42
  actual = parsed.to_md.gsub(Rundoc::CodeSection::AUTOGEN_WARNING, "")
43
43
  assert_equal expected, actual
44
44
  end
@@ -56,7 +56,7 @@ class ParserTest < Minitest::Test
56
56
  Dir.mktmpdir do |dir|
57
57
  Dir.chdir(dir) do
58
58
  expected = "\nIn file `foo/newb.rb` write:\n\n```\nputs 'hello world'\n$ cat foo/newb.rb\nputs 'hello world'\n```\n"
59
- parsed = Rundoc::Parser.new(contents)
59
+ parsed = parse_contents(contents)
60
60
  actual = parsed.to_md.gsub(Rundoc::CodeSection::AUTOGEN_WARNING, "")
61
61
  assert_equal expected, actual
62
62
  end
@@ -270,36 +270,36 @@ class PegParserTest < Minitest::Test
270
270
 
271
271
  def test_rundoc_sub_commands_no_quotes
272
272
  input = +""
273
- input << %(:::-- rundoc.depend_on ../foo/bar.md\n)
273
+ input << %(:::-- rundoc.require ../foo/bar.md\n)
274
274
 
275
275
  parser = Rundoc::PegParser.new.command_with_stdin
276
276
  tree = parser.parse_with_debug(input)
277
277
 
278
278
  actual = @transformer.apply(tree)
279
- assert_equal :"rundoc.depend_on", actual.keyword
279
+ assert_equal :"rundoc.require", actual.keyword
280
280
  end
281
281
 
282
282
  def test_seattle_style_method_call
283
283
  input = +""
284
- input << %(rundoc.depend_on '../foo/bar.md')
284
+ input << %(rundoc.require '../foo/bar.md')
285
285
  parser = Rundoc::PegParser.new.method_call
286
286
  tree = parser.parse_with_debug(input)
287
287
 
288
288
  actual = @transformer.apply(tree)
289
289
 
290
- assert_equal :"rundoc.depend_on", actual.keyword
290
+ assert_equal :"rundoc.require", actual.keyword
291
291
  end
292
292
 
293
293
  def test_rundoc_seattle_sub_command
294
294
  input = +""
295
- input << %(:::>> rundoc.depend_on '../foo/bar.md'\n)
295
+ input << %(:::>> rundoc.require '../foo/bar.md'\n)
296
296
 
297
297
  parser = Rundoc::PegParser.new.command
298
298
  tree = parser.parse_with_debug(input)
299
299
 
300
300
  actual = @transformer.apply(tree)
301
301
 
302
- assert_equal :"rundoc.depend_on", actual.keyword
302
+ assert_equal :"rundoc.require", actual.keyword
303
303
  end
304
304
 
305
305
  def test_positional_args
@@ -190,4 +190,26 @@ class RegexTest < Minitest::Test
190
190
 
191
191
  assert_equal contents.strip, match.to_s.strip
192
192
  end
193
+
194
+ def test_codeblock_optional_newline_regex
195
+ code_block_with_newline = <<~MD
196
+ hi
197
+ ```
198
+ :::>> $ echo "hello"
199
+ ```
200
+ MD
201
+ code_block_without_newline = code_block_with_newline.strip
202
+
203
+ expected = <<~MD.strip
204
+ ```
205
+ :::>> $ echo "hello"
206
+ ```
207
+ MD
208
+ regex = Rundoc::Parser::CODEBLOCK_REGEX
209
+ match = code_block_with_newline.match(regex)
210
+ assert_equal expected, match.to_s.strip
211
+
212
+ match = code_block_without_newline.match(regex)
213
+ assert_equal expected, match.to_s.strip
214
+ end
193
215
  end
@@ -0,0 +1,231 @@
1
+ require "test_helper"
2
+
3
+ class SystemsCliTest < Minitest::Test
4
+ def exe_path
5
+ root_dir.join("bin").join("rundoc")
6
+ end
7
+
8
+ def test_git
9
+ Dir.mktmpdir do |dir|
10
+ dir = Pathname(dir)
11
+ contents = fixture_path("simple_git").join("rundoc.md").read
12
+
13
+ dir.join("rundoc.md").write(contents)
14
+ run!("#{exe_path} #{dir.join("rundoc.md")}")
15
+
16
+ output_dir = dir.join(SUCCESS_DIRNAME)
17
+ .tap { |p| assert p.exist? }
18
+
19
+ assert output_dir.join(".git").exist?
20
+
21
+ readme = output_dir
22
+ .join("README.md")
23
+ .tap { |p| assert p.exist? }
24
+
25
+ assert readme.exist?
26
+
27
+ actual = strip_autogen_warning(readme.read)
28
+ assert actual.include?("$ echo \"hello world\"")
29
+ end
30
+ end
31
+
32
+ def test_help
33
+ output = run!("#{exe_path} --help")
34
+ assert output.include?("Usage:")
35
+ end
36
+
37
+ def test_force_fail_dir_protection
38
+ Dir.mktmpdir do |dir|
39
+ dir = Pathname(dir)
40
+ rundoc = dir.join("RUNDOC.md")
41
+ rundoc.write "Done"
42
+
43
+ not_empty = dir.join(FAILURE_DIRNAME).tap(&:mkpath).join("not_empty.txt")
44
+ not_empty.write("Not empty")
45
+
46
+ run!("#{exe_path} #{rundoc}", raise_on_nonzero_exit: false)
47
+ assert !$?.success?
48
+
49
+ assert not_empty.exist?
50
+
51
+ run!("#{exe_path} #{rundoc} --force", raise_on_nonzero_exit: false)
52
+ assert $?.success?
53
+ assert !not_empty.exist?
54
+ end
55
+ end
56
+
57
+ def test_force_success_dir_protection
58
+ Dir.mktmpdir do |dir|
59
+ dir = Pathname(dir)
60
+
61
+ rundoc = dir.join("RUNDOC.md")
62
+ rundoc.write "Done"
63
+
64
+ not_empty = dir.join(SUCCESS_DIRNAME).tap(&:mkpath).join("not_empty.txt")
65
+ not_empty.write("Not empty")
66
+
67
+ run!("#{exe_path} #{rundoc}", raise_on_nonzero_exit: false)
68
+ assert !$?.success?
69
+
70
+ assert not_empty.exist?
71
+
72
+ run!("#{exe_path} #{rundoc} --force", raise_on_nonzero_exit: false)
73
+ assert $?.success?
74
+ assert !not_empty.exist?
75
+ end
76
+ end
77
+
78
+ def test_dotenv
79
+ Dir.mktmpdir do |dir|
80
+ key = SecureRandom.hex
81
+ dir = Pathname(dir)
82
+ dotenv = dir.join("another").join("directory").tap(&:mkpath).join(".env")
83
+
84
+ dotenv.write <<~EOF
85
+ FLORP="#{key}"
86
+ EOF
87
+
88
+ rundoc = dir.join("RUNDOC.md")
89
+ rundoc.write <<~EOF
90
+ ```
91
+ :::>> $ echo $FLORP
92
+ ```
93
+ EOF
94
+
95
+ run!("#{exe_path} #{rundoc} --dotenv-path #{dotenv}")
96
+
97
+ readme = dir.join(SUCCESS_DIRNAME)
98
+ .tap { |p| assert p.exist? }
99
+ .join("README.md")
100
+ .tap { |p| assert p.exist? }
101
+
102
+ actual = strip_autogen_warning(readme.read)
103
+ expected = <<~EOF
104
+ ```
105
+ $ echo $FLORP
106
+ #{key}
107
+ ```
108
+ EOF
109
+ assert_equal expected.strip, actual.strip
110
+ end
111
+ end
112
+
113
+ def test_screenshots_dir
114
+ Dir.mktmpdir do |dir|
115
+ dir = Pathname(dir)
116
+ rundoc = dir.join("RUNDOC.md")
117
+ screenshots_dirname = "lol_screenshots"
118
+ rundoc.write <<~EOF
119
+ ```
120
+ :::>> website.visit(name: "example", url: "http://example.com")
121
+ :::>> website.screenshot(name: "example")
122
+ ```
123
+ EOF
124
+
125
+ run!("#{exe_path} #{rundoc} --screenshots-dir #{screenshots_dirname}")
126
+
127
+ dir.join(SUCCESS_DIRNAME)
128
+ .tap { |p| assert p.exist? }
129
+ .join(screenshots_dirname)
130
+ .tap { |p| assert p.exist? }
131
+
132
+ readme = dir.join(SUCCESS_DIRNAME).join("README.md").read
133
+ actual = strip_autogen_warning(readme)
134
+
135
+ expected = "![Screenshot of http://example.com/](#{screenshots_dirname}/screenshot_1.png)"
136
+ assert_equal expected, actual.strip
137
+ end
138
+ end
139
+
140
+ def test_output_filename
141
+ Dir.mktmpdir do |dir|
142
+ dir = Pathname(dir)
143
+ rundoc = dir.join("RUNDOC.md")
144
+ failure_dir = dir.join("lol")
145
+ rundoc.write "Done"
146
+
147
+ assert !failure_dir.exist?
148
+
149
+ run!("#{exe_path} #{rundoc} --output-filename tutorial.md")
150
+
151
+ tutorial_md = dir.join(SUCCESS_DIRNAME)
152
+ .tap { |p| assert p.exist? }
153
+ .join("tutorial.md")
154
+ .tap { |p| assert p.exist? }
155
+
156
+ actual = strip_autogen_warning(tutorial_md.read)
157
+ expected = "Done"
158
+
159
+ assert_equal expected.strip, actual.strip
160
+ end
161
+ end
162
+
163
+ def test_on_failure_dir
164
+ Dir.mktmpdir do |dir|
165
+ dir = Pathname(dir)
166
+ rundoc = dir.join("RUNDOC.md")
167
+ failure_dir = dir.join("lol")
168
+ rundoc.write <<~EOF
169
+ ```
170
+ :::>> $ touch lol.txt
171
+ :::>> $ echo "hello world" && exit 1
172
+ ```
173
+ EOF
174
+
175
+ assert !failure_dir.exist?
176
+
177
+ run!("#{exe_path} #{rundoc} --on-failure-dir #{failure_dir}", raise_on_nonzero_exit: false)
178
+ assert !$?.success?
179
+
180
+ assert failure_dir.exist?
181
+ assert !Dir.exist?(dir.join(FAILURE_DIRNAME))
182
+ assert failure_dir.join("lol.txt").exist?
183
+ end
184
+ end
185
+
186
+ def test_on_success_dir
187
+ Dir.mktmpdir do |dir|
188
+ dir = Pathname(dir)
189
+ rundoc = dir.join("RUNDOC.md")
190
+ success_dir = dir.join("lol")
191
+ rundoc.write "Done"
192
+
193
+ assert !success_dir.exist?
194
+ run!("#{exe_path} #{rundoc} --on-success-dir #{success_dir}")
195
+
196
+ assert success_dir.exist?
197
+ assert !Dir.exist?(dir.join(SUCCESS_DIRNAME))
198
+
199
+ readme = success_dir.join("README.md")
200
+ actual = strip_autogen_warning(readme.read)
201
+ expected = "Done"
202
+
203
+ assert_equal expected.strip, actual.strip
204
+ end
205
+ end
206
+
207
+ def test_simple_file
208
+ Dir.mktmpdir do |dir|
209
+ dir = Pathname(dir)
210
+ rundoc = dir.join("RUNDOC.md")
211
+ rundoc.write <<~EOF
212
+ ```
213
+ :::>> $ echo "hello world"
214
+ ```
215
+ EOF
216
+
217
+ run!("#{exe_path} #{rundoc}")
218
+
219
+ readme = dir.join(SUCCESS_DIRNAME).join("README.md")
220
+ actual = strip_autogen_warning(readme.read)
221
+ expected = <<~EOF
222
+ ```
223
+ $ echo "hello world"
224
+ hello world
225
+ ```
226
+ EOF
227
+
228
+ assert_equal expected.strip, actual.strip
229
+ end
230
+ end
231
+ end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require "simplecov"
2
+ SimpleCov.start
3
+
1
4
  require "bundler"
2
5
 
3
6
  Bundler.require
@@ -7,5 +10,75 @@ require "minitest/autorun"
7
10
  require "mocha/minitest"
8
11
  require "tmpdir"
9
12
 
10
- def assert_tests_run
13
+ class Minitest::Test
14
+ SUCCESS_DIRNAME = Rundoc::CLI::DEFAULTS::ON_SUCCESS_DIR
15
+ FAILURE_DIRNAME = Rundoc::CLI::DEFAULTS::ON_FAILURE_DIR
16
+
17
+ def default_context(
18
+ output_dir: nil,
19
+ source_path: nil,
20
+ screenshots_dirname: nil
21
+ )
22
+
23
+ Rundoc::Context::Execution.new(
24
+ output_dir: output_dir || Pathname("/dev/null"),
25
+ source_path: source_path || Pathname("/dev/null"),
26
+ screenshots_dirname: screenshots_dirname || Pathname("/dev/null")
27
+ )
28
+ end
29
+
30
+ def parse_contents(
31
+ contents,
32
+ output_dir: nil,
33
+ source_path: nil,
34
+ screenshots_dirname: nil
35
+ )
36
+ context = default_context(
37
+ output_dir: output_dir,
38
+ source_path: source_path,
39
+ screenshots_dirname: screenshots_dirname
40
+ )
41
+ Rundoc::Parser.new(
42
+ contents,
43
+ context: context
44
+ )
45
+ end
46
+
47
+ def root_dir
48
+ Pathname(__dir__).join("..").expand_path
49
+ end
50
+
51
+ def fixture_path(dir = "")
52
+ root_dir.join("test").join("fixtures").join(dir)
53
+ end
54
+
55
+ def run!(cmd, raise_on_nonzero_exit: true)
56
+ out = `#{cmd} 2>&1`
57
+ raise "Command: #{cmd} failed: #{out}" if !$?.success? && raise_on_nonzero_exit
58
+ out
59
+ end
60
+
61
+ def strip_autogen_warning(string)
62
+ string.gsub!(Rundoc::CodeSection::AUTOGEN_WARNING, "")
63
+ string.gsub!(/<!-- STOP.*STOP -->/m, "")
64
+ string
65
+ end
66
+
67
+ class FakeExit
68
+ def initialize
69
+ @called = false
70
+ @value = nil
71
+ end
72
+
73
+ def exit(value = nil)
74
+ @called = true
75
+ @value = value
76
+ end
77
+
78
+ def called?
79
+ @called
80
+ end
81
+
82
+ attr_reader :value
83
+ end
11
84
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rundoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Schneeman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-09 00:00:00.000000000 Z
11
+ date: 2024-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: RunDOC turns docs to runable code
168
182
  email:
169
183
  - richard.schneeman+rubygems@gmail.com
@@ -177,6 +191,7 @@ files:
177
191
  - ".gitignore"
178
192
  - ".standard.yml"
179
193
  - CHANGELOG.md
194
+ - CONTRIBUTING.md
180
195
  - Dockerfile
181
196
  - Gemfile
182
197
  - README.md
@@ -184,6 +199,7 @@ files:
184
199
  - bin/rundoc
185
200
  - lib/rundoc.rb
186
201
  - lib/rundoc/cli.rb
202
+ - lib/rundoc/cli_argument_parser.rb
187
203
  - lib/rundoc/code_command.rb
188
204
  - lib/rundoc/code_command/background.rb
189
205
  - lib/rundoc/code_command/background/log/clear.rb
@@ -211,11 +227,26 @@ files:
211
227
  - lib/rundoc/code_command/website/visit.rb
212
228
  - lib/rundoc/code_command/write.rb
213
229
  - lib/rundoc/code_section.rb
230
+ - lib/rundoc/context/after_build.rb
231
+ - lib/rundoc/context/execution.rb
214
232
  - lib/rundoc/parser.rb
215
233
  - lib/rundoc/peg_parser.rb
216
234
  - lib/rundoc/version.rb
217
235
  - rundoc.gemspec
218
236
  - test/fixtures/build_logs/rundoc.md
237
+ - test/fixtures/cnb/ruby/download.md
238
+ - test/fixtures/cnb/ruby/image_structure.md
239
+ - test/fixtures/cnb/ruby/intro.md
240
+ - test/fixtures/cnb/ruby/multiple_langs.md
241
+ - test/fixtures/cnb/ruby/rundoc.md
242
+ - test/fixtures/cnb/ruby/what_is_pack_build.md
243
+ - test/fixtures/cnb/shared/call_to_action.md
244
+ - test/fixtures/cnb/shared/configure_builder.md
245
+ - test/fixtures/cnb/shared/install_pack.md
246
+ - test/fixtures/cnb/shared/pack_build.md
247
+ - test/fixtures/cnb/shared/procfile.md
248
+ - test/fixtures/cnb/shared/use_the_image.md
249
+ - test/fixtures/cnb/shared/what_is_a_builder.md
219
250
  - test/fixtures/depend_on/dependency/rundoc.md
220
251
  - test/fixtures/depend_on/main/rundoc.md
221
252
  - test/fixtures/java/rundoc.md
@@ -227,7 +258,12 @@ files:
227
258
  - test/fixtures/require/dependency/rundoc.md
228
259
  - test/fixtures/require/main/rundoc.md
229
260
  - test/fixtures/screenshot/rundoc.md
261
+ - test/fixtures/simple_git/rundoc.md
262
+ - test/integration/after_build_test.rb
230
263
  - test/integration/print_test.rb
264
+ - test/integration/require_test.rb
265
+ - test/integration/website_test.rb
266
+ - test/rundoc/cli_argument_parser_test.rb
231
267
  - test/rundoc/code_commands/append_file_test.rb
232
268
  - test/rundoc/code_commands/background_test.rb
233
269
  - test/rundoc/code_commands/bash_test.rb
@@ -239,6 +275,7 @@ files:
239
275
  - test/rundoc/peg_parser_test.rb
240
276
  - test/rundoc/regex_test.rb
241
277
  - test/rundoc/test_parse_java.rb
278
+ - test/system/exe_cli_test.rb
242
279
  - test/test_helper.rb
243
280
  homepage: https://github.com/schneems/rundoc
244
281
  licenses:
@@ -259,7 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
259
296
  - !ruby/object:Gem::Version
260
297
  version: '0'
261
298
  requirements: []
262
- rubygems_version: 3.5.3
299
+ rubygems_version: 3.5.9
263
300
  signing_key:
264
301
  specification_version: 4
265
302
  summary: RunDOC generates runable code from docs