barthes 0.0.3 → 0.0.4

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.
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Barthes
2
2
 
3
+ ![](600px-Roland_Barthes_signature.svg.png)
4
+
3
5
  TODO: Write a gem description
4
6
 
5
7
  ## Installation
data/TODO.md ADDED
@@ -0,0 +1,9 @@
1
+ * embed strftime format or date command format datetime to json
2
+ * embed or in json expectations
3
+ * json schema
4
+ * サブコマンドではなくする
5
+ * global Barthes.config object
6
+
7
+ --------------------------
8
+ compare -> method, feature, scenario, action
9
+ xpath change (describe security groups)
data/bin/barthes CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env ruby
1
2
  $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
2
3
  require 'barthes/cli'
3
4
  Barthes::CLI.start
@@ -0,0 +1,71 @@
1
+ require 'barthes/cache'
2
+
3
+ module Barthes
4
+ class Action
5
+ def initialize(env, options)
6
+ @options = options
7
+ @env = env.dup
8
+ client_class = Object.const_get(@env['client_class'])
9
+ @client = client_class.new(env)
10
+ end
11
+
12
+ def indent(size, string)
13
+ string.split("\n").map {|line| "\t" * size + "#{line}\n" }
14
+ end
15
+
16
+ def action(action)
17
+ @env.update(action['environment']) if action['environment']
18
+ params = evaluate_params(action['params'])
19
+
20
+ if action['expectations']
21
+ if action['max_loop']
22
+ action['max_loop'].to_i.times do
23
+ sleep action['sleep'].to_i/1000 if action['sleep']
24
+
25
+ response = @client.action(params)
26
+ action['expectations'].each do |expectation|
27
+ result = @client.compare(response, evaluate_params(expectation))
28
+ expectation.update(result)
29
+ end
30
+ if action['expectations'].all? {|e| e['result'] == true }
31
+ break
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ sleep action['sleep'].to_i/1000 if action['sleep']
38
+
39
+ action['request'] = params
40
+ action['response'] = response = @client.action(params)
41
+
42
+ if action['expectations']
43
+ action['expectations'].each do |expectation|
44
+ result = @client.compare(response, evaluate_params(expectation))
45
+ expectation.update(result)
46
+ end
47
+ end
48
+
49
+ if cache_config = action['cache']
50
+ value = @client.extract(cache_config, response)
51
+ action['cache']['value'] = value
52
+ Barthes::Cache.set(cache_config['key'], value)
53
+ end
54
+ action
55
+ end
56
+
57
+ def evaluate_params(params)
58
+ new_params = {}
59
+ params.each do |k, v|
60
+ if v.class == String
61
+ new_v = v.gsub(/\$\{(.+?)\}/) { @env[$1] }
62
+ new_v = new_v.gsub(/\@\{(.+?)\}/) { p $1; Barthes::Cache.get($1) }
63
+ else
64
+ new_v = v
65
+ end
66
+ new_params[k] = new_v
67
+ end
68
+ new_params
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,28 @@
1
+
2
+ module Barthes
3
+ class Cache
4
+ @cache = {}
5
+
6
+ class << self
7
+ def load(cache)
8
+ @cache = cache
9
+ end
10
+
11
+ def reset
12
+ @cache = {}
13
+ end
14
+
15
+ def get(key)
16
+ @cache[key]
17
+ end
18
+
19
+ def set(key, value)
20
+ @cache[key] = value
21
+ end
22
+
23
+ def to_hash
24
+ @cache
25
+ end
26
+ end
27
+ end
28
+ end
data/lib/barthes/cli.rb CHANGED
@@ -1,48 +1,20 @@
1
- require 'barthes/converter'
1
+ require 'barthes/runner'
2
+ require 'barthes/reporter/default'
2
3
  require 'json'
3
4
  require 'thor'
4
- require 'rspec'
5
5
 
6
6
  module Barthes
7
7
  class CLI < Thor
8
- desc 'convert', 'convert json into rspec'
9
- def convert(*paths)
10
- files = expand_paths(paths, '.json')
11
- files.each do |file|
12
- json = JSON.parse File.read(file)
13
- converter = Barthes::Converter.new(file, json)
14
- spec = converter.convert(json)
15
- File.write("#{file.gsub(/.json$/, '')}_spec.rb", spec)
16
- end
17
- end
18
-
19
- desc 'exec', 'execute tests from json files'
20
- option :rspec, :type => :string, :aliases => :r
8
+ desc 'execute', 'execute tests from json files'
21
9
  option :environment, :type => :string, :aliases => :e
10
+ option :verbose, :type => :boolean, :aliases => :v
11
+ option :dryrun, :type => :boolean, :aliases => :d
12
+ option :from, :type => :numeric, :aliases => :f, :default => 1
13
+ option :to, :type => :numeric, :aliases => :t
14
+ option :config_path, :type => :string, :aliases => :c
15
+ option :load_path, :type => :string, :aliases => :l
22
16
  def exec(*paths)
