right_support 2.11.3 → 2.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/lib/right_support/notifiers/airbrake.rb +194 -0
- data/lib/right_support/notifiers/base.rb +73 -0
- data/lib/right_support/notifiers/blacklisters/base.rb +48 -0
- data/lib/right_support/notifiers/blacklisters/canonical.rb +60 -0
- data/lib/right_support/notifiers/blacklisters/regular_expression.rb +86 -0
- data/{features/support/file_utils_bundler_mixin.rb → lib/right_support/notifiers/blacklisters/simple.rb} +21 -20
- data/lib/right_support/notifiers/blacklisters/snake_case.rb +60 -0
- data/lib/right_support/notifiers/blacklisters/wildcard.rb +65 -0
- data/lib/right_support/notifiers/blacklisters.rb +34 -0
- data/lib/right_support/notifiers/logger.rb +94 -0
- data/lib/right_support/notifiers/notification.rb +57 -0
- data/lib/right_support/notifiers/utilities/backtrace_decoder.rb +234 -0
- data/lib/right_support/notifiers/utilities.rb +29 -0
- data/lib/right_support/notifiers.rb +32 -0
- data/lib/right_support/rack/request_logger.rb +13 -9
- data/lib/right_support.rb +1 -0
- data/right_support.gemspec +19 -70
- metadata +17 -69
- data/.coveralls.yml +0 -2
- data/.rspec +0 -3
- data/.simplecov +0 -6
- data/.travis.yml +0 -13
- data/Gemfile +0 -51
- data/Gemfile.lock +0 -153
- data/features/balancer_error_handling.feature +0 -34
- data/features/balancer_health_check.feature +0 -33
- data/features/hash_tools.feature +0 -27
- data/features/http_client_timeout.feature +0 -19
- data/features/serialization.feature +0 -113
- data/features/step_definitions/hash_tools_steps.rb +0 -41
- data/features/step_definitions/http_client_steps.rb +0 -27
- data/features/step_definitions/request_balancer_steps.rb +0 -93
- data/features/step_definitions/ruby_steps.rb +0 -176
- data/features/step_definitions/serialization_steps.rb +0 -133
- data/features/step_definitions/server_steps.rb +0 -134
- data/features/support/env.rb +0 -148
- data/right_support.rconf +0 -9
- data/spec/config/feature_set_spec.rb +0 -83
- data/spec/crypto/signed_hash_spec.rb +0 -73
- data/spec/data/hash_tools_spec.rb +0 -602
- data/spec/data/mash_spec.rb +0 -313
- data/spec/data/token_spec.rb +0 -21
- data/spec/data/uuid_spec.rb +0 -45
- data/spec/db/cassandra_model_part1_spec.rb +0 -84
- data/spec/db/cassandra_model_part2_spec.rb +0 -73
- data/spec/db/cassandra_model_spec.rb +0 -375
- data/spec/fixtures/encrypted_priv_rsa.pem +0 -30
- data/spec/fixtures/good_priv_dsa.pem +0 -12
- data/spec/fixtures/good_priv_rsa.pem +0 -15
- data/spec/fixtures/good_pub_dsa.ssh +0 -1
- data/spec/fixtures/good_pub_rsa.pem +0 -5
- data/spec/fixtures/good_pub_rsa.ssh +0 -1
- data/spec/log/exception_logger_spec.rb +0 -76
- data/spec/log/filter_logger_spec.rb +0 -66
- data/spec/log/mixin_spec.rb +0 -141
- data/spec/log/multiplexer_spec.rb +0 -54
- data/spec/log/null_logger_spec.rb +0 -36
- data/spec/log/step_level_logger_spec.rb +0 -49
- data/spec/log/system_logger_spec.rb +0 -172
- data/spec/net/address_helper_spec.rb +0 -57
- data/spec/net/dns_spec.rb +0 -187
- data/spec/net/http_client_spec.rb +0 -181
- data/spec/net/lb/health_check_spec.rb +0 -417
- data/spec/net/lb/round_robin_spec.rb +0 -15
- data/spec/net/lb/sticky_spec.rb +0 -92
- data/spec/net/request_balancer_spec.rb +0 -690
- data/spec/net/s3_helper_spec.rb +0 -160
- data/spec/net/ssl_spec.rb +0 -42
- data/spec/net/string_encoder_spec.rb +0 -58
- data/spec/rack/log_setter_spec.rb +0 -5
- data/spec/rack/request_logger_spec.rb +0 -225
- data/spec/rack/request_tracker_spec.rb +0 -115
- data/spec/rack/runtime_spec.rb +0 -49
- data/spec/ruby/easy_singleton_spec.rb +0 -72
- data/spec/ruby/object_extensions_spec.rb +0 -27
- data/spec/ruby/string_extensions_spec.rb +0 -98
- data/spec/spec_helper.rb +0 -188
- data/spec/stats/activity_spec.rb +0 -425
- data/spec/stats/exceptions_spec.rb +0 -247
- data/spec/stats/helpers_spec.rb +0 -685
- data/spec/validation/openssl_spec.rb +0 -37
- data/spec/validation/ssh_spec.rb +0 -39
@@ -1,113 +0,0 @@
|
|
1
|
-
Feature: JSON serialization
|
2
|
-
In order to facilitate Ruby apps' use of external JSON data stores
|
3
|
-
RightSupport should cleanly serialize arbitrary Ruby objects to JSON without data loss or semantic ambiguity
|
4
|
-
So app code can be idiomatic and focus on the business problem, not the encoding details
|
5
|
-
|
6
|
-
Background:
|
7
|
-
Given a serializer named 'RightSupport::Data::Serializer'
|
8
|
-
And a stateful Ruby class named 'GotState'
|
9
|
-
|
10
|
-
Scenario Outline: Ruby types with a native JSON representation
|
11
|
-
When I serialize the Ruby value: <ruby>
|
12
|
-
Then the serialized value should be: <json>
|
13
|
-
And the serialized value should round-trip cleanly
|
14
|
-
|
15
|
-
Examples:
|
16
|
-
| ruby | json |
|
17
|
-
| true | true |
|
18
|
-
| false | false |
|
19
|
-
| nil | null |
|
20
|
-
| 0 | 0 |
|
21
|
-
| 42 | 42 |
|
22
|
-
| -32 | -32 |
|
23
|
-
| 3.1415926535 | 3.1415926535 |
|
24
|
-
| 0xFFFFFFFFFFFFFFFFFFFFFFFF | 79228162514264337593543950335 |
|
25
|
-
| "hello, world!" | "hello, world!" |
|
26
|
-
| [0,true,nil,['a',false]] | [0,true,null,["a",false]] |
|
27
|
-
| {"one"=>2} | {"one":2} |
|
28
|
-
| {"hash"=>{"lucky"=>777,"seq"=>[2,3]}} | {"hash":{"lucky":777,"seq":[2,3]}} |
|
29
|
-
|
30
|
-
Scenario: complex Ruby structures with a native JSON representation
|
31
|
-
When I serialize a complex random data structure
|
32
|
-
Then the serialized value should round-trip cleanly
|
33
|
-
|
34
|
-
Scenario: invalid UTF-8 characters
|
35
|
-
When I serialize the Ruby value: "\xC0\xBCscript>\xC0\xBC/script>"
|
36
|
-
Then the serialized value should have no invalid characters
|
37
|
-
|
38
|
-
Scenario: valid UTF-8 characters
|
39
|
-
When I serialize the Ruby value: "onê"
|
40
|
-
Then the serialized value should be: "onê"
|
41
|
-
And the serialized value should round-trip cleanly
|
42
|
-
|
43
|
-
Scenario Outline: object-escaped Symbol
|
44
|
-
When I serialize the Ruby value: <ruby>
|
45
|
-
Then the serialized value should be: <json>
|
46
|
-
And the serialized value should round-trip cleanly
|
47
|
-
|
48
|
-
Examples:
|
49
|
-
| ruby | json |
|
50
|
-
| :my_symbol | ":my_symbol" |
|
51
|
-
| :'weird symbol' | ":weird symbol" |
|
52
|
-
|
53
|
-
Scenario Outline: object-escaped Time
|
54
|
-
When I serialize the Ruby value: <ruby>
|
55
|
-
Then the serialized value should be: <json>
|
56
|
-
And the serialized value should round-trip cleanly
|
57
|
-
|
58
|
-
Examples:
|
59
|
-
| ruby | json |
|
60
|
-
| Time.at(1234567890) | "2009-02-13T23:31:30Z" |
|
61
|
-
| Time.at(1234567890).utc | "2009-02-13T23:31:30Z" |
|
62
|
-
|
63
|
-
Scenario Outline: object-escaped String
|
64
|
-
When I serialize the Ruby value: <ruby>
|
65
|
-
Then the serialized value should be: <json>
|
66
|
-
And the serialized value should round-trip cleanly
|
67
|
-
|
68
|
-
Examples:
|
69
|
-
| ruby | json |
|
70
|
-
| ":not_a_symbol" | {"_ruby_class":"String","value":":not_a_symbol"} |
|
71
|
-
|
72
|
-
Scenario Outline: Ruby Class and Module types
|
73
|
-
|
74
|
-
Scenario Outline: Ruby Class and Module types
|
75
|
-
When I serialize the Ruby value: <ruby>
|
76
|
-
Then the serialized value should be a JSON object
|
77
|
-
And the serialized value should round-trip cleanly
|
78
|
-
|
79
|
-
Examples:
|
80
|
-
| ruby |
|
81
|
-
| String |
|
82
|
-
| RightSupport::Ruby::EasySingleton |
|
83
|
-
| RightSupport::Net::HTTPClient |
|
84
|
-
| Hash |
|
85
|
-
| Kernel |
|
86
|
-
|
87
|
-
Scenario Outline: arbitrary Ruby objects
|
88
|
-
When I serialize the Ruby value: <ruby>
|
89
|
-
Then the serialized value should be a JSON object
|
90
|
-
And the serialized value should have a suitable _ruby_class
|
91
|
-
|
92
|
-
Examples:
|
93
|
-
| ruby |
|
94
|
-
| RightSupport::Crypto::SignedHash.new() |
|
95
|
-
| GotState.new |
|
96
|
-
|
97
|
-
Scenario: arbitrary Ruby object round-trip, happy path
|
98
|
-
When I serialize the Ruby value: GotState.new
|
99
|
-
Then the serialized value should round-trip cleanly
|
100
|
-
|
101
|
-
Scenario: arbitrary Ruby object round-trip, sad path
|
102
|
-
When I serialize the Ruby value: GotState.new
|
103
|
-
And an eldritch force deletes a key from the serialized value
|
104
|
-
And the serialized value should fail to round-trip
|
105
|
-
|
106
|
-
Scenario: unrecognized Ruby object class
|
107
|
-
When I unserialize the JSON value: {"_ruby_class":"DoesNotExist","hello":"world"}
|
108
|
-
Then the unserialized object should be an RightSupport::Data::UnknownType
|
109
|
-
And the unserialized object should have a "hello" attribute with value: "world"
|
110
|
-
|
111
|
-
Scenario: unrecognized Ruby object class
|
112
|
-
When I serialize the Ruby value: RightSupport::Data::UnknownType.new("DoesNotExist", {"hello" => "world"})
|
113
|
-
Then the serialized value should be: {"_ruby_class":"DoesNotExist","hello":"world"}
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
Given /^a hash map with the form (.*)$/ do |hash|
|
4
|
-
@hash = JSON.parse(hash)
|
5
|
-
end
|
6
|
-
|
7
|
-
Given /^a path array (.*)$/ do |path|
|
8
|
-
@path = JSON.parse(path)
|
9
|
-
end
|
10
|
-
|
11
|
-
Given /^a value (.*)$/ do |value|
|
12
|
-
@value = value
|
13
|
-
end
|
14
|
-
|
15
|
-
When /^I call the deep_get method$/ do
|
16
|
-
@deep_get_value = RightSupport::Data::HashTools.deep_get(@hash, @path)
|
17
|
-
end
|
18
|
-
|
19
|
-
When /^I call the deep_set! method$/ do
|
20
|
-
RightSupport::Data::HashTools.deep_set!(@hash, @path, @value)
|
21
|
-
end
|
22
|
-
|
23
|
-
When /^I call the deep_merge! method with the source: (.*)$/ do |source|
|
24
|
-
RightSupport::Data::HashTools.deep_merge!(@hash, JSON.parse(source))
|
25
|
-
end
|
26
|
-
|
27
|
-
When /^I call the deep_remove! method with the source: (.*)$/ do |source|
|
28
|
-
RightSupport::Data::HashTools.deep_remove!(@hash, JSON.parse(source))
|
29
|
-
end
|
30
|
-
|
31
|
-
Then /^The hash should be: (.*)$/ do |hash|
|
32
|
-
@hash == JSON.parse(hash)
|
33
|
-
end
|
34
|
-
|
35
|
-
Then /^The deep_get method response should be: (.*)$/ do |expression|
|
36
|
-
@deep_get_value == expression
|
37
|
-
end
|
38
|
-
|
39
|
-
Then /^The generate method response should be: (.*)$/ do |expression|
|
40
|
-
@generated_value == expression
|
41
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
When /^a client makes a (buggy )?request to '(.*)'$/ do |buggy, path|
|
2
|
-
t = RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:timeout]
|
3
|
-
o = RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:open_timeout]
|
4
|
-
When "a client makes a #{buggy}request to '#{path}' with timeout #{t} and open_timeout #{o}"
|
5
|
-
end
|
6
|
-
|
7
|
-
|
8
|
-
When /^a client makes a (buggy )?request to '(.*)' with timeout (\d+) and open_timeout (\d+)$/ do |buggy, path, timeout, open_timeout|
|
9
|
-
buggy = !(buggy.nil? || buggy.empty?)
|
10
|
-
|
11
|
-
@mock_servers.should_not be_nil
|
12
|
-
@mock_servers.size.should == 1
|
13
|
-
|
14
|
-
timeout = timeout.to_i
|
15
|
-
open_timeout = open_timeout.to_i
|
16
|
-
url = @mock_servers.first.url
|
17
|
-
|
18
|
-
@http_client = RightSupport::Net::HTTPClient.new(:timeout=>timeout, :open_timeout=>open_timeout)
|
19
|
-
@request_t0 = Time.now
|
20
|
-
begin
|
21
|
-
raise ArgumentError, "Fall down go boom!" if buggy
|
22
|
-
@http_client.get("#{url}#{path}", {:timeout => timeout, :open_timeout => open_timeout})
|
23
|
-
rescue Exception => e
|
24
|
-
@request_error = e
|
25
|
-
end
|
26
|
-
@request_t1 = Time.now
|
27
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
# Rails' constantize method to convert passed in policy to the actual class
|
2
|
-
def constantize(camel_cased_word)
|
3
|
-
names = camel_cased_word.split('::')
|
4
|
-
names.shift if names.empty? || names.first.empty?
|
5
|
-
|
6
|
-
constant = Object
|
7
|
-
names.each do |name|
|
8
|
-
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
9
|
-
end
|
10
|
-
constant
|
11
|
-
end
|
12
|
-
|
13
|
-
Given /^(\w+) balancing policy$/ do |policy|
|
14
|
-
@health_check = Proc.new do |endpoint|
|
15
|
-
begin
|
16
|
-
RightSupport::Net::HTTPClient.new.get(endpoint, {:timeout => 1, :open_timeout => 1})
|
17
|
-
true
|
18
|
-
rescue Exception => e
|
19
|
-
false
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
@options ||= { :policy => constantize("RightSupport::Net::LB::" + policy), :health_check => @health_check }
|
24
|
-
end
|
25
|
-
|
26
|
-
When /^a client makes a (buggy )?load-balanced request to '(.*)'$/ do |buggy, path|
|
27
|
-
t = RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:timeout]
|
28
|
-
o = RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:open_timeout]
|
29
|
-
step "a client makes a #{buggy}load-balanced request to '#{path}' with timeout #{t} and open_timeout #{o}"
|
30
|
-
end
|
31
|
-
|
32
|
-
When /^a client makes a (buggy )?load-balanced request to '(.*)' with timeout (\d+) and open_timeout (\d+)$/ do |buggy, path, timeout, open_timeout|
|
33
|
-
buggy = !(buggy.nil? || buggy.empty?)
|
34
|
-
|
35
|
-
@mock_servers.should_not be_nil
|
36
|
-
@mock_servers.empty?.should be_false
|
37
|
-
|
38
|
-
timeout = timeout.to_i
|
39
|
-
open_timeout = open_timeout.to_i
|
40
|
-
urls = @mock_servers.map { |s| s.url }
|
41
|
-
@request_balancer = RightSupport::Net::RequestBalancer.new(urls)
|
42
|
-
@request_attempts = 0
|
43
|
-
@request_t0 = Time.now
|
44
|
-
@http_client = RightSupport::Net::HTTPClient.new
|
45
|
-
begin
|
46
|
-
@request_balancer.request do |url|
|
47
|
-
@request_attempts += 1
|
48
|
-
raise ArgumentError, "Fall down go boom!" if buggy
|
49
|
-
@http_client.get("#{url}#{path}", {:timeout => timeout, :open_timeout => open_timeout})
|
50
|
-
end
|
51
|
-
rescue Exception => e
|
52
|
-
@request_error = e
|
53
|
-
end
|
54
|
-
@request_t1 = Time.now
|
55
|
-
end
|
56
|
-
|
57
|
-
Then /^the request should (\w+ ?\w*)$/ do |behavior|
|
58
|
-
case behavior
|
59
|
-
when 'complete'
|
60
|
-
error_expected = false
|
61
|
-
when 'raise'
|
62
|
-
error_expected = true
|
63
|
-
when /raise (\w+)/
|
64
|
-
error_expected = true
|
65
|
-
error_class_expected = /raise (\w+)/.match(behavior)[1]
|
66
|
-
else
|
67
|
-
raise ArgumentError, "Unknown request behavior #{behavior}"
|
68
|
-
end
|
69
|
-
|
70
|
-
if !error_expected && @request_error
|
71
|
-
puts '!' * 80
|
72
|
-
puts @request_error.class.inspect
|
73
|
-
puts @request_error.class.superclass.inspect
|
74
|
-
puts '!' * 80
|
75
|
-
end
|
76
|
-
@request_error.should be_nil unless error_expected
|
77
|
-
@request_error.should_not be_nil if error_expected
|
78
|
-
@request_error.class.name.should =~ Regexp.new(error_class_expected) if error_class_expected
|
79
|
-
end
|
80
|
-
|
81
|
-
Then /^the request should (\w+ ?\w*) in less than (\d+) seconds?$/ do |behavior, time|
|
82
|
-
step "the request should #{behavior}"
|
83
|
-
#allow 10% margin of error due to Ruby/OS scheduler variance
|
84
|
-
(@request_t1.to_f - @request_t0.to_f).should <= (time.to_f * 1.10)
|
85
|
-
end
|
86
|
-
|
87
|
-
Then /^the request should be attempted once$/ do
|
88
|
-
@request_attempts.should == 1
|
89
|
-
end
|
90
|
-
|
91
|
-
Then /^the request should be attempted ([0-9]+) times$/ do |n|
|
92
|
-
@request_attempts.should == n.to_i
|
93
|
-
end
|
@@ -1,176 +0,0 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
|
3
|
-
Given /^a Ruby application$/ do
|
4
|
-
ruby_app_root.should_not be_nil
|
5
|
-
end
|
6
|
-
|
7
|
-
Given /^a Gemfile$/ do
|
8
|
-
gemfile = ruby_app_path('Gemfile')
|
9
|
-
unless File.exist?(gemfile)
|
10
|
-
basedir = File.expand_path('../../..', __FILE__)
|
11
|
-
File.open(gemfile, 'w') do |file|
|
12
|
-
file.puts "gem 'right_support', :path=>'#{basedir}'"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
Given /^a gem dependency on '(.*)'$/ do |dependency|
|
18
|
-
step 'a Gemfile'
|
19
|
-
gem, version = dependency.split(/\s+/, 2)
|
20
|
-
gemfile = ruby_app_path('Gemfile')
|
21
|
-
File.open(gemfile, 'a') do |file|
|
22
|
-
file.puts "gem '#{gem}', '#{version}'"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
Given /^a Rakefile$/ do
|
27
|
-
rakefile = ruby_app_path('Rakefile')
|
28
|
-
unless File.exist?(rakefile)
|
29
|
-
File.open(rakefile, 'w') do |file|
|
30
|
-
file.puts "# Auto-generated by #{__FILE__}"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
Given /^the Rakefile contains a RightSupport::CI::RakeTask$/ do
|
36
|
-
step 'a Rakefile'
|
37
|
-
rakefile = ruby_app_path('Rakefile')
|
38
|
-
File.open(rakefile, 'w') do |file|
|
39
|
-
file.puts "require 'right_support/ci/rake_task'"
|
40
|
-
file.puts "RightSupport::CI::RakeTask.new"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
Given /^the Rakefile contains a RightSupport::CI::RakeTask with parameter '(.*)'$/ do |ns|
|
45
|
-
step 'a Rakefile'
|
46
|
-
rakefile = ruby_app_path('Rakefile')
|
47
|
-
File.open(rakefile, 'w') do |file|
|
48
|
-
file.puts "require 'right_support/ci/rake_task'"
|
49
|
-
file.puts "RightSupport::CI::RakeTask.new(#{ns})"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
Given /^a trivial (failing )?RSpec spec$/ do |failing|
|
54
|
-
spec_dir = ruby_app_path('spec')
|
55
|
-
spec = ruby_app_path('spec', 'trivial_spec.rb')
|
56
|
-
FileUtils.mkdir_p(spec_dir)
|
57
|
-
unless File.exist?(spec)
|
58
|
-
File.open(spec, 'w') do |file|
|
59
|
-
file.puts "describe String do"
|
60
|
-
file.puts " it 'has a size' do"
|
61
|
-
file.puts " 'joe'.size.should == 3"
|
62
|
-
file.puts " end"
|
63
|
-
file.puts
|
64
|
-
file.puts " it 'is stringy' do"
|
65
|
-
file.puts " pending"
|
66
|
-
file.puts " end"
|
67
|
-
unless failing.nil?
|
68
|
-
file.puts
|
69
|
-
file.puts "it 'meets an impossible ideal' do"
|
70
|
-
file.puts " raise NotImplementedError, 'inconceivable!'"
|
71
|
-
file.puts "end"
|
72
|
-
end
|
73
|
-
file.puts "end"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
Given /^a trivial (failing )?Cucumber feature$/ do |failing|
|
79
|
-
features_dir = ruby_app_path('features')
|
80
|
-
steps_dir = ruby_app_path('features', 'step_definitions')
|
81
|
-
feature = ruby_app_path('features', 'trivial.feature')
|
82
|
-
steps = ruby_app_path('features', 'step_definitions', 'trivial_steps.rb')
|
83
|
-
FileUtils.mkdir_p(features_dir)
|
84
|
-
FileUtils.mkdir_p(steps_dir)
|
85
|
-
|
86
|
-
unless File.exist?(steps)
|
87
|
-
File.open(steps, 'w') do |file|
|
88
|
-
file.puts "When /^the night has come and the land is dark$/ do; end"
|
89
|
-
file.puts "When /^the moon is the only light we see$/ do; end"
|
90
|
-
file.puts "Then /^I won't be afraid.*$/ do; end"
|
91
|
-
file.puts "Then /^as long as you stand.*by me$/ do; end"
|
92
|
-
file.puts "Then /^you run away as fast as you can$/ do; raise NotImplementedError; end"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
unless File.exist?(feature)
|
96
|
-
File.open(feature, 'w') do |file|
|
97
|
-
file.puts "Feature: Song Lyrics from the 1950s"
|
98
|
-
file.puts
|
99
|
-
file.puts " Scenario: Stand By Me"
|
100
|
-
file.puts " When the night has come and the land is dark"
|
101
|
-
file.puts " And the moon is the only light we see"
|
102
|
-
file.puts " Then I won't be afraid, oh, I won't be afraid"
|
103
|
-
if failing.nil?
|
104
|
-
file.puts " And as long as you stand, stand by me"
|
105
|
-
else
|
106
|
-
file.puts " And you run away as fast as you can"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
When /^I install the bundle$/ do
|
113
|
-
ruby_app_shell('bundle install')
|
114
|
-
end
|
115
|
-
|
116
|
-
When /^I rake '(.*)'$/ do |task|
|
117
|
-
@ruby_app_output = ruby_app_shell("bundle exec rake #{task} --trace ", :ignore_errors => true)
|
118
|
-
end
|
119
|
-
|
120
|
-
When /^I debug the app shell$/ do
|
121
|
-
STDOUT.puts "Opening shell in a separate window."
|
122
|
-
if RUBY_PLATFORM =~ /darwin/
|
123
|
-
ruby_app_shell("open -a Terminal .")
|
124
|
-
else
|
125
|
-
raise "Don't know how to open an app shell for #{RUBY_PLATFORM}; please contribute your knowledge to #{__FILE__}"
|
126
|
-
end
|
127
|
-
STDOUT.puts "Press Enter to continue Cucumber execution..."
|
128
|
-
STDOUT.flush
|
129
|
-
STDIN.readline
|
130
|
-
end
|
131
|
-
|
132
|
-
Then /^the output should contain '(.*)'$/ do |expected_output|
|
133
|
-
@ruby_app_output.should include(expected_output)
|
134
|
-
end
|
135
|
-
|
136
|
-
Then /^the output should not contain '(.*)'$/ do |expected_output|
|
137
|
-
@ruby_app_output.should_not include(expected_output)
|
138
|
-
end
|
139
|
-
|
140
|
-
Then /^the directory '(.*)' should contain files/ do |dir|
|
141
|
-
dir = ruby_app_path(dir)
|
142
|
-
File.directory?(dir).should be_true
|
143
|
-
Dir[File.join(dir, '*')].should_not be_empty
|
144
|
-
end
|
145
|
-
|
146
|
-
Then /^the file '(.*)' should mention ([0-9]) (passing|failing) test cases?$/ do |file, n, pass_fail|
|
147
|
-
file = ruby_app_path(file)
|
148
|
-
n = Integer(n)
|
149
|
-
|
150
|
-
Pathname.new(file).should exist
|
151
|
-
|
152
|
-
doc = Nokogiri.XML(File.open(file, 'r'))
|
153
|
-
|
154
|
-
all_testcases = doc.css('testcase').size
|
155
|
-
failing_testcases = doc.css('testcase failure').size
|
156
|
-
passing_testcases = all_testcases - failing_testcases
|
157
|
-
|
158
|
-
case pass_fail
|
159
|
-
when 'passing'
|
160
|
-
passing_testcases.should == n
|
161
|
-
when 'failing'
|
162
|
-
failing_testcases.should == n
|
163
|
-
else
|
164
|
-
raise NotImplementedError, "WTF #{pass_fail}"
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
Then /^the command should (succeed|fail)$/ do |success|
|
169
|
-
if success == 'succeed'
|
170
|
-
$?.exitstatus.should == 0
|
171
|
-
elsif success == 'fail'
|
172
|
-
$?.exitstatus.should_not == 0
|
173
|
-
else
|
174
|
-
raise NotImplementedError, "Unknown expectation #{success}"
|
175
|
-
end
|
176
|
-
end
|
@@ -1,133 +0,0 @@
|
|
1
|
-
Given /^a serializer named '(.+)'$/ do |klass|
|
2
|
-
@serializer = klass.to_const
|
3
|
-
end
|
4
|
-
|
5
|
-
Given /^a stateful Ruby class named '(.*)'$/ do |name|
|
6
|
-
name = name.to_sym
|
7
|
-
ivars = 1 + rand(10)
|
8
|
-
|
9
|
-
|
10
|
-
Kernel.__send__(:remove_const, name) if Kernel.const_defined?(name)
|
11
|
-
|
12
|
-
@stateful_ruby_class = Class.new(Object)
|
13
|
-
Kernel.__send__(:const_set, name, @stateful_ruby_class)
|
14
|
-
|
15
|
-
@stateful_ruby_class.instance_eval do
|
16
|
-
define_method(:initialize) do
|
17
|
-
ivars.times do
|
18
|
-
self.instance_variable_set("@instance_variable_#{random_value(Integer)}", random_value(nil, [String]))
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
define_method(:==) do |other|
|
23
|
-
result = (Set.new(self.instance_variables) == Set.new(other.instance_variables))
|
24
|
-
|
25
|
-
self.instance_variables.each do |ivar|
|
26
|
-
result &&= (self.instance_variable_get(ivar) == other.instance_variable_get(ivar))
|
27
|
-
end
|
28
|
-
|
29
|
-
result
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
When /^I serialize the Ruby value: (.*)$/ do |expression|
|
35
|
-
@ruby_value = eval(expression)
|
36
|
-
@serialized_value = @serializer.dump(@ruby_value)
|
37
|
-
end
|
38
|
-
|
39
|
-
When /^I unserialize the JSON value: (.*)$/ do |value|
|
40
|
-
@serialized_value = value
|
41
|
-
@ruby_value = @serializer.load(@serialized_value)
|
42
|
-
end
|
43
|
-
|
44
|
-
When /^I serialize a complex random data structure$/ do
|
45
|
-
@ruby_value = random_value(nil, [String])
|
46
|
-
@serialized_value = @serializer.dump(@ruby_value)
|
47
|
-
end
|
48
|
-
|
49
|
-
When /^an eldritch force deletes a key from the serialized value$/ do
|
50
|
-
hash = RightSupport::Data::Serializer::Encoder.load(@serialized_value)
|
51
|
-
hash.delete(hash.keys[rand(hash.keys.size)])
|
52
|
-
@serialized_value = @serializer.dump(hash)
|
53
|
-
end
|
54
|
-
|
55
|
-
Then /^the serialized value should be: (.*)$/ do |expression|
|
56
|
-
if (@serialized_value =~ /^\{/) || (expression =~ /^\{/)
|
57
|
-
# Hash: ordering of JSON representation is unimportant; load as pure JSON and compare values
|
58
|
-
RightSupport::Data::Serializer::Encoder.load(@serialized_value).should ==
|
59
|
-
RightSupport::Data::Serializer::Encoder.load(expression)
|
60
|
-
else
|
61
|
-
# Any other data: exact comparison
|
62
|
-
@serialized_value.should == expression
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
Then /^the serialized value should round-trip cleanly$/ do
|
67
|
-
case @ruby_value
|
68
|
-
when Float
|
69
|
-
# Floating-point numbers lose some precision due to truncation
|
70
|
-
@serializer.load(@serialized_value).should be_within(0.000001).of(@ruby_value)
|
71
|
-
when Time
|
72
|
-
# Times are stored with accuracy ~ 1 sec
|
73
|
-
@serializer.load(@serialized_value).to_i.should == @ruby_value.to_i
|
74
|
-
else
|
75
|
-
# Everything else should compare identical
|
76
|
-
@serializer.load(@serialized_value).should == @ruby_value
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
Then /^the serialized value should have no invalid characters$/ do
|
81
|
-
if @serialized_value.respond_to?(:valid_encoding?)
|
82
|
-
# modern Rubies
|
83
|
-
@serialized_value.valid_encoding?.should be_true
|
84
|
-
else
|
85
|
-
# Ruby 1.8
|
86
|
-
raised = false
|
87
|
-
begin
|
88
|
-
iconv = Iconv.new('UTF-8', 'UTF-8')
|
89
|
-
iconv.iconv(@serialized_value)
|
90
|
-
rescue Exception => e
|
91
|
-
raised = true
|
92
|
-
end
|
93
|
-
|
94
|
-
raised.should be_false
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
When /^the serialized value should fail to round\-trip$/ do
|
99
|
-
@serializer.load(@serialized_value).should_not == @ruby_value
|
100
|
-
end
|
101
|
-
|
102
|
-
Then /^the serialized value should be a JSON (.*)$/ do |json_type|
|
103
|
-
case json_type
|
104
|
-
when 'object'
|
105
|
-
@serialized_value.should =~ /^\{.*\}$/
|
106
|
-
when 'string'
|
107
|
-
@serialized_value.should =~ /^".*"$/
|
108
|
-
when 'number'
|
109
|
-
@serialized_value.should =~ /^".*"$/
|
110
|
-
when 'true', 'false', 'null'
|
111
|
-
@serialized_value.should == json_type
|
112
|
-
else
|
113
|
-
raise NotImplementedError, "Unknown JSON type"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
Then /^the serialized value should have a suitable _ruby_class$/ do
|
118
|
-
@serialized_value.should =~ /"_ruby_class":"#{Regexp.escape(@ruby_value.class.name)}"/
|
119
|
-
end
|
120
|
-
|
121
|
-
Then /^the unserialized object should be an? (.*)$/ do |class_name|
|
122
|
-
klass = class_name.to_const
|
123
|
-
klass.should_not be_nil
|
124
|
-
@ruby_value.should be_a(klass)
|
125
|
-
end
|
126
|
-
|
127
|
-
Then /^the unserialized object should have a "(.*)" attribute with value: (.*)$/ do |attr, value|
|
128
|
-
attr = attr.to_sym
|
129
|
-
value = eval(value)
|
130
|
-
|
131
|
-
@ruby_value.should respond_to(attr)
|
132
|
-
@ruby_value.__send__(attr).should == value
|
133
|
-
end
|