rainforest-cli 1.2.2 → 1.3.0

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,10 @@
1
+ #! example_test
2
+ # title: Example Test
3
+ # tags: foo,bar,baz
4
+ # start_uri: /start_uri
5
+
6
+ This is a step action.
7
+ This is a question?
8
+
9
+ # redirect: foo
10
+ - another_test
@@ -0,0 +1,11 @@
1
+ #! example_test (Test ID - only edit if this test has not yet been uploaded)
2
+ # title: Example Test
3
+ # tags: foo,bar,baz
4
+ # start_uri: /start_uri
5
+
6
+ - another_test
7
+
8
+ # redirect: true
9
+
10
+ This is a step action.
11
+ This is a question?
@@ -0,0 +1,74 @@
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
data/spec/spec_helper.rb CHANGED
@@ -13,6 +13,13 @@ RSpec.configure do |config|
13
13
  # the seed, which is printed after each run.
14
14
  # --seed 1234
15
15
  config.order = 'random'
16
+
17
+ config.before do
18
+ progressbar_mock = double('ProgressBar')
19
+ allow(ProgressBar).to receive(:create).and_return(progressbar_mock)
20
+ allow(progressbar_mock).to receive(:increment)
21
+ ENV['RAINFOREST_API_TOKEN'] = nil
22
+ end
16
23
  end
17
24
 
18
25
  RSpec::Matchers.define :test_with_file_name do |expected_name|
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
  describe RainforestCli::TestFiles do
3
3
  describe '#test_data' do
4
- let(:test_folder) { File.dirname(__FILE__) + '/rainforest-example' }
5
- subject { described_class.new(test_folder) }
4
+ let(:test_directory) { File.dirname(__FILE__) + '/rainforest-example' }
5
+ let(:options) { instance_double('RainforestCli::Options', test_folder: test_directory) }
6
+ subject { described_class.new(options) }
6
7
 
7
8
  let(:rfml_test) { subject.test_data.first }
8
- let(:text_file) { File.read(test_folder + '/example_test.rfml') }
9
+ let(:text_file) { File.read(test_directory + '/example_test.rfml') }
9
10
 
10
11
  it 'parses all available tests on initialization' do
