roqua-support 0.1.34 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76f68fbee8a7db03ddae10fbe3d141df7684d51dddf04b31ffe1928afb43c695
4
- data.tar.gz: 71b36fe4a8d228e2cde4d0650b7fddfa7cf02d32e5020ec30cc4d8249acc2b6b
3
+ metadata.gz: 3b7684543b65ccc1553042df3e832dba5f40a8f42d0ff15fa31f42d865755b32
4
+ data.tar.gz: 3ba17388d2c2b947756ddb1ca3b4172a6bcbde85bef76b0c70a5eb9fe7fe16d5
5
5
  SHA512:
6
- metadata.gz: 628059e56300c65b3414e0f66b9cf883a5994cbb9299dd0c19a08d231ebf3de4454aed75383819f4fe812801b88c5ef7c426ba9163883b2b5acd4cd665d48ef3
7
- data.tar.gz: 02f51d281d67e3c432ab4a5ba5e85ab8a7a89b7ca4851220c71400a2e444c470233c7be97c7f9f5a6f138c0907deb542ddfcb589c6c79eebff0660eea1af9f89
6
+ metadata.gz: 880ee19112ad1e4f596a451228b7b3b6f5b07ad381f0d1706ee00c42b070af2c8dd3048a26363183c09ba9ceb2f7e34c72b3289b11f8829ee0e02a613e173742
7
+ data.tar.gz: fa8da4fcb52839b129019a08f4ba852cc629af98944c9aef9add34c4ef2244ace706e59f53765b551c95da8a6231bed7a096afeb0e4dacfa7e7a1d02a5f14f17
@@ -21,6 +21,13 @@ before_script:
21
21
  paths:
22
22
  - .gems
23
23
 
24
+ .ruby_25: &ruby_25
25
+ image: registry.roqua.nl/roqua/docker-base-images:ruby-2.5
26
+ cache:
27
+ key: ruby_25
28
+ paths:
29
+ - .gems
30
+
24
31
  rails_42_ruby_23:
25
32
  <<: *ruby_23
26
33
  script:
@@ -36,6 +43,11 @@ rails_50_ruby_24:
36
43
  script:
37
44
  - bundle exec appraisal rails50 bundle exec rspec
38
45
 
46
+ rails_50_ruby_25:
47
+ <<: *ruby_25
48
+ script:
49
+ - bundle exec appraisal rails50 bundle exec rspec
50
+
39
51
  rails_51_ruby_23:
40
52
  <<: *ruby_23
41
53
  script:
@@ -46,6 +58,11 @@ rails_51_ruby_24:
46
58
  script:
47
59
  - bundle exec appraisal rails51 bundle exec rspec
48
60
 
61
+ rails_51_ruby_25:
62
+ <<: *ruby_25
63
+ script:
64
+ - bundle exec appraisal rails51 bundle exec rspec
65
+
49
66
  rails_52_ruby_23:
50
67
  <<: *ruby_23
51
68
  script:
@@ -55,3 +72,8 @@ rails_52_ruby_24:
55
72
  <<: *ruby_24
56
73
  script:
57
74
  - bundle exec appraisal rails52 bundle exec rspec
75
+
76
+ rails_52_ruby_25:
77
+ <<: *ruby_25
78
+ script:
79
+ - bundle exec appraisal rails52 bundle exec rspec
@@ -1,3 +1,12 @@
1
+ ## 0.3.0
2
+
3
+ * Support for Ruby 2.5
4
+ * Removed Fixnum#clamp, since Fixnum was deprecated and the clamp method was never used.
5
+
6
+ ## 0.2.0
7
+
8
+ * Removed Array#stable_sort_by, since it was not stable and the name was wrong.
9
+
1
10
  ## 0.1.21
2
11
 
3
12
  * Add Errors.add_parameters(add_to: 'error_report')
data/Gemfile CHANGED
@@ -9,7 +9,7 @@ gem 'roqua_styleguide', git: 'https://gitlab.roqua.nl/roqua/styleguide.git'
9
9
  group :test do
