ruby-pwsh 0.10.2 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,286 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pwsh::Util do
6
+ context '.invalid_directories?' do
7
+ let(:valid_path_a) { 'C:/some/folder' }
8
+ let(:valid_path_b) { 'C:/another/folder' }
9
+ let(:valid_paths) { 'C:/some/folder;C:/another/folder' }
10
+ let(:invalid_path) { 'C:/invalid/path' }
11
+ let(:mixed_paths) { 'C:/some/folder;C:/invalid/path;C:/another/folder' }
12
+ let(:empty_string) { '' }
13
+ let(:empty_members) { 'C:/some/folder;;C:/another/folder' }
14
+
15
+ it 'returns false if passed nil' do
16
+ expect(described_class.invalid_directories?(nil)).to be false
17
+ end
18
+
19
+ it 'returns false if passed an empty string' do
20
+ expect(described_class.invalid_directories?('')).to be false
21
+ end
22
+
23
+ it 'returns false if one valid path is provided' do
24
+ expect(described_class).to receive(:on_windows?).and_return(true)
25
+ expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
26
+ expect(described_class.invalid_directories?(valid_path_a)).to be false
27
+ end
28
+
29
+ it 'returns false if a collection of valid paths is provided' do
30
+ expect(described_class).to receive(:on_windows?).and_return(true)
31
+ expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
32
+ expect(File).to receive(:directory?).with(valid_path_b).and_return(true)
33
+ expect(described_class.invalid_directories?(valid_paths)).to be false
34
+ end
35
+
36
+ it 'returns true if there is only one path and it is invalid' do
37
+ expect(described_class).to receive(:on_windows?).and_return(true)
38
+ expect(File).to receive(:directory?).with(invalid_path).and_return(false)
39
+ expect(described_class.invalid_directories?(invalid_path)).to be true
40
+ end
41
+
42
+ it 'returns true if the collection has on valid and one invalid member' do
43
+ expect(described_class).to receive(:on_windows?).and_return(true)
44
+ expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
45
+ expect(File).to receive(:directory?).with(valid_path_b).and_return(true)
46
+ expect(File).to receive(:directory?).with(invalid_path).and_return(false)
47
+ expect(described_class.invalid_directories?(mixed_paths)).to be true
48
+ end
49
+
50
+ it 'returns false if collection has empty members but other entries are valid' do
51
+ expect(described_class).to receive(:on_windows?).and_return(true)
52
+ expect(File).to receive(:directory?).with(valid_path_a).and_return(true)
53
+ expect(File).to receive(:directory?).with(valid_path_b).and_return(true)
54
+ allow(File).to receive(:directory?).with('')
55
+ expect(described_class.invalid_directories?(empty_members)).to be false
56
+ end
57
+ end
58
+
59
+ let(:camel_case_hash) do
60
+ {
61
+ a: 1,
62
+ appleButter: %w[a b c],
63
+ someKeyValue: {
64
+ nestedKey: 1,
65
+ anotherNestedKey: 2
66
+ }
67
+ }
68
+ end
69
+ let(:kebab_case_hash) do
70
+ {
71
+ a: 1,
72
+ 'apple-butter': %w[a b c],
73
+ 'some-key-value': {
74
+ 'nested-key': 1,
75
+ 'another-nested-key': 2
76
+ }
77
+ }
78
+ end
79
+ let(:pascal_case_hash) do
80
+ {
81
+ A: 1,
82
+ AppleButter: %w[a b c],
83
+ SomeKeyValue: {
84
+ NestedKey: 1,
85
+ AnotherNestedKey: 2
86
+ }
87
+ }
88
+ end
89
+ let(:pascal_case_hash_in_an_array) do
90
+ [
91
+ 'just a string',
92
+ {
93
+ SomeKey: 'a value'
94
+ },
95
+ 1,
96
+ {
97
+ AnotherKey: {
98
+ NestedKey: 1,
99
+ NestedArray: [
100
+ 1,
101
+ 'another string',
102
+ { SuperNestedKey: 'value' }
103
+ ]
104
+ }
105
+ }
106
+ ]
107
+ end
108
+ let(:snake_case_hash) do
109
+ {
110
+ a: 1,
111
+ apple_butter: %w[a b c],
112
+ some_key_value: {
113
+ nested_key: 1,
114
+ another_nested_key: 2
115
+ }
116
+ }
117
+ end
118
+ let(:snake_case_hash_in_an_array) do
119
+ [
120
+ 'just a string',
121
+ {
122
+ some_key: 'a value'
123
+ },
124
+ 1,
125
+ {
126
+ another_key: {
127
+ nested_key: 1,
128
+ nested_array: [
129
+ 1,
130
+ 'another string',
131
+ { super_nested_key: 'value' }
132
+ ]
133
+ }
134
+ }
135
+ ]
136
+ end
137
+ let(:camel_case_string) { 'thisIsAString' }
138
+ let(:kebab_case_string) { 'this-is-a-string' }
139
+ let(:pascal_case_string) { 'ThisIsAString' }
140
+ let(:snake_case_string) { 'this_is_a_string' }
141
+
142
+ context '.snake_case' do
143
+ it 'converts a string to snake_case' do
144
+ expect(described_class.snake_case(camel_case_string)).to eq snake_case_string
145
+ expect(described_class.snake_case(kebab_case_string)).to eq snake_case_string
146
+ expect(described_class.snake_case(pascal_case_string)).to eq snake_case_string
147
+ end
148
+ end
149
+
150
+ context '.snake_case_hash_keys' do
151
+ it 'snake_cases the keys in a passed hash' do
152
+ expect(described_class.snake_case_hash_keys(camel_case_hash)).to eq snake_case_hash
153
+ expect(described_class.snake_case_hash_keys(kebab_case_hash)).to eq snake_case_hash
154
+ expect(described_class.snake_case_hash_keys(pascal_case_hash)).to eq snake_case_hash
155
+ expect(described_class.snake_case_hash_keys(pascal_case_hash_in_an_array)).to eq snake_case_hash_in_an_array
156
+ end
157
+ end
158
+
159
+ context '.pascal_case' do
160
+ it 'converts a string to PascalCase' do
161
+ expect(described_class.pascal_case(camel_case_string)).to eq pascal_case_string
162
+ expect(described_class.pascal_case(kebab_case_string)).to eq pascal_case_string
163
+ expect(described_class.pascal_case(snake_case_string)).to eq pascal_case_string
164
+ end
165
+ end
166
+
167
+ context '.pascal_case_hash_keys' do
168
+ it 'PascalCases the keys in a passed hash' do
169
+ expect(described_class.pascal_case_hash_keys(camel_case_hash)).to eq pascal_case_hash
170
+ expect(described_class.pascal_case_hash_keys(kebab_case_hash)).to eq pascal_case_hash
171
+ expect(described_class.pascal_case_hash_keys(snake_case_hash)).to eq pascal_case_hash
172
+ expect(described_class.pascal_case_hash_keys(snake_case_hash_in_an_array)).to eq pascal_case_hash_in_an_array
173
+ end
174
+ end
175
+
176
+ context '.symbolize_hash_keys' do
177
+ let(:array_with_string_keys_in_hashes) do
178
+ [
179
+ 'just a string',
180
+ {
181
+ 'some_key' => 'a value'
182
+ },
183
+ 1,
184
+ {
185
+ 'another_key' => {
186
+ 'nested_key' => 1,
187
+ 'nested_array' => [
188
+ 1,
189
+ 'another string',
190
+ { 'super_nested_key' => 'value' }
191
+ ]
192
+ }
193
+ }
194
+ ]
195
+ end
196
+ let(:array_with_symbol_keys_in_hashes) do
197
+ [
198
+ 'just a string',
199
+ {
200
+ some_key: 'a value'
201
+ },
202
+ 1,
203
+ {
204
+ another_key: {
205
+ nested_key: 1,
206
+ nested_array: [
207
+ 1,
208
+ 'another string',
209
+ { super_nested_key: 'value' }
210
+ ]
211
+ }
212
+ }
213
+ ]
214
+ end
215
+
216
+ it 'converts all string hash keys into symbols' do
217
+ expect(described_class.symbolize_hash_keys(array_with_string_keys_in_hashes)).to eq array_with_symbol_keys_in_hashes
218
+ end
219
+ end
220
+
221
+ context '.escape_quotes' do
222
+ it 'handles single quotes' do
223
+ expect(described_class.escape_quotes("The 'Cats' go 'meow'!")).to match(/The ''Cats'' go ''meow''!/)
224
+ end
225
+
226
+ it 'handles double single quotes' do
227
+ expect(described_class.escape_quotes("The ''Cats'' go 'meow'!")).to match(/The ''''Cats'''' go ''meow''!/)
228
+ end
229
+
230
+ it 'handles double quotes' do
231
+ expect(described_class.escape_quotes("The 'Cats' go \"meow\"!")).to match(/The ''Cats'' go "meow"!/)
232
+ end
233
+
234
+ it 'handles dollar signs' do
235
+ expect(described_class.escape_quotes("This should show \$foo variable")).to match(/This should show \$foo variable/)
236
+ end
237
+ end
238
+
239
+ context '.format_powershell_value' do
240
+ let(:ruby_array) { ['string', 1, :symbol, true] }
241
+ let(:powershell_array) { "@('string', 1, symbol, $true)" }
242
+ let(:ruby_hash) do
243
+ {
244
+ string: 'string',
245
+ number: 1,
246
+ symbol: :some_symbol,
247
+ boolean: true,
248
+ nested_hash: {
249
+ another_string: 'foo',
250
+ another_number: 2,
251
+ array: [1, 2, 3]
252
+ }
253
+ }
254
+ end
255
+ let(:powershell_hash) { "@{string = 'string'; number = 1; symbol = some_symbol; boolean = $true; nested_hash = @{another_string = 'foo'; another_number = 2; array = @(1, 2, 3)}}" }
256
+ it 'returns a symbol as a non-interpolated string' do
257
+ expect(described_class.format_powershell_value(:apple)).to eq('apple')
258
+ end
259
+ it 'returns a number as a non interpolated string' do
260
+ expect(described_class.format_powershell_value(101)).to eq('101')
261
+ expect(described_class.format_powershell_value(1.1)).to eq('1.1')
262
+ end
263
+ it 'returns boolean values as the appropriate PowerShell automatic variable' do
264
+ expect(described_class.format_powershell_value(true)).to eq('$true')
265
+ expect(described_class.format_powershell_value(:false)).to eq('$false') # rubocop:disable Lint/BooleanSymbol
266
+ end
267
+ it 'returns a string as an escaped string' do
268
+ expect(described_class.format_powershell_value('some string')).to eq("'some string'")
269
+ end
270
+ it 'returns an array as a string representing a PowerShell array' do
271
+ expect(described_class.format_powershell_value(ruby_array)).to eq(powershell_array)
272
+ end
273
+ it 'returns a hash as a string representing a PowerShell hash' do
274
+ expect(described_class.format_powershell_value(ruby_hash)).to eq(powershell_hash)
275
+ end
276
+ it 'raises an error if an unknown type is passed' do
277
+ expect { described_class.format_powershell_value(described_class) }.to raise_error(/unsupported type Module/)
278
+ end
279
+ end
280
+
281
+ context '.custom_powershell_property' do
282
+ it 'returns a powershell hash with the name and expression keys' do
283
+ expect(described_class.custom_powershell_property('apple', '$_.SomeValue / 5')).to eq("@{Name = 'apple'; Expression = {$_.SomeValue / 5}}")
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pwsh do
6
+ it 'has a version number' do
7
+ expect(described_class::VERSION).not_to be nil
8
+ expect(described_class::VERSION).to be_a_kind_of(String)
9
+ end
10
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pwsh::WindowsPowerShell do
6
+ describe '.version' do
7
+ context 'on non-Windows platforms', unless: Pwsh::Util.on_windows? do
8
+ it 'is not defined' do
9
+ expect(defined?(described_class.version)).to eq(nil)
10
+ end
11
+ end
12
+
13
+ context 'On Windows', if: Pwsh::Util.on_windows? do
14
+ context 'when Windows PowerShell version is greater than three' do
15
+ it 'detects a Windows PowerShell version' do
16
+ allow_any_instance_of(Win32::Registry).to receive(:[]).with('PowerShellVersion').and_return('5.0.10514.6')
17
+ expect(described_class.version).to eq('5.0.10514.6')
18
+ end
19
+
20
+ it 'calls the Windows PowerShell three registry path' do
21
+ reg_key = instance_double('bob')
22
+ allow(reg_key).to receive(:[]).with('PowerShellVersion').and_return('5.0.10514.6')
23
+ allow_any_instance_of(Win32::Registry).to receive(:open).with('SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine', Win32::Registry::KEY_READ | 0x100).and_yield(reg_key)
24
+
25
+ described_class.version
26
+ end
27
+
28
+ it 'does not call Windows PowerShell one registry path' do
29
+ reg_key = instance_double('bob')
30
+ allow(reg_key).to receive(:[]).with('PowerShellVersion').and_return('5.0.10514.6')
31
+ allow_any_instance_of(Win32::Registry).to receive(:open).with('SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine', Win32::Registry::KEY_READ | 0x100).and_yield(reg_key)
32
+ expect_any_instance_of(Win32::Registry).not_to receive(:open).with('SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine', Win32::Registry::KEY_READ | 0x100)
33
+
34
+ described_class.version
35
+ end
36
+ end
37
+
38
+ context 'when Windows PowerShell version is less than three' do
39
+ it 'detects a Windows PowerShell version' do
40
+ allow_any_instance_of(Win32::Registry).to receive(:[]).with('PowerShellVersion').and_return('2.0')
41
+
42
+ expect(described_class.version).to eq('2.0')
43
+ end
44
+
45
+ it 'calls the Windows PowerShell one registry path' do
46
+ reg_key = instance_double('bob')
47
+ allow(reg_key).to receive(:[]).with('PowerShellVersion').and_return('2.0')
48
+ allow_any_instance_of(Win32::Registry).to receive(:open).with('SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine',
49
+ Win32::Registry::KEY_READ | 0x100).and_yield(reg_key)
50
+ allow_any_instance_of(Win32::Registry).to receive(:open).with('SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine',
51
+ Win32::Registry::KEY_READ | 0x100).and_raise(Win32::Registry::Error.new(2), 'nope')
52
+
53
+ expect(described_class.version).to eq('2.0')
54
+ end
55
+ end
56
+
57
+ context 'when Windows PowerShell is not installed' do
58
+ it 'returns nil and not throw' do
59
+ allow_any_instance_of(Win32::Registry).to receive(:open).with('SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine',
60
+ Win32::Registry::KEY_READ | 0x100).and_raise(Win32::Registry::Error.new(2), 'nope')
61
+ allow_any_instance_of(Win32::Registry).to receive(:open).with('SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine',
62
+ Win32::Registry::KEY_READ | 0x100).and_raise(Win32::Registry::Error.new(2), 'nope')
63
+
64
+ expect(described_class.version).to eq(nil)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ describe '.compatible_version?' do
71
+ context 'on non-Windows platforms', unless: Pwsh::Util.on_windows? do
72
+ it 'returns false' do
73
+ expect(described_class.compatible_version?).to eq(false)
74
+ end
75
+ end
76
+
77
+ context 'On Windows', if: Pwsh::Util.on_windows? do
78
+ context 'when the Windows PowerShell major version is nil' do
79
+ it 'returns false' do
80
+ expect(described_class).to receive(:version).and_return(nil)
81
+ expect(described_class.compatible_version?).to eq(false)
82
+ end
83
+ end
84
+ context 'when the Windows PowerShell major version is less than two' do
85
+ it 'returns false' do
86
+ expect(described_class).to receive(:version).and_return('1.0')
87
+ expect(described_class.compatible_version?).to eq(false)
88
+ end
89
+ end
90
+ context 'when the Windows PowerShell major version is two' do
91
+ it 'returns true if .NET 3.5 is installed' do
92
+ expect(described_class).to receive(:version).and_return('2.0')
93
+ allow_any_instance_of(Win32::Registry).to receive(:open).with('SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5', Win32::Registry::KEY_READ | 0x100).and_yield
94
+ expect(described_class.compatible_version?).to eq(true)
95
+ end
96
+ it 'returns false if .NET 3.5 is not installed' do
97
+ expect(described_class).to receive(:version).and_return('2.0')
98
+ allow_any_instance_of(Win32::Registry).to receive(:open).with('SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5', Win32::Registry::KEY_READ | 0x100).and_raise(Win32::Registry::Error, 1)
99
+ expect(described_class.compatible_version?).to eq(false)
100
+ end
101
+ end
102
+ context 'when the Windows PowerShell major version is three' do
103
+ it 'returns true' do
104
+ expect(described_class).to receive(:version).and_return('3.0')
105
+ expect(described_class.compatible_version?).to eq(true)
106
+ end
107
+ end
108
+ context 'when the Windows PowerShell major version is greater than three' do
109
+ it 'returns true' do
110
+ expect(described_class).to receive(:version).and_return('4.0')
111
+ expect(described_class.compatible_version?).to eq(true)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end