flexirest 1.13.0 → 1.13.1

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: 4953df31ca4ca1d055e7a80ce2cd7a0df8e53cc4b67544b80d1a91ee2aa366a4
4
- data.tar.gz: 0f500061fd78240f0f2c2d8c19934d5c6c5f777f32de82c8bc2330415fd6c768
3
+ metadata.gz: 152b5d789cff3ee4ccd09c6090d4f5bee5b431a96fb34797d5d189882585c235
4
+ data.tar.gz: 91c220948c05caec4b7f625d618c1b3e180272013a8dee3157bd66cbaf039bbb
5
5
  SHA512:
6
- metadata.gz: 6c45c501ef89cc34a66a66ca585088e7af146348b2c42ffd0c36fe4559a957ae4bc5f579b207b238c5d0e5a0625bb1000f937a144a2107ce3eff79272d07286a
7
- data.tar.gz: 9ea32ee11733ee70ea539d37f094fb8e9f730c82c4a14f84e5322102ab380af0c5dc12a3ac258968e8ec9a6ebd6b84ae780e54ec9a518744888c6ee62be40e7f
6
+ metadata.gz: 7440c4c8b5122e296360ece864f8ffd9ba59ae83429badd94c587ce700ecab20e823b3cff166c2623ecde5a5f5697737caf1684ac3237f5b20a63213d2dc42e0
7
+ data.tar.gz: e54a1e79e49dca9a29ed9c6d04ee43ea7a0da4943b6b873ff30d9df8377605d418a84ad391cccaad60d65102f9d43936b191bb2a5f6c4f8889ca011381e7a529
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.13.1
4
+
5
+ Bugfix:
6
+
7
+ - Ruby 4.0 removed `ostruct` from the standard library, and Flexirest builds OpenStructs internally, so it is now required explicitly and declared as a runtime dependency rather than relying on the host application to provide it
8
+ - Proxy routes with parameters (e.g. `get "/things/:id"`) no longer mutate the string they are given, so declaring one with a frozen string literal works. Previously `ProxyBase.add_mapping` built the regex with `gsub!` on the caller's string, which warns under Ruby 3.4+ chilled string literals and raises `FrozenError` under `--enable=frozen-string-literal`
9
+ - A forced URL is now duplicated before `before_request` callbacks run, so the documented `request.url.gsub!` pattern works when the URL passed to `_request` is a frozen string literal
10
+
3
11
  ## 1.13.0
4
12
 
5
13
  Bugfix:
data/Rakefile CHANGED
@@ -1,3 +1,8 @@
1
+ # IMPORTANT: bundler/setup so a bare `rake spec` runs the same suite as CI's
2
+ # `bundle exec rake`. Several specs are defined conditionally on
3
+ # Gem.loaded_specs["api-auth"], which only lists *activated* gems - without Bundler
4
+ # those guards read false and the examples silently vanish rather than fail.
5
+ require "bundler/setup"
1
6
  require "bundler/gem_tasks"
2
7
  require 'rspec/core/rake_task'
3
8
  RSpec::Core::RakeTask.new('spec')
data/flexirest.gemspec CHANGED
@@ -38,6 +38,9 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency 'rest-client'
39
39
  spec.add_development_dependency 'timecop'
40
40
 
41
+ # A default gem up to Ruby 3.4 and dropped from the stdlib in 4.0, so declare it
42
+ # rather than assume the host application provides it.
43
+ spec.add_runtime_dependency "ostruct"
41
44
  spec.add_runtime_dependency "mime-types"
42
45
  spec.add_runtime_dependency "multi_json"
43
46
  spec.add_runtime_dependency "crack"
@@ -39,11 +39,14 @@ module Flexirest
39
39
  @mappings ||= []
40
40
 
41
41
  if match.is_a?(String) && (param_keys = match.scan(/:\w+/)) && param_keys.any?
