copy_tuner_client 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +9 -0
- data/Appraisals +15 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +161 -0
- data/README.md +4 -0
- data/Rakefile +28 -0
- data/copy_tuner_client.gemspec +33 -0
- data/features/rails.feature +270 -0
- data/features/step_definitions/copycopter_server_steps.rb +64 -0
- data/features/step_definitions/rails_steps.rb +172 -0
- data/features/support/env.rb +11 -0
- data/features/support/rails_server.rb +124 -0
- data/gemfiles/2.3.gemfile +7 -0
- data/gemfiles/2.3.gemfile.lock +105 -0
- data/gemfiles/3.0.gemfile +7 -0
- data/gemfiles/3.0.gemfile.lock +147 -0
- data/gemfiles/3.1.gemfile +11 -0
- data/gemfiles/3.1.gemfile.lock +191 -0
- data/init.rb +1 -0
- data/lib/copy_tuner_client/cache.rb +144 -0
- data/lib/copy_tuner_client/client.rb +136 -0
- data/lib/copy_tuner_client/configuration.rb +224 -0
- data/lib/copy_tuner_client/errors.rb +12 -0
- data/lib/copy_tuner_client/i18n_backend.rb +92 -0
- data/lib/copy_tuner_client/poller.rb +44 -0
- data/lib/copy_tuner_client/prefixed_logger.rb +45 -0
- data/lib/copy_tuner_client/process_guard.rb +92 -0
- data/lib/copy_tuner_client/rails.rb +21 -0
- data/lib/copy_tuner_client/railtie.rb +12 -0
- data/lib/copy_tuner_client/request_sync.rb +39 -0
- data/lib/copy_tuner_client/version.rb +7 -0
- data/lib/copy_tuner_client.rb +75 -0
- data/lib/tasks/copy_tuner_client_tasks.rake +20 -0
- data/spec/copy_tuner_client/cache_spec.rb +273 -0
- data/spec/copy_tuner_client/client_spec.rb +236 -0
- data/spec/copy_tuner_client/configuration_spec.rb +305 -0
- data/spec/copy_tuner_client/i18n_backend_spec.rb +157 -0
- data/spec/copy_tuner_client/poller_spec.rb +108 -0
- data/spec/copy_tuner_client/prefixed_logger_spec.rb +37 -0
- data/spec/copy_tuner_client/process_guard_spec.rb +118 -0
- data/spec/copy_tuner_client/request_sync_spec.rb +47 -0
- data/spec/copy_tuner_client_spec.rb +19 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/client_spec_helpers.rb +8 -0
- data/spec/support/defines_constants.rb +44 -0
- data/spec/support/fake_client.rb +53 -0
- data/spec/support/fake_copy_tuner_app.rb +175 -0
- data/spec/support/fake_html_safe_string.rb +20 -0
- data/spec/support/fake_logger.rb +68 -0
- data/spec/support/fake_passenger.rb +27 -0
- data/spec/support/fake_resque_job.rb +18 -0
- data/spec/support/fake_unicorn.rb +13 -0
- data/spec/support/middleware_stack.rb +13 -0
- data/spec/support/writing_cache.rb +17 -0
- data/tmp/projects.json +1 -0
- metadata +389 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.join(PROJECT_ROOT, "spec", "support", "fake_copy_tuner_app")
|
2
|
+
|
3
|
+
Given /^I have a copy_tuner project with an api key of "([^"]*)"$/ do |api_key|
|
4
|
+
FakeCopyTunerApp.add_project api_key
|
5
|
+
end
|
6
|
+
|
7
|
+
Given /^the "([^"]*)" project has the following blurbs:$/ do |api_key, table|
|
8
|
+
project = FakeCopyTunerApp.project(api_key)
|
9
|
+
table.hashes.each do |blurb_hash|
|
10
|
+
key = blurb_hash['key']
|
11
|
+
data = { 'draft' => { key => blurb_hash['draft content'] },
|
12
|
+
'published' => { key => blurb_hash['published content'] } }
|
13
|
+
project.update(data)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
When /^the the following blurbs are updated in the "([^"]*)" project:$/ do |api_key, table|
|
18
|
+
Given %{the "#{api_key}" project has the following blurbs:}, table
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^the "([^"]*)" project should have the following blurbs:$/ do |api_key, table|
|
22
|
+
project = FakeCopyTunerApp.project(api_key)
|
23
|
+
table.hashes.each do |blurb_hash|
|
24
|
+
key = blurb_hash['key']
|
25
|
+
|
26
|
+
if blurb_hash['draft content']
|
27
|
+
unless project.draft[key] == blurb_hash['draft content']
|
28
|
+
raise "Expected #{blurb_hash['draft content']} for #{key} but got #{project.draft[key]}\nExisting keys: #{project.draft.inspect}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
if blurb_hash['published content']
|
33
|
+
unless project.published[key] == blurb_hash['published content']
|
34
|
+
raise "Expected #{blurb_hash['published content']} for #{key} but got #{project.published[key]}\nExisting keys: #{project.published.inspect}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
Then /^the "([^"]*)" project should have the following error blurbs:$/ do |api_key, table|
|
41
|
+
prefix = 'en.activerecord.errors.models'
|
42
|
+
|
43
|
+
rows = table.hashes.map do |error_blurb|
|
44
|
+
"| #{prefix}.#{error_blurb['key']} | #{error_blurb['draft content']} |"
|
45
|
+
end
|
46
|
+
|
47
|
+
steps %{
|
48
|
+
Then the "#{api_key}" project should have the following blurbs:
|
49
|
+
| key | draft content |
|
50
|
+
#{rows.join("\n")}
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
Then /^the "([^"]*)" project should not have the "([^"]*)" blurb$/ do |api_key, blurb_key|
|
55
|
+
project = FakeCopyTunerApp.project(api_key)
|
56
|
+
project.draft[blurb_key].should be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
When /^I wait for changes to be synchronized$/ do
|
60
|
+
sleep(3)
|
61
|
+
end
|
62
|
+
|
63
|
+
FakeCopyTunerApp.start
|
64
|
+
After { FakeCopyTunerApp.reset }
|
@@ -0,0 +1,172 @@
|
|
1
|
+
When "I generate a rails application" do
|
2
|
+
if Rails::VERSION::MAJOR == 3
|
3
|
+
subcommand = 'new'
|
4
|
+
if Rails::VERSION::MINOR == 0
|
5
|
+
options = ''
|
6
|
+
else
|
7
|
+
options = '--skip-bundle'
|
8
|
+
end
|
9
|
+
else
|
10
|
+
subcommand = ''
|
11
|
+
options = ''
|
12
|
+
end
|
13
|
+
|
14
|
+
run_simple("rails _#{Rails::VERSION::STRING}_ #{subcommand} testapp #{options}")
|
15
|
+
cd("testapp")
|
16
|
+
|
17
|
+
if Rails::VERSION::MAJOR == 3
|
18
|
+
append_to_file("Gemfile", <<-GEMS)
|
19
|
+
gem "thin"
|
20
|
+
gem "sham_rack"
|
21
|
+
gem "sinatra"
|
22
|
+
gem "json"
|
23
|
+
GEMS
|
24
|
+
run_simple("bundle install --local")
|
25
|
+
|
26
|
+
When %{I remove lines containing "rjs" from "config/environments/development.rb"}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
When /^I configure the copy_tuner client with api key "([^"]*)"$/ do |api_key|
|
31
|
+
write_file("config/initializers/copy_tuner.rb", <<-RUBY)
|
32
|
+
CopyTunerClient.configure do |config|
|
33
|
+
config.api_key = "#{api_key}"
|
34
|
+
config.polling_delay = 1
|
35
|
+
config.host = 'localhost'
|
36
|
+
config.secure = false
|
37
|
+
config.port = #{FakeCopyTunerApp.port}
|
38
|
+
end
|
39
|
+
RUBY
|
40
|
+
|
41
|
+
if Rails::VERSION::MAJOR == 3
|
42
|
+
append_to_file("Gemfile", <<-GEMS)
|
43
|
+
gem "copy_tuner_client", :path => "../../.."
|
44
|
+
GEMS
|
45
|
+
else
|
46
|
+
in_current_dir { FileUtils.rm_f("vendor/plugins/copy_tuner") }
|
47
|
+
run_simple("ln -s #{PROJECT_ROOT} vendor/plugins/copy_tuner")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
When "I start the application" do
|
52
|
+
in_current_dir do
|
53
|
+
RailsServer.start(ENV['RAILS_PORT'], @announce_stderr)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
When /^I start the application in the "([^"]+)" environment$/ do |environment|
|
58
|
+
in_current_dir do
|
59
|
+
old_environment = ENV['RAILS_ENV']
|
60
|
+
begin
|
61
|
+
ENV['RAILS_ENV'] = environment
|
62
|
+
RailsServer.start(ENV['RAILS_PORT'], @announce_stderr)
|
63
|
+
ensure
|
64
|
+
ENV['RAILS_ENV'] = old_environment
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
When /^I visit (\/.*)$/ do |path|
|
70
|
+
@last_response = RailsServer.get(path)
|
71
|
+
end
|
72
|
+
|
73
|
+
When /^I configure the copy_tuner client to use published data$/ do
|
74
|
+
in_current_dir do
|
75
|
+
config_path = "config/initializers/copy_tuner.rb"
|
76
|
+
contents = IO.read(config_path)
|
77
|
+
contents.sub!("end", " config.development_environments = []\nend")
|
78
|
+
File.open(config_path, "w") { |file| file.write(contents) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
When /^I configure the copy_tuner client to have a polling delay of (\d+) seconds$/ do |polling_delay|
|
83
|
+
in_current_dir do
|
84
|
+
config_path = "config/initializers/copy_tuner.rb"
|
85
|
+
contents = IO.read(config_path)
|
86
|
+
contents.sub!(/config.polling_delay = .+/, "config.polling_delay = #{polling_delay}")
|
87
|
+
File.open(config_path, "w") { |file| file.write(contents) }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
Then /^the copy_tuner client version and environment should have been logged$/ do
|
92
|
+
client_version = CopyTunerClient::VERSION
|
93
|
+
environment_info = "[Ruby: #{RUBY_VERSION}]"
|
94
|
+
environment_info << " [Rails: #{Rails::VERSION::STRING}]"
|
95
|
+
environment_info << " [Env: development]"
|
96
|
+
steps %{
|
97
|
+
Then the log should contain "Client #{client_version} ready"
|
98
|
+
Then the log should contain "Environment Info: #{environment_info}"
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
Then /^the log should contain "([^"]*)"$/ do |line|
|
103
|
+
prefix = "** [CopyTuner] "
|
104
|
+
pattern = Regexp.compile([Regexp.escape(prefix), Regexp.escape(line)].join(".*"))
|
105
|
+
log_path = "log/development.log"
|
106
|
+
in_current_dir do
|
107
|
+
File.open(log_path) do |file|
|
108
|
+
unless file.readlines.any? { |file_line| file_line =~ pattern }
|
109
|
+
raise "In log file:\n#{IO.read(log_path)}\n\nMissing line:\n#{pattern}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
Then /^the log should not contain "([^"]*)"$/ do |line|
|
116
|
+
log_path = "log/development.log"
|
117
|
+
in_current_dir do
|
118
|
+
File.open(log_path) do |file|
|
119
|
+
if bad_line = file.readlines.detect { |file_line| file_line.include?(line) }
|
120
|
+
raise "In log file:\n#{log_path}\n\nGot unexpected line:\n#{bad_line}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
When /^I successfully rake "([^"]*)"$/ do |task|
|
127
|
+
run_simple("rake #{task}")
|
128
|
+
end
|
129
|
+
|
130
|
+
Then /^the response should contain "([^"]+)"$/ do |text|
|
131
|
+
@last_response.body.should include(text)
|
132
|
+
end
|
133
|
+
|
134
|
+
When /^I route the "([^"]+)" resource$/ do |resource|
|
135
|
+
if Rails::VERSION::MAJOR == 3
|
136
|
+
draw = "Testapp::Application.routes.draw do\n"
|
137
|
+
else
|
138
|
+
draw = "ActionController::Routing::Routes.draw do |map|\nmap."
|
139
|
+
end
|
140
|
+
|
141
|
+
routes = "#{draw}resources :#{resource}\nend"
|
142
|
+
|
143
|
+
overwrite_file("config/routes.rb", routes)
|
144
|
+
end
|
145
|
+
|
146
|
+
When /^I run a short lived process that sets the key "([^"]*)" to "([^"]*)"$/ do |key, value|
|
147
|
+
if Rails::VERSION::MAJOR == 3
|
148
|
+
run_simple %[script/rails runner 'I18n.translate("#{key}", :default => "#{value}")']
|
149
|
+
else
|
150
|
+
run_simple %[script/runner 'I18n.translate("#{key}", :default => "#{value}")']
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
When /^I remove lines containing "([^"]*)" from "([^"]*)"$/ do |content, filename|
|
155
|
+
in_current_dir do
|
156
|
+
result = ""
|
157
|
+
File.open(filename, "r") do |file|
|
158
|
+
file.each_line do |line|
|
159
|
+
result << line unless line.include?(content)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
File.open(filename, "w") do |file|
|
164
|
+
file.write(result)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
After do
|
171
|
+
RailsServer.stop
|
172
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'sham_rack'
|
2
|
+
require 'aruba/cucumber'
|
3
|
+
require 'rails/version'
|
4
|
+
|
5
|
+
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
6
|
+
$LOAD_PATH << File.join(PROJECT_ROOT, 'lib')
|
7
|
+
require "copy_tuner_client/version"
|
8
|
+
|
9
|
+
Before do
|
10
|
+
@aruba_timeout_seconds = 15
|
11
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
# Starts a Rails application server in a fork and waits for it to be responsive
|
4
|
+
class RailsServer
|
5
|
+
HOST = 'localhost'.freeze
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :instance
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.start(port = nil, debug = nil)
|
12
|
+
self.instance = new(port, debug)
|
13
|
+
self.instance.start
|
14
|
+
self.instance
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.stop
|
18
|
+
self.instance.stop if instance
|
19
|
+
self.instance = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get(path)
|
23
|
+
self.instance.get(path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.post(path, data)
|
27
|
+
self.instance.post(path, data)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.run(port, silent)
|
31
|
+
if silent
|
32
|
+
require 'stringio'
|
33
|
+
$stdout = StringIO.new
|
34
|
+
$stderr = StringIO.new
|
35
|
+
end
|
36
|
+
|
37
|
+
require './config/environment'
|
38
|
+
require 'thin'
|
39
|
+
|
40
|
+
if Rails::VERSION::MAJOR == 3
|
41
|
+
rails = Rails.application
|
42
|
+
else
|
43
|
+
rails = ActionController::Dispatcher.new
|
44
|
+
end
|
45
|
+
app = Identify.new(rails)
|
46
|
+
|
47
|
+
Thin::Logging.silent = silent
|
48
|
+
Rack::Handler::Thin.run(app, :Port => port, :AccessLog => [])
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.app_host
|
52
|
+
self.instance.app_host
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(port, debug)
|
56
|
+
@port = (port || 3001).to_i
|
57
|
+
@debug = debug
|
58
|
+
end
|
59
|
+
|
60
|
+
def start
|
61
|
+
@pid = fork do
|
62
|
+
command = "ruby -r#{__FILE__} -e 'RailsServer.run(#{@port}, #{(!@debug).inspect})'"
|
63
|
+
puts command if @debug
|
64
|
+
exec(command)
|
65
|
+
end
|
66
|
+
wait_until_responsive
|
67
|
+
end
|
68
|
+
|
69
|
+
def stop
|
70
|
+
if @pid
|
71
|
+
Process.kill('INT', @pid)
|
72
|
+
Process.wait(@pid)
|
73
|
+
@pid = nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def get(path)
|
78
|
+
puts "GET #{path}" if @debug
|
79
|
+
Net::HTTP.start(HOST, @port) { |http| http.get(path) }
|
80
|
+
end
|
81
|
+
|
82
|
+
def post(path, data)
|
83
|
+
puts "POST #{path}\n#{data}" if @debug
|
84
|
+
Net::HTTP.start(HOST, @port) { |http| http.post(path, data) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def wait_until_responsive
|
88
|
+
20.times do
|
89
|
+
if responsive?
|
90
|
+
return true
|
91
|
+
else
|
92
|
+
sleep(0.5)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
raise "Couldn't connect to Rails application server at #{HOST}:#{@port}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def responsive?
|
99
|
+
response = Net::HTTP.start(HOST, @port) { |http| http.get('/__identify__') }
|
100
|
+
response.is_a?(Net::HTTPSuccess)
|
101
|
+
rescue Errno::ECONNREFUSED, Errno::EBADF
|
102
|
+
return false
|
103
|
+
end
|
104
|
+
|
105
|
+
def app_host
|
106
|
+
"http://#{HOST}:#{@port}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# From Capybara::Server
|
110
|
+
|
111
|
+
class Identify
|
112
|
+
def initialize(app)
|
113
|
+
@app = app
|
114
|
+
end
|
115
|
+
|
116
|
+
def call(env)
|
117
|
+
if env["PATH_INFO"] == "/__identify__"
|
118
|
+
[200, {}, 'OK']
|
119
|
+
else
|
120
|
+
@app.call(env)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
PATH
|
2
|
+
remote: /Users/mat_aki/gem/copy-tuner-ruby-client
|
3
|
+
specs:
|
4
|
+
copy_tuner_client (0.0.1)
|
5
|
+
i18n (>= 0.5.0)
|
6
|
+
json
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actionmailer (2.3.14)
|
12
|
+
actionpack (= 2.3.14)
|
13
|
+
actionpack (2.3.14)
|
14
|
+
activesupport (= 2.3.14)
|
15
|
+
rack (~> 1.1.0)
|
16
|
+
activerecord (2.3.14)
|
17
|
+
activesupport (= 2.3.14)
|
18
|
+
activeresource (2.3.14)
|
19
|
+
activesupport (= 2.3.14)
|
20
|
+
activesupport (2.3.14)
|
21
|
+
addressable (2.2.6)
|
22
|
+
appraisal (0.4.0)
|
23
|
+
bundler
|
24
|
+
rake
|
25
|
+
aruba (0.3.7)
|
26
|
+
childprocess (>= 0.1.9)
|
27
|
+
cucumber (>= 0.10.5)
|
28
|
+
rspec (>= 2.6.0)
|
29
|
+
bourne (1.0)
|
30
|
+
mocha (= 0.9.8)
|
31
|
+
builder (3.0.0)
|
32
|
+
childprocess (0.2.2)
|
33
|
+
ffi (~> 1.0.6)
|
34
|
+
crack (0.3.1)
|
35
|
+
cucumber (0.10.7)
|
36
|
+
builder (>= 2.1.2)
|
37
|
+
diff-lcs (>= 1.1.2)
|
38
|
+
gherkin (~> 2.4.0)
|
39
|
+
json (>= 1.4.6)
|
40
|
+
term-ansicolor (>= 1.0.5)
|
41
|
+
daemons (1.1.4)
|
42
|
+
diff-lcs (1.1.3)
|
43
|
+
eventmachine (0.12.10)
|
44
|
+
ffi (1.0.11)
|
45
|
+
gherkin (2.4.21)
|
46
|
+
json (>= 1.4.6)
|
47
|
+
i18n (0.6.0)
|
48
|
+
json (1.6.1)
|
49
|
+
mocha (0.9.8)
|
50
|
+
rake
|
51
|
+
rack (1.1.2)
|
52
|
+
rails (2.3.14)
|
53
|
+
actionmailer (= 2.3.14)
|
54
|
+
actionpack (= 2.3.14)
|
55
|
+
activerecord (= 2.3.14)
|
56
|
+
activeresource (= 2.3.14)
|
57
|
+
activesupport (= 2.3.14)
|
58
|
+
rake (>= 0.8.3)
|
59
|
+
rake (0.9.2)
|
60
|
+
rspec (2.7.0)
|
61
|
+
rspec-core (~> 2.7.0)
|
62
|
+
rspec-expectations (~> 2.7.0)
|
63
|
+
rspec-mocks (~> 2.7.0)
|
64
|
+
rspec-core (2.7.1)
|
65
|
+
rspec-expectations (2.7.0)
|
66
|
+
diff-lcs (~> 1.1.2)
|
67
|
+
rspec-mocks (2.7.0)
|
68
|
+
sham_rack (1.3.3)
|
69
|
+
rack
|
70
|
+
sinatra (1.2.7)
|
71
|
+
rack (~> 1.1)
|
72
|
+
tilt (>= 1.2.2, < 2.0)
|
73
|
+
sqlite3 (1.3.4)
|
74
|
+
sqlite3-ruby (1.3.3)
|
75
|
+
sqlite3 (>= 1.3.3)
|
76
|
+
term-ansicolor (1.0.7)
|
77
|
+
thin (1.3.1)
|
78
|
+
daemons (>= 1.0.9)
|
79
|
+
eventmachine (>= 0.12.6)
|
80
|
+
rack (>= 1.0.0)
|
81
|
+
tilt (1.3.3)
|
82
|
+
webmock (1.7.7)
|
83
|
+
addressable (~> 2.2, > 2.2.5)
|
84
|
+
crack (>= 0.1.7)
|
85
|
+
yard (0.7.3)
|
86
|
+
|
87
|
+
PLATFORMS
|
88
|
+
ruby
|
89
|
+
|
90
|
+
DEPENDENCIES
|
91
|
+
appraisal (~> 0.4)
|
92
|
+
aruba (~> 0.3.2)
|
93
|
+
bourne
|
94
|
+
copy_tuner_client!
|
95
|
+
cucumber (~> 0.10.0)
|
96
|
+
i18n
|
97
|
+
rails (= 2.3.14)
|
98
|
+
rake (= 0.9.2)
|
99
|
+
rspec (~> 2.3)
|
100
|
+
sham_rack
|
101
|
+
sinatra
|
102
|
+
sqlite3-ruby
|
103
|
+
thin
|
104
|
+
webmock
|
105
|
+
yard
|