10
10
  gem 'actionpack', '>= 4.0'
11
11
  gem 'active_interaction', '~> 3.0'
12
- gem 'appsignal'
12
+ gem 'appsignal', '~> 2.9.6'
13
13
  gem 'climate_control' # For ENV modification in specs
14
14
  gem 'combustion', '~> 0.5.2'
15
15
  gem 'fakefs', require: 'fakefs/safe'
@@ -8,7 +8,7 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- roqua-support (0.1.33)
11
+ roqua-support (0.3.0)
12
12
  active_interaction (~> 3.0)
13
13
  activesupport (>= 3.2, < 6)
14
14
  naught (~> 1.0)
@@ -47,7 +47,7 @@ GEM
47
47
  bundler
48
48
  rake
49
49
  thor (>= 0.14.0)
50
- appsignal (2.3.1)
50
+ appsignal (2.9.6)
51
51
  rack
52
52
  arel (7.1.4)
53
53
  ast (2.3.0)
@@ -181,7 +181,7 @@ DEPENDENCIES
181
181
  actionpack (>= 4.0)
182
182
  active_interaction (~> 3.0)
183
183
  appraisal
184
- appsignal
184
+ appsignal (~> 2.9.6)
185
185
  bundler (~> 1.0)
186
186
  climate_control
187
187
  combustion (~> 0.5.2)
@@ -195,8 +195,8 @@ DEPENDENCIES
195
195
  rspec (>= 2.12.0, < 4.0)
196
196
  rspec-instrumentation-matcher
197
197
  rspec-rails
198
- sqlite3
198
+ sqlite3 (~> 1.3.6)
199
199
  timecop
200
200
 
201
201
  BUNDLED WITH
202
- 1.16.4
202
+ 1.16.6
@@ -1,5 +1,5 @@
1
1
  module Roqua
2
2
  module Support
3
- VERSION = '0.1.34'.freeze
3
+ VERSION = '0.3.0'.freeze
4
4
  end
5
5
  end
@@ -1,4 +1,3 @@
1
-
2
1
  class RoquaLoggingRailtie < Rails::Railtie
3
2
  config.after_initialize do |app|
4
3
  RoquaLoggingRailtie.configure
@@ -3,7 +3,8 @@ module Roqua
3
3
  module BaseProbe
4
4
  def enable
5
5
  new.tap do |probe|
6
- Appsignal::Minutely.probes << probe unless Appsignal::Minutely.probes.map(&:class).include?(probe.class)
6
+ probe_sym = probe.class.to_s.to_sym
7
+ Appsignal::Minutely.probes.register(probe_sym, probe) unless Appsignal::Minutely.probes[probe_sym]
7
8
  end
8
9
  end
9
10
  end
@@ -1,5 +1,5 @@
1
1
  require 'logger'
2
- require 'roqua/logging/roqua_logging_railtie'
2
+ require 'roqua/logging/roqua_logging_railtie' if defined?(Rails)
3
3
  require 'roqua/support/instrumentation'
4
4
  require 'roqua/support/log_wrapper'
5
5
  require 'roqua/support/errors'
@@ -62,7 +62,6 @@ module Roqua
62
62
  parameters: parameters}
63
63
  exception_info[:notification_urls] = notification_urls if notification_urls.present?
64
64
  exception_info[:backtrace] = exception.backtrace unless skip_backtrace
65
- puts exception_info.inspect
66
65
  Roqua.logger.error('roqua.exception', exception_info)
67
66
  end
68
67
  rescue Exception
@@ -28,6 +28,6 @@ Gem::Specification.new do |gem|
28
28
  gem.add_development_dependency 'delayed_job_active_record'
29
29
  gem.add_development_dependency 'rake'
30
30
  gem.add_development_dependency 'rspec', '>= 2.12.0', '< 4.0'
31
- gem.add_development_dependency 'sqlite3'
31
+ gem.add_development_dependency 'sqlite3', '~> 1.3.6'
32
32
  gem.add_development_dependency 'timecop'