42
- param_keys.each do |key|
43
- match.gsub!(key, "([^/]+)")
44
- end
42
+ # Build the pattern from a copy rather than mutating the caller's string. A
43
+ # route is almost always declared with a string literal, and under Ruby 3.4+
44
+ # those are chilled (mutating one warns); with frozen string literals enabled
45
+ # - Ruby 4.0's --enable=frozen-string-literal, or a magic comment - the same
46
+ # mutation raises FrozenError and the proxy class fails to load.
47
+ pattern = param_keys.reduce(match.dup) { |acc, key| acc.gsub(key, "([^/]+)") }
45
48
  param_keys = param_keys.map {|k| k.gsub(":", "").to_sym}
46
- match = Regexp.new(match)
49
+ match = Regexp.new(pattern)
47
50
  end
48
51
 
49
52
  @mappings << OpenStruct.new(http_method:method_type, match:match, block:block, param_keys:param_keys)
@@ -426,7 +426,10 @@ module Flexirest
426
426
  def prepare_url
427
427
  missing = []
428
428
  if @forced_url && @forced_url.present?
429
- @url = @forced_url
429
+ # dup for the same reason as the branch below: before_request callbacks are
430
+ # documented to rewrite the URL in place with gsub!, and a forced URL is
431
+ # usually a string literal from the caller.
432
+ @url = @forced_url.dup
430
433
  else
431
434
  @url = @method[:url].dup
432
435
  matches = @url.scan(/(:[a-z_-]+)/)
@@ -1,3 +1,3 @@
1
1
  module Flexirest
2
- VERSION = "1.13.0"
2
+ VERSION = "1.13.1"
3
3
  end
data/lib/flexirest.rb CHANGED
@@ -1,3 +1,7 @@
1
+ # ostruct stopped being a default gem in Ruby 4.0, and Flexirest builds OpenStructs in
2
+ # Request and ProxyBase, so require it explicitly rather than relying on the host
3
+ # application having pulled it in.
4
+ require "ostruct"
1
5
  require 'active_support/all'
2
6
  require "flexirest/version"
3
7
  require "flexirest/attribute_parsing"
@@ -42,7 +42,11 @@ class SubClassedCallbacksExample < CallbacksExample
42
42
  end
43
43
 
44
44
  describe Flexirest::Callbacks do
45
- let(:request) { OpenStruct.new(get_params:{}, post_params:{}, url:"http://www.example.com", headers:Flexirest::HeadersList.new) }
45
+ # The unary + matters: these examples exercise callbacks rewriting the URL in place
46
+ # with gsub!, which is the documented API (docs/using-callbacks.md). A real request
47
+ # hands callbacks a mutable String, so the double has to as well - a frozen literal
48
+ # here would fail under frozen string literals for a reason the library doesn't have.
49
+ let(:request) { OpenStruct.new(get_params:{}, post_params:{}, url:+"http://www.example.com", headers:Flexirest::HeadersList.new) }
46
50
  let(:response) { OpenStruct.new(body:"") }
47
51
 
48
52
  it "should call through to adjust the parameters" do
@@ -5,6 +5,27 @@ describe Flexirest::ConnectionManager do
5
5
  Flexirest::ConnectionManager.reset!
6
6
  end
7
7
 
8
+ # IMPORTANT: The two typhoeus examples below set a *global* adapter. Reset it in an
9
+ # after hook rather than on the last line of each example: if the example raises
10
+ # first that line never runs, every later spec in the suite inherits
11
+ # adapter = :typhoeus, and they all fail with ":typhoeus is not registered on
12
+ # Faraday::Adapter". Specs run in random order, so that turns one local failure into
13
+ # a suite-wide cascade whose size depends on the seed.
14
+ after(:each) do
15
+ Flexirest::Base._reset_configuration!
16
+ end
17
+
18
+ # Gem.loaded_specs only lists gems that have been *activated*, not every gem in the
19
+ # bundle, so it is not a reliable way to ask whether faraday-typhoeus is installed -
20
+ # when it reads as absent the require is skipped and :typhoeus is never registered.
21
+ # Just attempt the require and let the older typhoeus-provided adapter be the
22
+ # fallback.
23
+ def require_typhoeus_adapter
24
+ require 'faraday/typhoeus'
25
+ rescue LoadError
26
+ require 'typhoeus/adapters/faraday'
27
+ end
28
+
8
29
  it "should have a get_connection method" do
