Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
139 commits
Select commit Hold shift + click to select a range
b76608b
Spike: native YAML decoding on the stock parser, no fork
reuvenharrison Aug 3, 2026
456a979
Port all 41 types to UnmarshalYAML on the stock parser
reuvenharrison Aug 3, 2026
2b2a07f
Wire the loader to the native path
reuvenharrison Aug 3, 2026
32005a9
Revert the apis-guru fixture churn
reuvenharrison Aug 3, 2026
a50e066
Suppress YAML 1.1 timestamp resolution before decoding
reuvenharrison Aug 3, 2026
7f760b4
Comments describe the code, not the change
reuvenharrison Aug 3, 2026
4a209a4
Generate the repetitive UnmarshalYAML methods
reuvenharrison Aug 3, 2026
9fad1ec
Use a generic helper in the generated UnmarshalYAML bodies
reuvenharrison Aug 3, 2026
0ed2a5a
Fix explicit-null responses and arbitrary-key ref origins
reuvenharrison Aug 3, 2026
fe4d402
Give any-typed values JSON-shaped numbers
reuvenharrison Aug 3, 2026
c45017b
Close three more origin gaps
reuvenharrison Aug 3, 2026
602a7d6
Delete TestOrigin_OriginExistsInProperties
reuvenharrison Aug 3, 2026
4ebab9d
Delete the __origin__ tests
reuvenharrison Aug 3, 2026
aec3e3d
Give a document root its own position as Origin.Key
reuvenharrison Aug 3, 2026
a299f84
Delete the __origin__ consumer layer, and group origins in origin.go
reuvenharrison Aug 3, 2026
8e04ac1
Use the stock parser directly in openapi3
reuvenharrison Aug 3, 2026
ca4456d
Normalise any-element slices and maps, and accept int in an enum
reuvenharrison Aug 3, 2026
ddd9bec
Take openapi2 off the yaml fork, minimally
reuvenharrison Aug 3, 2026
6b321c0
Drop the oasdiff/yaml and yaml3 dependencies
reuvenharrison Aug 3, 2026
3f09ffb
Derive block extents from the node tree
reuvenharrison Aug 3, 2026
517cb7e
Stamp a resolved $ref against the file it came from
reuvenharrison Aug 3, 2026
bdf1fbe
Merge remote-tracking branch 'upstream/master' into spike/native-yaml…
reuvenharrison Aug 3, 2026
c7f66cb
Say what the package-level origin state actually costs
reuvenharrison Aug 3, 2026
ed8329e
Satisfy the generated-artifact and lint gates
reuvenharrison Aug 3, 2026
5d698b7
Guard the per-decode origin state with a lock
reuvenharrison Aug 3, 2026
8197f83
Rescope the yaml-usage guard to the decode layer
reuvenharrison Aug 3, 2026
6315603
Compare the guard's count numerically
reuvenharrison Aug 3, 2026
9ff2337
Reach the end of a block that ends in a block scalar
reuvenharrison Aug 5, 2026
754b77a
Merge remote-tracking branch 'upstream/master' into spike/native-yaml…
reuvenharrison Aug 6, 2026
a27deb9
openapi3: give every native decode path the same normalizations
reuvenharrison Aug 12, 2026
1639d81
openapi3: generate the ref unmarshaler with its extra argument
reuvenharrison Aug 12, 2026
2bf75b8
openapi3: satisfy the loader-chaining lint gate
reuvenharrison Aug 12, 2026
744a235
openapi3: release the per-decode origin state when the decode ends
reuvenharrison Aug 12, 2026
427bb44
openapi3: correct the comments describing the retained tree
reuvenharrison Aug 12, 2026
1071ced
openapi3: accept boolean schemas
reuvenharrison Aug 25, 2026
c8032b2
Merge branch 'feat/boolean-schemas' into tmp-1238-fix
reuvenharrison Aug 25, 2026
c0f57a2
openapi3: decode boolean schemas on the native path
reuvenharrison Aug 25, 2026
79ac3c4
openapi3: ignore the fields next to a Reference Object's $ref in ever…
fenollp Oct 19, 2026
0375a5d
openapi3: apply a 3.1 schema's $ref siblings alongside the referenced…
fenollp Oct 19, 2026
cb14646
openapi3: marshal the fields written next to a $ref
fenollp Oct 15, 2026
11caa38
openapi3: tell apart a $ref being resolved as different kinds of objects
fenollp Oct 19, 2026
c59eda0
openapi3: merge the fields next to a path item's $ref with the item i…
fenollp Oct 19, 2026
98fd8d4
openapi3: internalize, version and locate the keywords next to a sche…
fenollp Oct 20, 2026
52aade8
openapi3: test $ref siblings with the cases of #1271
abramchikd Oct 20, 2026
2420538
changelog: fixup rebased messes (#1372)
fenollp Oct 22, 2026
15948ef
Add fuzz targets (#1373)
fenollp Oct 22, 2026
454df67
openapi3: set the failing schema on JSON Schema 2020-12 validation er…
frodeaa Oct 23, 2026
7dd0f6c
openapi3filter: parse number values as decimal only (#1366)
LuisFigueroaG Oct 24, 2026
db92bf3
Merge branch 'master' into spike/native-yaml-stock-goyaml
reuvenharrison Oct 25, 2026
b56349e
openapi3: two problems the merge with master surfaced
reuvenharrison Oct 25, 2026
d7919dc
openapi3: key case no longer depends on which encoding/json the build…
reuvenharrison Oct 25, 2026
75944f3
openapi3: keep the concurrency test out of the short suite
reuvenharrison Oct 25, 2026
7772f99
openapi3: refuse infinity and NaN where the document is read
reuvenharrison Oct 25, 2026
4a2abc9
openapi3: move the node index to internal/nodeindex
reuvenharrison Oct 25, 2026
bf57e8b
openapi3: take the lock only when a decode produces origins
reuvenharrison Oct 25, 2026
38e12e5
openapi3: say what holding the lock across the decode requires
reuvenharrison Oct 25, 2026
d991b57
openapi3: record why the decode state is an atomic and not a lock
reuvenharrison Oct 25, 2026
ad8558f
openapi3: say that the subtree decode guard is defensive
reuvenharrison Oct 25, 2026
8cf4c15
openapi3: one assignment per step in unmarshal's yaml path
reuvenharrison Oct 25, 2026
afcf396
openapi3: unmarshal reads as yaml, then json, then both errors
reuvenharrison Oct 25, 2026
5c5819e
openapi3: marshal a ref holding neither $ref nor a value as null
fenollp Oct 25, 2026
c5fa940
openapi2conv: fix nil dereferences and input mutation in FromV3
fenollp Oct 25, 2026
5a3af78
fuzz: seed from all of testdata and the APIs-guru corpus, cover the Y…
fenollp Oct 25, 2026
bc07540
openapi3: marshal a ref holding neither $ref nor a value as null
fenollp Oct 25, 2026
4331cdd
openapi2conv: fix nil dereferences and input mutation in FromV3
fenollp Oct 25, 2026
2d55b6a
fuzz: seed from all of testdata and the APIs-guru corpus, cover the Y…
fenollp Oct 25, 2026
2f987bd
fuzz: port the fuzz targets off github.com/oasdiff/yaml
fenollp Oct 26, 2026
3343590
fuzz: cover internal/nodeindex
fenollp Oct 26, 2026
ad82761
fuzz: add crashers found against #1238
fenollp Oct 25, 2026
669c89b
Merge branch 'master' into spike/native-yaml-stock-goyaml
reuvenharrison Oct 26, 2026
3a29179
openapi3: a mapping that merges itself expands to nothing
reuvenharrison Oct 26, 2026
96abc8d
nodeindex: a node ends no earlier than what it contains
reuvenharrison Oct 26, 2026
7fb763d
openapi3, nodeindex: name the upstream change each workaround waits for
reuvenharrison Oct 26, 2026
b87d8e1
openapi3, nodeindex: the fixes the new fuzz targets asked for
reuvenharrison Oct 26, 2026
dc5633b
openapi3: a second origin seed that fails on master and passes here
reuvenharrison Oct 26, 2026
8424c16
openapi3filter: decode query, path, header and cookie params with typ…
Yi-111-a Oct 22, 2026
44f4af5
openapi3filter: typeless const/enum decode with a slice of types, ext…
Oct 22, 2026
0d96dff
openapi3filter: simplify typeless const/enum type derivation, name su…
Oct 26, 2026
b8b4f18
openapi3filter: derive typeless const/enum candidate types in O(values)
Yi-111-a Oct 26, 2026
c0b6991
nodeindex: a node with no text has no extent (ported from #1382)
reuvenharrison Oct 26, 2026
77a18db
nodeindex: hold an entry to its own lines (ported from #1382)
reuvenharrison Oct 26, 2026
bc710bc
openapi3: a tagged timestamp is a string too, as it is on the json path
reuvenharrison Oct 26, 2026
21622f0
openapi2conv: handle some nil derefs (#1384)
reuvenharrison Oct 26, 2026
0790e96
nodeindex: a line ending is a break, not a character on the line
reuvenharrison Oct 26, 2026
4b868ce
ci: a minimize budget the minimizer can finish in (#1385)
reuvenharrison Oct 26, 2026
9ff7e37
openapi3: return a typed error for a disallowed external $ref (#1370)
reuvenharrison Oct 26, 2026
8d12901
openapi3: reject a multipleOf of zero or less in Schema.Validate (#1379)
LuisFigueroaG Oct 27, 2026
2e311b6
openapi3filter: treat a handler that writes no status as a 200 in Val…
LuisFigueroaG Oct 27, 2026
b959388
deps: update oasdiff/yaml to v0.1.3 (#1387)
reuvenharrison Oct 28, 2026
f074d9a
openapi3: validate the pattern of a schema without type in Schema.Val…
LuisFigueroaG Oct 29, 2026
f58588b
openapi3: set maxLength in Schema.WithMaxLengthDecodedBase64 (#1401)
LuisFigueroaG Oct 29, 2026
aaf4e27
openapi2conv: FromV3 no longer turns a binary header into a form fiel…
fenollp Oct 29, 2026
3fbcfc9
openapi3: internalize webhook references (#1408)
KashifManzer Oct 30, 2026
5aa7973
openapi2conv: keep required and format on a converted form field (#1405)
reuvenharrison Oct 30, 2026
7c95f0a
openapi2conv: escape a base path converted to a server of its own (#1…
reuvenharrison Oct 30, 2026
74727a2
internal: add nodeindex (decoding YAML natively 1/3) (#1382)
reuvenharrison Oct 30, 2026
545c898
openapi3: UnmarshalYAML for the types (decoding YAML natively 2/3) (#…
reuvenharrison Oct 30, 2026
1a0fab2
openapi3: keep component content when internalizing a ref to a file (…
akasakariko Oct 30, 2026
638c06d
Merge branch 'master' into spike/native-yaml-stock-goyaml
reuvenharrison Oct 31, 2026
6bfc8a4
openapi3: name the target type in a decoder error, not the shadow
reuvenharrison Oct 28, 2026
e1ccc16
openapi3: pin that an underscored key stays a string
reuvenharrison Oct 28, 2026
1fb09a3
openapi3: keep the error assertion off err.Error()
reuvenharrison Oct 28, 2026
ed9e062
openapi3: hold the decode to the json path's reading of scalars
reuvenharrison Oct 30, 2026
f4f8c9e
openapi3: regenerate the API docs after the merge with master
reuvenharrison Oct 31, 2026
3d94c22
openapi3: skip nil map entries when internalizing refs
fenollp Oct 31, 2026
17aed50
openapi3: never name an internalized component ""
fenollp Oct 31, 2026
81a32c0
openapi3: leave unfollowed refs alone when internalizing
fenollp Oct 31, 2026
0d11ec9
openapi3: report a ref into a missing part of its own document
fenollp Oct 31, 2026
edb3ecd
openapi3: record no path for a ref that resolves to nothing
fenollp Oct 31, 2026
c26b4a2
openapi3: follow the $ref of a file a ref points to as a whole
fenollp Oct 31, 2026
80b6048
openapi2, openapi3: do not discard errors decoding extensions
fenollp Oct 31, 2026
2471495
openapi3: terminate Schema.IsEmpty on cyclic schemas
fenollp Oct 31, 2026
b484990
openapi2, openapi3: write missing required maps as null in YAML too
fenollp Oct 31, 2026
e3e3b24
openapi3filter: no panic decoding a form body without a schema
fenollp Oct 31, 2026
1cdf081
openapi3filter: decode YAML bodies with non-string keys to map[string…
fenollp Oct 31, 2026
6c870be
openapi2: emit YAML from the generic form in FuzzUnmarshalFromData
fenollp Oct 31, 2026
e57ca64
openapi3: validate discriminators and the schemas their mapping loads
fenollp Nov 1, 2026
84645cd
openapi3: add FuzzInternalizeRefs
fenollp Oct 31, 2026
767eb7d
openapi3: add FuzzInternalizeRefsKeepsMeaning
fenollp Oct 31, 2026
3d3b367
openapi3: add FuzzValidateOptions
fenollp Oct 31, 2026
fafe475
openapi3: add FuzzInternalizeRefsCustomResolver
fenollp Oct 31, 2026
48e3ec4
openapi3: write a nil dependentRequired list as null in YAML too
fenollp Oct 31, 2026
5a0cd1e
openapi3: add FuzzMarshalYAML
fenollp Oct 31, 2026
d43935b
openapi3filter: add FuzzValidateResponse
fenollp Oct 31, 2026
683e535
openapi3filter: add FuzzBodyDecoder
fenollp Oct 31, 2026
99d5439
routers: add FuzzRoutersAgree
fenollp Oct 31, 2026
d8955bb
openapi3: nit
fenollp Oct 31, 2026
76af206
ci: check out before setup-go so its cache works
fenollp Nov 1, 2026
2fe77d6
openapi3filter: test deepObject array index limits (#1412)
connabyss Nov 1, 2026
b3222b4
Merge branch 'master' into spike/native-yaml-stock-goyaml
reuvenharrison Nov 1, 2026
515022b
openapi3: stamp the root key on the component a ref wrapper holds
reuvenharrison Nov 1, 2026
93d5e6b
openapi3: read a mapping key as the text the document wrote
reuvenharrison Nov 1, 2026
53014b6
openapi3: seed FuzzLoadWithOrigins with keys that resolve alike
reuvenharrison Nov 1, 2026
b91a681
openapi3: scope whole-file schema fragments to their document (#1413)
Aryangupta-05 Nov 1, 2026
320b82c
Merge remote-tracking branch 'upstream/master' into pr-1238-next
fenollp Nov 1, 2026
5060412
openapi3: refuse an alias that contains itself before decoding
fenollp Nov 1, 2026
70ce1ee
openapi3: read a scalar with an application's own tag as its text
fenollp Nov 1, 2026
4bc0e03
openapi3: %q the anchor name the cycle error reports
reuvenharrison Nov 1, 2026
e1760cc
openapi3: assert the reloaded document, not only its json
reuvenharrison Nov 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/docs/openapi2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ backwards-compatible with version 2, version 3 elements have been used.

See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md

FUNCTIONS

func UnmarshalFromData(data []byte, doc *T) error
UnmarshalFromData loads a document from swagger 2.0 bytes in either JSON or
YAML. The v3 side has Loader for this; here the whole job is the decode.


TYPES

type Header struct {
Expand Down
187 changes: 178 additions & 9 deletions .github/docs/openapi3.txt

Large diffs are not rendered by default.

130 changes: 130 additions & 0 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: fuzz
on:
pull_request:
push:
branches:
- master
schedule:
# Nightly, so a long run has a chance to reach code a 90s PR run never does.
- cron: '17 3 * * *'
workflow_dispatch:
inputs:
fuzztime:
description: 'How long to fuzz each target (go test -fuzztime syntax)'
required: false
default: 30m

permissions:
contents: read

jobs:
fuzz:
name: ${{ matrix.target }}
runs-on: ubuntu-latest
# A budget of 15m plus corpus minimization has to fit, and a hung target
# must not hold a runner forever.
timeout-minutes: 45
env:
# Keep in sync with the go workflow, whose cache this restores.
APISGURU_COMMIT: f7207cf0a5c56081d275ebae4cf615249323385d
GO111MODULE: 'on'
CGO_ENABLED: '0'
strategy:
# Every target reports independently: one crasher must not hide the rest.
fail-fast: false
matrix:
include:
- {package: ./openapi3, target: FuzzLoadFromData}
- {package: ./openapi3, target: FuzzLoadWithOrigins}
- {package: ./openapi3, target: FuzzYAMLMatchesJSON}
- {package: ./openapi3, target: FuzzSchemaVisitJSON}
- {package: ./openapi3, target: FuzzInternalizeRefs}
- {package: ./openapi3, target: FuzzInternalizeRefsKeepsMeaning}
- {package: ./openapi3, target: FuzzValidateOptions}
- {package: ./openapi3, target: FuzzInternalizeRefsCustomResolver}
- {package: ./openapi3, target: FuzzMarshalYAML}
- {package: ./openapi2, target: FuzzUnmarshalFromData}
- {package: ./internal/nodeindex, target: FuzzNew}
- {package: ./openapi2conv, target: FuzzToV3}
- {package: ./openapi3filter, target: FuzzValidateRequest}
- {package: ./openapi3filter, target: FuzzValidateResponse}
- {package: ./openapi3filter, target: FuzzBodyDecoder}
- {package: ./routers, target: FuzzRoutersAgree}
steps:

# Checked out first: setup-go keys its module and build cache on go.sum,
# and without one it caches nothing.
- uses: actions/checkout@v6

- uses: actions/setup-go@v6
with:
go-version: stable

# The APIs-guru corpus seeds the fuzzers alongside testdata. The go
# workflow caches it, so fetch it only when that cache is missing.
- name: APIs-guru corpus cache
id: apisguru
uses: actions/cache/restore@v4
with:
path: |
openapi2/testdata/APIs-guru-openapi-directory-*
openapi3/testdata/APIs-guru-openapi-directory-*
key: suite-${{ env.APISGURU_COMMIT }}

- name: Fetch APIs-guru corpus
if: steps.apisguru.outputs.cache-hit != 'true'
run: |
dir=openapi3/testdata/APIs-guru-openapi-directory-${APISGURU_COMMIT:0:7}
mkdir -p "$dir"
curl -fsSL "https://github.com/APIs-guru/openapi-directory/tarball/$APISGURU_COMMIT" | tar -xz -C "$dir"

# The generated corpus lives under $GOCACHE/fuzz and is what makes fuzzing
# cumulative: without it every run restarts from the seed corpus. The key
# carries the run id so each run writes a fresh entry, and restore-keys
# falls back to the most recent one for this target.
- name: Fuzzing corpus cache
uses: actions/cache@v4
with:
path: ~/.cache/go-build/fuzz
key: fuzz-${{ matrix.target }}-${{ github.run_id }}
restore-keys: fuzz-${{ matrix.target }}-

- name: Pick a budget
id: budget
run: |
if [[ -n '${{ inputs.fuzztime }}' ]]; then
fuzztime='${{ inputs.fuzztime }}'
elif [[ '${{ github.event_name }}' = schedule ]]; then
fuzztime=15m
else
fuzztime=90s
fi
echo "fuzztime=$fuzztime" >>"$GITHUB_OUTPUT"

# -run='^$' skips the ordinary tests: the seed corpus is already replayed by
# `go test ./...` in the go workflow, so this job only spends time fuzzing.
#
# The minimize budget is small on purpose. A minimize that cannot finish
# inside it writes the candidate it had and the job fails with "fuzzing
# process hung or terminated unexpectedly while minimizing", whose
# candidate then passes on replay: a red build and nothing to act on. The
# budget only decides how small the saved input gets, so spending less of
# it costs a larger seed and buys a signal that means what it says.
- name: Fuzz ${{ matrix.target }}
run: |
go test \
-run='^$' \
-fuzz='^${{ matrix.target }}$' \
-fuzztime='${{ steps.budget.outputs.fuzztime }}' \
-fuzzminimizetime=10s \
${{ matrix.package }}

# A failing input is written next to the package it broke. Upload it so the
# crasher can be committed to the seed corpus, where it becomes a permanent
# regression test replayed by `go test ./...`.
- if: failure()
uses: actions/upload-artifact@v4
with:
name: crashers-${{ matrix.target }}
path: '**/testdata/fuzz/**'
if-no-files-found: ignore
19 changes: 12 additions & 7 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@ jobs:
name: ${{ matrix.go }} on ${{ matrix.os }}
steps:

# Checked out first: setup-go keys its module and build cache on go.sum,
# and without one it caches nothing.
- uses: actions/checkout@v6

- uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go }}

- if: runner.os == 'Linux'
run: sudo apt install silversearcher-ag

- uses: actions/checkout@v6

- name: Test suite fixtures cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
openapi2/testdata/APIs-guru-openapi-directory-*
Expand Down Expand Up @@ -90,6 +92,9 @@ jobs:
- run: go test -v -count=10 -run TestIssue741 -race ./...
env:
CGO_ENABLED: '1'
- run: go test -v -count=10 -run TestConcurrentDecodeDoesNotLeakOrigins -race ./...
env:
CGO_ENABLED: '1'
- run: git --no-pager diff --exit-code

- if: runner.os == 'Linux'
Expand Down Expand Up @@ -117,9 +122,9 @@ jobs:
! git grep -IErn '\s$'

- if: runner.os == 'Linux'
name: Ensure use of unmarshal
name: Ensure yaml stays inside the decode layer
run: |
[[ "$(git grep -F yaml. -- openapi3/ | grep -v _test.go | grep -v origin.go | wc -l)" = 2 ]]
[[ "$(git grep -F yaml. -- openapi3/ | grep -v _test.go | grep -vE 'openapi3/(origin|marsh|refs|loader|native_yaml.*|nativeyaml.*)[.](go|tmpl)' | wc -l)" -eq 0 ]]

- if: runner.os == 'Linux'
name: Use `loader := NewLoader(); loader.Load ...`
Expand Down Expand Up @@ -201,9 +206,9 @@ jobs:
- if: runner.os == 'Linux'
name: Ensure readableType() covers all possible values of resolved var
run: |
[[ "$(git grep -F 'var resolved ' -- openapi3/loader.go | awk '{print $4}' | sort | tr '\n' ' ')" = "$RESOLVEDS" ]]
[[ "$(git grep -F 'var resolved ' -- openapi3/loader.go | awk '{print $4}' | sort | uniq | tr '\n' ' ')" = "$RESOLVEDS" ]]
env:
RESOLVEDS: 'Callback CallbackRef ExampleRef HeaderRef LinkRef ParameterRef PathItem RequestBodyRef ResponseRef SchemaRef SecuritySchemeRef '
RESOLVEDS: 'CallbackRef ExampleRef HeaderRef LinkRef ParameterRef PathItem RequestBodyRef ResponseRef SchemaRef SecuritySchemeRef '

check-goimports:
runs-on: ubuntu-latest
Expand Down
41 changes: 27 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,28 +1,41 @@
.DEFAULT_GOAL := prepare
.DEFAULT_GOAL := all
.PHONY: help generate format test test-fast fuzz all

.PHONY: help generate format test prepare
# How long to spend on each fuzz target. Override: make fuzz FUZZTIME=10m
FUZZTIME ?= 60s

help:
@printf '%s\n' \
'Usage: make <target>' \
'' \
' generate Regenerate Go code, map helpers, and API documentation.' \
' format Apply the repository formatters and import cleanup.' \
' test Run the full Go package test suite.' \
' prepare Run generation, formatting, and tests in sequence.'
## all: Run generation, formatting, and tests in sequence
all: generate format test

## generate: Regenerate Go code, map helpers, and API documentation
generate:
go generate ./...
./maps.sh
./docs.sh

## format: Apply the repository formatters and import cleanup
format:
go fmt ./...

## test: Run the full Go package test suite
test:
go test ./...

prepare:
$(MAKE) generate
$(MAKE) format
$(MAKE) test
## test-fast: Run tests skipping the slow ones
test-fast:
go test -short ./...

## fuzz: Fuzz each target for FUZZTIME (default 60s)
fuzz:
go test -run='^$$' -fuzz='^FuzzLoadFromData$$' -fuzztime=$(FUZZTIME) ./openapi3
go test -run='^$$' -fuzz='^FuzzLoadWithOrigins$$' -fuzztime=$(FUZZTIME) ./openapi3
go test -run='^$$' -fuzz='^FuzzYAMLMatchesJSON$$' -fuzztime=$(FUZZTIME) ./openapi3
go test -run='^$$' -fuzz='^FuzzSchemaVisitJSON$$' -fuzztime=$(FUZZTIME) ./openapi3
go test -run='^$$' -fuzz='^FuzzUnmarshalFromData$$' -fuzztime=$(FUZZTIME) ./openapi2
go test -run='^$$' -fuzz='^FuzzNew$$' -fuzztime=$(FUZZTIME) ./internal/nodeindex
go test -run='^$$' -fuzz='^FuzzToV3$$' -fuzztime=$(FUZZTIME) ./openapi2conv
go test -run='^$$' -fuzz='^FuzzValidateRequest$$' -fuzztime=$(FUZZTIME) ./openapi3filter

## help: list targets
help:
@grep -E '^## ' $(MAKEFILE_LIST) | sed 's/## / make /'
Loading