client-api-builder 0.5.5 → 0.6.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: 7ba2a10bca8dbdf440a037007da9858446a7c1b165575d49510e7ed37d9d53d6
4
- data.tar.gz: aeb66f9fbfeeefb4d946975641dba14002706ac07117dcaca5d41d89dbf10a7d
3
+ metadata.gz: ae35befd024cba590ae2f644877243c536612ef9ce0e66c6c7c69f2481a7fc20
4
+ data.tar.gz: cd843e5f96ed9a63f9fb4012ab94b7ebe7b8bd443fa2cec35fe04e1bf50e0806
5
5
  SHA512:
6
- metadata.gz: a346879ca1a8dac4f6c849c68fb3c2553bdb298e490a0c5da6f38768d0a18f858d08c21ddbf119bff2975f5023d38592711292240437c721e111caa7023ec5bb
7
- data.tar.gz: 4f0faf034b9749c59cdb2c1d79adf7109e1bcd8ed1b85a1ffa189622a793d34d0f26df0c4e3a5f674700831c28f1ded0f40c8f9765657cc457e9da10b4f374e1
6
+ metadata.gz: a97833f34c6dde60bc8edbe9d38180e6f2904884ceb5b85a38e43358856e6e9c95f57e06f4356c0a10fe50d33801513e89132b452482bd689abf610a9ac53894
7
+ data.tar.gz: 9686a7f14ed8144f3e310cddf9abdf0681bfd237149397adba9d1376ca5d47a106530e099e165d22264bd7178b663e026a9e0658a2e95ef6a9b1fb1c3beb874e
data/.cursor.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "rules": [
3
+ {
4
+ "name": "Ruby spec file",
5
+ "pattern": "^lib/(.+)\\.rb$",
6
+ "target": "spec/${1}_spec.rb"
7
+ },
8
+ {
9
+ "name": "Ruby implementation file",
10
+ "pattern": "^spec/(.+)_spec\\.rb$",
11
+ "target": "lib/${1}.rb"
12
+ },
13
+ {
14
+ "name": "Related client_api_builder files",
15
+ "pattern": "^(?:lib|spec)/client_api_builder/(.+)\\.rb$",
16
+ "related": [
17
+ "lib/client_api_builder/${1}.rb",
18
+ "spec/client_api_builder/${1}_spec.rb"
19
+ ]
20
+ },
21
+ {
22
+ "name": "Main library file",
23
+ "pattern": "^(?:lib|spec)/client_api_builder/.+\\.rb$",
24
+ "related": [
25
+ "lib/client-api-builder.rb"
26
+ ]
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,53 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ lint:
11
+ name: RuboCop
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Ruby
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: '3.4'
20
+ bundler-cache: true
21
+
22
+ - name: Run RuboCop
23
+ run: bundle exec rubocop --format github
24
+
25
+ test:
26
+ name: Tests (Ruby ${{ matrix.ruby }})
27
+ runs-on: ubuntu-latest
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ ruby: ['3.2', '3.3', '3.4']
32
+
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+
36
+ - name: Set up Ruby ${{ matrix.ruby }}
37
+ uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby }}
40
+ bundler-cache: true
41
+
42
+ - name: Run tests
43
+ run: bundle exec rspec
44
+
45
+ - name: Upload coverage to Codecov
46
+ if: matrix.ruby == '3.4'
47
+ uses: codecov/codecov-action@v4
48
+ with:
49
+ files: coverage/coverage.xml
50
+ fail_ci_if_error: false
51
+ verbose: true
52
+ env:
53
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
data/.rubocop.yml ADDED
@@ -0,0 +1,79 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.2
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+ Exclude:
6
+ - 'bin/**/*'
7
+ - 'vendor/**/*'
8
+ - 'coverage/**/*'
9
+
10
+ # Relaxed metrics for existing codebase
11
+ Metrics/MethodLength:
12
+ Max: 100
13
+
14
+ Metrics/AbcSize:
15
+ Max: 80
16
+
17
+ Metrics/ClassLength:
18
+ Max: 200
19
+
20
+ Metrics/ModuleLength:
21
+ Max: 320
22
+
23
+ Metrics/CyclomaticComplexity:
24
+ Max: 30
25
+
26
+ Metrics/PerceivedComplexity:
27
+ Max: 30
28
+
29
+ Metrics/BlockLength:
30
+ Exclude:
31
+ - 'spec/**/*'
32
+ - '*.gemspec'
33
+
34
+ Metrics/ParameterLists:
35
+ Max: 7
36
+
37
+ # Style preferences
38
+ Style/Documentation:
39
+ Enabled: false
40
+
41
+ Style/FrozenStringLiteralComment:
42
+ EnforcedStyle: always
43
+
44
+ Layout/LineLength:
45
+ Max: 170
46
+ Exclude:
47
+ - 'spec/**/*'
48
+
49
+ # File naming - allow hyphenated gem name
50
+ Naming/FileName:
51
+ Exclude:
52
+ - 'lib/client-api-builder.rb'
53
+
54
+ # Allow short parameter names for unused exception variables
55
+ Naming/MethodParameterName:
56
+ AllowedNames:
57
+ - e
58
+ - _e
59
+ - io
60
+
61
+ # Gemspec settings
62
+ Gemspec/RequiredRubyVersion:
63
+ Enabled: false
64
+
65
+ # Style relaxations for existing code patterns
66
+ Style/OptionalBooleanParameter:
67
+ Enabled: false
68
+
69
+ Style/StringConcatenation:
70
+ Enabled: false
71
+
72
+ Style/FormatStringToken:
73
+ Enabled: false
74
+
75
+ # Note: Previously had exclusions for Style/ClassVars, Style/PerlBackrefs, and
76
+ # Lint/RescueException in router.rb - these have been fixed:
77
+ # - ClassVars: Changed to thread-local storage
78
+ # - PerlBackrefs: Changed to Regexp.last_match
79
+ # - RescueException: Changed to StandardError
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.1.0
1
+ 3.4.2
data/ARCHITECTURE.md ADDED
@@ -0,0 +1,223 @@
1
+ # Client API Builder Architecture
2
+
3
+ This document describes the internal architecture and design of the Client API Builder gem.
4
+
5
+ ## Overview
6
+
7
+ Client API Builder is a Ruby gem that provides a declarative way to create API clients. It uses a modular architecture with several key components working together to provide a flexible and extensible API client framework.
8
+
9
+ ## File Structure
10
+
11
+ ```
12
+ lib/
13
+ ├── client-api-builder.rb # Main entry point, autoloads, error classes
14
+ └── client_api_builder/
15
+ ├── router.rb # Core Router module with route DSL
16
+ ├── nested_router.rb # NestedRouter class for hierarchical APIs
17
+ ├── section.rb # Section module for creating nested routers
18
+ ├── net_http_request.rb # Net::HTTP request execution and streaming
19
+ ├── query_params.rb # Custom query parameter builder
20
+ ├── active_support_notifications.rb # ActiveSupport instrumentation
21
+ └── active_support_log_subscriber.rb # ActiveSupport logging
22
+ ```
23
+
24
+ ## Core Components
25
+
26
+ ### 1. Router Module (`ClientApiBuilder::Router`)
27
+
28
+ The `Router` module is the core component that provides the main functionality for defining and executing API requests.
29
+
30
+ **Class Methods** (defined in `ClassMethods`):
31
+ - `base_url`: Sets the base URL for all requests
32
+ - `header`: Adds headers to requests (supports values, symbols, or procs)
33
+ - `route`: Defines API endpoints with dynamic method generation
34
+ - `body_builder`: Configures request body formatting (`:to_json`, `:to_query`, `:query_params`, or custom)
35
+ - `query_builder`: Configures query parameter formatting
36
+ - `query_param`: Adds query parameters to all requests
37
+ - `connection_option`: Sets Net::HTTP connection options
38
+ - `configure_retries`: Sets retry behavior (max_retries, sleep time)
39
+ - `namespace`: Groups routes under a common path prefix
40
+
41
+ **Instance Methods**:
42
+ - `build_headers`: Constructs request headers, evaluating procs/symbols
43
+ - `build_connection_options`: Merges default and request-specific options
44
+ - `build_query`: Formats query parameters using configured builder
45
+ - `build_body`: Formats request body using configured builder
46
+ - `build_uri`: Constructs full URI with base_url, path, and query
47
+ - `handle_response`: Processes API responses, parses JSON by default
48
+ - `request_wrapper`: Manages request execution with retry and instrumentation
49
+ - `root_router`: Returns self (overridden in NestedRouter)
50
+
51
+ **Instance Attributes** (via `attr_reader`):
52
+ - `response`: The last Net::HTTP response object
53
+ - `request_options`: Hash of method, uri, body, headers, connection_options
54
+ - `total_request_time`: Duration of last request in seconds
55
+ - `request_attempts`: Number of attempts for last request
56
+
57
+ ### 2. Route Code Generation
58
+
59
+ The `route` class method dynamically generates two methods per endpoint using `generate_route_code`:
60
+
61
+ ```ruby
62
+ route :get_user, '/users/:id', expected_response_code: 200
63
+ ```
64
+
65
+ Generates:
66
+ - `get_user_raw_response(id:, **options, &block)` - Makes HTTP request, sets `@response` and `@request_options`
67
+ - `get_user(id:, **options, &block)` - Wraps raw_response with retry logic, response code validation, and response handling
68
+
69
+ **Path Parameters**: Extracted from `:param` or `{param}` syntax in path
70
+ **Body/Query Parameters**: Extracted from `body:` and `query:` options using symbol values
71
+
72
+ ### 3. HTTP Method Auto-Detection
73
+
74
+ When `method:` is not specified in route options, `auto_detect_http_method` infers it from the method name:
75
+
76
+ | Prefix Pattern | HTTP Method |
77
+ |---------------|-------------|
78
+ | `post`, `create`, `add`, `insert` | POST |
79
+ | `put`, `update`, `modify`, `change` | PUT |
80
+ | `patch` | PATCH |
81
+ | `delete`, `remove` | DELETE |
82
+ | (default) | GET |
83
+
84
+ ### 4. Nested Router (`ClientApiBuilder::NestedRouter`)
85
+
86
+ Enables hierarchical API client organization:
87
+
88
+ ```ruby
89
+ section :users do
90
+ route :list, '/'
91
+ route :get, '/:id'
92
+ end
93
+ # Usage: client.users.get(id: 123)
94
+ ```
95
+
96
+ Key behaviors:
97
+ - Includes `ClientApiBuilder::Router` module
98
+ - Stores `root_router` reference to access shared state
99
+ - Stores `nested_router_options` passed from section definition
100
+ - Overrides `base_url` to fall back to root_router's base_url
101
+ - Delegates `handle_response` to root_router
102
+ - Overrides `get_instance_method` to access root_router's instance variables in paths
103
+
104
+ ### 5. Section Module (`ClientApiBuilder::Section`)
105
+
106
+ Creates nested routers dynamically using `InheritanceHelper::ClassBuilder::Utils.create_class`:
107
+
108
+ ```ruby
109
+ def section(name, nested_router_options={}, &block)
110
+ # Creates: MyClient::UsersNestedRouter < ClientApiBuilder::NestedRouter
111
+ # Defines: MyClient.users_router (class method)
112
+ # Defines: MyClient#users (instance method, memoized)
113
+ end
114
+ ```
115
+
116
+ ### 6. NetHTTP::Request Module
117
+
118
+ Provides HTTP request execution using Net::HTTP:
119
+
120
+ **Methods**:
121
+ - `request(method:, uri:, body:, headers:, connection_options:)` - Standard request with optional block
122
+ - `stream(...)` - Streams response body in chunks via `read_body`
123
+ - `stream_to_io(..., io:)` - Writes streamed chunks to an IO object
124
+ - `stream_to_file(..., file:)` - Opens file and streams to it
125
+
126
+ **Supported HTTP Methods** (via `METHOD_TO_NET_HTTP_CLASS`):
127
+ `copy`, `delete`, `get`, `head`, `lock`, `mkcol`, `move`, `options`, `patch`, `post`, `propfind`, `proppatch`, `put`, `trace`, `unlock`
128
+
129
+ ### 7. QueryParams Class
130
+
131
+ Standalone query parameter builder (used when ActiveSupport unavailable):
132
+
133
+ - Handles nested hashes with bracket notation: `user[name]=John`
134
+ - Handles arrays: `ids[]=1&ids[]=2`
135
+ - Configurable separators: `name_value_separator` (default `=`), `param_separator` (default `&`)
136
+ - Supports custom escape proc
137
+
138
+ ### 8. ActiveSupport Integration
139
+
140
+ **ActiveSupportNotifications** (conditionally included when ActiveSupport defined):
141
+ - Overrides `instrument_request` to use `ActiveSupport::Notifications.instrument`
142
+ - Event name: `client_api_builder.request`
143
+ - Payload includes `client: self`
144
+
145
+ **ActiveSupportLogSubscriber**:
146
+ - Subscribes to `client_api_builder.request` events for logging
147
+
148
+ ## Design Patterns
149
+
150
+ ### Module Inclusion Pattern
151
+
152
+ ```ruby
153
+ module ClientApiBuilder
154
+ module Router
155
+ def self.included(base)
156
+ base.extend InheritanceHelper::Methods
157
+ base.extend ClassMethods
158
+ base.include ::ClientApiBuilder::Section
159
+ base.include ::ClientApiBuilder::NetHTTP::Request
160
+ base.include(::ClientApiBuilder::ActiveSupportNotifications) if defined?(ActiveSupport)
161
+ base.send(:attr_reader, :response, :request_options, :total_request_time, :request_attempts)
162
+ end
163
+ end
164
+ end
165
+ ```
166
+
167
+ ### Builder Pattern
168
+
169
+ Request components built separately then combined:
170
+ ```ruby
171
+ __uri__ = build_uri(__path__, __query__, __options__)
172
+ __body__ = build_body(__body__, __options__)
173
+ __headers__ = build_headers(__options__)
174
+ __connection_options__ = build_connection_options(__options__)
175
+ ```
176
+
177
+ ### Configuration Inheritance
178
+
179
+ Uses `inheritance-helper` gem's `add_value_to_class_method` for configuration that properly inherits to subclasses:
180
+ ```ruby
181
+ def base_url(url = nil)
182
+ return default_options[:base_url] unless url
183
+ add_value_to_class_method(:default_options, base_url: url)
184
+ end
185
+ ```
186
+
187
+ ## Configuration Hierarchy
188
+
189
+ 1. **Default Options**: `Router.default_options` returns frozen hash with defaults
190
+ 2. **Class-level Configuration**: Set through DSL methods, stored via `add_value_to_class_method`
191
+ 3. **Instance-level**: Access class config, can override in method calls
192
+ 4. **Request-level**: `**__options__` parameter on generated methods
193
+
194
+ ## Error Handling
195
+
196
+ - `ClientApiBuilder::Error`: Base error class
197
+ - `ClientApiBuilder::UnexpectedResponse`: Raised when response code doesn't match expected codes
198
+ - Stores `response` for inspection
199
+ - Response procs: Per-route custom response handling stored in `default_options[:response_procs]`
200
+ - Retry on exception: `retry_request?` method (always returns true by default, override to customize)
201
+
202
+ ## Streaming Support
203
+
204
+ Routes can specify streaming behavior:
205
+
206
+ ```ruby
207
+ route :download, '/file', stream: :file # stream_to_file, requires file: argument
208
+ route :stream, '/events', stream: :io # stream_to_io, requires io: argument
209
+ route :process, '/data', stream: :block # stream with block for each chunk
210
+ route :download, '/file', stream: true # alias for :file
211
+ ```
212
+
213
+ ## Dependencies
214
+
215
+ - `inheritance-helper`: Class inheritance and configuration management
216
+ - `json`: JSON parsing and serialization (stdlib)
217
+ - `net/http`: HTTP request handling (stdlib)
218
+ - `cgi`: URL encoding in QueryParams (stdlib)
219
+ - `active_support` (optional): Enhanced query building and instrumentation
220
+
221
+ ## Thread Safety
222
+
223
+ The library is not thread-safe. Each client instance maintains state (`@response`, `@request_options`, etc.) that would cause race conditions if shared across threads. Create separate client instances per thread.
data/CLAUDE.md ADDED
@@ -0,0 +1,92 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Client API Builder is a Ruby gem for creating API clients through declarative configuration. It uses Ruby's module inclusion pattern with `ClientApiBuilder::Router` as the core component.
8
+
9
+ ## Common Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ bundle install
14
+
15
+ # Run all tests
16
+ bundle exec rspec
17
+
18
+ # Run a single test file
19
+ bundle exec rspec spec/client_api_builder/router_spec.rb
20
+
21
+ # Run a specific test by line number
22
+ bundle exec rspec spec/client_api_builder/router_spec.rb:42
23
+
24
+ # Run linter
25
+ bundle exec rubocop
26
+
27
+ # Build the gem
28
+ gem build client-api-builder.gemspec
29
+ ```
30
+
31
+ ## Architecture
32
+
33
+ ### Core Components
34
+
35
+ - **Router** (`lib/client_api_builder/router.rb`): Main module providing `route`, `base_url`, `header`, `body_builder`, `query_builder`, and `configure_retries` class methods. Uses `InheritanceHelper::Methods` for configuration inheritance.
36
+
37
+ - **NestedRouter** (`lib/client_api_builder/nested_router.rb`): Enables hierarchical API organization. Maintains reference to `root_router` and shares configuration with parent.
38
+
39
+ - **Section** (`lib/client_api_builder/section.rb`): Provides `section` class method for creating nested route groups via dynamically generated classes.
40
+
41
+ - **NetHTTP::Request** (`lib/client_api_builder/net_http_request.rb`): HTTP request execution using `Net::HTTP`. Handles standard requests and streaming (`:file`, `:io`, `:block` modes).
42
+
43
+ - **QueryParams** (`lib/client_api_builder/query_params.rb`): Custom query parameter builder used when ActiveSupport's `to_query` is unavailable.
44
+
45
+ - **ActiveSupportNotifications/LogSubscriber**: Optional integration for logging and instrumentation when ActiveSupport is present.
46
+
47
+ ### Route Code Generation
48
+
49
+ The `route` class method in Router uses `generate_route_code` to dynamically create two methods per route:
50
+ 1. `method_name_raw_response` - Makes the HTTP request
51
+ 2. `method_name` - Wraps the request with retry logic and response handling
52
+
53
+ ### HTTP Method Auto-Detection
54
+
55
+ Methods are auto-detected from route names: `post/create/add/insert` → POST, `put/update/modify/change` → PUT, `patch` → PATCH, `delete/remove` → DELETE, others → GET.
56
+
57
+ ### Configuration Hierarchy
58
+
59
+ 1. `default_options` class method (base defaults)
60
+ 2. Class-level configuration via DSL methods
61
+ 3. Instance-level overrides
62
+ 4. Request-level options (`**__options__`)
63
+
64
+ ## Key Patterns
65
+
66
+ - Module inclusion with `self.included(base)` extending ClassMethods and including InstanceMethods
67
+ - `add_value_to_class_method` from `inheritance-helper` for configuration inheritance
68
+ - Response procs stored per method name for custom response handling
69
+ - `root_router` method for accessing the top-level router from nested routers
70
+
71
+ ## Dependencies
72
+
73
+ - `inheritance-helper` (runtime): Class inheritance and method management
74
+ - `webmock` (test): HTTP request stubbing
75
+ - `activesupport` (optional): Enhanced query param building and instrumentation
76
+
77
+ ## Code Commits
78
+
79
+ Format using angular formatting:
80
+ ```
81
+ <type>(<scope>): <short summary>
82
+ ```
83
+ - **type**: build|ci|docs|feat|fix|perf|refactor|test
84
+ - **scope**: The feature or component of the service we're working on
85
+ - **summary**: Summary in present tense. Not capitalized. No period at the end.
86
+
87
+ ## Documentation Maintenance
88
+
89
+ When modifying the codebase, keep documentation in sync:
90
+ - **ARCHITECTURE.md** - Update when adding/removing classes, changing component relationships, or altering data flow patterns
91
+ - **README.md** - Update when adding new features, changing public APIs, or modifying usage examples
92
+ - **Code comments** - Update inline documentation when changing method signatures or behavior
data/Gemfile CHANGED
@@ -5,13 +5,11 @@ source 'http://rubygems.org'
5
5
  gem 'inheritance-helper'
6
6
 
7
7
  group :development do
8
- gem 'rake'
9
- gem 'rubocop'
10
- end
11
-
12
- group :spec do
13
8
  gem 'activesupport'
9
+ gem 'rake'
14
10
  gem 'rspec'
11
+ gem 'rubocop'
15
12
  gem 'simplecov'
13
+ gem 'simplecov-cobertura'
16
14
  gem 'webmock'
17
15
  end
data/Gemfile.lock CHANGED
@@ -1,73 +1,105 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activesupport (7.0.2.3)
5
- concurrent-ruby (~> 1.0, >= 1.0.2)
4
+ activesupport (8.1.2)
5
+ base64
6
+ bigdecimal
7
+ concurrent-ruby (~> 1.0, >= 1.3.1)
8
+ connection_pool (>= 2.2.5)
9
+ drb
6
10
  i18n (>= 1.6, < 2)
11
+ json
12
+ logger (>= 1.4.2)
7
13
  minitest (>= 5.1)
8
- tzinfo (~> 2.0)
9
- addressable (2.8.0)
10
- public_suffix (>= 2.0.2, < 5.0)
11
- ast (2.4.2)
12
- concurrent-ruby (1.1.9)
13
- crack (0.4.5)
14
+ securerandom (>= 0.3)
15
+ tzinfo (~> 2.0, >= 2.0.5)
16
+ uri (>= 0.13.1)
17
+ addressable (2.8.8)
18
+ public_suffix (>= 2.0.2, < 8.0)
19
+ ast (2.4.3)
20
+ base64 (0.3.0)
21
+ bigdecimal (4.0.1)
22
+ concurrent-ruby (1.3.6)
23
+ connection_pool (3.0.2)
24
+ crack (1.0.1)
25
+ bigdecimal
14
26
  rexml
15
- diff-lcs (1.5.0)
16
- docile (1.4.0)
17
- hashdiff (1.0.1)
18
- i18n (1.10.0)
27
+ diff-lcs (1.6.2)
28
+ docile (1.4.1)
29
+ drb (2.2.3)
30
+ hashdiff (1.2.1)
31
+ i18n (1.14.8)
19
32
  concurrent-ruby (~> 1.0)
20
33
  inheritance-helper (0.2.5)
21
- minitest (5.15.0)
22
- parallel (1.21.0)
23
- parser (3.1.1.0)
34
+ json (2.18.0)
35
+ language_server-protocol (3.17.0.5)
36
+ lint_roller (1.1.0)
37
+ logger (1.7.0)
38
+ minitest (6.0.1)
39
+ prism (~> 1.5)
40
+ parallel (1.27.0)
41
+ parser (3.3.10.1)
24
42
  ast (~> 2.4.1)
25
- public_suffix (4.0.6)
43
+ racc
44
+ prism (1.9.0)
45
+ public_suffix (7.0.2)
46
+ racc (1.8.1)
26
47
  rainbow (3.1.1)
27
- rake (13.0.6)
28
- regexp_parser (2.2.1)
29
- rexml (3.2.5)
30
- rspec (3.11.0)
31
- rspec-core (~> 3.11.0)
32
- rspec-expectations (~> 3.11.0)
33
- rspec-mocks (~> 3.11.0)
34
- rspec-core (3.11.0)
35
- rspec-support (~> 3.11.0)
36
- rspec-expectations (3.11.0)
48
+ rake (13.3.1)
49
+ regexp_parser (2.11.3)
50
+ rexml (3.4.4)
51
+ rspec (3.13.2)
52
+ rspec-core (~> 3.13.0)
53
+ rspec-expectations (~> 3.13.0)
54
+ rspec-mocks (~> 3.13.0)
55
+ rspec-core (3.13.6)
56
+ rspec-support (~> 3.13.0)
57
+ rspec-expectations (3.13.5)
37
58
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.11.0)
39
- rspec-mocks (3.11.0)
59
+ rspec-support (~> 3.13.0)
60
+ rspec-mocks (3.13.7)
40
61
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.11.0)
42
- rspec-support (3.11.0)
43
- rubocop (1.26.0)
62
+ rspec-support (~> 3.13.0)
63
+ rspec-support (3.13.7)
64
+ rubocop (1.84.0)
65
+ json (~> 2.3)
66
+ language_server-protocol (~> 3.17.0.2)
67
+ lint_roller (~> 1.1.0)
44
68
  parallel (~> 1.10)
45
- parser (>= 3.1.0.0)
69
+ parser (>= 3.3.0.2)
46
70
  rainbow (>= 2.2.2, < 4.0)
47
- regexp_parser (>= 1.8, < 3.0)
48
- rexml
49
- rubocop-ast (>= 1.16.0, < 2.0)
71
+ regexp_parser (>= 2.9.3, < 3.0)
72
+ rubocop-ast (>= 1.49.0, < 2.0)
50
73
  ruby-progressbar (~> 1.7)
51
- unicode-display_width (>= 1.4.0, < 3.0)
52
- rubocop-ast (1.16.0)
53
- parser (>= 3.1.1.0)
54
- ruby-progressbar (1.11.0)
55
- simplecov (0.21.2)
74
+ unicode-display_width (>= 2.4.0, < 4.0)
75
+ rubocop-ast (1.49.0)
76
+ parser (>= 3.3.7.2)
77
+ prism (~> 1.7)
78
+ ruby-progressbar (1.13.0)
79
+ securerandom (0.4.1)
80
+ simplecov (0.22.0)
56
81
  docile (~> 1.1)
57
82
  simplecov-html (~> 0.11)
58
83
  simplecov_json_formatter (~> 0.1)
59
- simplecov-html (0.12.3)
84
+ simplecov-cobertura (3.1.0)
85
+ rexml
86
+ simplecov (~> 0.19)
87
+ simplecov-html (0.13.2)
60
88
  simplecov_json_formatter (0.1.4)
61
- tzinfo (2.0.4)
89
+ tzinfo (2.0.6)
62
90
  concurrent-ruby (~> 1.0)
63
- unicode-display_width (2.1.0)
64
- webmock (3.14.0)
91
+ unicode-display_width (3.2.0)
92
+ unicode-emoji (~> 4.1)
93
+ unicode-emoji (4.2.0)
94
+ uri (1.1.1)
95
+ webmock (3.26.1)
65
96
  addressable (>= 2.8.0)
66
97
  crack (>= 0.3.2)
67
98
  hashdiff (>= 0.4.0, < 2.0.0)
68
99
 
69
100
  PLATFORMS
70
- x86_64-darwin-21
101
+ arm64-darwin-24
102
+ ruby
71
103
 
72
104
  DEPENDENCIES
73
105
  activesupport
@@ -76,7 +108,8 @@ DEPENDENCIES
76
108
  rspec
77
109
  rubocop
78
110
  simplecov
111
+ simplecov-cobertura
79
112
  webmock
80
113
 
81
114
  BUNDLED WITH
82
- 2.3.3
115
+ 2.6.2