rake-funnel 0.0.1.pre

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 (111) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +21 -0
  5. data/Gemfile +29 -0
  6. data/Guardfile +24 -0
  7. data/README.md +29 -0
  8. data/Rakefile +77 -0
  9. data/build.cmd +30 -0
  10. data/bundle.cmd +26 -0
  11. data/config/.gitignore +1 -0
  12. data/config/.local.yaml.example +9 -0
  13. data/config/default.yaml +5 -0
  14. data/config/dev.yaml +0 -0
  15. data/config/production.yaml +3 -0
  16. data/lib/rake/funnel/ambiguous_file_error.rb +29 -0
  17. data/lib/rake/funnel/execution_error.rb +26 -0
  18. data/lib/rake/funnel/extensions/camel_case.rb +19 -0
  19. data/lib/rake/funnel/extensions/common_path.rb +52 -0
  20. data/lib/rake/funnel/extensions/disable_colors.rb +27 -0
  21. data/lib/rake/funnel/extensions/rexml.rb +23 -0
  22. data/lib/rake/funnel/extensions/shell.rb +56 -0
  23. data/lib/rake/funnel/framework.rb +15 -0
  24. data/lib/rake/funnel/integration/progress_report.rb +70 -0
  25. data/lib/rake/funnel/integration/sync_output.rb +8 -0
  26. data/lib/rake/funnel/integration/teamcity/nunit_plugin.rb +59 -0
  27. data/lib/rake/funnel/integration/teamcity/progress_report.rb +33 -0
  28. data/lib/rake/funnel/integration/teamcity/service_messages.rb +40 -0
  29. data/lib/rake/funnel/integration/teamcity/teamcity.rb +15 -0
  30. data/lib/rake/funnel/integration/teamcity.rb +5 -0
  31. data/lib/rake/funnel/support/finder.rb +51 -0
  32. data/lib/rake/funnel/support/mapper.rb +81 -0
  33. data/lib/rake/funnel/support/mapper_styles/default.rb +31 -0
  34. data/lib/rake/funnel/support/mapper_styles/msbuild.rb +33 -0
  35. data/lib/rake/funnel/support/mapper_styles/msdeploy.rb +47 -0
  36. data/lib/rake/funnel/support/mapper_styles/nunit.rb +33 -0
  37. data/lib/rake/funnel/support/mono.rb +17 -0
  38. data/lib/rake/funnel/support/patch.rb +37 -0
  39. data/lib/rake/funnel/support/template_engine.rb +26 -0
  40. data/lib/rake/funnel/support/which.rb +15 -0
  41. data/lib/rake/funnel/tasks/bin_path.rb +34 -0
  42. data/lib/rake/funnel/tasks/copy.rb +54 -0
  43. data/lib/rake/funnel/tasks/environments.rb +74 -0
  44. data/lib/rake/funnel/tasks/environments_support/loader.rb +37 -0
  45. data/lib/rake/funnel/tasks/msbuild.rb +52 -0
  46. data/lib/rake/funnel/tasks/msbuild_support/build_tool.rb +28 -0
  47. data/lib/rake/funnel/tasks/msdeploy.rb +58 -0
  48. data/lib/rake/funnel/tasks/msdeploy_support/registry_patch.rb +84 -0
  49. data/lib/rake/funnel/tasks/nunit.rb +46 -0
  50. data/lib/rake/funnel/tasks/paket.rb +39 -0
  51. data/lib/rake/funnel/tasks/quick_template.rb +45 -0
  52. data/lib/rake/funnel/tasks/side_by_side_specs.rb +33 -0
  53. data/lib/rake/funnel/tasks/side_by_side_specs_support/remover.rb +62 -0
  54. data/lib/rake/funnel/tasks/timing.rb +100 -0
  55. data/lib/rake/funnel/tasks/timing_support/report.rb +89 -0
  56. data/lib/rake/funnel/tasks/timing_support/statistics.rb +26 -0
  57. data/lib/rake/funnel/tasks/zip.rb +66 -0
  58. data/lib/rake/funnel/version.rb +5 -0
  59. data/lib/rake/funnel.rb +7 -0
  60. data/rake-funnel.gemspec +28 -0
  61. data/spec/rake/funnel/execution_error_spec.rb +67 -0
  62. data/spec/rake/funnel/extensions/camel_case_spec.rb +17 -0
  63. data/spec/rake/funnel/extensions/common_path_spec.rb +56 -0
  64. data/spec/rake/funnel/extensions/disable_colors_spec.rb +33 -0
  65. data/spec/rake/funnel/extensions/rexml_spec.rb +20 -0
  66. data/spec/rake/funnel/extensions/shell_spec.rb +237 -0
  67. data/spec/rake/funnel/integration/progress_report_spec.rb +149 -0
  68. data/spec/rake/funnel/integration/sync_output_spec.rb +16 -0
  69. data/spec/rake/funnel/integration/teamcity/nunit_plugin_spec.rb +112 -0
  70. data/spec/rake/funnel/integration/teamcity/progress_report_spec.rb +174 -0
  71. data/spec/rake/funnel/integration/teamcity/service_messages_spec.rb +136 -0
  72. data/spec/rake/funnel/integration/teamcity/teamcity_spec.rb +34 -0
  73. data/spec/rake/funnel/support/finder_spec.rb +210 -0
  74. data/spec/rake/funnel/support/mapper_spec.rb +87 -0
  75. data/spec/rake/funnel/support/mapper_styles/msdeploy_spec.rb +222 -0
  76. data/spec/rake/funnel/support/mapper_styles/nunit_spec.rb +25 -0
  77. data/spec/rake/funnel/support/mapper_styles/styles_spec.rb +214 -0
  78. data/spec/rake/funnel/support/mono_spec.rb +57 -0
  79. data/spec/rake/funnel/support/patch_spec.rb +108 -0
  80. data/spec/rake/funnel/support/template_engine_spec.rb +65 -0
  81. data/spec/rake/funnel/support/which_spec.rb +65 -0
  82. data/spec/rake/funnel/tasks/bin_path_spec.rb +40 -0
  83. data/spec/rake/funnel/tasks/copy_spec.rb +101 -0
  84. data/spec/rake/funnel/tasks/environments_spec.rb +237 -0
  85. data/spec/rake/funnel/tasks/environments_support/loader_spec.rb +114 -0
  86. data/spec/rake/funnel/tasks/msbuild_spec.rb +91 -0
  87. data/spec/rake/funnel/tasks/msbuild_support/build_tool_spec.rb +21 -0
  88. data/spec/rake/funnel/tasks/msdeploy_spec.rb +243 -0
  89. data/spec/rake/funnel/tasks/msdeploy_support/registry_patch_spec.rb +139 -0
  90. data/spec/rake/funnel/tasks/nunit_spec.rb +76 -0
  91. data/spec/rake/funnel/tasks/paket_spec.rb +184 -0
  92. data/spec/rake/funnel/tasks/quick_template_spec.rb +89 -0
  93. data/spec/rake/funnel/tasks/side_by_side_specs_spec.rb +58 -0
  94. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/FooCode.cs +0 -0
  95. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/FooSpecs.cs +0 -0
  96. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/Sample.csproj +28 -0
  97. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/Specs.cs +0 -0
  98. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/subdir/BarCode.cs +0 -0
  99. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/subdir/BarSpecs.cs +0 -0
  100. data/spec/rake/funnel/tasks/side_by_side_specs_support/remover_spec.rb +116 -0
  101. data/spec/rake/funnel/tasks/timing_spec.rb +133 -0
  102. data/spec/rake/funnel/tasks/timing_support/report_spec.rb +129 -0
  103. data/spec/rake/funnel/tasks/zip_spec.rb +119 -0
  104. data/spec/spec_helper.rb +32 -0
  105. data/tools/MSDeploy/Microsoft.Web.Delegation.dll +0 -0
  106. data/tools/MSDeploy/Microsoft.Web.Deployment.Tracing.dll +0 -0
  107. data/tools/MSDeploy/Microsoft.Web.Deployment.dll +0 -0
  108. data/tools/MSDeploy/en/msdeploy.resources.dll +0 -0
  109. data/tools/MSDeploy/msdeploy.exe +0 -0
  110. data/tools/MSDeploy/msdeploy.exe.config +6 -0
  111. metadata +253 -0