33
33
  end
@@ -2,20 +2,17 @@ require 'roqua/core_ext/enumerable/sort_by_alphanum'
2
2
 
3
3
  describe Enumerable do
4
4
  describe '#sort_by_alphanum' do
5
+ let(:input) { ["004some11thing", "004some10thing", "3another"] }
5
6
  it 'sorts by chunks' do
6
- ["004some11thing",
7
- "004some10thing",
8
- "3another"].sort_by_alphanum.should == ["3another", "004some10thing", "004some11thing"]
7
+ expect(input.sort_by_alphanum).to eq ["3another", "004some10thing", "004some11thing"]
9
8
  end
10
9
 
11
10
  it 'can take a block which can transform values before comparison' do
12
- ["004some11thing",
13
- "004some10thing",
14
- "3another"].sort_by_alphanum(&:reverse).should == ["004some10thing", "004some11thing", "3another"]
11
+ expect(input.sort_by_alphanum(&:reverse)).to eq ["004some10thing", "004some11thing", "3another"]
15
12
  end
16
13
 
17
14
  it 'compares number chunks as integers' do
18
- %w(004 3).sort_by_alphanum.should == %w(3 004)
15
+ expect(%w(004 3).sort_by_alphanum).to eq %w(3 004)
19
16
  end
20
17
  end
21
- end
18
+ end
@@ -6,11 +6,13 @@ end
6
6
 
7
7
  describe Fabricate do
8
8
  it "returns singleton objects" do
9
- Fabricate.singleton(:one).should == Fabricate.singleton(:one)
9
+ # Fabricate.singleton(:one).should == Fabricate.singleton(:one)
10
+ expect(Fabricate.singleton(:one)).to eq Fabricate.singleton(:one)
10
11
  end
11
12
 
12
13
  it 'maintains multiple singletons' do
13
- Fabricate.singleton(:one).should_not == Fabricate.singleton(:two)
14
+ # Fabricate.singleton(:one).should_not == Fabricate.singleton(:two)
15
+ expect(Fabricate.singleton(:one)).not_to eq Fabricate.singleton(:two)
14
16
  end
15
17
 
16
18
  it 'clears singletons' do
@@ -19,4 +21,3 @@ describe Fabricate do
19
21
  expect(Fabricate.singleton(:one)).not_to eq(the_one)
20
22
  end
21
23
  end
22
-
@@ -40,7 +40,7 @@ describe Roqua::Probes::DelayedJobProbe do
40
40
  expect { Roqua::Probes::DelayedJobProbe.enable }
41
41
  .to change { Appsignal::Minutely.probes.count }.by(1)
42
42
 
43
- expect(Appsignal::Minutely.probes.map(&:class)).to include(Roqua::Probes::DelayedJobProbe)
43
+ expect(Appsignal::Minutely.probes[:"Roqua::Probes::DelayedJobProbe"]).to be
44
44
  end
45
45
 
46
46
  it 'will not add the same probe twice if called multiple times' do
@@ -23,7 +23,7 @@ describe 'Helper methods' do
23
23
  end
24
24
 
25
25
  it 'returns the value returned by the block' do
26
- with_instrumentation('testevent') { 1 + 1 }.should == 2
26
+ expect(with_instrumentation('testevent') { 1 + 1 }).to eq 2
27
27
  end
28
28
  end
29
29
 
@@ -4,7 +4,7 @@ require 'stringio'
4
4
 
5
5
  module Roqua
6
6
  describe LogWrapper do
7
- before { Roqua.stub(appname: 'roqua-support-testsuite') }
7
+ before { allow(Roqua).to receive(:appname).and_return('roqua-support-testsuite') }
8
8
 
9
9
  let(:logstream) { StringIO.new }
10
10
  let(:logger) { Logger.new(logstream) }
@@ -17,17 +17,17 @@ module Roqua
17
17
  describe '#add' do
18
18
  it 'writes event name to log' do
19
19
  logwrapper.add :info, "testevent"
