rainforest-cli 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 855968ae7a28f0b1023fd41714fefc0fca6b5ad2
4
- data.tar.gz: b4eb76a7382c5645811cbb4cbd97a12eb9385d2a
3
+ metadata.gz: 70b8d8fad3a7886f4cdff271fc383dca7614061a
4
+ data.tar.gz: b9bc2a5e63a3b95ad661a6d74212f9b01a8cefee
5
5
  SHA512:
6
- metadata.gz: 83cf3f5e28a712add5c8077beecfdd869627f911bf9ad66aae75abb7090204ada77c19f450133437f028ca152cc8786198651b5ec4e5b4e168e00025988730d3
7
- data.tar.gz: 5615003a01351ffd1d9acd7ba924580f767c2a2d72f1e14ead0be38097e83c3402a2343d71b58b0fa7fc99b77d80f562ea1bec11b34ea272186cc084beb53bd9
6
+ metadata.gz: c0888185bfefe12bf782dbf73c380b5c75dc3d36bdc8971031b467ff716b152989ebfcafe24ded4c67fe2a190f20a5e87a2ef0fcc8c7ddf880af2cf98ec4be9a
7
+ data.tar.gz: f0080514d2ae49f2bec4662e746343ab8336e721f97e32f3f00250d340b24444cd4290aaa88bb90b59d7d3bab65676b026c26051ba3247294d62b409e8d574f1
data/CHANGELOG.md CHANGED
@@ -1,7 +1,12 @@
1
1
  # Rainforest CLI Changelog
2
2
 
3
+ ## 1.4.0
4
+ - Support for new `--version` command. (4362c85fe599a02eaa1b772d184be31e692e934e, @epaulet)
5
+ - Validate duplicate RFML IDs before uploading. (67f71d053c755eaf92c1bd205931e89e903b88c9, @curtis-rainforestqa)
6
+ - Add `folders` commands for a folder ID reference. (4ab19fec0924b4764e140fb3c5aa85f1dbfe4006, @epaulet)
7
+
3
8
  ## 1.3.1 - 11th April 2016
4
- - Support crowd selection
9
+ - Support crowd selection. (03fedacfb7a6e69a174fb3e0e1fd75218fdbbfa9, @ukd1)
5
10
 
6
11
  ## 1.3.0 - 7th April 2016