@@ -0,0 +1,16 @@
1
+ describe Rake::Funnel::Integration::SyncOutput do
2
+ before {
3
+ allow($stdout).to receive(:sync=)
4
+ allow($stderr).to receive(:sync=)
5
+
6
+ expect(subject).to be
7
+ }
8
+
9
+ it 'should immediately flush stdout' do
10
+ expect($stdout).to have_received(:sync=).with(true)
11
+ end
12
+
13
+ it 'should immediately flush stderr' do
14
+ expect($stdout).to have_received(:sync=).with(true)
15
+ end
16
+ end
@@ -0,0 +1,112 @@
1
+ include Rake::Funnel::Support
2
+
3
+ describe Rake::Funnel::Integration::TeamCity::NUnitPlugin do
4
+ let(:env_var) { nil }
5
+ let(:which) { nil }
6
+ let(:nunit_exe_contents) { nil }
7
+
8
+ before {
9
+ allow(ENV).to receive(:[]).with(described_class::ENV_VAR).and_return(env_var)
10
+ allow(Which).to receive(:which).and_return(which)
11
+ allow(File).to receive(:read).with(which).and_return(nunit_exe_contents)
12
+ allow(Dir).to receive(:glob).and_return([])
13
+ allow(RakeFileUtils).to receive(:mkdir_p)
14
+ allow(Rake).to receive(:rake_output_message)
15
+ }
16
+
17
+ def binary_version(*version_parts)
18
+ version = version_parts.map { |p| p.to_s + "\0" }.join(".\0")
19
+ "F\0i\0l\0e\0V\0e\0r\0s\0i\0o\0n" + "\0" * 3 + version + "\0" * 3
20
+ end
21
+
22
+ describe 'success' do
23
+ let(:env_var) { '/path/to/nunit plugins/nunit' }
24
+ let(:addin_dlls) { [env_var + 'addin.dll'] }
25
+ let(:which) { 'path/to/nunit-console.exe' }
26
+ let(:nunit_exe_contents) { "binary #{binary_version(1, 2, 3, 4)} binary" }
27
+
28
+ before {
29
+ allow(Dir).to receive(:glob).and_return(addin_dlls)
30
+ allow(RakeFileUtils).to receive(:cp)
31
+ }
32
+
33
+ before {
34
+ described_class.setup('nunit-console.exe')
35
+ }
36
+
37
+ it 'should create addin directory' do
38
+ expect(RakeFileUtils).to have_received(:mkdir_p).with(File.join(File.dirname(which), 'addins'))
39
+ end
40
+
41
+ it 'should enumerate addin files' do
42
+ expect(Dir).to have_received(:glob).with(/#{Regexp.escape(env_var + '-1.2.3.*')}$/)
43
+ end
44
+
45
+ it 'should copy the addin from TeamCity to NUnit' do
46
+ expect(RakeFileUtils).to have_received(:cp).with(addin_dlls, File.join(File.dirname(which), 'addins'))
47
+ end
48
+
49
+ it 'should report that the addin is installed' do
50
+ expect(Rake).to have_received(:rake_output_message).with("Installing TeamCity NUnit addin for version 1.2.3 in #{which}")
51
+ end
52
+
53
+ context 'Windows-style path in environment variable', platform: :win32 do
54
+ let(:env_var) { 'C:\path\to\nunit plugins\nunit-' }
55
+
56
+ it 'should convert path to Ruby-style' do
57
+ expect(Dir).to have_received(:glob).with(%r|^C:/path/to/nunit plugins/nunit-|)
58
+ end
59
+ end
60
+ end
61
+
62
+ describe 'failures' do
63
+ before {
64
+ described_class.setup('nunit-console.exe')
65
+ }
66
+
67
+ context 'TeamCity plugin path not in environment' do
68
+ let(:env_var) { nil }
69
+
70
+ it 'should skip' do
71
+ expect(File).to_not have_received(:read)
72
+ end
73
+ end
74
+
75
+ context 'NUnit executable not found' do
76
+ let(:env_var) { '/path/to/nunit plugins/nunit' }
77
+ let(:which) { nil }
78
+
79
+ it 'should skip' do
80
+ expect(File).to_not have_received(:read)
81
+ end
82
+ end
83
+
84
+ context 'NUnit executable without version' do
85
+ let(:env_var) { '/path/to/nunit plugins/nunit' }
86
+ let(:which) { 'path/to/nunit-console.exe' }
87
+ let(:nunit_exe_contents) { 'version number not available ' }
88
+
89
+ it 'should report that the version could not be read' do
90
+ expect(Rake).to have_received(:rake_output_message).with("Could read version from NUnit executable in #{which}")
91
+ end
92
+
93
+ it 'should skip' do
94
+ expect(Dir).not_to have_received(:glob)
95
+ end
96
+ end
97
+
98
+ context 'plugin for NUnit version not available' do
99
+ let(:env_var) { '/path/to/nunit plugins/nunit' }
100
+ let(:which) { 'path/to/nunit-console.exe' }
101
+ let(:nunit_exe_contents) { binary_version(1, 2, 3, 4) }
102
+
103
+ it 'should report that the addin version is not available' do
104
+ expect(Rake).to have_received(:rake_output_message).with(/Could not find TeamCity NUnit addin for version 1\.2\.3 in .*#{env_var}$/)
105
+ end
106
+
107
+ it 'should skip' do
108
+ expect(RakeFileUtils).not_to have_received(:mkdir_p)
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,174 @@
1
+ include Rake
2
+ include Rake::Funnel::Integration
3
+ include Rake::Funnel::Integration::TeamCity
4
+
5
+ describe Rake::Funnel::Integration::TeamCity::ProgressReport do
6
+ include DSL
7
+
8
+ let(:teamcity_running?) { false }
9
+ let(:teamcity_rake_runner?) { false }
10
+
11
+ before {
12
+ allow(TeamCity).to receive(:running?).and_return(teamcity_running?)
13
+ allow(TeamCity).to receive(:rake_runner?).and_return(teamcity_rake_runner?)
14
+ allow(ServiceMessages).to receive(:block_opened)
15
+ allow(ServiceMessages).to receive(:block_closed)
16
+ allow(ServiceMessages).to receive(:progress_start)
17
+ allow(ServiceMessages).to receive(:progress_finish)
18
+ allow(ServiceMessages).to receive(:build_problem)
19
+
20
+ Task.clear
21
+ }
22
+
23
+ subject! {
24
+ described_class.new
25
+ }
26
+
27
+ after {
28
+ subject.disable!
29
+ }
30
+
31
+ shared_examples :block_report do
32
+ it 'should write block start' do
33
+ expect(ServiceMessages).to have_received(:block_opened).with(name: 'task')
34
+ end
35
+
36
+ it 'should write block end' do
37
+ expect(ServiceMessages).to have_received(:block_closed).with(name: 'task')
38
+ end
39
+ end
40
+
41
+ shared_examples :no_block_report do
42
+ it 'should not write block start' do
43
+ expect(ServiceMessages).not_to have_received(:block_opened)
44
+ end
45
+
46
+ it 'should not write block end' do
47
+ expect(ServiceMessages).not_to have_received(:block_closed)
48
+ end
49
+ end
50
+
51
+ context 'when task succeeds' do
52
+ before {
53
+ task :task
54
+
55
+ Task[:task].invoke
56
+ }
57
+
58
+ it 'should not report build problems' do
59
+ expect(ServiceMessages).to_not have_received(:build_problem)
60
+ end
61
+
62
+ context 'not on TeamCity' do
63
+ it_behaves_like :no_block_report
64
+ end
65
+
66
+ context 'on TeamCity' do
67
+ let(:teamcity_running?) { true }
68
+
69
+ context 'without rake runner' do
70
+ it_behaves_like :block_report
71
+ end
72
+
73
+ context 'with rake runner' do
74
+ let(:teamcity_rake_runner?) { true }
75
+
76
+ it_behaves_like :no_block_report
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'when task fails' do
82
+ class SpecificError < StandardError; end
83
+
84
+ before {
85
+ module Rake
86
+ class ApplicationAbortedException < StandardError
87
+ attr_reader :inner_exception
88
+
89
+ def initialize(other_exception)
90
+ @inner_exception = other_exception
91
+ end
92
+ end
93
+ end
94
+ }
95
+
96
+ let(:error) { SpecificError.new('task error' * 4000) }
97
+
98
+ before {
99
+ task :task do
100
+ raise error
101
+ end
102
+
103
+ begin
104
+ Task[:task].invoke
105
+ rescue ApplicationAbortedException => e
106
+ rescue SpecificError => e
107
+ @raised_error = e
108
+ end
109
+ }
110
+
111
+ context 'not on TeamCity' do
112
+ it_behaves_like :no_block_report
113
+
114
+ it 'should not swallow the error' do
115
+ expect(@raised_error).to be_a_kind_of(SpecificError)
116
+ end
117
+ end
118
+
119
+ context 'on TeamCity' do
120
+ let(:teamcity_running?) { true }
121
+
122
+ describe 'build problems' do
123
+ it 'should report build problems' do
124
+ expect(ServiceMessages).to have_received(:build_problem)
125
+ end
126
+
127
+ it 'should report the error message' do
128
+ expect(ServiceMessages).to have_received(:build_problem).with(hash_including({ description: be_an_instance_of(String) }))
129
+ end
130
+
131
+ it 'should report the first 4000 characters of the error message' do
132
+ expect(ServiceMessages).to have_received(:build_problem).with(hash_including({ description: have(4000).items }))
133
+ end
134
+ end
135
+
136
+ context 'without rake runner' do
137
+ it_behaves_like :block_report
138
+
139
+ it 'should report the error as a build problem' do
140
+ expect(ServiceMessages).to have_received(:build_problem)
141
+ end
142
+ end
143
+
144
+ context 'with rake runner' do
145
+ let(:teamcity_rake_runner?) { true }
146
+ let(:error) {
147
+ ApplicationAbortedException.new(SpecificError.new('inner message'))
148
+ }
149
+
150
+ it 'should report the inner error as a build problem (as it will be wrapped in a ApplicationAbortedException)' do
151
+ expect(ServiceMessages).to have_received(:build_problem).with({ description: 'inner message' })
152
+ end
153
+
154
+ it_behaves_like :no_block_report
155
+ end
156
+ end
157
+ end
158
+
159
+ context 'when progess report was disabled' do
160
+ let(:teamcity_running?) { true }
161
+
162
+ before {
163
+ subject.disable!
164
+
165
+ task :task
166
+
167
+ Task[:task].invoke
168
+ }
169
+
170
+ it 'should not write' do
171
+ expect(ServiceMessages).to_not have_received(:block_opened)
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,136 @@
1
+ include Rake::Funnel::Integration
2
+
3
+ describe Rake::Funnel::Integration::TeamCity::ServiceMessages do
4
+ before {
5
+ allow(TeamCity).to receive(:running?).and_return(teamcity_running?)
6
+ allow($stdout).to receive(:puts)
7
+ }
8
+
9
+ context 'when running outside TeamCity' do
10
+ let(:teamcity_running?) { false }
11
+
12
+ it 'should not publish messages' do
13
+ described_class.progress_start 'foo'
14
+
15
+ expect($stdout).not_to have_received(:puts)
16
+ end
17
+ end
18
+
19
+ context 'when running inside TeamCity' do
20
+ let(:teamcity_running?) { true }
21
+
22
+ describe 'escaping' do
23
+ context 'when publishing messages without special characters' do
24
+ it 'should not escape' do
25
+ described_class.progress_start "the message"
26
+
27
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart 'the message']")
28
+ end
29
+ end
30
+
31
+ context 'when publishing messages with special characters' do
32
+ it 'should escape apostrophes' do
33
+ described_class.progress_start "'"
34
+
35
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|'']")
36
+ end
37
+
38
+ it 'should escape line feeds' do
39
+ described_class.progress_start "\n"
40
+
41
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|n']")
42
+ end
43
+
44
+ it 'should escape carriage returns' do
45
+ described_class.progress_start "\r"
46
+
47
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|r']")
48
+ end
49
+
50
+ it 'should escape next lines' do
51
+ described_class.progress_start "\u0085"
52
+
53
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|x']")
54
+ end
55
+
56
+ it 'should escape line separators' do
57
+ described_class.progress_start "\u2028"
58
+
59
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|l']")
60
+ end
61
+
62
+ it 'should escape paragraph separators' do
63
+ described_class.progress_start "\u2029"
64
+
65
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|p']")
66
+ end
67
+
68
+ it 'should escape vertical bars' do
69
+ described_class.progress_start '|'
70
+
71
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '||']")
72
+ end
73
+
74
+ it 'should escape opening brackets' do
75
+ described_class.progress_start '['
76
+
77
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|[']")
78
+ end
79
+
80
+ it 'should escape closing brackets' do
81
+ described_class.progress_start ']'
82
+
83
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|]']")
84
+ end
85
+
86
+ it 'should escape all special characters in a string' do
87
+ described_class.progress_start "[\r|\n]"
88
+
89
+ expect($stdout).to have_received(:puts).with("##teamcity[progressStart '|[|r|||n|]']")
90
+ end
91
+ end
92
+ end
93
+
94
+ describe 'parameters' do
95
+ context 'when reporting a message without parameters' do
96
+ it 'should print the service message' do
97
+ described_class.enable_service_messages
98
+
99
+ expect($stdout).to have_received(:puts).with('##teamcity[enableServiceMessages]')
100
+ end
101
+ end
102
+
103
+ context 'when reporting a message with an unnamed parameter' do
104
+ it 'should print the service message' do
105
+ described_class.progress_message 'the message'
106
+
107
+ expect($stdout).to have_received(:puts).with("##teamcity[progressMessage 'the message']")
108
+ end
109
+ end
110
+
111
+ context 'when reporting a message with a named parameter' do
112
+ it 'should print the service message' do
113
+ described_class.block_opened({ name: 'block name' })
114
+
115
+ expect($stdout).to have_received(:puts).with("##teamcity[blockOpened name='block name']")
116
+ end
117
+ end
118
+
119
+ context 'when reporting a message with multiple named parameters' do
120
+ it 'should print the service message' do
121
+ described_class.test_started ({ name: 'test name', captureStandardOutput: true })
122
+
123
+ expect($stdout).to have_received(:puts).with("##teamcity[testStarted name='test name' captureStandardOutput='true']")
124
+ end
125
+ end
126
+
127
+ context 'when reporting a message with Ruby-style named parameters' do
128
+ it 'should print the service message' do
129
+ described_class.test_started ({ capture_standard_output: true })
130
+
131
+ expect($stdout).to have_received(:puts).with("##teamcity[testStarted captureStandardOutput='true']")
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,34 @@
1
+ describe Rake::Funnel::Integration::TeamCity do
2
+ before {
3
+ allow(ENV).to receive(:include?).with(described_class::ENV_VAR).and_return(teamcity_running?)
4
+ }
5
+
6
+ context 'when running outside TeamCity' do
7
+ let(:teamcity_running?) { false }
8
+
9
+ it 'should not detect TeamCity' do
10
+ expect(described_class.running?).to eq(false)
11
+ end
12
+
13
+ it "should not detect TeamCity's rake runner" do
14
+ expect(described_class.rake_runner?).to eq(false)
15
+ end
16
+ end
17
+
18
+ context 'when running inside TeamCity' do
19
+ let(:teamcity_running?) { true }
20
+
21
+ it 'should detect TeamCity' do
22
+ expect(described_class.running?).to eq(true)
23
+ end
24
+
25
+ it "should detect TeamCity's rake runner" do
26
+ module ::Rake
27
+ module TeamCityApplication
28
+ end
29
+ end
30
+
31
+ expect(described_class.rake_runner?).to eq(true)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,210 @@
1
+ include Rake::Funnel
2
+
3
+ describe Rake::Funnel::Support::Finder do
4
+ let(:pattern) { %W(#{temp_dir}/**/*.sln #{temp_dir}/**/*.??proj) }
5
+ let(:generate) { [] }
6
+ let(:temp_dir) { Dir.mktmpdir }
7
+
8
+ before {
9
+ Dir.chdir(temp_dir) do
10
+ ([] << generate).flatten.each do |file|
11
+ FileUtils.mkdir_p(File.dirname(file))
12
+ FileUtils.touch(file)
13
+ end
14
+ end
15
+ }
16
+
17
+ after {
18
+ FileUtils.rm_rf(temp_dir)
19
+ }
20
+
21
+ subject {
22
+ described_class.new(pattern, OpenStruct.new(name: 'task name'), 'error message')
23
+ }
24
+
25
+ def map_temp(*files)
26
+ mapped = files.map { |f| File.join(temp_dir, f) }
27
+ return mapped.first if mapped.one?
28
+ mapped
29
+ end
30
+
31
+ describe 'enumerable' do
32
+ let(:generate) { %w(1 2 3 4) }
33
+ let(:pattern) { '**/*' }
34
+
35
+ it 'should be enumerable' do
36
+ expect(described_class < Enumerable).to eq(true)
37
+ expect(subject.respond_to?(:each)).to eq(true)
38
+ expect(subject.each).to be_kind_of(Enumerator)
39
+ end
40
+
41
+ it 'should support enumerable methods' do
42
+ Dir.chdir(temp_dir) do
43
+ items = subject.map { |x| x }
44
+ expect(subject.all_or_default).to match_array(items)
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'patterns' do
50
+ let(:generate) { %w(1 2 3 4) }
51
+
52
+ context 'single pattern' do
53
+ let(:pattern) { '**/*' }
54
+
55
+ it 'should yield' do
56
+ Dir.chdir(temp_dir) do
57
+ expect(subject.all_or_default).to match_array(generate)
58
+ end
59
+ end
60
+ end
61
+
62
+ context 'pattern list' do
63
+ let(:pattern) { %w(**/*) }
64
+
65
+ it 'should yield' do
66
+ Dir.chdir(temp_dir) do
67
+ expect(subject.all_or_default).to match_array(generate)
68
+ end
69
+ end
70
+ end
71
+
72
+ context 'Rake::FileList' do
73
+ let(:pattern) { FileList['**/*'] }
74
+
75
+ it 'should yield' do
76
+ Dir.chdir(temp_dir) do
77
+ expect(subject.all_or_default).to match_array(generate)
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'patterns generating multiple matches per file' do
83
+ let(:pattern) { %w(**/* **/*) }
84
+
85
+ it 'should remove duplicates' do
86
+ Dir.chdir(temp_dir) do
87
+ expect(subject.all_or_default).to match_array(generate)
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ describe '#single' do
94
+ context 'no matching files' do
95
+ it 'should fail' do
96
+ Dir.chdir(temp_dir) do
97
+ expect(lambda { subject.single }).to raise_error(AmbiguousFileError, /error message/)
98
+ end
99
+ end
100
+ end
101
+
102
+ context 'more than one matching file' do
103
+ let(:generate) { %w(foo/project1.sln foo/project2.sln) }
104
+
105
+ it 'should fail' do
106
+ Dir.chdir(temp_dir) do
107
+ expect(lambda { subject.single }).to raise_error(AmbiguousFileError, /error message/)
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'one matching file' do
113
+ let(:generate) { 'foo/project.sln' }
114
+
115
+ it 'should yield match' do
116
+ Dir.chdir(temp_dir) do
117
+ expect(subject.single).to eq(map_temp(generate))
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ describe '#single_or_default' do
124
+ context 'no matching files' do
125
+ it 'should yield nil' do
126
+ Dir.chdir(temp_dir) do
127
+ expect(subject.single_or_default).to be_nil
128
+ end
129
+ end
130
+ end
131
+
132
+ context 'more than one matching file' do
133
+ let(:generate) { %w(foo/project1.sln foo/project2.sln) }
134
+
135
+ it 'should yield first match' do
136
+ Dir.chdir(temp_dir) do
137
+ expect(subject.single_or_default).to be_nil
138
+ end
139
+ end
140
+ end
141
+
142
+ context 'one matching file' do
143
+ let(:generate) { 'foo/project.sln' }
144
+
145
+ it 'should yield match' do
146
+ Dir.chdir(temp_dir) do
147
+ expect(subject.single_or_default).to eq(map_temp(generate))
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ describe '#all' do
154
+ context 'no matching files' do
155
+ it 'should fail' do
156
+ expect(lambda { subject.all }).to raise_error(AmbiguousFileError, /error message/)
157
+ end
158
+ end
159
+
160
+ context 'more than one matching file' do
161
+ let(:generate) { %w(foo/project1.sln foo/project2.sln) }
162
+
163
+ it 'should yield all matches' do
164
+ Dir.chdir(temp_dir) do
165
+ expect(subject.all).to match_array(map_temp(*generate))
166
+ end
167
+ end
168
+ end
169
+
170
+ context 'one matching file' do
171
+ let(:generate) { 'foo/project.sln' }
172
+
173
+ it 'should yield all matches' do
174
+ Dir.chdir(temp_dir) do
175
+ expect(subject.all).to match_array(map_temp(generate))
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ describe '#all_or_default' do
182
+ context 'no matching files' do
183
+ it 'should be empty' do
184
+ Dir.chdir(temp_dir) do
185
+ expect(subject.all_or_default).to be_empty
186
+ end
187
+ end
188
+ end
189
+
190
+ context 'more than one matching file' do
191
+ let(:generate) { %w(foo/project1.sln foo/project2.sln) }
192
+
193
+ it 'should yield all matches' do
194
+ Dir.chdir(temp_dir) do
195
+ expect(subject.all_or_default).to match_array(map_temp(*generate))
196
+ end
197
+ end
198
+ end
199
+
200
+ context 'one matching file' do
201
+ let(:generate) { 'foo/project.sln' }
202
+
203
+ it 'should yield all matches' do
204
+ Dir.chdir(temp_dir) do
205
+ expect(subject.all_or_default).to match_array(map_temp(generate))
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end