gene_system 0.3.2

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.
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GeneSystem::CLI do
4
+ let(:logger) { double(Logger) }
5
+ let(:err_logger) { double(Logger) }
6
+ let(:message) { 'All work and no play makes Jack a dull boy' }
7
+
8
+ before do
9
+ allow(described_class).to receive(:exit).and_return(double)
10
+ end
11
+
12
+ describe '.logger' do
13
+ let(:out) { double(STDOUT) }
14
+ before do
15
+ allow(Logger).to receive(:new).and_return(logger)
16
+ allow(logger).to receive(:formatter=)
17
+ subject.logger(out)
18
+ end
19
+
20
+ it 'creates a new logger to STDOUT' do
21
+ expect(Logger).to have_received(:new).with(out)
22
+ end
23
+ end
24
+
25
+ describe '.print_message' do
26
+ let(:logger) { double(Logger) }
27
+
28
+ before do
29
+ allow(described_class).to receive(:logger).and_return(logger)
30
+ allow(logger).to receive(:info)
31
+ described_class.print_message(message)
32
+ end
33
+
34
+ it 'prints message to stdout' do
35
+ expect(logger).to have_received(:info).with(message)
36
+ end
37
+ end
38
+
39
+ describe '.print_warning' do
40
+ let(:logger) { double(Logger) }
41
+
42
+ before do
43
+ allow(described_class).to receive(:logger).and_return(logger)
44
+ allow(logger).to receive(:warn)
45
+ described_class.print_warning(message)
46
+ end
47
+
48
+ it 'prints message to stdout' do
49
+ expect(logger).to have_received(:warn).with(message)
50
+ end
51
+ end
52
+
53
+ describe '.print_error' do
54
+ let(:logger) { double(Logger) }
55
+
56
+ before do
57
+ allow(described_class).to receive(:logger).and_return(logger)
58
+ allow(logger).to receive(:error)
59
+ described_class.print_error(message)
60
+ end
61
+
62
+ it 'prints message to stderr' do
63
+ expect(logger).to have_received(:error).with(message)
64
+ end
65
+ end
66
+
67
+ describe '.print_message_and_exit' do
68
+ let(:exit_code) { 2 }
69
+
70
+ before do
71
+ allow(described_class).to receive(:print_message)
72
+ described_class.print_message_and_exit(message, exit_code)
73
+ end
74
+
75
+ it 'prints message' do
76
+ expect(described_class).to have_received(:print_message).with(message)
77
+ end
78
+
79
+ it 'exits with set status' do
80
+ expect(described_class).to have_received(:exit).with(exit_code)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GeneSystem::Generators do
4
+ describe '::TEMPLATE_MANIFEST' do
5
+ let(:name) { 'my_dev_setup' }
6
+
7
+ before do
8
+ @manifest = Hashie::Mash.new(
9
+ described_class::TEMPLATE_MANIFEST.call(name)
10
+ )
11
+ end
12
+
13
+ it 'has expected name' do
14
+ expect(@manifest.name).to eq name
15
+ end
16
+
17
+ it 'has expected version' do
18
+ expect(@manifest.version).to eq '0.0.1'
19
+ end
20
+
21
+ it 'has gene system metadata' do
22
+ expect(@manifest.metadata.gene_system).not_to be nil
23
+ end
24
+
25
+ it 'renders app version into gene system metadata' do
26
+ expect(@manifest.metadata.gene_system.version)
27
+ .to eq GeneSystem::VERSION
28
+ end
29
+
30
+ it 'has default step' do
31
+ expect(@manifest.steps.first).to eq described_class::DEFAULT_STEP
32
+ end
33
+ end
34
+
35
+ describe '.render_empty_manifest' do
36
+ let(:name) { 'new_dev_setup' }
37
+ let(:path) { 'path/to/manifests' }
38
+
39
+ let(:manifest_path) { File.join(path, "#{name}.json") }
40
+ let(:manifest_file) { double }
41
+
42
+ let(:manifest) { 'manifest' }
43
+
44
+ before do
45
+ allow(File).to receive(:open)
46
+ .with(manifest_path, 'w')
47
+ .and_yield(manifest_file)
48
+ allow(manifest_file).to receive(:write)
49
+
50
+ allow(described_class::TEMPLATE_MANIFEST)
51
+ .to receive(:call).and_return(manifest)
52
+
53
+ described_class.render_empty_manifest(
54
+ name,
55
+ path
56
+ )
57
+ end
58
+
59
+ it 'renders blank manifest' do
60
+ expect(manifest_file)
61
+ .to have_received(:write)
62
+ .with("\"#{manifest}\"")
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,239 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GeneSystem::Manifest do
4
+ describe '.new_from_file' do
5
+ let(:file_path) { 'path/to/manifest' }
6
+ let(:exist) { true }
7
+ let(:manifest_name) { 'manifest name' }
8
+
9
+ let(:gene_system_meta) do
10
+ {
11
+ 'gene_system' => {
12
+ 'version' => GeneSystem::VERSION
13
+ }
14
+ }
15
+ end
16
+
17
+ let(:version) { '0.0.1' }
18
+ let(:platform) { 'macos' }
19
+ let(:content) do
20
+ {
21
+ 'name' => manifest_name,
22
+ 'version' => version,
23
+ 'platform' => platform,
24
+ 'metadata' => gene_system_meta,
25
+ 'steps' => []
26
+ }.to_json
27
+ end
28
+
29
+ before do
30
+ allow(File).to receive(:exist?).and_return(exist)
31
+ allow(File).to receive(:read).and_return(content)
32
+ allow(Jsonnet).to receive(:evaluate).and_call_original
33
+ end
34
+
35
+ context 'when file exists' do
36
+ before do
37
+ @parsed = described_class.new_from_file(file_path)
38
+ end
39
+
40
+ it 'reads file' do
41
+ expect(File).to have_received(:read).with(file_path)
42
+ end
43
+
44
+ it 'parses json' do
45
+ expect(Jsonnet).to have_received(:evaluate).with(content)
46
+ end
47
+
48
+ it 'returns manifest' do
49
+ expect(@parsed).to be_a GeneSystem::Manifest
50
+ end
51
+
52
+ it 'has name' do
53
+ expect(@parsed.name).to eq manifest_name
54
+ end
55
+
56
+ it 'has version' do
57
+ expect(@parsed.version).to eq version
58
+ end
59
+
60
+ it 'has platform' do
61
+ expect(@parsed.platform).to eq platform
62
+ end
63
+
64
+ it 'has metadata' do
65
+ expect(@parsed.metadata).to eq gene_system_meta
66
+ end
67
+ end
68
+
69
+ context 'when manifest is from a later version of gene_system' do
70
+ let(:gene_system_meta) do
71
+ {
72
+ 'gene_system' => {
73
+ 'version' => '999.999.999'
74
+ }
75
+ }
76
+ end
77
+
78
+ it 'raises incompatibility error' do
79
+ expect do
80
+ described_class.new_from_file(file_path)
81
+ end.to raise_error 'provided manifest is invalid or incompatible with '\
82
+ 'this version of gene_system'
83
+ end
84
+ end
85
+
86
+ context 'when gene_system metadata is missing' do
87
+ let(:gene_system_meta) { {} }
88
+ it 'raises incompatibility error' do
89
+ expect do
90
+ described_class.new_from_file(file_path)
91
+ end.to raise_error 'provided manifest is invalid or incompatible with '\
92
+ 'this version of gene_system'
93
+ end
94
+ end
95
+ end
96
+
97
+ describe '#name' do
98
+ let(:path) { 'path/to/manifest.json' }
99
+
100
+ let(:data) do
101
+ {
102
+ 'name' => 'test_manifest',
103
+ 'version' => '0.1.0',
104
+ 'steps' => []
105
+ }
106
+ end
107
+
108
+ before do
109
+ @manifest = described_class.new(path, data)
110
+ end
111
+
112
+ it 'returns name' do
113
+ expect(@manifest.name).to eq 'test_manifest'
114
+ end
115
+ end
116
+
117
+ describe '#version' do
118
+ let(:path) { 'path/to/manifest.json' }
119
+
120
+ let(:data) do
121
+ {
122
+ 'name' => 'test_manifest',
123
+ 'version' => '0.1.0',
124
+ 'steps' => []
125
+ }
126
+ end
127
+
128
+ before do
129
+ @manifest = described_class.new(path, data)
130
+ end
131
+
132
+ it 'returns version' do
133
+ expect(@manifest.version).to eq '0.1.0'
134
+ end
135
+ end
136
+
137
+ describe '#metadata' do
138
+ let(:path) { 'path/to/manifest.json' }
139
+ let(:meta) { { 'foo' => 'bar' } }
140
+
141
+ let(:data) do
142
+ {
143
+ 'name' => 'test_manifest',
144
+ 'version' => '0.1.0',
145
+ 'metadata' => meta,
146
+ 'steps' => []
147
+ }
148
+ end
149
+
150
+ before do
151
+ @manifest = described_class.new(path, data)
152
+ end
153
+
154
+ it 'returns metadata' do
155
+ expect(@manifest.metadata).to eq meta
156
+ end
157
+ end
158
+
159
+ describe '#platform' do
160
+ let(:path) { 'path/to/manifest.json' }
161
+ let(:platform) { 'macos' }
162
+
163
+ let(:data) do
164
+ {
165
+ 'name' => 'test_manifest',
166
+ 'version' => '0.1.0',
167
+ 'metadata' => { 'foo' => 'bar' },
168
+ 'platform' => platform,
169
+ 'steps' => []
170
+ }
171
+ end
172
+
173
+ before do
174
+ allow(GeneSystem::CLI).to receive(:print_warning)
175
+ @manifest = described_class.new(path, data)
176
+ end
177
+
178
+ it 'returns platform' do
179
+ expect(@manifest.platform).to eq platform
180
+ end
181
+
182
+ context 'when platform is unrecognized' do
183
+ let(:platform) { 'yolosys' }
184
+
185
+ before do
186
+ @platform = @manifest.platform
187
+ end
188
+
189
+ it 'returns platform' do
190
+ expect(@platform).to eq platform
191
+ end
192
+
193
+ it 'prints unrecognised platform warning' do
194
+ expect(GeneSystem::CLI)
195
+ .to have_received(:print_warning)
196
+ .with("WARN: unrecognized platform: #{platform}")
197
+ end
198
+ end
199
+ end
200
+
201
+ describe '#steps' do
202
+ let(:path) { 'path/to/manifest.json' }
203
+ let(:data) do
204
+ {
205
+ 'name' => 'test_manifest',
206
+ 'version' => '0.1.0',
207
+ 'steps' => []
208
+ }
209
+ end
210
+
211
+ let(:step) { double(GeneSystem::Step) }
212
+ let(:steps) { [step, step] }
213
+
214
+ before do
215
+ @manifest = described_class.new(path, data)
216
+ @manifest.instance_variable_set(:@steps, steps)
217
+ end
218
+
219
+ it 'returns all steps by defualt' do
220
+ expect(@manifest.steps).to eq steps
221
+ end
222
+
223
+ context 'when given a query' do
224
+ let(:target_step) { double(GeneSystem::Step) }
225
+ let(:steps) { [step, target_step, step] }
226
+
227
+ before do
228
+ query = ->(step) { step == target_step }
229
+ @manifest.instance_variable_set(:@steps, steps)
230
+
231
+ @result = @manifest.steps(query)
232
+ end
233
+
234
+ it 'returns steps responding to query' do
235
+ expect(@result).to eq [target_step]
236
+ end
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GeneSystem::Platform do
4
+ let(:is_posix) { true }
5
+ before do
6
+ allow(OS).to receive(:posix?).and_return(is_posix)
7
+ end
8
+
9
+ describe 'initialize' do
10
+ it 'returns a new platform' do
11
+ @platform = described_class.new
12
+ expect(@platform).to be_a(described_class)
13
+ end
14
+
15
+ context 'when system is not posix' do
16
+ let(:is_posix) { false }
17
+
18
+ it 'raises unsuppoorted platform RuntimeError' do
19
+ expect { described_class.new }.to raise_error(
20
+ RuntimeError,
21
+ 'unsupported platform'
22
+ )
23
+ end
24
+ end
25
+ end
26
+
27
+ describe '#execute_commands' do
28
+ let(:cmd) { 'do something' }
29
+ let(:cmds) { [cmd, cmd] }
30
+ let(:result) { 0 }
31
+
32
+ subject { described_class.new }
33
+
34
+ before do
35
+ allow(subject).to receive(:execute_command)
36
+ .and_return(result)
37
+ end
38
+
39
+ it 'executes commands' do
40
+ subject.execute_commands(cmds)
41
+
42
+ expect(subject)
43
+ .to have_received(:execute_command)
44
+ .with(cmd, {})
45
+ .twice
46
+ end
47
+
48
+ context 'when command fails' do
49
+ let(:result) { 1 }
50
+
51
+ it 'raises command failed runtime error' do
52
+ expect { subject.execute_commands(cmds) }.to raise_error(
53
+ RuntimeError,
54
+ "command `#{cmd}` failed - returned #{result}"
55
+ )
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#execute_command' do
61
+ let(:cmd) { 'do something {{awesome}}' }
62
+ let(:pid) { 1234 }
63
+ let(:result) { double(exitstatus: 999) }
64
+
65
+ subject { described_class.new }
66
+
67
+ before do
68
+ allow(Process).to receive(:spawn).and_return(pid)
69
+ allow(Process).to receive(:waitpid2).and_return([pid, result])
70
+
71
+ @result = subject.execute_command(cmd, awesome: 'cool')
72
+ end
73
+
74
+ it 'spawns process with command' do
75
+ expect(Process).to have_received(:spawn).with('do something cool')
76
+ end
77
+
78
+ it 'waits for processs to conclude' do
79
+ expect(Process).to have_received(:waitpid2).with(pid)
80
+ end
81
+
82
+ it 'returns status' do
83
+ expect(@result).to eq result.exitstatus
84
+ end
85
+ end
86
+
87
+ describe '#posix?' do
88
+ subject { described_class.new }
89
+
90
+ it 'returns true if system is posix' do
91
+ expect(subject.posix?).to be true
92
+ end
93
+ end
94
+ end