copy_tuner_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +9 -0
  4. data/Appraisals +15 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +161 -0
  7. data/README.md +4 -0
  8. data/Rakefile +28 -0
  9. data/copy_tuner_client.gemspec +33 -0
  10. data/features/rails.feature +270 -0
  11. data/features/step_definitions/copycopter_server_steps.rb +64 -0
  12. data/features/step_definitions/rails_steps.rb +172 -0
  13. data/features/support/env.rb +11 -0
  14. data/features/support/rails_server.rb +124 -0
  15. data/gemfiles/2.3.gemfile +7 -0
  16. data/gemfiles/2.3.gemfile.lock +105 -0
  17. data/gemfiles/3.0.gemfile +7 -0
  18. data/gemfiles/3.0.gemfile.lock +147 -0
  19. data/gemfiles/3.1.gemfile +11 -0
  20. data/gemfiles/3.1.gemfile.lock +191 -0
  21. data/init.rb +1 -0
  22. data/lib/copy_tuner_client/cache.rb +144 -0
  23. data/lib/copy_tuner_client/client.rb +136 -0
  24. data/lib/copy_tuner_client/configuration.rb +224 -0
  25. data/lib/copy_tuner_client/errors.rb +12 -0
  26. data/lib/copy_tuner_client/i18n_backend.rb +92 -0
  27. data/lib/copy_tuner_client/poller.rb +44 -0
  28. data/lib/copy_tuner_client/prefixed_logger.rb +45 -0
  29. data/lib/copy_tuner_client/process_guard.rb +92 -0
  30. data/lib/copy_tuner_client/rails.rb +21 -0
  31. data/lib/copy_tuner_client/railtie.rb +12 -0
  32. data/lib/copy_tuner_client/request_sync.rb +39 -0
  33. data/lib/copy_tuner_client/version.rb +7 -0
  34. data/lib/copy_tuner_client.rb +75 -0
  35. data/lib/tasks/copy_tuner_client_tasks.rake +20 -0
  36. data/spec/copy_tuner_client/cache_spec.rb +273 -0
  37. data/spec/copy_tuner_client/client_spec.rb +236 -0
  38. data/spec/copy_tuner_client/configuration_spec.rb +305 -0
  39. data/spec/copy_tuner_client/i18n_backend_spec.rb +157 -0
  40. data/spec/copy_tuner_client/poller_spec.rb +108 -0
  41. data/spec/copy_tuner_client/prefixed_logger_spec.rb +37 -0
  42. data/spec/copy_tuner_client/process_guard_spec.rb +118 -0
  43. data/spec/copy_tuner_client/request_sync_spec.rb +47 -0
  44. data/spec/copy_tuner_client_spec.rb +19 -0
  45. data/spec/spec_helper.rb +29 -0
  46. data/spec/support/client_spec_helpers.rb +8 -0
  47. data/spec/support/defines_constants.rb +44 -0
  48. data/spec/support/fake_client.rb +53 -0
  49. data/spec/support/fake_copy_tuner_app.rb +175 -0
  50. data/spec/support/fake_html_safe_string.rb +20 -0
  51. data/spec/support/fake_logger.rb +68 -0
  52. data/spec/support/fake_passenger.rb +27 -0
  53. data/spec/support/fake_resque_job.rb +18 -0
  54. data/spec/support/fake_unicorn.rb +13 -0
  55. data/spec/support/middleware_stack.rb +13 -0
  56. data/spec/support/writing_cache.rb +17 -0
  57. data/tmp/projects.json +1 -0
  58. 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,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "2.3.14"
6
+
7
+ gemspec :path=>"../"
@@ -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