20
- log.should include("testevent {}\n")
20
+ expect(log).to include("testevent {}\n")
21
21
  end
22
22
 
23
23
  it 'writes given parameters as json hash' do
24
24
  logwrapper.add :info, "testevent", extra: 'params', go: 'here'
25
- log.should include('testevent {"extra":"params","go":"here"}' + "\n")
25
+ expect(log).to include('testevent {"extra":"params","go":"here"}' + "\n")
26
26
  end
27
27
 
28
28
  it 'escapes newline characters in params' do
29
29
  logwrapper.add :info, "testevent", param: "this\nshould not have newlines"
30
- log.should include('testevent {"param":"this\nshould not have newlines"')
30
+ expect(log).to include('testevent {"param":"this\nshould not have newlines"')
31
31
  end
32
32
  end
33
33
 
@@ -36,25 +36,25 @@ module Roqua
36
36
  logwrapper.lifecycle 'testevent', extra: 'params' do
37
37
  1 + 1
38
38
  end
39
- log.should include('testevent:started {"extra":"params"}')
40
- log.should match(/testevent:finished.*"extra":"params"/)
39
+ expect(log).to include('testevent:started {"extra":"params"}')
40
+ expect(log).to match(/testevent:finished.*"extra":"params"/)
41
41
  end
42
42
 
43
43
  it 'logs the duration of the block with the finished event' do
44
44
  logwrapper.lifecycle('testevent') { 1 + 1 }
45
- log.should match(/testevent:finished.*"duration":/)
45
+ expect(log).to match(/testevent:finished.*"duration":/)
46
46
  end
47
47
 
48
48
  it 'returns the value returned by the block' do
49
- logwrapper.lifecycle('testevent') { 1 + 1 }.should == 2
49
+ expect(logwrapper.lifecycle('testevent') { 1 + 1 }).to eq 2
50
50
  end
51
51
 
52
52
  it 'logs the start and failure of a block if it raises' do
53
53
  logwrapper.lifecycle 'testevent' do
54
54
  raise StandardError, "Foo"
55
55
  end rescue nil
56
- log.should include('testevent:started')
57
- log.should include('testevent:failed {"exception":"StandardError","message":"Foo"}')
56
+ expect(log).to include('testevent:started')
57
+ expect(log).to include('testevent:failed {"exception":"StandardError","message":"Foo"}')
58
58
  end
59
59
 
60
60
  it 'reraises the exception' do
@@ -8,7 +8,8 @@ describe Roqua::Support::RequestLogger do
8
8
  let(:logger) { Logger.new(logstream) }
9
9
  let(:logwrapper) { Roqua::LogWrapper.new(logger) }
10
10
 
11
- before { Roqua.stub(logger: logwrapper) }
11
+ # before { Roqua.stub(logger: logwrapper) }
12
+ before { allow(Roqua).to receive(:logger).and_return(logwrapper) }
12
13
 
13
14
  def log
14
15
  logstream.string
@@ -29,47 +30,47 @@ describe Roqua::Support::RequestLogger do
29
30
 
30
31
  it "logs the URL" do
31
32
  subscriber.process_action(event)
32
- logstream.string.should include('/home')
33
+ expect(logstream.string).to include('/home')
33
34
  end
34
35
 
35
36
  it "does not log the query string" do
36
37
  subscriber.process_action(event)
37
- logstream.string.should_not include('?foo=bar')
38
+ expect(logstream.string).to_not include('?foo=bar')
38
39
  end
39
40
 
40
41
  it "logs the HTTP method" do
41
42
  subscriber.process_action(event)
42
- logstream.string.should include('"method":"GET"')
43
+ expect(logstream.string).to include('"method":"GET"')
43
44
  end
44
45
 
45
46
  it "logs the status code returned" do
46
47
  subscriber.process_action(event)
47
- logstream.string.should include('"status":200')
48
+ expect(logstream.string).to include('"status":200')
48
49
  end
49
50
 
50
51
  it "logs the controller and action" do
51
52
  subscriber.process_action(event)