11
12
  expect(rfml_test.title).to eq(text_file.match(/^# title: (.+)$/)[1])
@@ -16,7 +17,8 @@ describe RainforestCli::TestFiles do
16
17
  describe '#test_dictionary' do
17
18
  Test = Struct.new(:rfml_id, :id)
18
19
 
19
- subject { described_class.new }
20
+ let(:options) { instance_double('RainforestCli::Options', test_folder: nil) }
21
+ subject { described_class.new(options) }
20
22
  let(:tests) { [Test.new('foo', 123), Test.new('bar', 456), Test.new('baz', 789)] }
21
23
 
22
24
  before do
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+ describe RainforestCli::TestParser do
3
+ describe RainforestCli::TestParser::Step do
4
+ describe '#to_element' do
5
+ subject { described_class.new('action', 'response', 'redirect').to_element }
6
+ its([:redirection]) { is_expected.to eq('redirect') }
7
+
8
+ context 'with no redirect' do
9
+ subject { described_class.new('action', 'response', nil).to_element }
10
+ its([:redirection]) { is_expected.to eq('true') }
11
+ end
12
+ end
13
+ end
14
+
15
+ describe RainforestCli::TestParser::EmbeddedTest do
16
+ describe '#to_element' do
17
+ let(:primary_key_id) { 123 }
18
+ subject { described_class.new.to_element(primary_key_id) }
19
+
20
+ context 'with no redirect' do
21
+ its([:redirection]) { is_expected.to eq('true') }
22
+ end
23
+ end
24
+ end
25
+
26
+ describe RainforestCli::TestParser::Parser do
27
+ subject { described_class.new(file_name) }
28
+
29
+ describe '#process' do
30
+ context 'redirection' do
31
+ context 'step' do
32
+ context 'no redirection specified' do
33
+ let(:file_name) { File.dirname(__FILE__) + '/rainforest-example/example_test.rfml' }
34
+ it { has_redirection_value(subject.process, 'true') }
35
+ end
36
+
37
+ context 'redirection specified as true' do
38
+ let(:file_name) { File.dirname(__FILE__) + '/redirection-examples/redirect.rfml' }
39
+ it { has_redirection_value(subject.process, 'true') }
40
+ end
41
+
42
+ context 'redirection specified as not true or false' do
43
+ let(:file_name) { File.dirname(__FILE__) + '/redirection-examples/wrong_redirect.rfml' }
44
+ let(:redirect_line_no) { 7 }
45
+ it { has_parsing_error(subject.process, redirect_line_no) }
46
+ end
47
+ end
48
+
49
+ context 'embedded test' do
50
+ context 'redirection specified as false' do
51
+ let(:file_name) { File.dirname(__FILE__) + '/redirection-examples/no_redirect_embedded.rfml' }
52
+ it { has_redirection_value(subject.process, 'false') }
53
+ end
54
+
55
+ context 'redirection specified as true' do
56
+ let(:file_name) { File.dirname(__FILE__) + '/redirection-examples/redirect_embedded.rfml' }
57
+ it { has_redirection_value(subject.process, 'true') }
58
+ end
59
+
60
+ context 'redirection specified as not true or false' do
61
+ let(:file_name) { File.dirname(__FILE__) + '/redirection-examples/wrong_redirect_embedded.rfml' }
62
+ let(:redirect_line_no) { 8 }
63
+ it { has_parsing_error(subject.process, redirect_line_no) }
64
+ end
65
+ end
66
+
67
+ context 'poor syntax' do
68
+ context 'extra empty lines' do
69
+ let(:file_name) { File.dirname(__FILE__) + '/redirection-examples/wrong_redirect_spacing.rfml' }
70
+ let(:empty_line_no) { 8 }
71
+ it { has_parsing_error(subject.process, empty_line_no) }
72
+ end
73
+ end
74
+
75
+ def has_redirection_value(test, value)
76
+ step = test.steps.last
77
+ expect(step.redirection).to eq(value)
78
+ end
79
+
80
+ def has_parsing_error(test, line_no)
81
+ expect(test.errors[line_no]).to_not be_nil
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,12 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
  describe RainforestCli::Uploader do
3
3
  let(:options) { instance_double('RainforestCli::Options', token: 'foo', test_folder: test_directory) }
4
- let(:progress_bar_double) { double('ProgressBar') }
5
4
  subject { described_class.new(options) }
6
5
 
7
6
  before do
8
- allow(ProgressBar).to receive(:create).and_return(progress_bar_double)
9
- allow(progress_bar_double).to receive(:increment)
10
7
  allow_any_instance_of(RainforestCli::Validator).to receive(:validate_with_exception!)
11
8
  allow_any_instance_of(RainforestCli::RemoteTests).to receive(:primary_key_dictionary)
12
9
  .and_return({})
@@ -22,7 +19,7 @@ describe RainforestCli::Uploader do
22
19
  end
23
20
 
24
21
  it 'creates uploads the new tests with no steps' do
25
- expect(Rainforest::Test).to receive(:create).with(hash_including(:title, :start_uri, :rfml_id))
22
+ expect(Rainforest::Test).to receive(:create).with(hash_including(:title, :start_uri, :rfml_id, :source))
26
23
  .and_return(rf_test_double).twice
27
24
  subject.upload
28
25
  end
@@ -44,7 +41,8 @@ describe RainforestCli::Uploader do
44
41
  title: 'Example Test',
45
42
  source: 'rainforest-cli',
46
43
  tags: ['foo', 'bar', 'baz'],
47
- rfml_id: 'example_test'
44
+ rfml_id: 'example_test',
45
+ site_id: '456'
48
46
  })
49
47
  end
50
48
 
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.2.2
4
+ version: 1.3.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-03-21 00:00:00.000000000 Z
12
+ date: 2016-04-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
@@ -161,17 +161,17 @@ files:
161
161
  - README.md
162
162
  - Rakefile
163
163
  - bin/rainforest
164
- - circle.yml
165
164
  - lib/rainforest/cli.rb
166
165
  - lib/rainforest/cli/constants.rb
167
166
  - lib/rainforest/cli/csv_importer.rb
167
+ - lib/rainforest/cli/exporter.rb
168
168
  - lib/rainforest/cli/git_trigger.rb
169
169
  - lib/rainforest/cli/http_client.rb
170
170
  - lib/rainforest/cli/options.rb
171
171
  - lib/rainforest/cli/remote_tests.rb
172
172
  - lib/rainforest/cli/runner.rb
173
+ - lib/rainforest/cli/sites.rb
173
174
  - lib/rainforest/cli/test_files.rb
174
- - lib/rainforest/cli/test_importer.rb
175
175
  - lib/rainforest/cli/test_parser.rb
176
176
  - lib/rainforest/cli/uploader.rb
