barthes 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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