52
- logstream.string.should include('"controller":"home","action":"index"')
53
+ expect(logstream.string).to include('"controller":"home","action":"index"')
53
54
  end
54
55
 
55
56
  it 'logs request parameters' do
56
57
  subscriber.process_action(event)
57
- logstream.string.should include('"params":{"foo":"bar"}')
58
+ expect(logstream.string).to include('"params":{"foo":"bar"}')
58
59
  end
59
60
 
60
61
  it "logs how long the request took" do
61
62
  subscriber.process_action(event)
62
- logstream.string.should =~ /"duration":1000.0/
63
+ expect(logstream.string).to match /"duration":1000.0/
63
64
  end
64
65
 
65
66
  it "logs the view rendering time" do
66
67
  subscriber.process_action(event)
67
- logstream.string.should =~ /"view":0.01/
68
+ expect(logstream.string).to match /"view":0.01/
68
69
  end
69
70
 
70
71
  it "logs the database rendering time" do
71
72
  subscriber.process_action(event)
72
- logstream.string.should =~ /"db":0.02/
73
+ expect(logstream.string).to match /"db":0.02/
73
74
  end
74
75
 
75
76
  it 'logs extra information added in the controller' do
@@ -82,12 +83,12 @@ describe Roqua::Support::RequestLogger do
82
83
  end
83
84
  controller.new.index
84
85
  subscriber.process_action(event)
85
- logstream.string.should include('"current_user":"johndoe"')
86
+ expect(logstream.string).to include('"current_user":"johndoe"')
86
87
 
87
88
  # next request should not still maintain this data
88
89
  logstream.truncate 0
89
90
  subscriber.process_action(event)
90
- logstream.string.should_not include('current_user')
91
+ expect(logstream.string).to_not include('current_user')
91
92
  end
92
93
  end
93
94
 
@@ -104,15 +105,15 @@ describe Roqua::Support::RequestLogger do
104
105
 
105
106
  it "logs the 500 status when an exception occurred" do
106
107
  subscriber.process_action(event)
107
- logstream.string.should =~ /"status":500/
108
- logstream.string.should =~ /"error":"AbstractController::ActionNotFound:Route not found"/
108
+ expect(logstream.string).to match /"status":500/
109
+ expect(logstream.string).to match /"error":"AbstractController::ActionNotFound:Route not found"/
109
110
  end
110
111
 
111
112
  it "should return an unknown status when no status or exception is found" do
112
113
  event.payload[:status] = nil
113
114
  event.payload[:exception] = nil
114
115
  subscriber.process_action(event)
115
- logstream.string.should =~ /"status":0/
116
+ expect(logstream.string).to match /"status":0/
116
117
  end
117
118
  end
118
119
 
@@ -136,12 +137,12 @@ describe Roqua::Support::RequestLogger do
136
137
  it 'logs the redirect' do
137
138
  subscriber.redirect_to(redirect)
138
139
  subscriber.process_action(event)
139
- log.should include('"location":"http://example.com"')
140
+ expect(log).to include('"location":"http://example.com"')
140
141
 
141
142
  # next request should no longer get location
142
143
  logstream.truncate 0
143
144
  subscriber.process_action(event)
144
- log.should_not include('location')
145
+ expect(log).to_not include('location')
145
146
  end
146
147
  end
147
148
  end
@@ -3,7 +3,7 @@ require 'roqua/support'
3
3
  describe Roqua do
4
4
  describe '#logger' do
5
5
  it 'has a default' do
6
- Roqua.logger.should be_an_instance_of(Roqua::LogWrapper)
6
+ expect(Roqua.logger).to be_an_instance_of(Roqua::LogWrapper)
7
7
  end
8
8
  end
9
9
 
@@ -12,8 +12,8 @@ describe Roqua do
12
12
 
13
13
  it 'wraps a given logger' do
14
14
  Roqua.logger = logger
15
- Roqua.logger.should be_an_instance_of(Roqua::LogWrapper)
16
- Roqua.logger.logger.should == logger
15
+ expect(Roqua.logger).to be_an_instance_of(Roqua::LogWrapper)
16
+ expect(Roqua.logger.logger).to eq logger
17
17
  end