7
12
  - Export tests with embedded tests unflattened. (0ed4c62cac8a0d5fbd98f03190d3c18c48ac7119,
data/README.md CHANGED
@@ -62,6 +62,16 @@ Export all tests from Rainforest
62
62
  rainforest export
63
63
  ```
64
64
 
65
+ See a list of all of your sites and their IDs
66
+ ```bash
67
+ rainforest sites
68
+ ```
69
+
70
+ See a list of all of your smart folders and their IDs
71
+ ```bash
72
+ rainforest folders
73
+ ```
74
+
65
75
  ## Options
66
76
 
67
77
  ### General
@@ -134,6 +144,7 @@ Popular command line options are:
134
144
  - `--description "CI automatic run"` - add an arbitrary description for the run.
135
145
  - `--embed-tests` - Use with `rainforest export` to export your tests without extracting the
136
146
  steps of an embedded test.
147
+ - `--test-folder /path/to/directory` - Use with `rainforest [new, upload, export]`. If this option is not provided, rainforest-cli will, in the case of 'new' create a directory, or in the case of 'upload' and 'export' use the directory, at the default path `./spec/rainforest/`.
137
148
 
138
149
 
139
150
  #### Specifying Test IDs
@@ -15,7 +15,7 @@ require 'rainforest/cli/remote_tests'
15
15
  require 'rainforest/cli/validator'
16
16
  require 'rainforest/cli/exporter'
17
17
  require 'rainforest/cli/uploader'
18
- require 'rainforest/cli/sites'
18
+ require 'rainforest/cli/resources'
19
19
 
20
20
  module RainforestCli
21
21
  def self.start(args)
@@ -30,24 +30,12 @@ module RainforestCli
30
30
  end
31
31
 
32
32
  case options.command
33
- when 'run'
34
- runner = Runner.new(options)
35
- runner.run
36
- when 'new'
37
- t = TestFiles.new(options)
38
- t.create_file
39
- when 'validate'
40
- t = Validator.new(options)
41
- t.validate
42
- when 'upload'
43
- t = Uploader.new(options)
44
- t.upload
45
- when 'export'
46
- t = Exporter.new(options)
47
- t.export
48
- when 'sites'
49
- t = Sites.new(options)
50
- t.list_sites
33
+ when 'run' then Runner.new(options).run
34
+ when 'new' then TestFiles.new(options).create_file
35
+ when 'validate' then Validator.new(options).validate
36
+ when 'upload' then Uploader.new(options).upload
37
+ when 'export' then Exporter.new(options).export
38
+ when 'sites', 'folders' then Resources.new(options).public_send(options.command)
51
39
  else
52
40
  logger.fatal 'Unknown command'
53
41
  exit 2
@@ -53,6 +53,9 @@ module RainforestCli
53
53
  # NOTE: Disabling line length cop to allow for consistency of syntax
54
54
  # rubocop:disable Metrics/LineLength
55
55
  @parsed = ::OptionParser.new do |opts|
56
+ opts.set_program_name 'Rainforest CLI'
57
+ opts.version = RainforestCli::VERSION
58
+
56
59
  opts.on('--debug') do
57
60
  @debug = true
58
61
  end
@@ -138,6 +141,11 @@ module RainforestCli
138
141
  exit 0
139
142
  end
140
143
 
144
+ opts.on_tail('--version', 'Display gem version') do
145
+ puts opts.ver
146
+ exit 0
147
+ end
148
+
141
149
  end.parse!(@args)
142
150
  # rubocop:enable Metrics/LineLength
143
151
  # NOTE: end Rubocop exception
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+ class RainforestCli::Resources
3
+ def initialize(options)
4
+ @client = RainforestCli::HttpClient.new(token: options.token)
5
+ end
6
+
7
+ def sites
8
+ sites = @client.get('/sites')
9
+
10
+ if sites.empty?
11
+ logger.info('No sites found on your account.')
12
+ logger.info('Please visit https://app.rainforestqa.com/settings/sites to create and edit your sites.')
13
+ else
14
+ print_table('Site', sites) do |site|
15
+ { id: site['id'], name: site['name'] }
16
+ end
17
+ end
18
+ end
19
+
20
+ def folders
21
+ folders = @client.get('/folders')
22
+
23
+ if folders.empty?
24
+ logger.info('No folders found on your account.')
25
+ logger.info('Please visit https://app.rainforestqa.com/folders to create and edit your sites.')
26
+ else
27
+ print_table('Folder', folders) do |folder|
28
+ { id: folder['id'], name: folder['title'] }
29
+ end
30
+ end
31
+ end
32
+
33
+ def print_table(resource_name, resources)
34
+ id_col = "#{resource_name} ID"
35
+ table_heading = "#{id_col} | #{resource_name} Name"
36
+ puts table_heading
37
+ puts '-' * table_heading.length
38
+ resources.each do |resource|
39
+ resource_data = yield(resource)
40
+ puts "#{resource_data[:id].to_s.rjust(id_col.length)} | #{resource_data[:name]}"
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def logger
47
+ RainforestCli.logger
48
+ end
49
+ end
@@ -32,7 +32,9 @@ class RainforestCli::Validator
32
32
  # (no short-circuiting with ||)
33
33
  parsing_errors = has_parsing_errors?
34
34
  dependency_errors = has_test_dependency_errors?
35
- is_invalid = parsing_errors || dependency_errors
35
+ duplicate_rfml_id_errors = has_duplicate_rfml_id_errors?
36
+
37
+ is_invalid = parsing_errors || dependency_errors || duplicate_rfml_id_errors
36
38
 
37
39
  logger.info ''
38
40
  logger.info(is_invalid ? VALIDATIONS_FAILED : VALIDATIONS_PASSED)
@@ -48,6 +50,21 @@ class RainforestCli::Validator
48
50
  end
49
51
  end
50
52
 
53
+ def has_duplicate_rfml_id_errors?
54
+ duped_rfml_ids_and_counts = collect_duplicate_rfml_ids
55
+ return false unless duped_rfml_ids_and_counts.size > 0
56
+ duplicate_rfml_ids_notification(duped_rfml_ids_and_counts)
57
+ true
58
+ end
59
+
60
+ def collect_duplicate_rfml_ids
61
+ rfml_ids_and_counts = Hash.new(0)
62
+ local_tests.test_data.each do |test|
63
+ rfml_ids_and_counts[test.rfml_id] += 1
64
+ end
65
+ rfml_ids_and_counts.select {|_, count| count > 1}
66
+ end
67
+
51
68
  def has_parsing_errors?
52
69
  logger.info 'Validating parsing errors...'
53
70
  has_parsing_errors = rfml_tests.select { |t| t.errors.any? }
@@ -152,6 +169,16 @@ class RainforestCli::Validator
152
169
  logger.error ''
153
170
  end
154
171
 
172
+ def duplicate_rfml_ids_notification(duplicate_rfml_ids_and_counts)
173
+ logger.error "The test ids are not unique!"
174
+ logger.error ''
175
+ duplicate_rfml_ids_and_counts.each do |rfml_id, count|
176
+ count_str = count == 1 ? 'is 1 file' : "are #{count} files"
177
+ logger.error "\tThere #{count_str} with an id of #{rfml_id}"
178
+ end
179
+ logger.error ''
180
+ end
181
+
155
182
  def logger
156
183
  RainforestCli.logger
157
184
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module RainforestCli
3
- VERSION = '1.3.1'
3
+ VERSION = '1.4.0'
4
4
  end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+ describe RainforestCli::Resources do
3
+ let(:options) { instance_double('RainforestCli::Options', token: 'fake_token') }
4
+ subject { described_class.new(options) }
5
+
6
+ describe '#sites' do
7
+ context 'no sites configured' do
8
+ before do
9
+ allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return([])
10
+ end
11
+
12
+ it 'directs you to the site settings' do
13
+ # first line of text
14
+ expect(RainforestCli.logger).to receive(:info).with(an_instance_of(String))
15
+ # second line of text
16
+ expect(RainforestCli.logger).to receive(:info) do |message|
17
+ expect(message).to include('/settings/sites')
18
+ end
19
+
20
+ subject.sites
21
+ end
22
+ end
23
+
24
+ context 'with sites in account' do
25
+ let(:sites) do
26
+ [
27
+ {
28
+ 'id' => 123,
29
+ 'name' => 'The Foo Site'
30
+ },
31
+ {
32
+ 'id' => 456,
33
+ 'name'=> 'The Bar Site'
34
+ },
35
+ {
36
+ 'id' => 789,
37
+ 'name' => 'The Baz Site'
38
+ }
39
+ ]
40
+ end
41
+
42
+ before do
43
+ allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return(sites)
44
+ end
45
+
46
+ it 'calls the print method' do
47
+ expect(subject).to receive(:print_table).with('Site', sites).and_yield(sites.first)
48
+ subject.sites
49
+ end
50
+
51
+ it 'correctly formats the site information in the given block' do
52
+ expect(subject).to receive(:print_table) do |_resource_name, _resource, &blk|
53
+ site = sites.first
54
+ expect(blk.call(site)).to include(id: site['id'], name: site['name'])
55
+ end
56
+ subject.sites
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#folders' do
62
+ context 'no folders in account' do
63
+ before do
64
+ allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return([])
65
+ end
66
+
67
+ it 'directs you to the folders page' do
68
+ # first line of text
69
+ expect(RainforestCli.logger).to receive(:info).with(an_instance_of(String))
70
+ # second line of text
71
+ expect(RainforestCli.logger).to receive(:info) do |message|
72
+ expect(message).to include('/folders')
73
+ end
74
+
75
+ subject.folders
76
+ end
77
+ end
78
+
79
+ context 'with folders in account' do
80
+ let(:folders) do
81
+ [
82
+ {
83
+ 'id' => 123,
84
+ 'title' => 'The Foo Folder'
85
+ },
86
+ {
87
+ 'id' => 456,
88
+ 'title'=> 'The Bar Folder'
89
+ },
90
+ {
91
+ 'id' => 789,
92
+ 'title' => 'The Baz Folder'
93
+ }
94
+ ]
95
+ end
96
+
97
+ before do
98
+ allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return(folders)
99
+ end
100
+
101
+ it 'calls the print method' do
102
+ expect(subject).to receive(:print_table).with('Folder', folders).and_yield(folders.first)
103
+ subject.folders
104
+ end
105
+
106
+ it 'correctly formats the site information in the given block' do
107
+ expect(subject).to receive(:print_table) do |_resource_name, _resource, &blk|
108
+ folder = folders.first
109
+ expect(blk.call(folder)).to include(id: folder['id'], name: folder['title'])
110
+ end
111
+ subject.folders
112
+ end
113
+ end
114
+ end
115
+
116
+ describe '#print_table' do
117
+ let(:resource_id) { 123456 }
118
+ let(:resource_name) { 'resource name' }
119
+ let(:resources) { [ { id: resource_id, name: resource_name } ] }
120
+
121
+ it 'prints out the resources' do
122
+ expect(subject).to receive(:puts) do |message|
123
+ expect(message).to include('Resource ID')
124
+ expect(message).to include('Resource Name')
125
+ end
126
+
127
+ # Stub dashed the line dividing table header and body
128
+ expect(subject).to receive(:puts)
129
+
130
+ expect(subject).to receive(:puts) do |message|
131
+ expect(message).to include(resource_id.to_s)
132
+ expect(message).to include(resource_name)
133
+ end
134
+
135
+ subject.print_table('Resource', resources) do
136
+ { id: resource_id, name: resource_name }
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,7 @@
1
+ #! a-test
2
+ # title: New test
3
+ # start_uri: /
4
+ #
5
+
6
+ This is a step action.
7
+ This is a step question?
@@ -0,0 +1,7 @@
1
+ #! a-test
2
+ # title: Some other test
3
+ # start_uri: /
4
+ #
5
+
6
+ This is another action.
7
+ This is another question?
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe RainforestCli::Validator do
4
- let(:rfml_id_regex) { /^#! (.+?)($| .+?$)/ }
5
4
  let(:file_path) { File.join(test_directory, correct_file_name) }
6
5
 
7
6
  def notifies_with_correct_file_name
@@ -29,6 +28,8 @@ describe RainforestCli::Validator do
29
28
  end
30
29
 
31
30
  shared_examples 'it detects all the correct errors' do
31
+ let(:tested_method) { :validate }
32
+ let(:raises_error) { false }
32
33
  let(:options) { instance_double('RainforestCli::Options', test_folder: test_directory, token: 'api_token') }
33
34
  subject { described_class.new(options) }
34
35
 
@@ -92,10 +93,24 @@ describe RainforestCli::Validator do
92
93
  end
93
94
 
94
95
  describe '#validate' do
95
- let(:tested_method) { :validate }
96
- let(:raises_error) { false }
97
-
98
96
  it_behaves_like 'it detects all the correct errors'
97
+
98
+ context 'when multiple tests have the same rfml_ids' do
99
+ let(:test_directory) { File.expand_path(File.join(__FILE__, '../validation-examples/duplicate_rfml_ids')) }
100
+ let(:options) { instance_double('RainforestCli::Options', test_folder: test_directory, token: 'api_token') }
101
+
102
+ subject { described_class.new(options) }
103
+
104
+ before do
105
+ allow(subject).to receive(:remote_rfml_ids) { [] }
106
+ end
107
+
108
+ it 'logs the errors' do
109
+ expect(subject).to receive(:duplicate_rfml_ids_notification).with({'a-test' => 2}).and_call_original
110
+
111
+ subject.validate
112
+ end
113
+ end
99
114
  end
100
115
 
101
116
  describe '#validate_with_exception!' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rainforest-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Russell Smith
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-04-11 00:00:00.000000000 Z
12
+ date: 2016-04-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
@@ -169,8 +169,8 @@ files:
169
169
  - lib/rainforest/cli/http_client.rb
170
170
  - lib/rainforest/cli/options.rb
171
171
  - lib/rainforest/cli/remote_tests.rb
172
+ - lib/rainforest/cli/resources.rb
172
173
  - lib/rainforest/cli/runner.rb
173
- - lib/rainforest/cli/sites.rb
174
174
  - lib/rainforest/cli/test_files.rb
175
175
  - lib/rainforest/cli/test_parser.rb
176
176
  - lib/rainforest/cli/uploader.rb
@@ -193,8 +193,8 @@ files:
193
193
  - spec/redirection-examples/wrong_redirect_embedded.rfml
194
194
  - spec/redirection-examples/wrong_redirect_spacing.rfml
195
195
  - spec/remote_tests_spec.rb
196
+ - spec/resources_spec.rb
196
197
  - spec/runner_spec.rb
197
- - spec/sites_spec.rb
198
198
  - spec/spec_helper.rb
199
199
  - spec/test_files_spec.rb
200
200
  - spec/test_parser_spec.rb
@@ -203,6 +203,8 @@ files:
203
203
  - spec/validation-examples/circular_embeds/test2.rfml
204
204
  - spec/validation-examples/correct_embeds/embedded_test.rfml
205
205
  - spec/validation-examples/correct_embeds/test_with_embedded.rfml
206
+ - spec/validation-examples/duplicate_rfml_ids/file1.rfml
207
+ - spec/validation-examples/duplicate_rfml_ids/file2.rfml
206
208
  - spec/validation-examples/missing_embeds/correct_test.rfml
207
209
  - spec/validation-examples/missing_embeds/incorrect_test.rfml
208
210
  - spec/validation-examples/parse_errors/no_parse_errors.rfml
@@ -251,8 +253,8 @@ test_files:
251
253
  - spec/redirection-examples/wrong_redirect_embedded.rfml
252
254
  - spec/redirection-examples/wrong_redirect_spacing.rfml
253
255
  - spec/remote_tests_spec.rb
256
+ - spec/resources_spec.rb
254
257
  - spec/runner_spec.rb
255
- - spec/sites_spec.rb
256
258
  - spec/spec_helper.rb
257
259
  - spec/test_files_spec.rb
258
260
  - spec/test_parser_spec.rb
@@ -261,6 +263,8 @@ test_files:
261
263
  - spec/validation-examples/circular_embeds/test2.rfml
262
264
  - spec/validation-examples/correct_embeds/embedded_test.rfml
263
265
  - spec/validation-examples/correct_embeds/test_with_embedded.rfml
266
+ - spec/validation-examples/duplicate_rfml_ids/file1.rfml
267
+ - spec/validation-examples/duplicate_rfml_ids/file2.rfml
264
268
  - spec/validation-examples/missing_embeds/correct_test.rfml
265
269
  - spec/validation-examples/missing_embeds/incorrect_test.rfml
266
270
  - spec/validation-examples/parse_errors/no_parse_errors.rfml
@@ -268,3 +272,4 @@ test_files:
268
272
  - spec/validation-examples/parse_errors/no_question_mark.rfml
269
273
  - spec/validation-examples/parse_errors/no_rfml_id.rfml
270
274
  - spec/validator_spec.rb
275
+ has_rdoc:
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
- class RainforestCli::Sites
3
- def initialize(options)
4
- @client = RainforestCli::HttpClient.new(token: options.token)
5
- end
6
-
7
- def list_sites
8
- sites = fetch_sites
9
-
10
- if sites.empty?
11
- logger.info('No configured sites found on your account.')
12
- logger.info('Please visit https://app.rainforestqa.com/settings/sites to create and edit your sites.')
13
- else
14
- print_site_table(sites)
15
- end
16
- end
17
-
18
- def print_site_table(sites)
19
- puts 'Site ID | Site Name'
20
- puts '-------------------'
21
- sites.each do |site|
22
- puts "#{site['id'].to_s.rjust(7)} | #{site['name']}"
23
- end
24
- end
25
-
26
- private
27
-
28
- def fetch_sites
29
- @sites ||= @client.get('/sites')
30
- end
31
-
32
- def logger
33
- RainforestCli.logger
34
- end
35
- end
data/spec/sites_spec.rb DELETED
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
- describe RainforestCli::Sites do
3
- let(:options) { instance_double('RainforestCli::Options', token: 'fake_token') }
4
- subject { described_class.new(options) }
5
-
6
- let(:sites) do
7
- [
8
- {
9
- 'id' => 123,
10
- 'name' => 'The Foo Site'
11
- },
12
- {
13
- 'id' => 456,
14
- 'name'=> 'The Bar Site'
15
- },
16
- {
17
- 'id' => 789,
18
- 'name' => 'The Baz Site'
19
- }
20
- ]
21
- end
22
-
23
- describe '#list_sites' do
24
- context 'no sites configured' do
25
- before do
26
- allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return([])
27
- end
28
-
29
- it 'directs you to the site settings' do
30
- # first line of text
31
- expect(RainforestCli.logger).to receive(:info).with(an_instance_of(String))
32
- # second line of text
33
- expect(RainforestCli.logger).to receive(:info) do |message|
34
- expect(message).to include('/settings/sites')
35
- end
36
-
37
- subject.list_sites
38
- end
39
- end
40
-
41
- context 'with sites configured' do
42
- before do
43
- allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return(sites)
44
- end
45
-
46
- it 'prints the site table' do
47
- expect(subject).to receive(:print_site_table).with(sites)
48
- subject.list_sites
49
- end
50
-
51
- end
52
- end
53
-
54
- describe '#print_site_table' do
55
- it 'prints out the sites' do
56
- expect(subject).to receive(:puts) do |message|
57
- expect(message).to include('Site ID')
58
- expect(message).to include('Site Name')
59
- end
60
-
61
- # The line dividing table header and body
62
- expect(subject).to receive(:puts)
63
-
64
- sites.each do |site|
65
- expect(subject).to receive(:puts) do |message|
66
- expect(message).to include(site['id'].to_s)
67
- expect(message).to include(site['name'])
68
- end
69
- end
70
-
71
- subject.print_site_table(sites)
72
- end
73
- end
74
- end