groovenauts-thor 0.19.1 → 0.19.1.1

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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -24
  3. data/groovenauts-thor.gemspec +1 -1
  4. data/lib/thor/base.rb +1 -1
  5. data/lib/thor/core_ext/ordered_hash.rb +63 -94
  6. data/lib/thor/parser/arguments.rb +1 -1
  7. data/lib/thor/parser/option.rb +0 -15
  8. data/lib/thor/version.rb +1 -1
  9. data/spec/actions/create_file_spec.rb +168 -0
  10. data/spec/actions/create_link_spec.rb +96 -0
  11. data/spec/actions/directory_spec.rb +169 -0
  12. data/spec/actions/empty_directory_spec.rb +129 -0
  13. data/spec/actions/file_manipulation_spec.rb +392 -0
  14. data/spec/actions/inject_into_file_spec.rb +135 -0
  15. data/spec/actions_spec.rb +331 -0
  16. data/spec/base_spec.rb +298 -0
  17. data/spec/command_spec.rb +79 -0
  18. data/spec/core_ext/hash_with_indifferent_access_spec.rb +48 -0
  19. data/spec/core_ext/ordered_hash_spec.rb +115 -0
  20. data/spec/exit_condition_spec.rb +19 -0
  21. data/spec/fixtures/application.rb +2 -0
  22. data/spec/fixtures/app{1}/README +3 -0
  23. data/spec/fixtures/bundle/execute.rb +6 -0
  24. data/spec/fixtures/bundle/main.thor +1 -0
  25. data/spec/fixtures/command.thor +10 -0
  26. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  27. data/spec/fixtures/doc/COMMENTER +11 -0
  28. data/spec/fixtures/doc/README +3 -0
  29. data/spec/fixtures/doc/block_helper.rb +3 -0
  30. data/spec/fixtures/doc/config.rb +1 -0
  31. data/spec/fixtures/doc/config.yaml.tt +1 -0
  32. data/spec/fixtures/doc/excluding/%file_name%.rb.tt +1 -0
  33. data/spec/fixtures/enum.thor +10 -0
  34. data/spec/fixtures/group.thor +128 -0
  35. data/spec/fixtures/invoke.thor +131 -0
  36. data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
  37. data/spec/fixtures/preserve/script.sh +3 -0
  38. data/spec/fixtures/script.thor +220 -0
  39. data/spec/fixtures/subcommand.thor +17 -0
  40. data/spec/group_spec.rb +222 -0
  41. data/spec/helper.rb +80 -0
  42. data/spec/invocation_spec.rb +120 -0
  43. data/spec/line_editor/basic_spec.rb +28 -0
  44. data/spec/line_editor/readline_spec.rb +69 -0
  45. data/spec/line_editor_spec.rb +43 -0
  46. data/spec/parser/argument_spec.rb +53 -0
  47. data/spec/parser/arguments_spec.rb +66 -0
  48. data/spec/parser/option_spec.rb +210 -0
  49. data/spec/parser/options_spec.rb +414 -0
  50. data/spec/quality_spec.rb +75 -0
  51. data/spec/rake_compat_spec.rb +72 -0
  52. data/spec/register_spec.rb +227 -0
  53. data/spec/runner_spec.rb +246 -0
  54. data/spec/sandbox/application.rb +2 -0
  55. data/spec/sandbox/app{1}/README +3 -0
  56. data/spec/sandbox/bundle/execute.rb +6 -0
  57. data/spec/sandbox/bundle/main.thor +1 -0
  58. data/spec/sandbox/command.thor +10 -0
  59. data/spec/sandbox/doc/%file_name%.rb.tt +1 -0
  60. data/spec/sandbox/doc/COMMENTER +11 -0
  61. data/spec/sandbox/doc/README +3 -0
  62. data/spec/sandbox/doc/block_helper.rb +3 -0
  63. data/spec/sandbox/doc/config.rb +1 -0
  64. data/spec/sandbox/doc/config.yaml.tt +1 -0
  65. data/spec/sandbox/doc/excluding/%file_name%.rb.tt +1 -0
  66. data/spec/sandbox/enum.thor +10 -0
  67. data/spec/sandbox/group.thor +128 -0
  68. data/spec/sandbox/invoke.thor +131 -0
  69. data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
  70. data/spec/sandbox/preserve/script.sh +3 -0
  71. data/spec/sandbox/script.thor +220 -0
  72. data/spec/sandbox/subcommand.thor +17 -0
  73. data/spec/shell/basic_spec.rb +337 -0
  74. data/spec/shell/color_spec.rb +119 -0
  75. data/spec/shell/html_spec.rb +31 -0
  76. data/spec/shell_spec.rb +47 -0
  77. data/spec/subcommand_spec.rb +71 -0
  78. data/spec/thor_spec.rb +505 -0
  79. data/spec/util_spec.rb +196 -0
  80. metadata +146 -4