18
18
  end
19
19
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roqua-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.34
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marten Veldthuis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-16 00:00:00.000000000 Z
11
+ date: 2019-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_interaction
@@ -152,16 +152,16 @@ dependencies:
152
152
  name: sqlite3
153
153
  requirement: !ruby/object:Gem::Requirement
154
154
  requirements:
155
- - - ">="
155
+ - - "~>"
156
156
  - !ruby/object:Gem::Version
157
- version: '0'
157
+ version: 1.3.6
158
158
  type: :development
159
159
  prerelease: false
160
160
  version_requirements: !ruby/object:Gem::Requirement
161
161
  requirements:
162
- - - ">="
162
+ - - "~>"
163
163
  - !ruby/object:Gem::Version
164
- version: '0'
164
+ version: 1.3.6
165
165
  - !ruby/object:Gem::Dependency
166
166
  name: timecop
167
167
  requirement: !ruby/object:Gem::Requirement
@@ -207,11 +207,9 @@ files:
207
207
  - lib/roqua/core_ext/active_interaction/filters/duration_filter.rb
208
208
  - lib/roqua/core_ext/active_interaction/rails_instrumentation.rb
209
209
  - lib/roqua/core_ext/activerecord/uniq_find_or_create.rb
210
- - lib/roqua/core_ext/array/stable_sort_by.rb
211
210
  - lib/roqua/core_ext/delayed_job/activity_monitoring.rb
212
211
  - lib/roqua/core_ext/enumerable/sort_by_alphanum.rb
213
212
  - lib/roqua/core_ext/fabrication/singleton.rb
214
- - lib/roqua/core_ext/fixnum/clamp.rb
215
213
  - lib/roqua/logging/roqua_logging_railtie.rb
216
214
  - lib/roqua/probes/base_probe.rb
217
215
  - lib/roqua/probes/delayed_job_probe.rb
@@ -243,11 +241,9 @@ files:
243
241
  - spec/roqua/core_ext/active_interaction/duration_filter_spec.rb
244
242
  - spec/roqua/core_ext/active_interaction/rails_intrumentation_spec.rb
245
243
  - spec/roqua/core_ext/activerecord/uniq_find_or_create_spec.rb
246
- - spec/roqua/core_ext/array/stable_sort_by_spec.rb
247
244
  - spec/roqua/core_ext/delayed_job/activity_monitoring_spec.rb
248
245
  - spec/roqua/core_ext/enumerable/sort_by_alphanum_spec.rb
249
246
  - spec/roqua/core_ext/fabrication/singleton_spec.rb
250
- - spec/roqua/core_ext/fixnum/clamp_spec.rb
251
247
  - spec/roqua/logging/roqua_logging_railtie_spec.rb
252
248
  - spec/roqua/probes/delayed_job_probe_spec.rb
253
249
  - spec/roqua/probes/monitoring_probe_spec.rb
@@ -286,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
286
282
  version: '0'
287
283
  requirements: []
288
284
  rubyforge_project:
289
- rubygems_version: 2.7.6
285
+ rubygems_version: 2.7.9
290
286
  signing_key:
291
287
  specification_version: 4
292
288
  summary: Helper objects and proxies used by a lot of RoQua applications
@@ -297,11 +293,9 @@ test_files:
297
293
  - spec/roqua/core_ext/active_interaction/duration_filter_spec.rb
298
294
  - spec/roqua/core_ext/active_interaction/rails_intrumentation_spec.rb
299
295
  - spec/roqua/core_ext/activerecord/uniq_find_or_create_spec.rb
300
- - spec/roqua/core_ext/array/stable_sort_by_spec.rb
301
296
  - spec/roqua/core_ext/delayed_job/activity_monitoring_spec.rb
302
297
  - spec/roqua/core_ext/enumerable/sort_by_alphanum_spec.rb