177
177
  - lib/rainforest/cli/validator.rb
@@ -179,15 +179,25 @@ files:
179
179
  - rainforest-cli.gemspec
180
180
  - spec/cli_spec.rb
181
181
  - spec/csv_importer_spec.rb
182
+ - spec/exporter_spec.rb
182
183
  - spec/fixtures/variables.txt
183
184
  - spec/git_trigger_spec.rb
184
185
  - spec/http_client_spec.rb
185
186
  - spec/options_spec.rb
186
187
  - spec/rainforest-example/example_test.rfml
188
+ - spec/redirection-examples/no_redirect.rfml
189
+ - spec/redirection-examples/no_redirect_embedded.rfml
190
+ - spec/redirection-examples/redirect.rfml
191
+ - spec/redirection-examples/redirect_embedded.rfml
192
+ - spec/redirection-examples/wrong_redirect.rfml
193
+ - spec/redirection-examples/wrong_redirect_embedded.rfml
194
+ - spec/redirection-examples/wrong_redirect_spacing.rfml
187
195
  - spec/remote_tests_spec.rb
188
196
  - spec/runner_spec.rb
197
+ - spec/sites_spec.rb
189
198
  - spec/spec_helper.rb
190
199
  - spec/test_files_spec.rb
200
+ - spec/test_parser_spec.rb
191
201
  - spec/uploader_spec.rb
192
202
  - spec/validation-examples/circular_embeds/test1.rfml
193
203
  - spec/validation-examples/circular_embeds/test2.rfml
@@ -227,15 +237,25 @@ summary: Command line utility for Rainforest QA
227
237
  test_files:
228
238
  - spec/cli_spec.rb
229
239
  - spec/csv_importer_spec.rb
240
+ - spec/exporter_spec.rb
230
241
  - spec/fixtures/variables.txt
231
242
  - spec/git_trigger_spec.rb
232
243
  - spec/http_client_spec.rb
233
244
  - spec/options_spec.rb
234
245
  - spec/rainforest-example/example_test.rfml
246
+ - spec/redirection-examples/no_redirect.rfml
247
+ - spec/redirection-examples/no_redirect_embedded.rfml
248
+ - spec/redirection-examples/redirect.rfml
249
+ - spec/redirection-examples/redirect_embedded.rfml
250
+ - spec/redirection-examples/wrong_redirect.rfml
251
+ - spec/redirection-examples/wrong_redirect_embedded.rfml
252
+ - spec/redirection-examples/wrong_redirect_spacing.rfml
235
253
  - spec/remote_tests_spec.rb
236
254
  - spec/runner_spec.rb
255
+ - spec/sites_spec.rb
237
256
  - spec/spec_helper.rb
238
257
  - spec/test_files_spec.rb
258
+ - spec/test_parser_spec.rb
239
259
  - spec/uploader_spec.rb
240
260
  - spec/validation-examples/circular_embeds/test1.rfml
241
261
  - spec/validation-examples/circular_embeds/test2.rfml