23
- ENV['BARTHES_ENV_PATH'] = options[:environment] if options[:environment]
24
- convert(*paths)
25
- paths = expand_paths(paths, '.json').map {|path| "#{path.gsub(/.json$/, '')}_spec.rb" }
26
- paths += options[:rspec].split(/\s/) if options[:rspec]
27
- RSpec::Core::Runner.run(paths)
28
- end
29
-
30
- no_commands do
31
- def expand_paths(paths, suffix)
32
- files = []
33
- if paths.empty?
34
- files += Dir["./**/*#{suffix}"]
35
- else
36
- paths.each do |path|
37
- if FileTest.directory?(path)
38
- files += Dir["#{path}/**/*#{suffix}"]
39
- elsif FileTest.file?(path)
40
- files << path
41
- end
42
- end
43
- end
44
- files
45
- end
17
+ Runner.new(options).run(paths)
46
18
  end
47
19
  end
48
20
  end
@@ -0,0 +1,32 @@
1
+
2
+ module Barthes
3
+ class Reporter
4
+ def initialize(options)
5
+ @reporters = []
6
+ if options[:reporter]
7
+ reporter_classes = options[:reporter].split(',')
8
+ reporter_classes.each do |klass_name|
9
+ klass = Object.get_const(klass_name)
10
+ @reporters << klass.new
11
+ end
12
+ else
13
+ @reporters = [Reporter::Default.new(options)]
14
+ end
15
+ end
16
+
17
+ def report(event, *args, &block)
18
+ @reporters.each do |r|
19
+ m = :"before_#{event.to_s}"
20
+ r.send(m, *args) if r.respond_to?(m)
21
+ end
22
+
23
+ result = yield
24
+
25
+ @reporters.each do |r|
26
+ m = :"after_#{event.to_s}"
27
+ args << result
28
+ r.send(m, *args) if r.respond_to?(m)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,52 @@
1
+
2
+ module Barthes
3
+ class Reporter
4
+ class Default
5
+ def initialize(options)
6
+ @options = options
7
+ end
8
+
9
+ def before_feature(num, name)
10
+ puts "#{name} (##{num})"
11
+ end
12
+
13
+ def before_scenario(num, name, scenario, scenarios)
14
+ puts ("\t" * scenarios.size) + "#{name} (##{num})"
15
+ end
16
+
17
+ def before_action(num, name, action, scenarios)
18
+ print ("\t" * scenarios.size) + "#{name} (##{num})"
19
+ end
20
+
21
+ def after_action(num, name, action, scenarios, result)
22
+ if @options[:verbose]
23
+ puts
24
+ puts indent scenarios.size + 1, "request:"
25
+ puts indent scenarios.size + 2, JSON.pretty_generate(action['request'])
26
+ puts indent scenarios.size + 1, "response:"
27
+ puts indent scenarios.size + 2, JSON.pretty_generate(action['response'])
28
+ end
29
+ expectations = result['expectations']
30
+ expectations.each do |expectation|
31
+ if expectation['result'] == false
32
+ puts indent scenarios.size + 1, "failed expectation:"
33
+ puts indent scenarios.size + 2, JSON.pretty_generate(expectation)
34
+ end
35
+ end
36
+ flag = ''
37
+ if expectations.empty? || expectations.all? {|r| r['result'] == true }
38
+ flag = 'success'
39
+ else
40
+ flag = 'failure'
41
+ end
42
+ puts indent(scenarios.size, " -> #{flag}")
43
+ end
44
+
45
+ def indent(num, string)
46
+ string.split("\n").map do |line|
47
+ ("\t" * num) + line
48
+ end.join("\n")
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,25 @@
1
+
2
+ module Barthes
3
+ class Reporter
4
+ class JunitXml
5
+ def after_run(features)
6
+ features.each do |feature|
7
+ end
8
+ end
9
+
10
+ def walk_feature
11
+ end
12
+
13
+ def render_testcase(xml, action)
14
+ xml.testcase do
15
+ xml.stdout
16
+ xml.failure
17
+ xml.skipped
18
+ xml.error
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ __END__
@@ -0,0 +1,119 @@
1
+ require 'json'
2
+ require 'barthes/action'
3
+ require 'barthes/reporter'
4
+ require 'barthes/cache'
5
+
6
+ module Barthes
7
+ class Runner
8
+ def initialize(options)
9
+ load_cache
10
+ load_config
11
+ load_environments(options[:environment])
12
+ @reporter = Reporter.new(options)
13
+ @options = options
14
+ end
15
+
16
+ def load_cache
17
+ path = Dir.pwd + '/barthes-cache.json'
18
+ if File.exists?(path)
19
+ Barthes::Cache.load JSON.parse File.read(path)
20
+ end
21
+ end
22
+
23
+ def load_config
24
+ path = Dir.pwd + '/.barthes'
25
+ load path if File.exists?(path)
26
+ end
27
+
28
+ def load_environments(environment)
29
+ @env = {}
30
+ env_paths = environment.split(',')
31
+ env_paths.each do |path|
32
+ @env.update JSON.parse File.read(path)
33
+ end
34
+ end
35
+
36
+ def expand_paths(paths, suffix)
37
+ files = []
38
+ if paths.empty?
39
+ files += Dir["./**/*#{suffix}"]
40
+ else
41
+ paths.each do |path|
42
+ if FileTest.directory?(path)
43
+ files += Dir["#{path}/**/*#{suffix}"]
44
+ elsif FileTest.file?(path)
45
+ files << path
46
+ end
47
+ end
48
+ end
49
+ files
50
+ end
51
+
52
+ def run(paths)
53
+ files = expand_paths(paths, '_spec.json')
54
+ @reporter.report(:run, files) do
55
+ @num = 1
56
+ results = []
57
+ files.each do |file|
58
+ json = JSON.parse File.read(file)
59
+ @reporter.report(:feature, @num, json[1]) do
60
+ @num += 1
61
+ #Barthes::Cache.reset ## load config or reset
62
+ feature_results = walk_json(json.last, [file])
63
+ results += results
64
+ end
65
+ end
66
+ results
67
+ end
68
+ puts JSON.pretty_generate Barthes::Cache.to_hash
69
+ end
70
+
71
+ def in_range?
72
+ flag = @num >= @options[:from]
73
+ flag = flag && (@num >= @options[:to]) if @options[:to]
74
+ flag
75
+ end
76
+
77
+ def walk_json(json, scenarios)
78
+ if json.class == Array
79
+ case json.first
80
+ when 'scenario'
81
+ handle_scenario(json, scenarios)
82
+ @num += 1
83
+ scenarios.push(json.first)
84
+ walk_json(json.last, scenarios)
85
+ scenarios.pop
86
+ when 'action'
87
+ handle_action(json, scenarios) if in_range?
88
+ @num += 1
89
+ else
90
+ json.each do |element|
91
+ walk_json(element, scenarios)
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ def handle_scenario(scenario, scenarios)
98
+ return if @failed
99
+ @reporter.report(:scenario, @num, scenario[1], scenario.last, scenarios) do
100
+ end
101
+ end
102
+
103
+ def handle_action(action, scenarios)
104
+ return if @failed
105
+ name, content = action[1], action.last
106
+ env = @env.dup
107
+ env.update(content['environment']) if content['environment']
108
+ @reporter.report(:action, @num, name, action.last, scenarios) do
109
+ if !@options[:dryrun] && !@failed
110
+ content = Action.new(env, @options).action(content)
111
+ if content['expectations'] && content['expectations'].any? {|e| e['result'] == false }
112
+ @failed = true
113
+ end
114
+ end
115
+ content
116
+ end
117
+ end
118
+ end
119
+ end
@@ -1,3 +1,3 @@
1
1
  module Barthes
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: barthes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-10-26 00:00:00.000000000 Z
12
+ date: 2014-11-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -100,19 +100,22 @@ extensions: []
100
100
  extra_rdoc_files: []