303
298
  - spec/roqua/core_ext/fabrication/singleton_spec.rb
304
- - spec/roqua/core_ext/fixnum/clamp_spec.rb
305
299
  - spec/roqua/logging/roqua_logging_railtie_spec.rb
306
300
  - spec/roqua/probes/delayed_job_probe_spec.rb
307
301
  - spec/roqua/probes/monitoring_probe_spec.rb
@@ -1,37 +0,0 @@
1
- class Array
2
- # Method for stably sorting elements in an array on multiple attributes.
3
- #
4
- # * Pass the method a block with two arrays containing the attributes for which the
5
- # elements should be subsequently sorted. The first attribute is applied last.
6
- # If for some attribute the sort order should be reversed, the parameters x and y can
7
- # be exchanged between the arrays.
8
- #
9
- # ==== Example
10
- # my_array.stable_sort_by{|x, y| [
11
- # x.attribute1,
12
- # y.attribute2,
13
- # y.attribute3,
14
- # y.attribute4
15
- # ] <=> [
16
- # y.attribute1,
17
- # x.attribute2,
18
- # x.attribute3,
19
- # x.attribute4
20
- # ]}
21
- #
22
- def stable_sort_by
23
- sort do |x, y|
24
- if not x
25
- -1
26
- elsif not y
27
- 1
28
- else
29
- if block_given?
30
- yield x, y
31
- else
32
- x <=> y
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,8 +0,0 @@
1
- class Fixnum
2
- def clamp(low, high)
3
- raise "Low (#{low}) must be lower than high (#{high})" unless low < high
4
- return low if self < low
5
- return high if self > high
6
- self
7
- end
8
- end
@@ -1,40 +0,0 @@
1
- require 'roqua/core_ext/array/stable_sort_by'
2
-
3
- describe Array do
4
- describe "#stable_sort_by" do
5
- it "wraps #sort" do
6
- array = []
7
- array.should_receive(:sort)
8
- array.stable_sort_by
9
- end
10
-
11
- it "sorts nil values before all others" do
12
- [1, nil, 3].stable_sort_by.should == [nil, 1, 3]
13
- end
14
-
15
- it "defaults to regular comparison" do
16
- [1, 3, 2].stable_sort_by.should == [1, 2, 3]
17
- end
18
-
19
- it "accepts a block to do complex comparison" do
20
- [{a: 2, b: 2, c: 3},
21
- {a: 2, b: 2, c: 4},
22
- {a: 1, b: 1, c: 6}].stable_sort_by do |x, y|
23
- [x[:a], x[:b], x[:c]] <=> [y[:a], y[:b], y[:c]]
24
- end.should == [{a: 1, b: 1, c: 6},
25
- {a: 2, b: 2, c: 3},
26
- {a: 2, b: 2, c: 4}]
27
- end
28
-
29
- it "leaves items in original order if they are the same" do
30
- [{a: 2, b: 2, c: 4},
31
- {a: 2, b: 1, c: 3},
32
- {a: 1, b: 3, c: 6}].sort do |x, y|
33
- [x[:a], x[:b]] <=> [y[:a], y[:b]]
34
- end.should == [{a: 1, b: 3, c: 6},
35
- {a: 2, b: 1, c: 3},
36
- {a: 2, b: 2, c: 4}]
37
-
38
- end
39
- end
40
- end
@@ -1,23 +0,0 @@
1
- require 'roqua/core_ext/fixnum/clamp'
2
-
3
- describe Fixnum do
4
- describe '#clamp' do
5
- it "returns self if within bounds" do
6
- 5.clamp(1,10).should == 5
7
- end
8
-
9
- it "returns the lower bound if self < low" do
10
- 5.clamp(8,10).should == 8
11
- end
12
-
13
- it "returns the upper bound if self > high" do
14
- 5.clamp(1,3).should == 3
15
- end
16
-
17
- it "should raise an exception if the lower bound is greater than the upper bound" do
18
- expect {
19
- 5.clamp(10,1)
20
- }.to raise_error
21
- end
22
- end
23
- end