turbogenerator 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/before.sh, ADDED
File without changes
data/bin/turbo ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "thor"
4
+ require "turbo"
5
+
6
+ def get_real_path(path)
7
+ File.join(File.dirname(File.expand_path(__FILE__)), "../lib/#{path}")
8
+ end
9
+
10
+ class TurboApp < Thor
11
+
12
+ desc "generate", "Generate a workflow"
13
+ def generate(name)
14
+
15
+ if File.exist? "workflows/#{name}"
16
+ puts "workflow #{name} has already exist under workflows/#{name}"
17
+ return
18
+ end
19
+
20
+ FileUtils.mkdir_p "workflows"
21
+ FileUtils.mkdir_p "workflows/#{name}"
22
+
23
+ FileUtils.mkdir_p "workflows/#{name}/bin"
24
+ FileUtils.mkdir_p "workflows/#{name}/data"
25
+ FileUtils.mkdir_p "workflows/#{name}/scenarios"
26
+
27
+ FileUtils.copy File.join(File.dirname(File.expand_path(__FILE__)), "../lib/templates/before.sh"), "workflows/#{name}/bin/before.sh"
28
+ FileUtils.copy File.join(File.dirname(File.expand_path(__FILE__)), "../lib/templates/after.sh"), "workflows/#{name}/bin/after.sh"
29
+
30
+ FileUtils.copy File.join(File.dirname(File.expand_path(__FILE__)), "../lib/templates/resource.json"), "workflows/#{name}/data/resource.json"
31
+ FileUtils.copy File.join(File.dirname(File.expand_path(__FILE__)), "../lib/templates/resource-get.json"), "workflows/#{name}/scenarios/resource-get.json"
32
+
33
+ FileUtils.copy File.join(File.dirname(File.expand_path(__FILE__)), "../lib/templates/workflow.json"), "workflows/#{name}/workflow.json"
34
+
35
+ puts "workflow #{name} is generated under workflows/#{name}"
36
+ end
37
+
38
+ desc "start", "specify the workflow name"
39
+ method_option :config, :aliases => "-c", :desc => "configuration file"
40
+ def start(workflow)
41
+ config = options[:config]
42
+ turbo = Turbo.new(config)
43
+ turbo.run_workflow(workflow)
44
+ end
45
+
46
+ end
47
+
48
+ TurboApp.start
@@ -0,0 +1,5 @@
1
+ {
2
+ "chrome": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36",
3
+ "safari": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.71 (KHTML, like Gecko) Version/6.1 Safari/537.71",
4
+ "firefox": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/20100101 Firefox/18.0",
5
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "baseurl": "http://localhost:9527",
3
+ "method": "POST",
4
+ "headers": {
5
+ "Accept": "application/json",
6
+ "Content-Type": "application/json"
7
+ }
8
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "common_conf": "common.json",
3
+ "debug": "true"
4
+ }
@@ -0,0 +1,74 @@
1
+ #
2
+ # = Hash Recursive Merge
3
+ #
4
+ # Merges a Ruby Hash recursively, Also known as deep merge.
5
+ # Recursive version of Hash#merge and Hash#merge!.
6
+ #
7
+ # Category:: Ruby
8
+ # Package:: Hash
9
+ # Author:: Simone Carletti <weppos@weppos.net>
10
+ # Copyright:: 2007-2008 The Authors
11
+ # License:: MIT License
12
+ # Link:: http://www.simonecarletti.com/
13
+ # Source:: http://gist.github.com/gists/6391/
14
+ #
15
+ module HashRecursiveMerge
16
+
17
+ #
18
+ # Recursive version of Hash#merge!
19
+ #
20
+ # Adds the contents of +other_hash+ to +hsh+,
21
+ # merging entries in +hsh+ with duplicate keys with those from +other_hash+.
22
+ #
23
+ # Compared with Hash#merge!, this method supports nested hashes.
24
+ # When both +hsh+ and +other_hash+ contains an entry with the same key,
25
+ # it merges and returns the values from both arrays.
26
+ #
27
+ # h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
28
+ # h2 = {"b" => 254, "c" => 300, "c" => {"c1" => 16, "c3" => 94}}
29
+ # h1.rmerge!(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
30
+ #
31
+ # Simply using Hash#merge! would return
32
+ #
33
+ # h1.merge!(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
34
+ #
35
+ def rmerge!(other_hash)
36
+ merge!(other_hash) do |key, oldval, newval|
37
+ oldval.class == self.class ? oldval.rmerge!(newval) : newval
38
+ end
39
+ end
40
+
41
+ #
42
+ # Recursive version of Hash#merge
43
+ #
44
+ # Compared with Hash#merge!, this method supports nested hashes.
45
+ # When both +hsh+ and +other_hash+ contains an entry with the same key,
46
+ # it merges and returns the values from both arrays.
47
+ #
48
+ # Compared with Hash#merge, this method provides a different approch
49
+ # for merging nasted hashes.
50
+ # If the value of a given key is an Hash and both +other_hash+ abd +hsh
51
+ # includes the same key, the value is merged instead replaced with
52
+ # +other_hash+ value.
53
+ #
54
+ # h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
55
+ # h2 = {"b" => 254, "c" => 300, "c" => {"c1" => 16, "c3" => 94}}
56
+ # h1.rmerge(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
57
+ #
58
+ # Simply using Hash#merge would return
59
+ #
60
+ # h1.merge(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
61
+ #
62
+ def rmerge(other_hash)
63
+ r = {}
64
+ merge(other_hash) do |key, oldval, newval|
65
+ r[key] = oldval.class == self.class ? oldval.rmerge(newval) : newval
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+
72
+ class Hash
73
+ include HashRecursiveMerge
74
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ echo "after all scenarios ......"
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ echo "before all scenarios ......"
@@ -0,0 +1,14 @@
1
+ {
2
+ "baseurl": "http://localhost:9527",
3
+ "method": "GET",
4
+ "headers": {
5
+ "Accept": "application/json",
6
+ "Content-Type": "application/json"
7
+ },
8
+ "cases": [
9
+ {
10
+ "path": "/resource",
11
+ "success": "200 OK"
12
+ }
13
+ ]
14
+ }
@@ -0,0 +1 @@
1
+ {"name": "South Melbourne"}
@@ -0,0 +1,7 @@
1
+ {
2
+ "before": "bin/before.sh",
3
+ "scenarios": [
4
+ "resource-get.json"
5
+ ],
6
+ "after": "bin/after.sh"
7
+ }
data/lib/turbo.rb ADDED
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'json'
4
+ require 'term/ansicolor'
5
+
6
+ # Author:: Simone Carletti <weppos@weppos.net>
7
+ # Copyright:: 2007-2008 The Authors
8
+ # License:: MIT License
9
+ # Link:: http://www.simonecarletti.com/
10
+ # Source:: http://gist.github.com/gists/6391/
11
+ #
12
+ module HashRecursiveMerge
13
+ def rmerge!(other_hash)
14
+ merge!(other_hash) do |key, oldval, newval|
15
+ oldval.class == self.class ? oldval.rmerge!(newval) : newval
16
+ end
17
+ end
18
+
19
+ def rmerge(other_hash)
20
+ r = {}
21
+ merge(other_hash) do |key, oldval, newval|
22
+ r[key] = oldval.class == self.class ? oldval.rmerge(newval) : newval
23
+ end
24
+ end
25
+ end
26
+
27
+ class Hash
28
+ include HashRecursiveMerge
29
+ end
30
+
31
+ class String
32
+ include Term::ANSIColor
33
+ end
34
+
35
+ class Turbo
36
+
37
+ def initialize(conf)
38
+ f = File.join(File.dirname(File.expand_path(__FILE__)), conf ? conf : "config/turbo.conf")
39
+ @conf = JSON.parse(File.read(f))
40
+ @conf['conf_path'] = File.dirname(File.absolute_path(f))
41
+ end
42
+
43
+ def run_workflow(workflow=nil)
44
+ wf = JSON.parse(File.read("workflows/#{workflow}/workflow.json"))
45
+
46
+ @workflow_path = "workflows/#{workflow}"
47
+ @pre_command = "#{@workflow_path}/#{wf['before']}"
48
+ @post_command = "#{@workflow_path}/#{wf['after']}"
49
+
50
+ scenarios = wf['scenarios']
51
+
52
+ before
53
+ scenarios.each do |scenario|
54
+ run_scenario("#{@workflow_path}/scenarios/#{scenario}")
55
+ end
56
+ after
57
+
58
+ end
59
+
60
+ private
61
+ def before
62
+ system "#{@pre_command}"
63
+ end
64
+
65
+ def after
66
+ system "#{@post_command}"
67
+ end
68
+
69
+ def run(scenario=nil)
70
+ if scenario
71
+ run_scenario(scenario)
72
+ else
73
+ Dir.glob(@conf['scenarios_path']) do |json_file|
74
+ run_scenario(json_file)
75
+ end
76
+ end
77
+ end
78
+
79
+ def generate_header(obj)
80
+ headers = []
81
+ obj.each_pair do |k, v|
82
+ headers << "-H \"#{k}: #{v}\""
83
+ end
84
+ headers.join(' ')
85
+ end
86
+
87
+ def load_common
88
+ JSON.parse(File.read(@conf['conf_path'] + '/' + @conf['common_conf']))
89
+ end
90
+
91
+ def load_scenario(scenario)
92
+ JSON.parse(File.read(scenario))
93
+ end
94
+
95
+ def run_scenario(scenario)
96
+ common = load_common
97
+ config = common.rmerge(load_scenario(scenario))
98
+
99
+ if config['disabled']
100
+ puts "skipping scenario, #{scenario}".cyan
101
+ return
102
+ end
103
+
104
+ # generate all headers
105
+ headers = generate_header(config['headers'])
106
+
107
+ # generate HTTP method
108
+ method = "-X #{config['method']}"
109
+
110
+ # run each case here
111
+ config['cases'].each do |caze|
112
+ path = config['baseurl'] + caze['path']
113
+ data = config['method'] == "POST" || config['method'] == "PUT" ? "-d @#{@workflow_path}/#{caze['data']}" : ""
114
+
115
+ debug = @conf['debug'] == 'true' || config['debug'] == 'true' ? "-D - -o debug.log" : ""
116
+
117
+ real_command = "curl -is #{headers} #{method} #{data} #{path} #{debug}"
118
+ puts real_command
119
+ command = "#{real_command} | grep --color=auto -E \"#{caze['success']}\""
120
+
121
+ ret = system(command)
122
+
123
+ if ret
124
+ puts "#{'Success'}: #{real_command}".green
125
+ else
126
+ puts "#{'Error'}: #{real_command}".red
127
+ end
128
+ end
129
+ end
130
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: turbogenerator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Juntao Qiu
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-03-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.18.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.18.1
30
+ - !ruby/object:Gem::Dependency
31
+ name: term-ansicolor
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.3.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.3.0
46
+ description: turbo is a curl wrapper for make test based on HTTP (aka RESTFul App)
47
+ easier
48
+ email: juntao.qiu@gmail.com
49
+ executables:
50
+ - turbo
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - bin/before.sh,
55
+ - bin/turbo
56
+ - lib/config/browsers.json
57
+ - lib/config/common.json
58
+ - lib/config/turbo.conf
59
+ - lib/hash_recursive_merge.rb
60
+ - lib/templates/after.sh
61
+ - lib/templates/before.sh
62
+ - lib/templates/resource-get.json
63
+ - lib/templates/resource.json
64
+ - lib/templates/workflow.json
65
+ - lib/turbo.rb
66
+ homepage: https://github.com/abruzzi/turbo
67
+ licenses:
68
+ - MIT
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 1.8.28
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: turbo is a curl wrapper for make test based on HTTP more easier
91
+ test_files: []