rubycut-babushka 0.10.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +31 -0
  3. data/README.markdown +246 -0
  4. data/Rakefile +26 -0
  5. data/bin/babushka +11 -0
  6. data/deps/babushka.rb +101 -0
  7. data/deps/dev.rb +12 -0
  8. data/deps/fhs.rb +31 -0
  9. data/deps/git.rb +29 -0
  10. data/deps/homebrew.rb +30 -0
  11. data/deps/os_x.rb +33 -0
  12. data/deps/packages.rb +22 -0
  13. data/deps/pkg_managers.rb +110 -0
  14. data/deps/ruby.rb +23 -0
  15. data/deps/rubygems.rb +24 -0
  16. data/deps/system.rb +10 -0
  17. data/deps/templates/app.rb +68 -0
  18. data/deps/templates/external.rb +12 -0
  19. data/deps/templates/installer.rb +31 -0
  20. data/deps/templates/managed.rb +105 -0
  21. data/deps/templates/ppa.rb +24 -0
  22. data/deps/templates/src.rb +42 -0
  23. data/deps/templates/tmbundle.rb +15 -0
  24. data/lib/babushka.rb +28 -0
  25. data/lib/babushka/accepts_block_for.rb +72 -0
  26. data/lib/babushka/accepts_list_for.rb +49 -0
  27. data/lib/babushka/accepts_value_for.rb +24 -0
  28. data/lib/babushka/base.rb +78 -0
  29. data/lib/babushka/bug_reporter.rb +55 -0
  30. data/lib/babushka/cmdline.rb +133 -0
  31. data/lib/babushka/cmdline/handler.rb +41 -0
  32. data/lib/babushka/cmdline/helpers.rb +127 -0
  33. data/lib/babushka/cmdline/parser.rb +69 -0
  34. data/lib/babushka/colorizer.rb +59 -0
  35. data/lib/babushka/core_patches/array.rb +171 -0
  36. data/lib/babushka/core_patches/blank.rb +22 -0
  37. data/lib/babushka/core_patches/bytes.rb +52 -0
  38. data/lib/babushka/core_patches/hash.rb +107 -0
  39. data/lib/babushka/core_patches/hashish.rb +14 -0
  40. data/lib/babushka/core_patches/integer.rb +25 -0
  41. data/lib/babushka/core_patches/io.rb +8 -0
  42. data/lib/babushka/core_patches/numeric.rb +16 -0
  43. data/lib/babushka/core_patches/object.rb +27 -0
  44. data/lib/babushka/core_patches/string.rb +116 -0
  45. data/lib/babushka/core_patches/symbol.rb +12 -0
  46. data/lib/babushka/core_patches/try.rb +15 -0
  47. data/lib/babushka/core_patches/uri.rb +24 -0
  48. data/lib/babushka/dep.rb +470 -0
  49. data/lib/babushka/dep_context.rb +18 -0
  50. data/lib/babushka/dep_definer.rb +115 -0
  51. data/lib/babushka/dep_pool.rb +49 -0
  52. data/lib/babushka/dep_runner.rb +85 -0
  53. data/lib/babushka/dsl.rb +26 -0
  54. data/lib/babushka/git_repo.rb +185 -0
  55. data/lib/babushka/helpers/git_helpers.rb +32 -0
  56. data/lib/babushka/helpers/log_helpers.rb +176 -0
  57. data/lib/babushka/helpers/path_helpers.rb +34 -0
  58. data/lib/babushka/helpers/run_helpers.rb +145 -0
  59. data/lib/babushka/helpers/shell_helpers.rb +229 -0
  60. data/lib/babushka/helpers/suggest_helpers.rb +16 -0
  61. data/lib/babushka/helpers/uri_helpers.rb +36 -0
  62. data/lib/babushka/ip.rb +160 -0
  63. data/lib/babushka/lambda_chooser.rb +40 -0
  64. data/lib/babushka/levenshtein.rb +125 -0
  65. data/lib/babushka/meta_dep.rb +65 -0
  66. data/lib/babushka/meta_dep_context.rb +15 -0
  67. data/lib/babushka/parameter.rb +143 -0
  68. data/lib/babushka/pkg_helper.rb +81 -0
  69. data/lib/babushka/pkg_helpers/apt_helper.rb +61 -0
  70. data/lib/babushka/pkg_helpers/base_helper.rb +19 -0
  71. data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +48 -0
  72. data/lib/babushka/pkg_helpers/binports_helper.rb +34 -0
  73. data/lib/babushka/pkg_helpers/brew_helper.rb +110 -0
  74. data/lib/babushka/pkg_helpers/gem_helper.rb +120 -0
  75. data/lib/babushka/pkg_helpers/macports_helper.rb +22 -0
  76. data/lib/babushka/pkg_helpers/npm_helper.rb +45 -0
  77. data/lib/babushka/pkg_helpers/pacman_helper.rb +27 -0
  78. data/lib/babushka/pkg_helpers/pip_helper.rb +45 -0
  79. data/lib/babushka/pkg_helpers/src_helper.rb +16 -0
  80. data/lib/babushka/pkg_helpers/yum_helper.rb +25 -0
  81. data/lib/babushka/popen.rb +40 -0
  82. data/lib/babushka/prompt.rb +176 -0
  83. data/lib/babushka/renderable.rb +67 -0
  84. data/lib/babushka/resource.rb +215 -0
  85. data/lib/babushka/run_reporter.rb +60 -0
  86. data/lib/babushka/shell.rb +108 -0
  87. data/lib/babushka/source.rb +216 -0
  88. data/lib/babushka/source_pool.rb +146 -0
  89. data/lib/babushka/system_definitions.rb +97 -0
  90. data/lib/babushka/system_profile.rb +210 -0
  91. data/lib/babushka/task.rb +142 -0
  92. data/lib/babushka/vars.rb +108 -0
  93. data/lib/babushka/version_of.rb +65 -0
  94. data/lib/babushka/version_str.rb +57 -0
  95. data/lib/babushka/xml_string.rb +28 -0
  96. data/lib/components.rb +82 -0
  97. data/lib/fancypath/fancypath.rb +200 -0
  98. data/lib/inkan/inkan.rb +76 -0
  99. data/spec/acceptance/acceptance.rb +43 -0
  100. data/spec/acceptance_helper.rb +113 -0
  101. data/spec/archives/Blah.app.zip +0 -0
  102. data/spec/archives/archive.tar +0 -0
  103. data/spec/archives/archive.tar.bz2 +0 -0
  104. data/spec/archives/archive.tar.gz +0 -0
  105. data/spec/archives/archive.tbz2 +0 -0
  106. data/spec/archives/archive.tgz +0 -0
  107. data/spec/archives/archive.zip +0 -0
  108. data/spec/archives/content.txt +5 -0
  109. data/spec/archives/invalid_archive +5 -0
  110. data/spec/archives/nested archive/content.txt +5 -0
  111. data/spec/archives/nested_archive.tar +0 -0
  112. data/spec/archives/really_a_gzip.zip +0 -0
  113. data/spec/archives/test-0.3.1.tgz +0 -0
  114. data/spec/archives/tgz_archive +0 -0
  115. data/spec/archives/zip_without_extension +0 -0
  116. data/spec/babushka/accepts_for_spec.rb +174 -0
  117. data/spec/babushka/accepts_for_support.rb +72 -0
  118. data/spec/babushka/cmdline/console_spec.rb +11 -0
  119. data/spec/babushka/cmdline/help_spec.rb +61 -0
  120. data/spec/babushka/cmdline/version_spec.rb +10 -0
  121. data/spec/babushka/core_patches_spec.rb +171 -0
  122. data/spec/babushka/dep_context_spec.rb +58 -0
  123. data/spec/babushka/dep_definer_spec.rb +152 -0
  124. data/spec/babushka/dep_definer_support.rb +36 -0
  125. data/spec/babushka/dep_spec.rb +567 -0
  126. data/spec/babushka/dep_support.rb +29 -0
  127. data/spec/babushka/deps_spec.rb +113 -0
  128. data/spec/babushka/gem_helper_spec.rb +90 -0
  129. data/spec/babushka/git_repo_spec.rb +396 -0
  130. data/spec/babushka/ip_spec.rb +131 -0
  131. data/spec/babushka/lambda_chooser_spec.rb +115 -0
  132. data/spec/babushka/meta_dep_definer_spec.rb +127 -0
  133. data/spec/babushka/meta_dep_wrapper_spec.rb +32 -0
  134. data/spec/babushka/parameter_spec.rb +135 -0
  135. data/spec/babushka/path_helpers_spec.rb +102 -0
  136. data/spec/babushka/prompt_spec.rb +188 -0
  137. data/spec/babushka/renderable_spec.rb +100 -0
  138. data/spec/babushka/resource_spec.rb +141 -0
  139. data/spec/babushka/run_helpers_spec.rb +26 -0
  140. data/spec/babushka/shell_helpers_spec.rb +244 -0
  141. data/spec/babushka/shell_spec.rb +19 -0
  142. data/spec/babushka/source_pool_spec.rb +320 -0
  143. data/spec/babushka/source_pool_support.rb +31 -0
  144. data/spec/babushka/source_spec.rb +382 -0
  145. data/spec/babushka/source_support.rb +17 -0
  146. data/spec/babushka/system_profile_spec.rb +61 -0
  147. data/spec/babushka/task_spec.rb +141 -0
  148. data/spec/babushka/uri_spec.rb +13 -0
  149. data/spec/babushka/vars_spec.rb +59 -0
  150. data/spec/babushka/version_of_spec.rb +110 -0
  151. data/spec/babushka/version_str_spec.rb +130 -0
  152. data/spec/babushka/version_str_support.rb +37 -0
  153. data/spec/babushka/xml_string_spec.rb +98 -0
  154. data/spec/deps/bad/broken.rb +7 -0
  155. data/spec/deps/bad/working.rb +3 -0
  156. data/spec/deps/good/meta.rb +14 -0
  157. data/spec/deps/good/test.rb +11 -0
  158. data/spec/deps/outer/deps.rb +19 -0
  159. data/spec/deps/outer/more deps.rb +11 -0
  160. data/spec/deps/params/params.rb +10 -0
  161. data/spec/fancypath/fancypath_spec.rb +272 -0
  162. data/spec/fancypath_support.rb +10 -0
  163. data/spec/inkan/inkan_spec.rb +217 -0
  164. data/spec/renderable/different_example.conf.erb +4 -0
  165. data/spec/renderable/example.conf.erb +3 -0
  166. data/spec/renderable/example.sh +6 -0
  167. data/spec/renderable/with_binding.conf.erb +4 -0
  168. data/spec/renderable/xml_example.conf.erb +8 -0
  169. data/spec/repos/remote.git.tgz +0 -0
  170. data/spec/spec_helper.rb +87 -0
  171. metadata +238 -0
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe "cd" do
4
+ before do
5
+ @tmp_dir = tmp_prefix
6
+ `mkdir -p '#{@tmp_dir}'`
7
+ @tmp_dir_2 = File.join(tmp_prefix, '2')
8
+ `mkdir -p '#{@tmp_dir_2}'`
9
+
10
+ @original_pwd = Dir.pwd
11
+
12
+ @nonexistent_dir = File.join(tmp_prefix, 'nonexistent')
13
+ Dir.rmdir(@nonexistent_dir) if File.directory?(@nonexistent_dir)
14
+ end
15
+
16
+ it "should yield if no dir is given" do
17
+ has_yielded = false
18
+ cd(nil) {|path|
19
+ path.should be_an_instance_of(Fancypath)
20
+ Dir.pwd.should == @original_pwd
21
+ has_yielded = true
22
+ }
23
+ has_yielded.should be_true
24
+ end
25
+
26
+ it "should yield if no chdir is required" do
27
+ has_yielded = false
28
+ cd(@original_pwd) {|path|
29
+ path.should be_an_instance_of(Fancypath)
30
+ Dir.pwd.should == @original_pwd
31
+ has_yielded = true
32
+ }
33
+ has_yielded.should be_true
34
+ end
35
+ it "should change dir for the duration of the block" do
36
+ has_yielded = false
37
+ cd(@tmp_dir) {
38
+ Dir.pwd.should == @tmp_dir
39
+ has_yielded = true
40
+ }
41
+ has_yielded.should be_true
42
+ Dir.pwd.should == @original_pwd
43
+ end
44
+ it "should work recursively" do
45
+ cd(@tmp_dir) {
46
+ Dir.pwd.should == @tmp_dir
47
+ cd(@tmp_dir_2) {
48
+ Dir.pwd.should == @tmp_dir_2
49
+ }
50
+ Dir.pwd.should == @tmp_dir
51
+ }
52
+ Dir.pwd.should == @original_pwd
53
+ end
54
+ it "should fail on nonexistent dirs" do
55
+ L{ cd(@nonexistent_dir) }.should raise_error(Errno::ENOENT)
56
+ end
57
+ it "should create nonexistent dirs if :create => true is specified" do
58
+ cd(@nonexistent_dir, :create => true) {
59
+ Dir.pwd.should == @nonexistent_dir
60
+ }
61
+ Dir.pwd.should == @original_pwd
62
+ end
63
+ after {
64
+ Dir.rmdir(@nonexistent_dir) if File.directory?(@nonexistent_dir)
65
+ }
66
+ end
67
+
68
+ describe "in_build_dir" do
69
+ before {
70
+ @original_pwd = Dir.pwd
71
+ }
72
+ it "should change to the build dir with no args" do
73
+ in_build_dir {
74
+ Dir.pwd.should == "~/.babushka/build".p
75
+ }
76
+ Dir.pwd.should == @original_pwd
77
+ end
78
+ it "should append the supplied path when supplied" do
79
+ in_build_dir "tmp" do
80
+ Dir.pwd.should == "~/.babushka/build/tmp".p
81
+ end
82
+ Dir.pwd.should == @original_pwd
83
+ end
84
+ end
85
+
86
+ describe "in_download_dir" do
87
+ before {
88
+ @original_pwd = Dir.pwd
89
+ }
90
+ it "should change to the download dir with no args" do
91
+ in_download_dir {
92
+ Dir.pwd.should == "~/.babushka/downloads".p
93
+ }
94
+ Dir.pwd.should == @original_pwd
95
+ end
96
+ it "should append the supplied path when supplied" do
97
+ in_download_dir "tmp" do
98
+ Dir.pwd.should == "~/.babushka/downloads/tmp".p
99
+ end
100
+ Dir.pwd.should == @original_pwd
101
+ end
102
+ end
@@ -0,0 +1,188 @@
1
+ require 'spec_helper'
2
+
3
+ describe Prompt, "get_value" do
4
+ it "should raise when not running on a terminal" do
5
+ $stdin.should_receive(:tty?).and_return(false)
6
+ expect { Prompt.get_value('value') }.to raise_error(PromptUnavailable)
7
+ end
8
+
9
+ it "should raise when not running on a terminal and a default is present" do
10
+ $stdin.should_receive(:tty?).and_return(false)
11
+ expect { Prompt.get_value('value', :default => 'a default') }.to raise_error(PromptUnavailable)
12
+ end
13
+
14
+ it "should raise when a default is expected but not available" do
15
+ Base.task.should_receive(:opt).with(:defaults).and_return(true)
16
+ expect { Prompt.get_value('value') }.to raise_error(DefaultUnavailable)
17
+ end
18
+
19
+ it "should return the value" do
20
+ Prompt.should_receive(:log).with("value", {:newline => false})
21
+ Prompt.should_receive(:read_from_prompt).and_return('value')
22
+ Prompt.get_value('value').should == 'value'
23
+ end
24
+
25
+ describe "with default" do
26
+ it "should return the value when it's specified" do
27
+ Prompt.should_receive(:log).with("value [default]", {:newline => false})
28
+ Prompt.should_receive(:read_from_prompt).and_return('value')
29
+ Prompt.get_value('value', :default => 'default').should == 'value'
30
+ end
31
+ it "should return the default when no value is specified" do
32
+ Prompt.should_receive(:log).with("value [default]", {:newline => false})
33
+ Prompt.should_receive(:read_from_prompt).and_return('')
34
+ Prompt.get_value('value', :default => 'default').should == 'default'
35
+ end
36
+ it "should handle non-string defaults" do
37
+ Prompt.should_receive(:log).with("value [80]", {:newline => false})
38
+ Prompt.should_receive(:read_from_prompt).and_return('')
39
+ Prompt.get_value('value', :default => 80).should == '80'
40
+ end
41
+ end
42
+
43
+ it "should reject :choices and :choice_descriptions together" do
44
+ L{
45
+ Prompt.get_value('value', :choices => %w[a b c], :choice_descriptions => {:a => "description"})
46
+ }.should raise_error(ArgumentError, "You can't use the :choices and :choice_descriptions options together.")
47
+ end
48
+
49
+ describe "with choices" do
50
+ it "should accept a valid choice" do
51
+ Prompt.should_receive(:log).with("value (a,b,c)", {:newline => false})
52
+ Prompt.should_receive(:read_from_prompt).and_return('a')
53
+ Prompt.get_value('value', :choices => %w[a b c]).should == 'a'
54
+ end
55
+ it "should reject an invalid choice" do
56
+ Prompt.should_receive(:log).with("value (a,b,c)", {:newline => false})
57
+ Prompt.should_receive(:read_from_prompt).and_return('d')
58
+ Prompt.should_receive(:log).with("That's not a valid choice. value (a,b,c)", {:newline => false})
59
+ Prompt.should_receive(:read_from_prompt).and_return('a')
60
+ Prompt.get_value('value', :choices => %w[a b c]).should == 'a'
61
+ end
62
+ it "should reject non-string choices" do
63
+ L{
64
+ Prompt.get_value('value', :choices => [:a, :b])
65
+ }.should raise_error ArgumentError, "Choices must be passed as strings."
66
+ end
67
+ describe "with default" do
68
+ it "should accept a valid choice" do
69
+ Prompt.should_receive(:log).with("value (a,b,c) [b]", {:newline => false})
70
+ Prompt.should_receive(:read_from_prompt).and_return('a')
71
+ Prompt.get_value('value', :choices => %w[a b c], :default => 'b').should == 'a'
72
+ end
73
+ it "should reject an invalid choice" do
74
+ Prompt.should_receive(:log).with("value (a,b,c) [b]", {:newline => false})
75
+ Prompt.should_receive(:read_from_prompt).and_return('d')
76
+ Prompt.should_receive(:log).with("That's not a valid choice. value (a,b,c) [b]", {:newline => false})
77
+ Prompt.should_receive(:read_from_prompt).and_return('a')
78
+ Prompt.get_value('value', :choices => %w[a b c], :default => 'b').should == 'a'
79
+ end
80
+ describe "with no value specified" do
81
+ it "should accept a valid default" do
82
+ Prompt.should_receive(:log).with("value (a,b,c) [b]", {:newline => false})
83
+ Prompt.should_receive(:read_from_prompt).and_return('')
84
+ Prompt.get_value('value', :choices => %w[a b c], :default => 'b').should == 'b'
85
+ end
86
+ it "should reject an invalid default" do
87
+ Prompt.should_receive(:log).with("value (a,b,c) [d]", {:newline => false})
88
+ Prompt.should_receive(:read_from_prompt).and_return('')
89
+ Prompt.should_receive(:log).with("That's not a valid choice. value (a,b,c) [d]", {:newline => false})
90
+ Prompt.should_receive(:read_from_prompt).and_return('a')
91
+ Prompt.get_value('value', :choices => %w[a b c], :default => 'd').should == 'a'
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "with choice descriptions" do
98
+ it "should behave like choices, logging the descriptions" do
99
+ Prompt.should_receive(:log).with("There are 3 choices:")
100
+ Prompt.should_receive(:log).with("a - the first one")
101
+ Prompt.should_receive(:log).with("b - there's also this")
102
+ Prompt.should_receive(:log).with("c - or this")
103
+ Prompt.should_receive(:log).with("value", {:newline => false})
104
+ Prompt.should_receive(:read_from_prompt).and_return('d')
105
+ Prompt.should_receive(:log).with("That's not a valid choice. value", {:newline => false})
106
+ Prompt.should_receive(:read_from_prompt).and_return('a')
107
+ Prompt.get_value('value', :choice_descriptions => {'a' => "the first one", 'b' => "there's also this", 'c' => "or this"}).should == 'a'
108
+ end
109
+ end
110
+
111
+ describe "validation" do
112
+ it "should treat 'true' as valid" do
113
+ Prompt.should_receive(:read_from_prompt).and_return('value')
114
+ Prompt.get_value('value') {|value| true }.should == 'value'
115
+ end
116
+ it "should treat 'false' as invalid" do
117
+ Prompt.should_receive(:log).with("value", {:newline => false})
118
+ Prompt.should_receive(:read_from_prompt).and_return('another value')
119
+ Prompt.should_receive(:log).with("That wasn't valid. value", {:newline => false})
120
+ Prompt.should_receive(:read_from_prompt).and_return('value')
121
+ Prompt.get_value('value') {|value| value == 'value' }.should == 'value'
122
+ end
123
+ end
124
+ end
125
+
126
+ describe Prompt, "#get_path" do
127
+ it "should return the path" do
128
+ Prompt.should_receive(:log).with("path", {:newline => false})
129
+ Prompt.should_receive(:read_from_prompt).and_return(tmp_prefix)
130
+ Prompt.get_path('path', :type => :path).should == tmp_prefix
131
+ end
132
+ it "should return ~ intact" do
133
+ Prompt.should_receive(:log).with("path", {:newline => false})
134
+ Prompt.should_receive(:read_from_prompt).and_return('~')
135
+ Prompt.get_path('path').should == '~'
136
+ end
137
+ describe "with default" do
138
+ it "should return the value when it's specified" do
139
+ Prompt.should_receive(:log).with("path [/tmp]", {:newline => false})
140
+ Prompt.should_receive(:read_from_prompt).and_return(tmp_prefix)
141
+ Prompt.get_path('path', :default => '/tmp').should == tmp_prefix
142
+ end
143
+ it "should return the default when no value is specified" do
144
+ Prompt.should_receive(:log).with("path [/tmp]", {:newline => false})
145
+ Prompt.should_receive(:read_from_prompt).and_return('')
146
+ Prompt.get_path('path', :default => '/tmp').should == '/tmp'
147
+ end
148
+ end
149
+ describe "with nonexistent path" do
150
+ it "should fail" do
151
+ Prompt.should_receive(:log).with("path", {:newline => false})
152
+ Prompt.should_receive(:read_from_prompt).and_return((tmp_prefix / 'nonexistent').to_s)
153
+ Prompt.should_receive(:log).with("Doesn't exist, or not a directory. path", {:newline => false})
154
+ Prompt.should_receive(:read_from_prompt).and_return(tmp_prefix)
155
+ Prompt.get_path('path', :type => :path).should == tmp_prefix
156
+ end
157
+ it "should fail with a valid default" do
158
+ Prompt.should_receive(:log).with("path [/tmp]", {:newline => false})
159
+ Prompt.should_receive(:read_from_prompt).and_return((tmp_prefix / 'nonexistent').to_s)
160
+ Prompt.should_receive(:log).with("Doesn't exist, or not a directory. path [/tmp]", {:newline => false})
161
+ Prompt.should_receive(:read_from_prompt).and_return(tmp_prefix)
162
+ Prompt.get_path('path', :type => :path, :default => '/tmp').should == tmp_prefix
163
+ end
164
+ end
165
+ end
166
+
167
+ describe "'y' input" do
168
+ context "intentional" do
169
+ it "should return 'y'" do
170
+ Prompt.should_receive(:log).with("value", {:newline => false})
171
+ Prompt.should_receive(:read_from_prompt).and_return('y')
172
+ Prompt.should_receive(:log).with("Wait, do you mean the literal value 'y' [n]", {:newline => false})
173
+ Prompt.should_receive(:read_from_prompt).and_return('y')
174
+ Prompt.get_value('value').should == 'y'
175
+ end
176
+ end
177
+ context "unintentional" do
178
+ it "should ask for the value again with a custom log message" do
179
+ Prompt.should_receive(:log).with("value", {:newline => false})
180
+ Prompt.should_receive(:read_from_prompt).and_return('y')
181
+ Prompt.should_receive(:log).with("Wait, do you mean the literal value 'y' [n]", {:newline => false})
182
+ Prompt.should_receive(:read_from_prompt).and_return('n')
183
+ Prompt.should_receive(:log).with("Thought so :) Hit enter for the [default]. value", {:newline => false})
184
+ Prompt.should_receive(:read_from_prompt).and_return('value')
185
+ Prompt.get_value('value').should == 'value'
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'renderable' do
4
+ it "should not exist" do
5
+ subject.exists?.should be_false
6
+ end
7
+ describe '#render' do
8
+ before { subject.render(source_file) }
9
+ it "should exist" do
10
+ subject.exists?.should be_true
11
+ end
12
+ it "should have added the prefix" do
13
+ dest_file.read.should =~ Renderable::SEAL_REGEXP
14
+ end
15
+ it "should have interpolated the erb" do
16
+ dest_file.read.should =~ content
17
+ end
18
+ describe "#clean?" do
19
+ it "should be clean" do
20
+ subject.should be_clean
21
+ end
22
+ context "after shitting up the file" do
23
+ before {
24
+ shell "echo lulz >> #{subject.path}"
25
+ }
26
+ it "should not be clean" do
27
+ subject.should_not be_clean
28
+ end
29
+ end
30
+ end
31
+ describe '#from?' do
32
+ it "should be from the same content" do
33
+ subject.should be_from(source_file)
34
+ end
35
+ it "should not be from different content" do
36
+ subject.should_not be_from('spec/renderable/different_example.conf.erb')
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ describe Renderable do
43
+ context "with a config file" do
44
+ let(:source_file) { "spec/renderable/example.conf.erb" }
45
+ let(:dest_file) { tmp_prefix / 'example.conf' }
46
+ let(:content) { %r{root #{tmp_prefix};} }
47
+ subject { Renderable.new(dest_file) }
48
+ it_should_behave_like 'renderable'
49
+ end
50
+ context "with an xml file" do
51
+ let(:source_file) { "spec/renderable/xml_example.conf.erb" }
52
+ let(:dest_file) { tmp_prefix / 'xml_example.conf' }
53
+ let(:content) { %r{<key>Lol</key>} }
54
+ subject { Renderable.new(dest_file) }
55
+ it_should_behave_like 'renderable'
56
+ context "custom comment" do
57
+ before { subject.render(source_file, :comment => '<!--', :comment_suffix => '-->') }
58
+ it "should have rendered an xml comment in the output" do
59
+ dest_file.read.should =~ %r{<!-- Generated by babushka-[\d\.]+ at [^,]+, from \w{40}\. \w{40} -->}
60
+ end
61
+ after { dest_file.rm }
62
+ end
63
+ end
64
+ context "with a script containing a shebang" do
65
+ let(:source_file) { "spec/renderable/example.sh" }
66
+ let(:dest_file) { tmp_prefix / 'example.sh' }
67
+ let(:content) { %r{babushka 'benhoskings:up to date.repo'} }
68
+ subject { Renderable.new(dest_file) }
69
+ it_should_behave_like 'renderable'
70
+ end
71
+ describe "binding handling" do
72
+ subject { Renderable.new(tmp_prefix / 'example.conf') }
73
+ context "when no explicit binding is passed" do
74
+ before {
75
+ subject.instance_eval {
76
+ def custom_renderable_path
77
+ "from implicit binding"
78
+ end
79
+ }
80
+ subject.render('spec/renderable/with_binding.conf.erb')
81
+ }
82
+ it "should render using the implicit binding" do
83
+ (tmp_prefix / 'example.conf').read.should =~ /from implicit binding/
84
+ end
85
+ end
86
+ context "when an explicit binding is passed" do
87
+ before {
88
+ dep 'renderable binding spec' do
89
+ def custom_renderable_path
90
+ "from explicit binding"
91
+ end
92
+ end
93
+ subject.render('spec/renderable/with_binding.conf.erb', :context => Dep('renderable binding spec').context)
94
+ }
95
+ it "should render using the given binding" do
96
+ (tmp_prefix / 'example.conf').read.should =~ /from explicit binding/
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+
3
+ def archive_path
4
+ __FILE__.p.parent.parent / 'archives'
5
+ end
6
+
7
+ describe Resource do
8
+ it "should detect file types" do
9
+ Resource.type(archive_path / 'archive.zip').should == :zip
10
+ Resource.type(archive_path / 'archive.tgz').should == :gzip
11
+ end
12
+ it "should first attempt to detect type using file extension" do
13
+ Resource.type(archive_path / 'really_a_gzip.zip').should == :zip
14
+ end
15
+ it "should attempt to detect type via when there is no extension" do
16
+ Resource.type(archive_path / 'zip_without_extension').should == :zip
17
+ end
18
+ it "should detect supported archive types" do
19
+ Resource.for(archive_path / 'archive.tgz').should be_supported
20
+ Resource.for(archive_path / 'archive.tbz2').should be_supported
21
+ end
22
+ it "should raise an error on unsupported types" do
23
+ L{
24
+ Resource.for(archive_path / 'invalid_archive')
25
+ }.should raise_error("Don't know how to extract invalid_archive.")
26
+ end
27
+ it "should set the name" do
28
+ Resource.for(archive_path / 'archive.tar').name.should == 'archive'
29
+ Resource.for(archive_path / 'archive.tar.gz').name.should == 'archive'
30
+ end
31
+ it "should generate the proper command to extract the archive" do
32
+ {
33
+ 'tar' => "tar -xf '#{archive_path / 'archive.tar'}'",
34
+ 'tgz' => "tar -zxf '#{archive_path / 'archive.tgz'}'",
35
+ 'tbz2' => "tar -jxf '#{archive_path / 'archive.tbz2'}'",
36
+ 'zip' => "unzip -o '#{archive_path / 'archive.zip'}'"
37
+ }.each_pair {|ext,command|
38
+ Resource.for(archive_path / "archive.#{ext}").extract_command.should == command
39
+ }
40
+ end
41
+ it "should yield in the extracted dir" do
42
+ Resource.for(archive_path / "archive.tar").extract {
43
+ Dir.pwd.should == (tmp_prefix / 'archives/archive')
44
+ }
45
+ end
46
+ it "should yield in the nested dir if there is one" do
47
+ Resource.for(archive_path / "nested_archive.tar").extract {
48
+ Dir.pwd.should == (tmp_prefix / 'archives/nested_archive/nested archive')
49
+ }
50
+ end
51
+ it "should find a standard content dir as a nested dir" do
52
+ Resource.for(archive_path / "test-0.3.1.tgz").extract {
53
+ Dir.pwd.should == (tmp_prefix / 'archives/test-0.3.1/test-0.3.1')
54
+ Dir.glob('*').should == ['content.txt']
55
+ }
56
+ end
57
+ it "shouldn't descend into some dirs" do
58
+ Resource.for(archive_path / "Blah.app.zip").extract {
59
+ Dir.pwd.should == (tmp_prefix / 'archives/Blah.app')
60
+ Dir.glob('**/*').should == ['Blah.app', 'Blah.app/content.txt']
61
+ }
62
+ end
63
+ end
64
+
65
+ describe Resource, '#content_subdir' do
66
+ before {
67
+ @resource = Resource.new('test.zip')
68
+ }
69
+
70
+ context "when there is just a single file inside the archive" do
71
+ before {
72
+ Dir.stub!(:glob).and_return(['a dir'])
73
+ File.should_receive(:directory?).with('a dir').and_return(false)
74
+ }
75
+ it "should choose it, whatever it's called" do
76
+ @resource.content_subdir.should be_nil
77
+ end
78
+ end
79
+ context "when there is just a single non-descendable dir inside the archive" do
80
+ before {
81
+ Dir.stub!(:glob).and_return(['a dir.app'])
82
+ File.should_receive(:directory?).with('a dir.app').and_return(true)
83
+ }
84
+ it "should choose it, whatever it's called" do
85
+ @resource.content_subdir.should be_nil
86
+ end
87
+ end
88
+ context "when there is just a single dir inside the archive" do
89
+ before {
90
+ Dir.stub!(:glob).and_return(['a dir'])
91
+ File.should_receive(:directory?).with('a dir').and_return(true)
92
+ }
93
+ it "should choose it, whatever it's called" do
94
+ @resource.content_subdir.should == 'a dir'
95
+ end
96
+ end
97
+ context "when there is more than one dir" do
98
+ context "and none are named after the archive" do
99
+ before {
100
+ Dir.stub!(:glob).and_return(['contents', 'another'])
101
+ }
102
+ it "should return nil (so the original extraction dir is used)" do
103
+ @resource.content_subdir.should be_nil
104
+ end
105
+ end
106
+ context "and one is named after the archive" do
107
+ before {
108
+ Dir.stub!(:glob).and_return(['contents', 'test'])
109
+ }
110
+ it "should choose the directory named after the archive" do
111
+ @resource.content_subdir.should == 'test'
112
+ end
113
+ end
114
+ end
115
+ context "when there are non-descendable dirs" do
116
+ context "and none are named after the archive" do
117
+ before {
118
+ Dir.stub!(:glob).and_return(['contents', 'LaunchBar.app', 'RSpec.tmbundle'])
119
+ }
120
+ it "should not choose the non-descendable dir" do
121
+ @resource.content_subdir.should be_nil
122
+ end
123
+ end
124
+ context "and one is named after the archive" do
125
+ before {
126
+ Dir.stub!(:glob).and_return(['contents', 'test.app'])
127
+ }
128
+ it "should not choose the non-descendable dir" do
129
+ @resource.content_subdir.should be_nil
130
+ end
131
+ end
132
+ context "one is named after the archive, and a descendable dir is present too" do
133
+ before {
134
+ Dir.stub!(:glob).and_return(['contents', 'test.app', 'test'])
135
+ }
136
+ it "should choose the descendable dir" do
137
+ @resource.content_subdir.should == 'test'
138
+ end
139
+ end
140
+ end
141
+ end