101
101
  files:
102
102
  - .gitignore
103
+ - 600px-Roland_Barthes_signature.svg.png
103
104
  - Gemfile
104
105
  - LICENSE.txt
105
106
  - README.md
106
107
  - Rakefile
108
+ - TODO.md
107
109
  - barthes.gemspec
108
110
  - bin/barthes
109
111
  - lib/barthes.rb
112
+ - lib/barthes/action.rb
113
+ - lib/barthes/cache.rb
110
114
  - lib/barthes/cli.rb
111
- - lib/barthes/converter.rb
112
- - lib/barthes/templates/context.erb
113
- - lib/barthes/templates/describe.erb
114
- - lib/barthes/templates/expectations/xpath_value.erb
115
- - lib/barthes/templates/it.erb
115
+ - lib/barthes/reporter.rb
116
+ - lib/barthes/reporter/default.rb
117
+ - lib/barthes/reporter/junit_xml.rb
118
+ - lib/barthes/runner.rb
116
119
  - lib/barthes/version.rb
117
120
  homepage: ''
118
121
  licenses:
@@ -1,79 +0,0 @@
1
- # TODO: json includesion
2
- require 'erubis'
3
- require 'ostruct'
4
-
5
- module Barthes
6
- class Converter
7
- module Helpers
8
- def resolve_value(value)
9
- value = value.gsub(/\@\{(.+?)\}/) { '#{' + "$store['#{$1}']" + '}' }
10
- value = value.gsub(/\$\{(.+?)\}/) { '#{' + "@env['#{$1}']" + '}' }
11
- "%Q{#{value}}"
12
- end
13
- end
14
-
15
- def initialize(name, json)
16
- @name = name
17
- @json = json
18
- end
19
-
20
- def template(name)
21
- here = File.dirname(__FILE__)
22
- File.read(here + "/templates/#{name.to_s}.erb")
23
- end
24
-
25
- def render(template_name, indent, opts={}, &block)
26
- opts[:block] = block
27
- code = Erubis::Eruby.new(template(template_name)).result(
28
- OpenStruct.new(opts).instance_eval { extend Helpers; binding }
29
- )
30
- code = code.split(/\n/).join("\n" + ("\t" * indent)) if indent
31
- code
32
- end
33
-
34
- def convert(json)
35
- render(:describe, 0, :name => @name) do
36
- walk_json(json)
37
- end
38
- end
39
-
40
- def walk_json(arr)
41
- return if arr.class != Array
42
- rendered = []
43
- case arr.first
44
- when 'it'
45
- arr.last['_sleep'] = arr.last['sleep']
46
- arr.last['name'] = arr[1]
47
- rendered << render(:it, 1, arr.last) do
48
- walk_expectations(arr.last['expectations'], false).join(" && ")
49
- end
50
- when 'context'
51
- rendered << render(:context, 1, :name => arr[1]) do
52
- walk_json(arr.last)
53
- end
54
- else
55
- arr.each do |elem|
56
- rendered << walk_json(elem)
57
- end
58
- end
59
- rendered.join("\n\t")
60
- end
61
-
62
- # TODO: timeout
63
- def walk_expectations(arr, in_or)
64
- return if arr.nil?
65
- rendered = []
66
- arr.each do |elem|
67
- if elem.class == Array
68
- rendered << walk_expectations(elem, in_or).join(" && ")
69
- elsif elem.keys.first == 'Or'
70
- rendered << walk_expectations(elem.values, true).join(' || ')
71
- elsif elem['type'] == 'Value' || elem['type'] == 'StringComarison'
72
- rendered << render(:'expectations/xpath_value', 2, elem)
73
- end
74
- end
75
- rendered
76
- end
77
-
78
- end
79
- end
@@ -1,3 +0,0 @@
1
- context '<%= name %>' do
2
- <%= block.call %>
3
- end
@@ -1,17 +0,0 @@
1
- # coding: utf-8
2
- require 'json'
3
-
4
- describe '<%= name %>' do
5
- before(:all) do
6
- $store = {}
7
- @env = JSON.parse File.read(ENV['BARTHES_ENV_PATH'])
8
- client_klass = Object.const_get(@env['client_class'])
9
- @client = client_klass.new(@env)
10
- end
11
-
12
- <%= block.call %>
13
-
14
- after(:all) do
15
- File.write('.store', JSON.pretty_generate($store))
16
- end
17
- end
@@ -1,6 +0,0 @@
1
- lambda {
2
- doc = response.response.body.gsub(/xmlns=\"(.+?)\"/, '')
3
- <% if respond_to?(:value) %>
4
- doc.xpath('<%= xpath %>').text == <%= resolve_value(value) %>
5
- <% end %>
6
- }.call
@@ -1,39 +0,0 @@
1
- it '<%= name %>' do
2
- <% if respond_to?(:client) %>
3
- client_klass = Object.const_get('<%= client['class'] %>')
4
- client = client_klass.new(@env)
5
- <% end %>
6
- <% if respond_to?(:max_loop) && max_loop && respond_to?(:expectations) && expectations.size > 0 %>
7
- <%= max_loop %>.times do
8
- response = client.execute({
9
- <%- params.each do |k, v| %>
10
- <% next if v.nil? %>
11
- '<%= k %>' => <%= resolve_value(v) %>,
12
- <%- end %>
13
- })
14
- <% if respond_to?(:expectations) && expectations.size > 0 %>
15
- break if (<%= block.call %>)
16
- <% end %>
17
- <% if _sleep %>
18
- sleep <%= _sleep %> / 1000
19
- <% end %>
20
- end
21
- <% end %>
22
- response = client.execute({
23
- <% params.each do |k, v| next if v.nil? # TODO %>
24
- <% next if v.nil? %>
25
- '<%= k %>' => <%= resolve_value(v) %>,
26
- <% end %>
27
- })
28
- <% if respond_to?(:expectations) && expectations.size > 0 %>
29
- expect(
30
- <%= block.call %>
31
- ).to be_true
32
- <% end %>
33
- <% if _sleep %>
34
- sleep <%= _sleep %> / 1000
35
- <% end %>
36
- <% if respond_to?(:store) %>
37
- $store['<%= store['Key'] %>'] = doc.xpath('<%= store['Xpath'] %>').first.text
38
- <% end %>
39
- end