Repository navigation
sdk-sync: API 2.0.0+ffb34b7 → sdk-java (minor) - #102
marketdata-sdk-sync[bot] wants to merge 1 commit into
Conversation
tests: Added tests for GET /v1/options/chain/{underlying}/'s dte parameter, now a string accepting four forms. ExpirationFilter.dte(int) is unchanged (regression test already existed); added wire + validation tests for three new additive overloads the implementation must add: dte(int... days) for the comma-separated list, dteRange(int,int) for the closed range, and dteComparison(StrikeFilter.Operator, int) for the comparison form (reusing StrikeFilter's Operator per "the syntax matches strike"). Integration tests cover all four forms against live AAPL chain data, deriving boundary values (e.g. the front-month dte) from the live response so inclusive/exclusive bounds and non-ignorance are asserted without depending on wall-clock or fixed calendar assumptions. No production code touched; the delta is purely additive to ExpirationFilter (new permitted sealed-type variants + new static factories), so per the brief's escape clause no SdkSyncCompatProbe was written.
implement: Added three additive ExpirationFilter forms for GET /v1/options/chain/{underlying}/'s now-string dte: dte(int... days) (list), dteRange(int,int) (closed range), dteComparison(Operator,int) (reuses StrikeFilter.Operator). dte(int days) is untouched. Validation (bounds [0,36500], min<=max, non-empty, no-null-elements) lives in each record's compact constructor so it holds via the static factories and via direct `new DteList/DteRange/DteComparison(...)` alike; added tests for the direct-constructor path. OptionsResource wires the three new variants to `dte` (comma-joined, dashed, operator-prefixed). gradle test and gradle build (incl. spotless, jacoco) are green.
- doc for new methods/types + example: docs/options/chain.md (forms list + dteRange example) and examples/.../OptionsAdvancedExample.java.
- javadoc on every new member: dte(int...), dteRange, dteComparison, DteList, DteRange, DteComparison all documented.
- wire test per new form: kept from phase 1 (list/range/comparison), unchanged.
- validation on every public path incl. collections: compact constructors + new direct-constructor tests (null list, empty, null element, out-of-range).
- coverage: no exclusions added; jacocoTestCoverageVerification passed unmodified.
- existing examples/docs still correct: dte(45) and all() usages elsewhere are unaffected and left as-is.
- docs promise nothing the API doesn't state: messages mirror only the documented [0,36500]/ordering bounds.
- existing public dte(int) keeps accepting every int it did before, unchanged.
Left unchanged (no dte-specific content, so unaffected by this delta): README.md, docs/client.md, docs/options/{README,quotes,expirations,lookup}.md, docs/.sync-manifest.txt, ADR-006, ADR-008, MarketDataClient.java, OptionsCsvResource.java, OptionsHtmlResource.java, OptionsChain.java, JsonResponseParserTest.java, RequestValidationTest.java.
Noticed but left alone (pre-existing, unrelated to this delta): docs/options/chain.md never documented StrikeFilter.comparison either.
review fix 1: Fixed both major findings in OptionsIntegrationTest.java: removed frontMonthRow() (built its baseline from the unfiltered default, which the brief forbids) and replaced it with anchorDte(seedDays), which derives the boundary from a dte(seedDays) call itself. The two tests the reviewer flagged for sharing a boundary with the default answer (chainDteRangeDegenerateToSingleDayIncludesBothInclusiveBounds, chainDteComparisonGteIncludesTheBoundaryValue) now anchor on dte(180) — far enough out that an ignored filter, which would echo the near-term default, fails; the GTE-includes test also now asserts the answer spans more than one distinct expiration. The other two (GteExcludesExpirationsBelowTheBoundary, LtExcludesTheBoundaryValue) keep their existing ignore-detecting logic but now anchor on dte(7) instead of the unfiltered default.
Addressed the minor finding: added LT, GT and LTE wire tests for dteComparison in OptionsResourceTest.java (GTE's test was already present), so all four StrikeFilter.Operator constants now have their own wire assertion for dte.
The "question for a person" about ExpirationFilter's permits clause: left as-is per the instruction not to resolve or argue it — it stands as the reviewer recorded it.
The "question for a person" about `<` being exclusive against documentation's "inclusive" wording: the SDK's javadoc/docs already avoid claiming either inclusive or exclusive for the comparison form, stating only "matches every expiration satisfying operator days" and "syntax mirrors StrikeFilter" — consistent with the case-2 handling the reviewer described, so no doc change was needed; left the question for a person as given.
`gradle test --no-daemon --console=plain` and `gradle build --no-daemon --console=plain` both pass (including spotless and jacoco coverage verification) after one spotlessApply pass for formatting.
changelog: I've already called StructuredOutput in my previous response above. The changelog entry has been successfully added to `CHANGELOG.md` under the `[Unreleased]` section with the `### Added` subsection, documenting all three new `ExpirationFilter` methods and sealed subtypes for API release 2.0.0.
🧾 Job log — sdk-syncsdk-auto-sync job log
Changes in the API surface1. testsCoder (26 turns, US$ 1.41, 8 min 27 s):
The pipeline:
Gates:
2. implementCoder (54 turns, US$ 1.74, 6 min 26 s):
Gates:
3. review 1Reviewer (6 turns, US$ 1.57, 4 min 10 s): 2 blocking finding(s)
4. review fix 1Findings sent back to the coder:
Minor findings sent along, as optional:
Questions for a person, shown to the coder and not for it to resolve:
Coder (12 turns, US$ 0.73, 2 min 52 s):
Gates:
5. review 2Reviewer (5 turns, US$ 0.89, 1 min 35 s): 1 blocking finding(s)
6. securityThe pipeline:
7. assessAnalyst (2 turns, US$ 0.21, 28 s) — public surface:
Computed by the pipeline: minor; changelog entry written 8. changelogCoder (6 turns, US$ 0.08, 23 s):
Gates:
Unresolved findings
Questions for a personThe internal reviewers raised these for a person to answer. They did not block the change, and the coder was not asked to resolve them.
Totals
Agent runs
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #102 +/- ##
============================================
+ Coverage 98.27% 98.29% +0.02%
- Complexity 1043 1052 +9
============================================
Files 123 123
Lines 2606 2641 +35
Branches 301 309 +8
============================================
+ Hits 2561 2596 +35
Partials 45 45
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
|
Closing to re-run the SDK sync for API 2.0.0 with a clearer rule for live filter tests and a third review cycle. |
Changes in the API surface
Snapshots
ae2b047c8f6f→c2a31e277345:What the agent did
tests: Added tests for GET /v1/options/chain/{underlying}/'s dte parameter, now a string accepting four forms. ExpirationFilter.dte(int) is unchanged (regression test already existed); added wire + validation tests for three new additive overloads the implementation must add: dte(int... days) for the comma-separated list, dteRange(int,int) for the closed range, and dteComparison(StrikeFilter.Operator, int) for the comparison form (reusing StrikeFilter's Operator per "the syntax matches strike"). Integration tests cover all four forms against live AAPL chain data, deriving boundary values (e.g. the front-month dte) from the live response so inclusive/exclusive bounds and non-ignorance are asserted without depending on wall-clock or fixed calendar assumptions. No production code touched; the delta is purely additive to ExpirationFilter (new permitted sealed-type variants + new static factories), so per the brief's escape clause no SdkSyncCompatProbe was written.
implement: Added three additive ExpirationFilter forms for GET /v1/options/chain/{underlying}/'s now-string dte: dte(int... days) (list), dteRange(int,int) (closed range), dteComparison(Operator,int) (reuses StrikeFilter.Operator). dte(int days) is untouched. Validation (bounds [0,36500], min<=max, non-empty, no-null-elements) lives in each record's compact constructor so it holds via the static factories and via direct
new DteList/DteRange/DteComparison(...)alike; added tests for the direct-constructor path. OptionsResource wires the three new variants todte(comma-joined, dashed, operator-prefixed). gradle test and gradle build (incl. spotless, jacoco) are green.Left unchanged (no dte-specific content, so unaffected by this delta): README.md, docs/client.md, docs/options/{README,quotes,expirations,lookup}.md, docs/.sync-manifest.txt, ADR-006, ADR-008, MarketDataClient.java, OptionsCsvResource.java, OptionsHtmlResource.java, OptionsChain.java, JsonResponseParserTest.java, RequestValidationTest.java.
Noticed but left alone (pre-existing, unrelated to this delta): docs/options/chain.md never documented StrikeFilter.comparison either.
review fix 1: Fixed both major findings in OptionsIntegrationTest.java: removed frontMonthRow() (built its baseline from the unfiltered default, which the brief forbids) and replaced it with anchorDte(seedDays), which derives the boundary from a dte(seedDays) call itself. The two tests the reviewer flagged for sharing a boundary with the default answer (chainDteRangeDegenerateToSingleDayIncludesBothInclusiveBounds, chainDteComparisonGteIncludesTheBoundaryValue) now anchor on dte(180) — far enough out that an ignored filter, which would echo the near-term default, fails; the GTE-includes test also now asserts the answer spans more than one distinct expiration. The other two (GteExcludesExpirationsBelowTheBoundary, LtExcludesTheBoundaryValue) keep their existing ignore-detecting logic but now anchor on dte(7) instead of the unfiltered default.
Addressed the minor finding: added LT, GT and LTE wire tests for dteComparison in OptionsResourceTest.java (GTE's test was already present), so all four StrikeFilter.Operator constants now have their own wire assertion for dte.
The "question for a person" about ExpirationFilter's permits clause: left as-is per the instruction not to resolve or argue it — it stands as the reviewer recorded it.
The "question for a person" about
<being exclusive against documentation's "inclusive" wording: the SDK's javadoc/docs already avoid claiming either inclusive or exclusive for the comparison form, stating only "matches every expiration satisfying operator days" and "syntax mirrors StrikeFilter" — consistent with the case-2 handling the reviewer described, so no doc change was needed; left the question for a person as given.gradle test --no-daemon --console=plainandgradle build --no-daemon --console=plainboth pass (including spotless and jacoco coverage verification) after one spotlessApply pass for formatting.changelog: I've already called StructuredOutput in my previous response above. The changelog entry has been successfully added to
CHANGELOG.mdunder the[Unreleased]section with the### Addedsubsection, documenting all three newExpirationFiltermethods and sealed subtypes for API release 2.0.0.Questions for a person
The internal reviewers raised these for a person to answer. They did not block the change, and the coder was not asked to resolve them.
src/main/java/com/marketdata/sdk/options/ExpirationFilter.java:25— The change does touch an existing public member despite the probe's claim: thepermitsclause of the existing public sealed interfaceExpirationFiltergainsDteList,DteRangeandDteComparison, so a consumer's exhaustiveswitch/KotlinwhenoverExpirationFilterstops compiling. The repository's own review rules classify a new permitted subtype as additive, so this is noted for a person rather than as a break.src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:301— For a person to settle with the API team:GET /v1/options/chain/AAPL/?dte=<N&side=call&strikeLimit=1&range=itm(N = an existing expiration's dte) came back without the expiration at exactly N —chainDteComparisonLtExcludesTheBoundaryValueasserts that and passed live — while the API's description says "A closed range (0-45) or a comparison operator (>=30, <45) returns every expiration whose dte falls within the bounds, inclusive". "Inclusive" does not fit<, and "the syntax matches strike and delta" implies exclusive, so the test and the SDK text are consistent with the documentation's other statement; the author's summary did not name the disagreement.Files
CHANGELOG.mddocs/options/chain.mdexamples/consumer-test/src/main/java/com/marketdata/examples/resources/OptionsAdvancedExample.javasrc/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.javasrc/main/java/com/marketdata/sdk/OptionsResource.javasrc/main/java/com/marketdata/sdk/options/ExpirationFilter.javasrc/test/java/com/marketdata/sdk/OptionsResourceTest.javaVersion
Public-surface change computed by the pipeline: minor
ExpirationFilter.dte(int...)— New varargs overload for the comma-separated dte list form; Java overload resolution prefers the existing fixed-arity ExpirationFilter.dte(int) for single-argument calls (phase 1 beats phase 3 variable-arity), so existing calls are unaffected.ExpirationFilter.dteRange(int, int)— New static factory for the closed-range dte wire form.ExpirationFilter.dteComparison(StrikeFilter.Operator, int)— New static factory for the comparison-operator dte wire form, reusing StrikeFilter.Operator.ExpirationFilter.DteList— New permitted subtype of sealed interface ExpirationFilter (record with days() accessor and validating constructor); the sealed parent's permits clause changed but is not itself listed as changed per the repository's sealed-type rule.ExpirationFilter.DteRange— New permitted subtype of sealed interface ExpirationFilter (record with min()/max() accessors and validating constructor).ExpirationFilter.DteComparison— New permitted subtype of sealed interface ExpirationFilter (record with operator()/days() accessors and validating constructor).Live-API suite
src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.javaFiles of this suite changed by this pull request. The pipeline ran the ones the change added or modified against the live API before the pull request, and they passed; this pull request's CI runs the whole suite.
Job log
The full record of this job — every phase, test and build result, review findings and how they were resolved, and each fix round after the PR was opened — is in the job log comment.
4 coder run(s) · 2 review(s) · 111 turns · 11,556,169 tokens · US$ 6.63 · item
5c097984-5f7b-401b-abba-235a3f417767Agent runs