roqua-support 0.1.34 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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