@@ -0,0 +1,96 @@
1
+ require "helper"
2
+ require "thor/actions"
3
+ require "tempfile"
4
+
5
+ describe Thor::Actions::CreateLink do
6
+ before do
7
+ @silence = false
8
+ @hardlink_to = File.join(Dir.tmpdir, "linkdest.rb")
9
+ ::FileUtils.rm_rf(destination_root)
10
+ ::FileUtils.rm_rf(@hardlink_to)
11
+ end
12
+
13
+ def create_link(destination = nil, config = {}, options = {})
14
+ @base = MyCounter.new([1, 2], options, :destination_root => destination_root)
15
+ allow(@base).to receive(:file_name).and_return("rdoc")
16
+
17
+ @tempfile = Tempfile.new("config.rb")
18
+
19
+ @action = Thor::Actions::CreateLink.new(@base, destination, @tempfile.path,
20
+ {:verbose => !@silence}.merge(config))
21
+ end
22
+
23
+ def invoke!
24
+ capture(:stdout) { @action.invoke! }
25
+ end
26
+
27
+ def revoke!
28
+ capture(:stdout) { @action.revoke! }
29
+ end
30
+
31
+ def silence!
32
+ @silence = true
33
+ end
34
+
35
+ describe "#invoke!" do
36
+ it "creates a symbolic link for :symbolic => true" do
37
+ create_link("doc/config.rb", :symbolic => true)
38
+ invoke!
39
+ destination_path = File.join(destination_root, "doc/config.rb")
40
+ expect(File.exist?(destination_path)).to be true
41
+ expect(File.symlink?(destination_path)).to be true
42
+ end
43
+
44
+ it "creates a hard link for :symbolic => false" do
45
+ create_link(@hardlink_to, :symbolic => false)
46
+ invoke!
47
+ destination_path = @hardlink_to
48
+ expect(File.exist?(destination_path)).to be true
49
+ expect(File.symlink?(destination_path)).to be false
50
+ end
51
+
52
+ it "creates a symbolic link by default" do
53
+ create_link("doc/config.rb")
54
+ invoke!
55
+ destination_path = File.join(destination_root, "doc/config.rb")
56
+ expect(File.exist?(destination_path)).to be true
57
+ expect(File.symlink?(destination_path)).to be true
58
+ end
59
+
60
+ it "does not create a link if pretending" do
61
+ create_link("doc/config.rb", {}, :pretend => true)
62
+ invoke!
63
+ expect(File.exist?(File.join(destination_root, "doc/config.rb"))).to be false
64
+ end
65
+
66
+ it "shows created status to the user" do
67
+ create_link("doc/config.rb")
68
+ expect(invoke!).to eq(" create doc/config.rb\n")
69
+ end
70
+
71
+ it "does not show any information if log status is false" do
72
+ silence!
73
+ create_link("doc/config.rb")
74
+ expect(invoke!).to be_empty
75
+ end
76
+ end
77
+
78
+ describe "#identical?" do
79
+ it "returns true if the destination link exists and is identical" do
80
+ create_link("doc/config.rb")
81
+ expect(@action.identical?).to be false
82
+ invoke!
83
+ expect(@action.identical?).to be true
84
+ end
85
+ end
86
+
87
+ describe "#revoke!" do
88
+ it "removes the symbolic link of non-existent destination" do
89
+ create_link("doc/config.rb")
90
+ invoke!
91
+ File.delete(@tempfile.path)
92
+ revoke!
93
+ expect(File.symlink?(@action.destination)).to be false
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,169 @@
1
+ require "helper"
2
+ require "thor/actions"
3
+
4
+ describe Thor::Actions::Directory do
5
+ before do
6
+ ::FileUtils.rm_rf(destination_root)
7
+ allow(invoker).to receive(:file_name).and_return("rdoc")
8
+ end
9
+
10
+ def invoker
11
+ @invoker ||= WhinyGenerator.new([1, 2], {}, :destination_root => destination_root)
12
+ end
13
+
14
+ def revoker
15
+ @revoker ||= WhinyGenerator.new([1, 2], {}, :destination_root => destination_root, :behavior => :revoke)
16
+ end
17
+
18
+ def invoke!(*args, &block)
19
+ capture(:stdout) { invoker.directory(*args, &block) }
20
+ end
21
+
22
+ def revoke!(*args, &block)
23
+ capture(:stdout) { revoker.directory(*args, &block) }
24
+ end
25
+
26
+ def exists_and_identical?(source_path, destination_path)
27
+ %w[config.rb README].each do |file|
28
+ source = File.join(source_root, source_path, file)
29
+ destination = File.join(destination_root, destination_path, file)
30
+
31
+ expect(File.exist?(destination)).to be true
32
+ expect(FileUtils.identical?(source, destination)).to be true
33
+ end
34
+ end
35
+
36
+ describe "#invoke!" do
37
+ it "raises an error if the source does not exist" do
38
+ expect do
39
+ invoke! "unknown"
40
+ end.to raise_error(Thor::Error, /Could not find "unknown" in any of your source paths/)
41
+ end
42
+
43
+ it "does not create a directory in pretend mode" do
44
+ invoke! "doc", "ghost", :pretend => true
45
+ expect(File.exist?("ghost")).to be false
46
+ end
47
+
48
+ it "copies the whole directory recursively to the default destination" do
49
+ invoke! "doc"
50
+ exists_and_identical?("doc", "doc")
51
+ end
52
+
53
+ it "copies the whole directory recursively to the specified destination" do
54
+ invoke! "doc", "docs"
55
+ exists_and_identical?("doc", "docs")
56
+ end
57
+
58
+ it "copies only the first level files if recursive" do
59
+ invoke! ".", "commands", :recursive => false
60
+
61
+ file = File.join(destination_root, "commands", "group.thor")
62
+ expect(File.exist?(file)).to be true
63
+
64
+ file = File.join(destination_root, "commands", "doc")
65
+ expect(File.exist?(file)).to be false
66
+
67
+ file = File.join(destination_root, "commands", "doc", "README")
68
+ expect(File.exist?(file)).to be false
69
+ end
70
+
71
+ it "ignores files within excluding/ directories when exclude_pattern is provided" do
72
+ invoke! "doc", "docs", :exclude_pattern => /excluding\//
73
+ file = File.join(destination_root, "docs", "excluding", "rdoc.rb")
74
+ expect(File.exist?(file)).to be false
75
+ end
76
+
77
+ it "copies and evaluates files within excluding/ directory when no exclude_pattern is present" do
78
+ invoke! "doc", "docs"
79
+ file = File.join(destination_root, "docs", "excluding", "rdoc.rb")
80
+ expect(File.exist?(file)).to be true
81
+ expect(File.read(file)).to eq("BAR = BAR\n")
82
+ end
83
+
84
+ it "copies files from the source relative to the current path" do
85
+ invoker.inside "doc" do
86
+ invoke! "."
87
+ end
88
+ exists_and_identical?("doc", "doc")
89
+ end
90
+
91
+ it "copies and evaluates templates" do
92
+ invoke! "doc", "docs"
93
+ file = File.join(destination_root, "docs", "rdoc.rb")
94
+ expect(File.exist?(file)).to be true
95
+ expect(File.read(file)).to eq("FOO = FOO\n")
96
+ end
97
+
98
+ it "copies directories and preserves file mode" do
99
+ invoke! "preserve", "preserved", :mode => :preserve
100
+ original = File.join(source_root, "preserve", "script.sh")
101
+ copy = File.join(destination_root, "preserved", "script.sh")
102
+ expect(File.stat(original).mode).to eq(File.stat(copy).mode)
103
+ end
104
+
105
+ it "copies directories" do
106
+ invoke! "doc", "docs"
107
+ file = File.join(destination_root, "docs", "components")
108
+ expect(File.exist?(file)).to be true
109
+ expect(File.directory?(file)).to be true
110
+ end
111
+
112
+ it "does not copy .empty_directory files" do
113
+ invoke! "doc", "docs"
114
+ file = File.join(destination_root, "docs", "components", ".empty_directory")
115
+ expect(File.exist?(file)).to be false
116
+ end
117
+
118
+ it "copies directories even if they are empty" do
119
+ invoke! "doc/components", "docs/components"
120
+ file = File.join(destination_root, "docs", "components")
121
+ expect(File.exist?(file)).to be true
122
+ end
123
+
124
+ it "does not copy empty directories twice" do
125
+ content = invoke!("doc/components", "docs/components")
126
+ expect(content).not_to match(/exist/)
127
+ end
128
+
129
+ it "logs status" do
130
+ content = invoke!("doc")
131
+ expect(content).to match(/create doc\/README/)
132
+ expect(content).to match(/create doc\/config\.rb/)
133
+ expect(content).to match(/create doc\/rdoc\.rb/)
134
+ expect(content).to match(/create doc\/components/)
135
+ end
136
+
137
+ it "yields a block" do
138
+ checked = false
139
+ invoke!("doc") do |content|
140
+ checked ||= !!(content =~ /FOO/)
141
+ end
142
+ expect(checked).to be true
143
+ end
144
+
145
+ it "works with glob characters in the path" do
146
+ content = invoke!("app{1}")
147
+ expect(content).to match(/create app\{1\}\/README/)
148
+ end
149
+ end
150
+
151
+ describe "#revoke!" do
152
+ it "removes the destination file" do
153
+ invoke! "doc"
154
+ revoke! "doc"
155
+
156
+ expect(File.exist?(File.join(destination_root, "doc", "README"))).to be false
157
+ expect(File.exist?(File.join(destination_root, "doc", "config.rb"))).to be false
158
+ expect(File.exist?(File.join(destination_root, "doc", "components"))).to be false
159
+ end
160
+
161
+ it "works with glob characters in the path" do
162
+ invoke! "app{1}"
163
+ expect(File.exist?(File.join(destination_root, "app{1}", "README"))).to be true
164
+
165
+ revoke! "app{1}"
166
+ expect(File.exist?(File.join(destination_root, "app{1}", "README"))).to be false
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,129 @@
1
+ require "helper"
2
+ require "thor/actions"
3
+
4
+ describe Thor::Actions::EmptyDirectory do
5
+ before do
6
+ ::FileUtils.rm_rf(destination_root)
7
+ end
8
+
9
+ def empty_directory(destination, options = {})
10
+ @action = Thor::Actions::EmptyDirectory.new(base, destination)
11
+ end
12
+
13
+ def invoke!
14
+ capture(:stdout) { @action.invoke! }
15
+ end
16
+
17
+ def revoke!
18
+ capture(:stdout) { @action.revoke! }
19
+ end
20
+
21
+ def base
22
+ @base ||= MyCounter.new([1, 2], {}, :destination_root => destination_root)
23
+ end
24
+
25
+ describe "#destination" do
26
+ it "returns the full destination with the destination_root" do
27
+ expect(empty_directory("doc").destination).to eq(File.join(destination_root, "doc"))
28
+ end
29
+
30
+ it "takes relative root into account" do
31
+ base.inside("doc") do
32
+ expect(empty_directory("contents").destination).to eq(File.join(destination_root, "doc", "contents"))
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#relative_destination" do
38
+ it "returns the relative destination to the original destination root" do
39
+ base.inside("doc") do
40
+ expect(empty_directory("contents").relative_destination).to eq("doc/contents")
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#given_destination" do
46
+ it "returns the destination supplied by the user" do
47
+ base.inside("doc") do
48
+ expect(empty_directory("contents").given_destination).to eq("contents")
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "#invoke!" do
54
+ it "copies the file to the specified destination" do
55
+ empty_directory("doc")
56
+ invoke!
57
+ expect(File.exist?(File.join(destination_root, "doc"))).to be true
58
+ end
59
+
60
+ it "shows created status to the user" do
61
+ empty_directory("doc")
62
+ expect(invoke!).to eq(" create doc\n")
63
+ end
64
+
65
+ it "does not create a directory if pretending" do
66
+ base.inside("foo", :pretend => true) do
67
+ empty_directory("ghost")
68
+ end
69
+ expect(File.exist?(File.join(base.destination_root, "ghost"))).to be false
70
+ end
71
+
72
+ describe "when directory exists" do
73
+ it "shows exist status" do
74
+ empty_directory("doc")
75
+ invoke!
76
+ expect(invoke!).to eq(" exist doc\n")
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#revoke!" do
82
+ it "removes the destination file" do
83
+ empty_directory("doc")
84
+ invoke!
85
+ revoke!
86
+ expect(File.exist?(@action.destination)).to be false
87
+ end
88
+ end
89
+
90
+ describe "#exists?" do
91
+ it "returns true if the destination file exists" do
92
+ empty_directory("doc")
93
+ expect(@action.exists?).to be false
94
+ invoke!
95
+ expect(@action.exists?).to be true
96
+ end
97
+ end
98
+
99
+ context "protected methods" do
100
+ describe "#convert_encoded_instructions" do
101
+ before do
102
+ empty_directory("test_dir")
103
+ allow(@action.base).to receive(:file_name).and_return("expected")
104
+ end
105
+
106
+ it "accepts and executes a 'legal' %\w+% encoded instruction" do
107
+ expect(@action.send(:convert_encoded_instructions, "%file_name%.txt")).to eq("expected.txt")
108
+ end
109
+
110
+ it "accepts and executes a private %\w+% encoded instruction" do
111
+ @action.base.extend Module.new {
112
+ def private_file_name
113
+ "expected"
114
+ end
115
+ private :private_file_name
116
+ }
117
+ expect(@action.send(:convert_encoded_instructions, "%private_file_name%.txt")).to eq("expected.txt")
118
+ end
119
+
120
+ it "ignores an 'illegal' %\w+% encoded instruction" do
121
+ expect(@action.send(:convert_encoded_instructions, "%some_name%.txt")).to eq("%some_name%.txt")
122
+ end
123
+
124
+ it "ignores incorrectly encoded instruction" do
125
+ expect(@action.send(:convert_encoded_instructions, "%some.name%.txt")).to eq("%some.name%.txt")
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,392 @@
1
+ require "helper"
2
+
3
+ class Application; end
4
+
5
+ describe Thor::Actions do
6
+ def runner(options = {})
7
+ @runner ||= MyCounter.new([1], options, :destination_root => destination_root)
8
+ end
9
+
10
+ def action(*args, &block)
11
+ capture(:stdout) { runner.send(*args, &block) }
12
+ end
13
+
14
+ def exists_and_identical?(source, destination)
15
+ destination = File.join(destination_root, destination)
16
+ expect(File.exist?(destination)).to be true
17
+
18
+ source = File.join(source_root, source)
19
+ expect(FileUtils).to be_identical(source, destination)
20
+ end
21
+
22
+ def file
23
+ File.join(destination_root, "foo")
24
+ end
25
+
26
+ before do
27
+ ::FileUtils.rm_rf(destination_root)
28
+ end
29
+
30
+ describe "#chmod" do
31
+ it "executes the command given" do
32
+ expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName
33
+ action :chmod, "foo", 0755
34
+ end
35
+
36
+ it "does not execute the command if pretending" do
37
+ expect(FileUtils).not_to receive(:chmod_R) # rubocop:disable SymbolName
38
+ runner(:pretend => true)
39
+ action :chmod, "foo", 0755
40
+ end
41
+
42
+ it "logs status" do
43
+ expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName
44
+ expect(action(:chmod, "foo", 0755)).to eq(" chmod foo\n")
45
+ end
46
+
47
+ it "does not log status if required" do
48
+ expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName
49
+ expect(action(:chmod, "foo", 0755, :verbose => false)).to be_empty
50
+ end
51
+ end
52
+
53
+ describe "#copy_file" do
54
+ it "copies file from source to default destination" do
55
+ action :copy_file, "command.thor"
56
+ exists_and_identical?("command.thor", "command.thor")
57
+ end
58
+
59
+ it "copies file from source to the specified destination" do
60
+ action :copy_file, "command.thor", "foo.thor"
61
+ exists_and_identical?("command.thor", "foo.thor")
62
+ end
63
+
64
+ it "copies file from the source relative to the current path" do
65
+ runner.inside("doc") do
66
+ action :copy_file, "README"
67
+ end
68
+ exists_and_identical?("doc/README", "doc/README")
69
+ end
70
+
71
+ it "copies file from source to default destination and preserves file mode" do
72
+ action :copy_file, "preserve/script.sh", :mode => :preserve
73
+ original = File.join(source_root, "preserve/script.sh")
74
+ copy = File.join(destination_root, "preserve/script.sh")
75
+ expect(File.stat(original).mode).to eq(File.stat(copy).mode)
76
+ end
77
+
78
+ it "logs status" do
79
+ expect(action(:copy_file, "command.thor")).to eq(" create command.thor\n")
80
+ end
81
+
82
+ it "accepts a block to change output" do
83
+ action :copy_file, "command.thor" do |content|
84
+ "OMG" + content
85
+ end
86
+ expect(File.read(File.join(destination_root, "command.thor"))).to match(/^OMG/)
87
+ end
88
+ end
89
+
90
+ describe "#link_file" do
91
+ it "links file from source to default destination" do
92
+ action :link_file, "command.thor"
93
+ exists_and_identical?("command.thor", "command.thor")
94
+ end
95
+
96
+ it "links file from source to the specified destination" do
97
+ action :link_file, "command.thor", "foo.thor"
98
+ exists_and_identical?("command.thor", "foo.thor")
99
+ end
100
+
101
+ it "links file from the source relative to the current path" do
102
+ runner.inside("doc") do
103
+ action :link_file, "README"
104
+ end
105
+ exists_and_identical?("doc/README", "doc/README")
106
+ end
107
+
108
+ it "logs status" do
109
+ expect(action(:link_file, "command.thor")).to eq(" create command.thor\n")
110
+ end
111
+ end
112
+
113
+ describe "#get" do
114
+ it "copies file from source to the specified destination" do
115
+ action :get, "doc/README", "docs/README"
116
+ exists_and_identical?("doc/README", "docs/README")
117
+ end
118
+
119
+ it "uses just the source basename as destination if none is specified" do
120
+ action :get, "doc/README"
121
+ exists_and_identical?("doc/README", "README")
122
+ end
123
+
124
+ it "allows the destination to be set as a block result" do
125
+ action(:get, "doc/README") { |c| "docs/README" }
126
+ exists_and_identical?("doc/README", "docs/README")
127
+ end
128
+
129
+ it "yields file content to a block" do
130
+ action :get, "doc/README" do |content|
131
+ expect(content).to eq("__start__\nREADME\n__end__\n")
132
+ end
133
+ end
134
+
135
+ it "logs status" do
136
+ expect(action(:get, "doc/README", "docs/README")).to eq(" create docs/README\n")
137
+ end
138
+
139
+ it "accepts http remote sources" do
140
+ body = "__start__\nHTTPFILE\n__end__\n"
141
+ FakeWeb.register_uri(:get, "http://example.com/file.txt", :body => body)
142
+ action :get, "http://example.com/file.txt" do |content|
143
+ expect(content).to eq(body)
144
+ end
145
+ FakeWeb.clean_registry
146
+ end
147
+
148
+ it "accepts https remote sources" do
149
+ body = "__start__\nHTTPSFILE\n__end__\n"
150
+ FakeWeb.register_uri(:get, "https://example.com/file.txt", :body => body)
151
+ action :get, "https://example.com/file.txt" do |content|
152
+ expect(content).to eq(body)
153
+ end
154
+ FakeWeb.clean_registry
155
+ end
156
+ end
157
+
158
+ describe "#template" do
159
+ it "allows using block helpers in the template" do
160
+ action :template, "doc/block_helper.rb"
161
+
162
+ file = File.join(destination_root, "doc/block_helper.rb")
163
+ expect(File.read(file)).to eq("Hello world!")
164
+ end
165
+
166
+ it "evaluates the template given as source" do
167
+ runner.instance_variable_set("@klass", "Config")
168
+ action :template, "doc/config.rb"
169
+
170
+ file = File.join(destination_root, "doc/config.rb")
171
+ expect(File.read(file)).to eq("class Config; end\n")
172
+ end
173
+
174
+ it "copies the template to the specified destination" do
175
+ runner.instance_variable_set("@klass", "Config")
176
+ action :template, "doc/config.rb", "doc/configuration.rb"
177
+ file = File.join(destination_root, "doc/configuration.rb")
178
+ expect(File.exist?(file)).to be true
179
+ end
180
+
181
+ it "converts encoded instructions" do
182
+ expect(runner).to receive(:file_name).and_return("rdoc")
183
+ action :template, "doc/%file_name%.rb.tt"
184
+ file = File.join(destination_root, "doc/rdoc.rb")
185
+ expect(File.exist?(file)).to be true
186
+ end
187
+
188
+ it "accepts filename without .tt for template method" do
189
+ expect(runner).to receive(:file_name).and_return("rdoc")
190
+ action :template, "doc/%file_name%.rb"
191
+ file = File.join(destination_root, "doc/rdoc.rb")
192
+ expect(File.exist?(file)).to be true
193
+ end
194
+
195
+ it "logs status" do
196
+ runner.instance_variable_set("@klass", "Config")
197
+ expect(capture(:stdout) { runner.template("doc/config.rb") }).to eq(" create doc/config.rb\n")
198
+ end
199
+
200
+ it "accepts a block to change output" do
201
+ runner.instance_variable_set("@klass", "Config")
202
+ action :template, "doc/config.rb" do |content|
203
+ "OMG" + content
204
+ end
205
+ expect(File.read(File.join(destination_root, "doc/config.rb"))).to match(/^OMG/)
206
+ end
207
+
208
+ it "guesses the destination name when given only a source" do
209
+ action :template, "doc/config.yaml.tt"
210
+
211
+ file = File.join(destination_root, "doc/config.yaml")
212
+ expect(File.exist?(file)).to be true
213
+ end
214
+ end
215
+
216
+ describe "when changing existent files" do
217
+ before do
218
+ ::FileUtils.cp_r(source_root, destination_root)
219
+ end
220
+
221
+ def file
222
+ File.join(destination_root, "doc", "README")
223
+ end
224
+
225
+ describe "#remove_file" do
226
+ it "removes the file given" do
227
+ action :remove_file, "doc/README"
228
+ expect(File.exist?(file)).to be false
229
+ end
230
+
231
+ it "removes directories too" do
232
+ action :remove_dir, "doc"
233
+ expect(File.exist?(File.join(destination_root, "doc"))).to be false
234
+ end
235
+
236
+ it "does not remove if pretending" do
237
+ runner(:pretend => true)
238
+ action :remove_file, "doc/README"
239
+ expect(File.exist?(file)).to be true
240
+ end
241
+
242
+ it "logs status" do
243
+ expect(action(:remove_file, "doc/README")).to eq(" remove doc/README\n")
244
+ end
245
+
246
+ it "does not log status if required" do
247
+ expect(action(:remove_file, "doc/README", :verbose => false)).to be_empty
248
+ end
249
+ end
250
+
251
+ describe "#gsub_file" do
252
+ it "replaces the content in the file" do
253
+ action :gsub_file, "doc/README", "__start__", "START"
254
+ expect(File.binread(file)).to eq("START\nREADME\n__end__\n")
255
+ end
256
+
257
+ it "does not replace if pretending" do
258
+ runner(:pretend => true)
259
+ action :gsub_file, "doc/README", "__start__", "START"
260
+ expect(File.binread(file)).to eq("__start__\nREADME\n__end__\n")
261
+ end
262
+
263
+ it "accepts a block" do
264
+ action(:gsub_file, "doc/README", "__start__") { |match| match.gsub("__", "").upcase }
265
+ expect(File.binread(file)).to eq("START\nREADME\n__end__\n")
266
+ end
267
+
268
+ it "logs status" do
269
+ expect(action(:gsub_file, "doc/README", "__start__", "START")).to eq(" gsub doc/README\n")
270
+ end
271
+
272
+ it "does not log status if required" do
273
+ expect(action(:gsub_file, file, "__", :verbose => false) { |match| match * 2 }).to be_empty
274
+ end
275
+ end
276
+
277
+ describe "#append_to_file" do
278
+ it "appends content to the file" do
279
+ action :append_to_file, "doc/README", "END\n"
280
+ expect(File.binread(file)).to eq("__start__\nREADME\n__end__\nEND\n")
281
+ end
282
+
283
+ it "accepts a block" do
284
+ action(:append_to_file, "doc/README") { "END\n" }
285
+ expect(File.binread(file)).to eq("__start__\nREADME\n__end__\nEND\n")
286
+ end
287
+
288
+ it "logs status" do
289
+ expect(action(:append_to_file, "doc/README", "END")).to eq(" append doc/README\n")
290
+ end
291
+ end
292
+
293
+ describe "#prepend_to_file" do
294
+ it "prepends content to the file" do
295
+ action :prepend_to_file, "doc/README", "START\n"
296
+ expect(File.binread(file)).to eq("START\n__start__\nREADME\n__end__\n")
297
+ end
298
+
299
+ it "accepts a block" do
300
+ action(:prepend_to_file, "doc/README") { "START\n" }
301
+ expect(File.binread(file)).to eq("START\n__start__\nREADME\n__end__\n")
302
+ end
303
+
304
+ it "logs status" do
305
+ expect(action(:prepend_to_file, "doc/README", "START")).to eq(" prepend doc/README\n")
306
+ end
307
+ end
308
+
309
+ describe "#inject_into_class" do
310
+ def file
311
+ File.join(destination_root, "application.rb")
312
+ end
313
+
314
+ it "appends content to a class" do
315
+ action :inject_into_class, "application.rb", Application, " filter_parameters :password\n"
316
+ expect(File.binread(file)).to eq("class Application < Base\n filter_parameters :password\nend\n")
317
+ end
318
+
319
+ it "accepts a block" do
320
+ action(:inject_into_class, "application.rb", Application) { " filter_parameters :password\n" }
321
+ expect(File.binread(file)).to eq("class Application < Base\n filter_parameters :password\nend\n")
322
+ end
323
+
324
+ it "logs status" do
325
+ expect(action(:inject_into_class, "application.rb", Application, " filter_parameters :password\n")).to eq(" insert application.rb\n")
326
+ end
327
+
328
+ it "does not append if class name does not match" do
329
+ action :inject_into_class, "application.rb", "App", " filter_parameters :password\n"
330
+ expect(File.binread(file)).to eq("class Application < Base\nend\n")
331
+ end
332
+ end
333
+ end
334
+
335
+ describe "when adjusting comments" do
336
+ before do
337
+ ::FileUtils.cp_r(source_root, destination_root)
338
+ end
339
+
340
+ def file
341
+ File.join(destination_root, "doc", "COMMENTER")
342
+ end
343
+
344
+ unmodified_comments_file = /__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/
345
+
346
+ describe "#uncomment_lines" do
347
+ it "uncomments all matching lines in the file" do
348
+ action :uncomment_lines, "doc/COMMENTER", "green"
349
+ expect(File.binread(file)).to match(/__start__\n greenblue\n#\n# yellowblue\n#yellowred\n greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
350
+
351
+ action :uncomment_lines, "doc/COMMENTER", "red"
352
+ expect(File.binread(file)).to match(/__start__\n greenblue\n#\n# yellowblue\nyellowred\n greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
353
+ end
354
+
355
+ it "correctly uncomments lines with hashes in them" do
356
+ action :uncomment_lines, "doc/COMMENTER", "ind#igo"
357
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n ind#igo\n ind#igo\n__end__/)
358
+ end
359
+
360
+ it "does not modify already uncommented lines in the file" do
361
+ action :uncomment_lines, "doc/COMMENTER", "orange"
362
+ action :uncomment_lines, "doc/COMMENTER", "purple"
363
+ expect(File.binread(file)).to match(unmodified_comments_file)
364
+ end
365
+
366
+ it "does not uncomment the wrong line when uncommenting lines preceded by blank commented line" do
367
+ action :uncomment_lines, "doc/COMMENTER", "yellow"
368
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\nyellowblue\nyellowred\n #greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
369
+ end
370
+ end
371
+
372
+ describe "#comment_lines" do
373
+ it "comments lines which are not commented" do
374
+ action :comment_lines, "doc/COMMENTER", "orange"
375
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\n# orange\n purple\n ind#igo\n # ind#igo\n__end__/)
376
+
377
+ action :comment_lines, "doc/COMMENTER", "purple"
378
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\n# orange\n # purple\n ind#igo\n # ind#igo\n__end__/)
379
+ end
380
+
381
+ it "correctly comments lines with hashes in them" do
382
+ action :comment_lines, "doc/COMMENTER", "ind#igo"
383
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n # ind#igo\n # ind#igo\n__end__/)
384
+ end
385
+
386
+ it "does not modify already commented lines" do
387
+ action :comment_lines, "doc/COMMENTER", "green"
388
+ expect(File.binread(file)).to match(unmodified_comments_file)
389
+ end
390
+ end
391
+ end
392
+ end