ace-support-test-helpers 0.14.5 → 0.14.6

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: f964e2cbd1eb428c260e5190ddaefbef7905d1ee86e894cbcab9a2d2b985b628
4
- data.tar.gz: 6b8e0b1f8c3e0e88638d99b8d4abaea0a8378262bbae3c3784ae519d5859ecc2
3
+ metadata.gz: 95c5242cb44820418bda5f2d031055e5adab6a3fd8e2cacb88810622e7776ff2
4
+ data.tar.gz: 9a55229cf434d2a61122be1dcd9595eafbb4af1c87afc8d9c79b5f6fcace82da
5
5
  SHA512:
6
- metadata.gz: 8da847ee96be275ce048c97e55d3a0c6c659c2bf73ac472fbf4001fd3ca6eabc907658a2d2c333843f65dc059bb69b87cdec2ed1afa4965a8608ba4ccad5e174
7
- data.tar.gz: 6f5b8c776f80d9a799e06c64cc0238cefc346fec2f98715e92767369f56e2222a24dc84c4ff1070dc210ba54b09f3244f751de978ef695b4839604a4ca3a276b
6
+ metadata.gz: 2c189fbce23a0c3544780011c88d73d81f269232b2062f6c025d920883cb6872404c8d25f523ed60016741a700c2d5499c2faf977971ab84c716282f60b48fc2
7
+ data.tar.gz: e4e67a4240c9a183f72191f14273ad88457dd99951c593484bf9e1d62633209dc45bd5238296c8c2b82e89e50ea420070fedc0a66771eeefb0d3644c044c53a3
data/CHANGELOG.md CHANGED
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.14.6] - 2026-09-28
11
+
10
12
  ## [0.14.5] - 2026-09-24
11
13
 
12
14
  ### Fixed
@@ -0,0 +1,150 @@
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 HEAD_SHA, receipt.pull_request.head_sha
53
+ assert_equal SERVER_URL, receipt.pull_request.base_repository_url
54
+ assert_equal HEAD_SHA, receipt.to_h.dig(:pull_request, :head_sha)
55
+ end
56
+
57
+ def test_lifecycle_create_reconciles_to_exact_open_match
58
+ receipt = build_provider(lifecycle_runner(:create_existing)).create_pull_request(
59
+ **CREATE_IDENTITY, expected_head: HEAD_SHA, title: "Ship it"
60
+ )
61
+ assert_equal :existing, receipt.idempotency
62
+ assert_equal 25, receipt.pull_request.number
63
+ end
64
+
65
+ def test_lifecycle_create_rejects_stale_expected_head_without_mutation
66
+ provider = build_provider(lifecycle_runner(:create_existing))
67
+ error = assert_raises(Ace::Git::ProviderExpectedHeadConflictError) do
68
+ provider.create_pull_request(
69
+ **CREATE_IDENTITY, expected_head: OTHER_SHA, title: "Ship it"
70
+ )
71
+ end
72
+ assert_match(/head changed|does not match/i, error.message)
73
+ end
74
+
75
+ def test_lifecycle_create_conflicts_on_multiple_exact_matches
76
+ provider = build_provider(lifecycle_runner(:find_multi))
77
+ error = assert_raises(Ace::Git::ProviderConflictingMatchesError) do
78
+ provider.create_pull_request(
79
+ **CREATE_IDENTITY, expected_head: HEAD_SHA, title: "Ship it"
80
+ )
81
+ end
82
+ assert_match(/match/i, error.message)
83
+ end
84
+
85
+ def test_lifecycle_create_reports_unknown_outcome_with_reconciliation_identity
86
+ provider = build_provider(lifecycle_runner(:create_unknown))
87
+ error = assert_raises(Ace::Git::ProviderUnknownOutcomeError) do
88
+ provider.create_pull_request(
89
+ **CREATE_IDENTITY, expected_head: HEAD_SHA, title: "Ship it"
90
+ )
91
+ end
92
+ assert_match(/reconcile by exact identity/i, error.message)
93
+ assert_match(%r{owner/repo}, error.message)
94
+ end
95
+
96
+ def test_lifecycle_update_enforces_expected_head
97
+ provider = build_provider(lifecycle_runner(:update_stale))
98
+ error = assert_raises(Ace::Git::ProviderExpectedHeadConflictError) do
99
+ provider.update_pull_request(number: 25, expected_head: OTHER_SHA, title: "New title")
100
+ end
101
+ assert_match(/head changed/i, error.message)
102
+
103
+ receipt = build_provider(lifecycle_runner(:update_ok))
104
+ .update_pull_request(number: 25, expected_head: HEAD_SHA, title: "New title")
105
+ assert_equal :update, receipt.operation
106
+ assert_equal HEAD_SHA, receipt.pull_request.head_sha
107
+ end
108
+
109
+ def test_lifecycle_ready_classifies_capability
110
+ provider = build_provider(lifecycle_runner(ready_supported? ? :ready_ok : :ready_unsupported))
111
+ if ready_supported?
112
+ receipt = provider.ready_pull_request(number: 25, expected_head: HEAD_SHA)
113
+ assert_equal :ready, receipt.operation
114
+ else
115
+ error = assert_raises(Ace::Git::ProviderUnsupportedCapabilityError) do
116
+ provider.ready_pull_request(number: 25, expected_head: HEAD_SHA)
117
+ end
118
+ assert_match(/ready|capab|support/i, error.message)
119
+ end
120
+ end
121
+
122
+ def test_lifecycle_merge_enforces_expected_head_atomically
123
+ provider = build_provider(lifecycle_runner(merge_supported? ? :merge_ok : :merge_unsupported))
124
+ if merge_supported?
125
+ receipt = provider.merge_pull_request(number: 25, expected_head: HEAD_SHA, method: :squash)
126
+ assert_equal :merge, receipt.operation
127
+ assert_equal HEAD_SHA, receipt.pull_request.head_sha
128
+
129
+ error = assert_raises(Ace::Git::ProviderExpectedHeadConflictError) do
130
+ build_provider(lifecycle_runner(:merge_stale))
131
+ .merge_pull_request(number: 25, expected_head: OTHER_SHA, method: :squash)
132
+ end
133
+ assert_match(/head|match/i, error.message)
134
+ else
135
+ error = assert_raises(Ace::Git::ProviderUnsupportedCapabilityError) do
136
+ provider.merge_pull_request(number: 25, expected_head: HEAD_SHA, method: :squash)
137
+ end
138
+ assert_match(/atomic|expected[- ]head|capab|support/i, error.message)
139
+ end
140
+ end
141
+
142
+ def test_lifecycle_merge_rejects_unknown_methods
143
+ provider = build_provider(lifecycle_runner(:find_single))
144
+ assert_raises(ArgumentError) do
145
+ provider.merge_pull_request(number: 25, expected_head: HEAD_SHA, method: :fast_forward)
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ace
4
4
  module TestSupport
5
- VERSION = "0.14.5"
5
+ VERSION = "0.14.6"
6
6
  end
7
7
  end
@@ -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.5
4
+ version: 0.14.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Czyz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-09-24 00:00:00.000000000 Z
10
+ date: 2026-09-29 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