ace-support-test-helpers 0.14.5 → 0.14.7
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/ace/test_support/pull_request_lifecycle_contract.rb +155 -0
- data/lib/ace/test_support/version.rb +1 -1
- data/lib/ace/test_support.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a767b70c09feaae225240738ac2f27a142d03699e5238554b461d4c5131ab621
|
|
4
|
+
data.tar.gz: c2c991117721c5feec55811f404ebf805a75eef80f5ac17df84f4b31067efcbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9834e606ddf335a0fe451d288987273ce0c508f47527855a9ffc05f1fdcedbb332d8db4bc589b2681c5bbaf9961f75b9a65ec7c0672b9b6eadf0ca8122ef9979
|
|
7
|
+
data.tar.gz: 8041dc0beebc3d0f4be3168eec4d73412163bd0052402bf9630d00e0de63e261e33fc444dc7891c47fb00a939877eed564876e99ebea711c054e28af14c3c755
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.14.7] - 2026-10-04
|
|
11
|
+
|
|
12
|
+
### Technical
|
|
13
|
+
|
|
14
|
+
- Verify full source-repository and base-reference provenance in shared PR lifecycle receipts.
|
|
15
|
+
|
|
16
|
+
## [0.14.6] - 2026-09-28
|
|
17
|
+
|
|
10
18
|
## [0.14.5] - 2026-09-24
|
|
11
19
|
|
|
12
20
|
### Fixed
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ace
|
|
4
|
+
module TestSupport
|
|
5
|
+
# Shared PR-lifecycle contract parity suite.
|
|
6
|
+
#
|
|
7
|
+
# Provider packages include this module and supply scripted runners per
|
|
8
|
+
# symbolic scenario, proving identical normalized receipts, exact-identity
|
|
9
|
+
# matching, expected-head enforcement, idempotent create, unknown-outcome
|
|
10
|
+
# classification, and capability classification across every provider —
|
|
11
|
+
# with no network and no provider CLI.
|
|
12
|
+
#
|
|
13
|
+
# Host test class contract:
|
|
14
|
+
# - #build_provider(runner) -> Ace::Git::Providers::Base on the runner
|
|
15
|
+
# - #lifecycle_runner(scenario) -> scripted runner for the scenario
|
|
16
|
+
# - #ready_supported? [Boolean] provider can mark drafts ready
|
|
17
|
+
# - #merge_supported? [Boolean] provider enforces head atomically
|
|
18
|
+
module PullRequestLifecycleContract
|
|
19
|
+
SERVER_URL = "https://forge.example.com/owner/repo"
|
|
20
|
+
HEAD_SHA = "fc14c43d3660ac6c133959a6dec29603413f0e8a"
|
|
21
|
+
OTHER_SHA = "0123456789abcdef0123456789abcdef01234567"
|
|
22
|
+
|
|
23
|
+
IDENTITY = {
|
|
24
|
+
head_repository_url: SERVER_URL,
|
|
25
|
+
head_ref: "feature/x",
|
|
26
|
+
base_repository_url: SERVER_URL,
|
|
27
|
+
base_ref: "main"
|
|
28
|
+
}.freeze
|
|
29
|
+
|
|
30
|
+
# Create kwargs: the base repository is always the resolved server.
|
|
31
|
+
CREATE_IDENTITY = IDENTITY.except(:base_repository_url).freeze
|
|
32
|
+
|
|
33
|
+
def test_lifecycle_find_matches_exact_identity_with_provenance
|
|
34
|
+
prs = build_provider(lifecycle_runner(:find_single)).find_open_pull_requests(**IDENTITY)
|
|
35
|
+
assert_equal [25], prs.map(&:number)
|
|
36
|
+
pr = prs.first
|
|
37
|
+
assert_equal HEAD_SHA, pr.head_sha
|
|
38
|
+
assert_equal "feature/x", pr.head_ref
|
|
39
|
+
assert_equal "main", pr.base_ref
|
|
40
|
+
assert_equal SERVER_URL, pr.head_repository_url
|
|
41
|
+
assert_equal SERVER_URL, pr.base_repository_url
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_lifecycle_create_proves_head_and_reports_created
|
|
45
|
+
provider = build_provider(lifecycle_runner(:create_new))
|
|
46
|
+
receipt = provider.create_pull_request(
|
|
47
|
+
**CREATE_IDENTITY, expected_head: HEAD_SHA, title: "Ship it"
|
|
48
|
+
)
|
|
49
|
+
assert_instance_of Ace::Git::ProviderMutationReceipt, receipt
|
|
50
|
+
assert_equal :create, receipt.operation
|
|
51
|
+
assert_equal :created, receipt.idempotency
|
|
52
|
+
assert_equal 25, receipt.pull_request.number
|
|
53
|
+
assert_equal "feature/x", receipt.pull_request.head_ref
|
|
54
|
+
assert_equal "main", receipt.pull_request.base_ref
|
|
55
|
+
assert_equal SERVER_URL, receipt.pull_request.head_repository_url
|
|
56
|
+
assert_equal true, receipt.pull_request.draft
|
|
57
|
+
assert_equal HEAD_SHA, receipt.pull_request.head_sha
|
|
58
|
+
assert_equal SERVER_URL, receipt.pull_request.base_repository_url
|
|
59
|
+
assert_equal HEAD_SHA, receipt.to_h.dig(:pull_request, :head_sha)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_lifecycle_create_reconciles_to_exact_open_match
|
|
63
|
+
receipt = build_provider(lifecycle_runner(:create_existing)).create_pull_request(
|
|
64
|
+
**CREATE_IDENTITY, expected_head: HEAD_SHA, title: "Ship it"
|
|
65
|
+
)
|
|
66
|
+
assert_equal :existing, receipt.idempotency
|
|
67
|
+
assert_equal 25, receipt.pull_request.number
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_lifecycle_create_rejects_stale_expected_head_without_mutation
|
|
71
|
+
provider = build_provider(lifecycle_runner(:create_existing))
|
|
72
|
+
error = assert_raises(Ace::Git::ProviderExpectedHeadConflictError) do
|
|
73
|
+
provider.create_pull_request(
|
|
74
|
+
**CREATE_IDENTITY, expected_head: OTHER_SHA, title: "Ship it"
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
assert_match(/head changed|does not match/i, error.message)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_lifecycle_create_conflicts_on_multiple_exact_matches
|
|
81
|
+
provider = build_provider(lifecycle_runner(:find_multi))
|
|
82
|
+
error = assert_raises(Ace::Git::ProviderConflictingMatchesError) do
|
|
83
|
+
provider.create_pull_request(
|
|
84
|
+
**CREATE_IDENTITY, expected_head: HEAD_SHA, title: "Ship it"
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
assert_match(/match/i, error.message)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_lifecycle_create_reports_unknown_outcome_with_reconciliation_identity
|
|
91
|
+
provider = build_provider(lifecycle_runner(:create_unknown))
|
|
92
|
+
error = assert_raises(Ace::Git::ProviderUnknownOutcomeError) do
|
|
93
|
+
provider.create_pull_request(
|
|
94
|
+
**CREATE_IDENTITY, expected_head: HEAD_SHA, title: "Ship it"
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
assert_match(/reconcile by exact identity/i, error.message)
|
|
98
|
+
assert_match(%r{owner/repo}, error.message)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def test_lifecycle_update_enforces_expected_head
|
|
102
|
+
provider = build_provider(lifecycle_runner(:update_stale))
|
|
103
|
+
error = assert_raises(Ace::Git::ProviderExpectedHeadConflictError) do
|
|
104
|
+
provider.update_pull_request(number: 25, expected_head: OTHER_SHA, title: "New title")
|
|
105
|
+
end
|
|
106
|
+
assert_match(/head changed/i, error.message)
|
|
107
|
+
|
|
108
|
+
receipt = build_provider(lifecycle_runner(:update_ok))
|
|
109
|
+
.update_pull_request(number: 25, expected_head: HEAD_SHA, title: "New title")
|
|
110
|
+
assert_equal :update, receipt.operation
|
|
111
|
+
assert_equal HEAD_SHA, receipt.pull_request.head_sha
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_lifecycle_ready_classifies_capability
|
|
115
|
+
provider = build_provider(lifecycle_runner(ready_supported? ? :ready_ok : :ready_unsupported))
|
|
116
|
+
if ready_supported?
|
|
117
|
+
receipt = provider.ready_pull_request(number: 25, expected_head: HEAD_SHA)
|
|
118
|
+
assert_equal :ready, receipt.operation
|
|
119
|
+
else
|
|
120
|
+
error = assert_raises(Ace::Git::ProviderUnsupportedCapabilityError) do
|
|
121
|
+
provider.ready_pull_request(number: 25, expected_head: HEAD_SHA)
|
|
122
|
+
end
|
|
123
|
+
assert_match(/ready|capab|support/i, error.message)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_lifecycle_merge_enforces_expected_head_atomically
|
|
128
|
+
provider = build_provider(lifecycle_runner(merge_supported? ? :merge_ok : :merge_unsupported))
|
|
129
|
+
if merge_supported?
|
|
130
|
+
receipt = provider.merge_pull_request(number: 25, expected_head: HEAD_SHA, method: :squash)
|
|
131
|
+
assert_equal :merge, receipt.operation
|
|
132
|
+
assert_equal HEAD_SHA, receipt.pull_request.head_sha
|
|
133
|
+
|
|
134
|
+
error = assert_raises(Ace::Git::ProviderExpectedHeadConflictError) do
|
|
135
|
+
build_provider(lifecycle_runner(:merge_stale))
|
|
136
|
+
.merge_pull_request(number: 25, expected_head: OTHER_SHA, method: :squash)
|
|
137
|
+
end
|
|
138
|
+
assert_match(/head|match/i, error.message)
|
|
139
|
+
else
|
|
140
|
+
error = assert_raises(Ace::Git::ProviderUnsupportedCapabilityError) do
|
|
141
|
+
provider.merge_pull_request(number: 25, expected_head: HEAD_SHA, method: :squash)
|
|
142
|
+
end
|
|
143
|
+
assert_match(/atomic|expected[- ]head|capab|support/i, error.message)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_lifecycle_merge_rejects_unknown_methods
|
|
148
|
+
provider = build_provider(lifecycle_runner(:find_single))
|
|
149
|
+
assert_raises(ArgumentError) do
|
|
150
|
+
provider.merge_pull_request(number: 25, expected_head: HEAD_SHA, method: :fast_forward)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
data/lib/ace/test_support.rb
CHANGED
|
@@ -22,6 +22,7 @@ require_relative "test_support/fixtures/http_mocks" # Shared HTTP mocks for LLM
|
|
|
22
22
|
require_relative "test_support/fixtures/prompt_helpers" # Shared prompt stubbing helpers
|
|
23
23
|
require_relative "test_support/fixtures/test_runner_mocks" # Shared test runner mocks
|
|
24
24
|
require_relative "test_support/provider_contract" # Provider contract parity suite for forge provider gems
|
|
25
|
+
require_relative "test_support/pull_request_lifecycle_contract" # PR lifecycle contract parity suite
|
|
25
26
|
|
|
26
27
|
# Configure Minitest reporters by default
|
|
27
28
|
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-support-test-helpers
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.14.
|
|
4
|
+
version: 0.14.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michal Czyz
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-10-04 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: minitest
|
|
@@ -63,6 +63,7 @@ files:
|
|
|
63
63
|
- lib/ace/test_support/fixtures/test_runner_mocks.rb
|
|
64
64
|
- lib/ace/test_support/performance_helpers.rb
|
|
65
65
|
- lib/ace/test_support/provider_contract.rb
|
|
66
|
+
- lib/ace/test_support/pull_request_lifecycle_contract.rb
|
|
66
67
|
- lib/ace/test_support/sandbox_package_copy.rb
|
|
67
68
|
- lib/ace/test_support/subprocess_runner.rb
|
|
68
69
|
- lib/ace/test_support/test_environment.rb
|