data/circle.yml DELETED
@@ -1,3 +0,0 @@
1
- test:
2
- pre:
3
- - bundle exec circlemator style-check --base-branch=master
@@ -1,182 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'securerandom'
3
- require 'rainforest'
4
- require 'parallel'
5
- require 'ruby-progressbar'
6
-
7
- class RainforestCli::TestImporter
8
- attr_reader :options, :client, :test_files
9
-
10
- SAMPLE_FILE = <<EOF
11
- #! %s (Test ID - only edit if this test has not yet been uploaded)
12
- # title: New test
13
- # start_uri: /
14
- #
15
- # Lines starting with # are test attributes or comments
16
- # Possible attributes: #{RainforestCli::TestParser::Parser::TEXT_FIELDS.join(', ')}
17
- #
18
- # Steps are composed of two lines: an action and a question. Example:
19
- #
20
- # This is the step action.
21
- # This is the step question?
22
- #
23
-
24
- EOF
25
-
26
- def initialize(options)
27
- @options = options
28
- ::Rainforest.api_key = @options.token
29
- @test_files = RainforestCli::TestFiles.new(@options.test_folder)
30
- end
31
-
32
- def logger
33
- RainforestCli.logger
34
- end
35
-
36
- def threads
37
- RainforestCli::THREADS
38
- end
39
-
40
- def export
41
- tests = Rainforest::Test.all(page_size: 1000)
42
- p = ProgressBar.create(title: 'Rows', total: tests.count, format: '%a %B %p%% %t')
43
- Parallel.each(tests, in_threads: threads, finish: lambda { |_item, _i, _result| p.increment }) do |test|
44
-
45
- # File name
46
- file_name = sprintf('%010d', test.id) + '_' + test.title.strip.gsub(/[^a-z0-9 ]+/i, '').gsub(/ +/, '_').downcase
47
- file_name = create_new(file_name)
48
- File.truncate(file_name, 0)
49
-
50
- # Get the full test from the API
51
- test = Rainforest::Test.retrieve(test.id)
52
-
53
- File.open(file_name, 'a') do |file|
54
- file.puts _get_header(test)
55
-
56
- index = 0
57
- test.elements.each do |element|
58
- index = _process_element(file, element, index)
59
- end
60
- end
61
- end
62
- end
63
-
64
- def _process_element file, element, index
65
- case element[:type]
66
- when 'test'
67
- element[:element][:elements].each do |sub_element|
68
- index = _process_element(file, sub_element, index)
69
- end
70
- when 'step'
71
- file.puts '' unless index == 0
72
- file.puts "# step #{index + 1}" if @options.debug
73
- file.puts element[:element][:action]
74
- file.puts element[:element][:response]
75
- else
76
- raise "Unknown element type: #{element[:type]}"
77
- end
78
-
79
- index += 1
80
- index
81
- end
82
-
83
- # add comments if not already present
84
- def _get_header test
85
- out = []
86
-
87
- has_id = false
88
- test.description.to_s.strip.lines.map(&:chomp).each_with_index do |line, _line_no|
89
- line = line.gsub(/\#+$/, '').strip
90
-
91
- # make sure the test has an ID
92
- has_id = true if line[0] == '!'
93
-
94
- out << '#' + line
95
- end
96
-
97
- unless has_id
98
- browsers = test.browsers.map {|b| b[:name] if b[:state] == 'enabled' }.compact
99
- out = [
100
- "#! #{SecureRandom.uuid}",
101
- "# title: #{test.title}",
102
- "# start_uri: #{test.start_uri}",
103
- "# tags: #{test.tags.join(", ")}",
104
- "# browsers: #{browsers.join(", ")}",
105
- '#',
106
- ' ',
107
- ] + out
108
- end
109
-
110
- out.compact.join("\n")
111
- end
112
-
113
- def _get_id test
114
- id = nil
115
- test.description.to_s.strip.lines.map(&:chomp).each_with_index do |line, _line_no|
116
- line = line.gsub(/\#+$/, '').strip
117
- if line[0] == '!'
118
- id = line[1..-1].split(' ').first
119
- break
120
- end
121
- end
122
- id
123
- end
124
-
125
- def validate
126
- tests = {}
127
- has_errors = []
128
-
129
- Dir.glob(test_files.test_paths).each do |file_name|
130
- out = RainforestCli::TestParser::Parser.new(file_name).process
131
-
132
- tests[file_name] = out
133
- has_errors << file_name if out.errors != {}
134
- end
135
-
136
- if !has_errors.empty?
137
- logger.error 'Parsing errors:'
138
- logger.error ''
139
- has_errors.each do |file_name|
140
- logger.error ' ' + file_name
141
- tests[file_name].errors.each do |_line, error|
142
- logger.error "\t#{error}"
143
- end
144
- end
145
-
146
- exit 2
147
- end
148
-
149
- if @options.debug
150
- tests.each do |file_name, test|
151
- logger.debug test.inspect
152
- logger.debug "#{file_name}"
153
- logger.debug test.description
154
- test.steps.each do |step|
155
- logger.debug "\t#{step}"
156
- end
157
- end
158
- else
159
- logger.info '[VALID]'
160
- end
161
-
162
- return tests
163
- end
164
-
165
- def create_new file_name = nil
166
- name = @options.file_name if @options.file_name
167
- name = file_name if !file_name.nil?
168
- ext = test_files.file_extension
169
-
170
- uuid = SecureRandom.uuid
171
- name = "#{uuid}#{ext}" unless name
172
- name += ext unless name[-ext.length..-1] == ext
173
-
174
- FileUtils.mkdir_p(test_files.test_folder) unless Dir.exist?(test_files.test_folder)
175
- name = File.join([test_files.test_folder, name])
176
-
177
- File.open(name, 'w') { |file| file.write(sprintf(SAMPLE_FILE, uuid)) }
178
-
179
- logger.info "Created #{name}" if file_name.nil?
180
- name
181
- end
182
- end