9
30
  expect(Flexirest::ConnectionManager).to respond_to("get_connection")
10
31
  end
@@ -35,19 +56,17 @@ describe Flexirest::ConnectionManager do
35
56
  end
36
57
 
37
58
  it "should call 'in_parallel' for a session and yield procedure inside that block" do
38
- require 'faraday/typhoeus' if Gem.loaded_specs["faraday-typhoeus"].present?
59
+ require_typhoeus_adapter
39
60
  Flexirest::Base.adapter = :typhoeus
40
61
  Flexirest::ConnectionManager.get_connection("http://www.example.com").session
41
62
  expect { |b| Flexirest::ConnectionManager.in_parallel("http://www.example.com", &b)}.to yield_control
42
- Flexirest::Base._reset_configuration!
43
63
  end
44
64
 
45
65
  it "should raise Flexirest::MissingOptionalLibraryError if Typhoeus isn't available" do
46
- require 'faraday/typhoeus' if Gem.loaded_specs["faraday-typhoeus"].present?
66
+ require_typhoeus_adapter
47
67
  Flexirest::Base.adapter = :typhoeus
48
68
  Flexirest::ConnectionManager.get_connection("http://www.example.com").session
49
69
  expect(Flexirest::ConnectionManager).to receive(:require).and_raise(LoadError)
50
70
  expect { Flexirest::ConnectionManager.in_parallel("http://www.example.com")}.to raise_error(Flexirest::MissingOptionalLibraryError)
51
- Flexirest::Base._reset_configuration!
52
71
  end
53
72
  end
@@ -265,6 +265,18 @@ describe Flexirest::Base do
265
265
  expect(paths.sort).to eq(expected.sort)
266
266
  end
267
267
 
268
+ it "builds a parameterised route without mutating the string it was given" do
269
+ route = "/frozen/:id/:name".freeze
270
+ proxy = Class.new(Flexirest::ProxyBase)
271
+
272
+ expect { proxy.get(route) { passthrough } }.to_not raise_error
273
+ expect(route).to eq("/frozen/:id/:name")
274
+
275
+ mapping = proxy.instance_variable_get(:@mappings).last
276
+ expect(mapping.param_keys).to eq(%i[id name])
277
+ expect("/frozen/12/john").to match(mapping.match)
278
+ end
279
+
268
280
  it "properly passes basic HTTP auth credentials" do
269
281
  host, credentials, url_path = 'www.example.com', 'user:pass', '/getAll?id=1'
270
282
  ProxyClientExample.base_url "http://#{credentials}@#{host}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flexirest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.0
4
+ version: 1.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Jeffries
@@ -191,6 +191,20 @@ dependencies:
191
191
  - - ">="
192
192
  - !ruby/object:Gem::Version
193
193
  version: '0'
194
+ - !ruby/object:Gem::Dependency
195
+ name: ostruct
196
+ requirement: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ type: :runtime
202
+ prerelease: false
203
+ version_requirements: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
194
208
  - !ruby/object:Gem::Dependency
195
209
  name: mime-types
196
210
  requirement: !ruby/object:Gem::Requirement
@@ -405,7 +419,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
405
419
  - !ruby/object:Gem::Version
406
420
  version: '0'
407
421
  requirements: []
408
- rubygems_version: 3.6.9
422
+ rubygems_version: 4.0.10
409
423
  specification_version: 4
410
424
  summary: This gem is for accessing REST services in a flexible way. ActiveResource
411
425
  already exists for this, but it doesn't work where the resource naming doesn't follow