git.iko.soy/typeable/compaREST
on master help sign in
Tuple items (#108)

* Add implication checks for tuple items * Parse TupleItems from the source schema * Add tests * Refined report wording Co-authored-by: iko <ilyakooo0@gmail.com>

commitdcd32cbdd9ac41547e275fc316bad09f3ebb61dc authormniip <mniip@users.noreply.github.com> dateWed 21 Jul 2021, 16:28 (5 years ago) parent7029d24
26 files changed+799−14
src/OpenAPI/Checker/Report.hs+2 src/OpenAPI/Checker/Validate/Schema.hs+70−13 src/OpenAPI/Checker/Validate/Schema/Issues.hs+17 src/OpenAPI/Checker/Validate/Schema/JsonFormula.hs+5 src/OpenAPI/Checker/Validate/Schema/Process.hs+5−1 src/OpenAPI/Checker/Validate/Schema/Traced.hs+1 test/golden/common/tuple-items/heterogeneous-component-mismatch/a.yaml+28 test/golden/common/tuple-items/heterogeneous-component-mismatch/b.yaml+28 test/golden/common/tuple-items/heterogeneous-component-mismatch/report.md+37 test/golden/common/tuple-items/heterogeneous-component-mismatch/trace-tree.yaml+30 test/golden/common/tuple-items/heterogeneous-length-mismatch/a.yaml+29 test/golden/common/tuple-items/heterogeneous-length-mismatch/b.yaml+28 test/golden/common/tuple-items/heterogeneous-length-mismatch/report.md+37 test/golden/common/tuple-items/heterogeneous-length-mismatch/trace-tree.yaml+26 test/golden/common/tuple-items/homogeneous-component-mismatch/a.yaml+28 test/golden/common/tuple-items/homogeneous-component-mismatch/b.yaml+29 test/golden/common/tuple-items/homogeneous-component-mismatch/report.md+53 test/golden/common/tuple-items/homogeneous-component-mismatch/trace-tree.yaml+34 test/golden/common/tuple-items/homogeneous-length-mismatch/a.yaml+56 test/golden/common/tuple-items/homogeneous-length-mismatch/b.yaml+67 test/golden/common/tuple-items/homogeneous-length-mismatch/report.md+73 test/golden/common/tuple-items/homogeneous-length-mismatch/trace-tree.yaml+52 test/golden/common/tuple-items/homogeneous-vector/a.yaml+28 test/golden/common/tuple-items/homogeneous-vector/b.yaml+29 test/golden/common/tuple-items/homogeneous-vector/report.md+5 test/golden/common/tuple-items/homogeneous-vector/trace-tree.yaml+2
src/OpenAPI/Checker/Report.hs+2
@@ -233,10 +233,12 @@ jets =
233233 showParts (SingletonUnion (OfType Object) : xs@((SingletonUnion (InProperty _)) : _)) = showParts xs
234234 showParts (SingletonUnion (OfType Object) : xs@((SingletonUnion InAdditionalProperty) : _)) = showParts xs
235235 showParts (SingletonUnion (OfType Array) : xs@(SingletonUnion InItems : _)) = showParts xs
236+ showParts (SingletonUnion (OfType Array) : xs@(SingletonUnion (InItem _) : _)) = showParts xs
236237 showParts (y : ys) =
237238 ((\(OfType t) -> "(" <> describeJSONType t <> ")")
238239 @@> (\case
239240 InItems -> "[*]"
241+ InItem i -> "[" <> T.pack (show i) <> "]"
240242 InProperty p -> "." <> p
241243 InAdditionalProperty -> ".*")
242244 @@> typesExhausted)
src/OpenAPI/Checker/Validate/Schema.hs+70−13
@@ -7,15 +7,17 @@ where
77import Control.Monad.Writer
88import qualified Data.Aeson as A
99import Data.Coerce
10−import Data.Foldable (for_)
10+import Data.Foldable (for_, toList)
1111import Data.Functor
1212import Data.HList
1313import qualified Data.List.NonEmpty as NE
1414import qualified Data.Map as M
15+import Data.List (group, genericLength, genericIndex)
1516import Data.Maybe
1617import Data.OpenApi
1718import Data.Ord
1819import Data.Ratio
20+import Data.Semigroup
1921import qualified Data.Set as S
2022import Data.Text (Text)
2123import OpenAPI.Checker.Behavior
@@ -34,10 +36,11 @@ checkFormulas
3436 :: (ReassembleHList xs (CheckEnv (Referenced Schema)))
3537 => HList xs
3638 -> Behavior 'SchemaLevel
39+ -> ProdCons (Trace Schema)
3740 -> ProdCons (Traced (Definitions Schema))
3841 -> ProdCons (ForeachType JsonFormula, P.PathsPrefixTree Behave AnIssue 'SchemaLevel)
3942 -> SemanticCompatFormula ()
40−checkFormulas env beh defs (ProdCons (fp, ep) (fc, ec)) =
43+checkFormulas env beh trs defs (ProdCons (fp, ep) (fc, ec)) =
4144 case P.toList ep ++ P.toList ec of
4245 issues@(_ : _) -> for_ issues $ embedFormula beh . anItem
4346 [] -> do
@@ -105,25 +108,25 @@ checkFormulas env beh defs (ProdCons (fp, ep) (fc, ec)) =
105108 -- don't repeat the TypesRestricted issue
106109 for_ pss $ \(Disjunct ps) -> checkContradiction beh' Nothing ps
107110 (DNF pss, SingleDisjunct (Disjunct cs)) -> for_ pss $ \(Disjunct ps) -> do
108− for_ cs $ checkImplication env beh' ps -- avoid disjunction if there's only one conjunct
111+ for_ cs $ checkImplication env beh' trs ps -- avoid disjunction if there's only one conjunct
109112 (TopDNF, DNF css) ->
110113 -- producer is "open" (allows any value), but consumer has restrictions.
111114 -- In this case we want to show which restrictions were added. (instead
112115 -- of showing an empty list restrictions that couldn't be satisfied.)
113− for_ css $ \(Disjunct cs) -> for_ cs $ checkImplication env beh' S.empty
116+ for_ css $ \(Disjunct cs) -> for_ cs $ checkImplication env beh' trs S.empty
114117 (pss', css') -> for_ (tryPartition defs $ ProdCons (JsonFormula pss') (JsonFormula css')) $ \case
115118 (mPart, ProdCons pf cf) -> do
116119 let beh'' = foldr ((<<<) . step . InPartition) beh' mPart
117120 case (getJsonFormula pf, getJsonFormula cf) of
118121 (DNF pss, BottomDNF) -> for_ pss $ \(Disjunct ps) -> checkContradiction beh' mPart ps
119122 (DNF pss, SingleDisjunct (Disjunct cs)) -> for_ pss $ \(Disjunct ps) -> do
120− for_ cs $ checkImplication env beh'' ps
123+ for_ cs $ checkImplication env beh'' trs ps
121124 -- unlucky:
122125 (DNF pss, DNF css) -> for_ pss $ \(Disjunct ps) -> do
123126 anyOfAt
124127 beh'
125128 (issueFromDisjunct Nothing ps)
126− [for_ cs $ checkImplication env beh' ps | Disjunct cs <- S.toList css]
129+ [for_ cs $ checkImplication env beh' trs ps | Disjunct cs <- S.toList css]
127130 pure ()
128131 where
129132 anyBottomTypes f = getAny $
@@ -151,10 +154,11 @@ checkImplication
151154 :: (ReassembleHList xs (CheckEnv (Referenced Schema)))
152155 => HList xs
153156 -> Behavior 'TypedSchemaLevel
157+ -> ProdCons (Trace Schema) -- the traces of the root schemas used in this comparison
154158 -> S.Set (Condition t)
155159 -> Condition t
156160 -> SemanticCompatFormula ()
157−checkImplication env beh prods cons = case findExactly prods of
161+checkImplication env beh trs prods cons = case findExactly prods of
158162 Just e
159163 | all (satisfiesTyped e) prods ->
160164 if satisfiesTyped e cons
@@ -208,24 +212,69 @@ checkImplication env beh prods cons = case findExactly prods of
208212 False -> issueAt beh (NoMatchingFormat f)
209213
210214 Items _ cons' -> case foldSome (<>) prods $ \case
211− Items _ rs -> Just (rs NE.:| [])
215+ Items _ rs -> Just (Just (rs NE.:| []), mempty)
216+ TupleItems (map snd -> fs) -> Just (mempty, Just (fs NE.:| []))
212217 _ -> Nothing
213218 of
214− Just (tracedConjunct -> rs) -> checkCompatibility (beh >>> step InItems) env $ ProdCons rs cons'
215− Nothing -> issueAt beh NoMatchingItems
219+ Just (mItems, Just pfs)
220+ | not $ allSame (length <$> pfs) -> pure () -- vacuously
221+ | let plen = genericLength (NE.head pfs)
222+ -> clarifyIssue (AnItem beh (anIssue TupleToArray)) $ for_ [0 .. plen - 1] $ \i -> do
223+ let prod' = tracedConjunct $ case mItems of
224+ Just prods' -> ((`genericIndex` i) <$> pfs) <> prods'
225+ Nothing -> (`genericIndex` i) <$> pfs
226+ checkCompatibility (beh >>> step (InItem i)) env $ ProdCons prod' cons'
227+ Just (Just prods', Nothing) -> do
228+ let prod' = tracedConjunct prods'
229+ checkCompatibility (beh >>> step InItems) env $ ProdCons prod' cons'
230+ _ -> clarifyIssue (AnItem beh (anIssue NoMatchingItems)) $ do
231+ checkCompatibility (beh >>> step InItems) env $ ProdCons prodTopSchema cons'
232+
233+ TupleItems (map snd -> fs) -> case foldSome (<>) prods $ \case
234+ TupleItems (map snd -> fs') -> Just (Just $ fs' NE.:| [], Just . Max $ genericLength fs', Just . Min $ genericLength fs', mempty)
235+ MinItems m' -> Just (mempty, Just . Max $ m', mempty, mempty)
236+ MaxItems m' -> Just (mempty, mempty, Just . Min $ m', mempty)
237+ Items _ rs -> Just (mempty, mempty, mempty, Just (rs NE.:| []))
238+ _ -> Nothing
239+ of
240+ -- if the length constraints in the producer are contradictory:
241+ Just (_, Just (Max lowest), Just (Min highest), _) | lowest > highest -> pure ()
242+ -- We have an explicit tuple items clause...
243+ Just (Just pfs, Just (Max plen), _, _)
244+ | plen /= genericLength fs -- ...of wrong length
245+ -> issueAt beh (TupleItemsLengthChanged ProdCons {producer = plen, consumer = genericLength fs})
246+ | otherwise
247+ -> for_ [0 .. plen - 1] $ \i -> do
248+ checkCompatibility (beh >>> step (InItem i)) env $ ProdCons (tracedConjunct $ (`genericIndex` i) <$> pfs) (fs `genericIndex` i)
249+ -- We have a fixed length array in the producer...
250+ Just (Nothing, Just (Max plen), Just (Min plen'), mProd)
251+ | plen == plen'
252+ -> clarifyIssue (AnItem beh (anIssue ArrayToTuple)) $ case mProd of
253+ _ | plen /= genericLength fs -> -- ...of wrong length
254+ issueAt beh (TupleItemsLengthChanged ProdCons {producer = plen, consumer = genericLength fs})
255+ Just rs -> for_ [0 .. plen - 1] $ \i -> do
256+ checkCompatibility (beh >>> step (InItem i)) env $ ProdCons (tracedConjunct rs) (fs `genericIndex` i)
257+ -- ...and no "items" schema
258+ Nothing -> clarifyIssue (AnItem beh (anIssue NoMatchingTupleItems)) $ do
259+ for_ [0 .. plen - 1] $ \i -> do
260+ checkCompatibility (beh >>> step (InItem i)) env $ ProdCons prodTopSchema (fs `genericIndex` i)
261+ _ -> issueAt beh NoMatchingTupleItems
216262
217263 MaxItems m -> foldCheck min m NoMatchingMaxItems MatchingMaxItemsWeak $ \case
218264 MaxItems m' -> Just m'
265+ TupleItems fs -> Just $ toInteger $ length fs
219266 _ -> Nothing
220267
221268 MinItems m -> foldCheck max m NoMatchingMinItems MatchingMinItemsWeak $ \case
222269 MinItems m' -> Just m'
223− _ -> Nothing -- TODO: tuple items
270+ TupleItems fs -> Just $ toInteger $ length fs
271+ _ -> Nothing
224272
225273 UniqueItems -> case flip any prods $ \case
226274 UniqueItems -> True
227275 MaxItems 1 -> True
228− _ -> False -- TODO: tuple items
276+ TupleItems fs | length fs == 1 -> True
277+ _ -> False
229278 of
230279 True -> pure ()
231280 False -> issueAt beh NoMatchingUniqueItems
@@ -290,6 +339,14 @@ checkImplication env beh prods cons = case findExactly prods of
290339 | otherwise -> issueAt beh (weak ProdCons {producer = m', consumer = m})
291340 Nothing -> issueAt beh (missing m)
292341
342+ prodTopSchema = traced (producer trs >>> step ImplicitTopSchema) $ Inline mempty
343+
344+allSame :: (Foldable f, Eq a) => f a -> Bool
345+allSame xs = case group (toList xs) of
346+ [] -> True
347+ [_] -> True
348+ _ -> False
349+
293350foldSome :: (b -> b -> b) -> S.Set a -> (a -> Maybe b) -> Maybe b
294351foldSome combine xs extr =
295352 fmap (foldr1 combine) . NE.nonEmpty . mapMaybe extr . S.toList $ xs
@@ -353,7 +410,7 @@ instance Subtree Schema where
353410 structuralItems _ = structuralIssue
354411 checkSemanticCompatibility env beh schs = do
355412 let defs = getH env
356− checkFormulas env beh defs $ schemaToFormula <$> defs <*> schs
413+ checkFormulas env beh (ask <$> schs) defs $ schemaToFormula <$> defs <*> schs
357414
358415parseDiscriminatorValue :: Text -> Referenced Schema
359416parseDiscriminatorValue v = case A.fromJSON @(Referenced Schema) $ A.object ["$ref" A..= v] of
src/OpenAPI/Checker/Validate/Schema/Issues.hs+17
@@ -50,6 +50,14 @@ instance Issuable 'TypedSchemaLevel where
5050 NoMatchingPattern Pattern
5151 | -- | consumer declares the items of an array must satisfy some condition, producer doesn't
5252 NoMatchingItems
53+ | -- | producer and consumer declare that an array must be a tuple of a fixed length, but the lengths don't match
54+ TupleItemsLengthChanged (ProdCons Integer)
55+ | -- | consumer declares that the array is a tuple, but the producer doesn't, the length constraints match, but there were issues with the components
56+ ArrayToTuple
57+ | -- | producer declares that the array is a tuple, but the consumer doesn't, and there were issues with the components
58+ TupleToArray
59+ | -- | consumer declares that the array is a tuple, but the producer doesn't, and there aren't sufficient length constraints
60+ NoMatchingTupleItems
5361 | -- | consumer declares a maximum length of the array ($1), producer doesn't.
5462 NoMatchingMaxItems Integer
5563 | -- | consumer declares a maximum length of the array ($1), producer declares a weaker (higher) limit ($2)
@@ -105,6 +113,13 @@ instance Issuable 'TypedSchemaLevel where
105113 describeIssue Backward (NoMatchingPattern p) = para "Pattern (regular expression) removed: " <> codeBlock p
106114 describeIssue Forward NoMatchingItems = para "Array item schema has been added."
107115 describeIssue Backward NoMatchingItems = para "Array item schema has been removed."
116+ describeIssue _ (TupleItemsLengthChanged (ProdCons p c)) = para $ "Tuple length changed from " <> show' p <> " to " <> show' c <> "."
117+ describeIssue Forward ArrayToTuple = para "The array is now explicitly defined as a tuple."
118+ describeIssue Backward ArrayToTuple = para "The array is no longer explicitly defined as a tuple."
119+ describeIssue Forward TupleToArray = para "The array is no longer explicitly defined as a tuple."
120+ describeIssue Backward TupleToArray = para "The array is now explicitly defined as a tuple."
121+ describeIssue Forward NoMatchingTupleItems = para "The array is now explicitly defined as a tuple."
122+ describeIssue Backward NoMatchingTupleItems = para "The array is no longer explicitly defined as a tuple."
108123 describeIssue Forward (NoMatchingMaxItems n) = para $ "Maximum length of the array has been added " <> show' n <> "."
109124 describeIssue Backward (NoMatchingMaxItems n) = para $ "Maximum length of the array has been removed " <> show' n <> "."
110125 describeIssue _ (MatchingMaxItemsWeak (ProdCons p c)) = para $ "Maximum length of the array changed from " <> show' p <> " to " <> show' c <> "."
@@ -213,10 +228,12 @@ instance Behavable 'TypedSchemaLevel 'TypedSchemaLevel where
213228instance Behavable 'TypedSchemaLevel 'SchemaLevel where
214229 data Behave 'TypedSchemaLevel 'SchemaLevel
215230 = InItems
231+ | InItem Integer
216232 | InProperty Text
217233 | InAdditionalProperty
218234 deriving stock (Eq, Ord, Show)
219235
220236 describeBehaviour InItems = "Items"
237+ describeBehaviour (InItem i) = "Item " <> show' i
221238 describeBehaviour (InProperty p) = "Property " <> code p
222239 describeBehaviour InAdditionalProperty = "Additional properties"
src/OpenAPI/Checker/Validate/Schema/JsonFormula.hs+5
@@ -80,6 +80,9 @@ data Condition :: JsonType -> Type where
8080 :: !(ForeachType JsonFormula)
8181 -> !(Traced (Referenced Schema))
8282 -> Condition 'Array
83+ TupleItems
84+ :: ![(ForeachType JsonFormula, Traced (Referenced Schema))]
85+ -> Condition 'Array
8386 MaxItems :: !Integer -> Condition 'Array
8487 MinItems :: !Integer -> Condition 'Array
8588 UniqueItems :: Condition 'Array
@@ -109,6 +112,7 @@ showCondition = \case
109112 (MaxLength p) -> para $ "The length of the string should be less than or equal to " <> show' p <> "."
110113 (MinLength p) -> para $ "The length of the string should be more than or equal to " <> show' p <> "."
111114 (Items i _) -> para "The items of the array should satisfy:" <> showForEachJsonFormula i
115+ (TupleItems is) -> para ("There should be " <> show' (length is) <> " items in the array:") <> bulletList (showForEachJsonFormula . fst <$> is)
112116 (MaxItems n) -> para $ "The length of the array should be less than or equal to " <> show' n <> "."
113117 (MinItems n) -> para $ "The length of the array should be more than or equal to " <> show' n <> "."
114118 UniqueItems -> para "The elements in the array should be unique."
@@ -161,6 +165,7 @@ satisfiesTyped (TString s) (MinLength m) = fromIntegral (T.length s) >= m
161165satisfiesTyped (TString s) (Pattern p) = isJust $ match p s -- TODO: regex stuff #32
162166satisfiesTyped (TString s) (StringFormat f) = checkStringFormat f s
163167satisfiesTyped (TArray a) (Items f _) = all (`satisfies` f) a
168+satisfiesTyped (TArray a) (TupleItems fs) = length fs == F.length a && and (zipWith satisfies (F.toList a) (fst <$> fs))
164169satisfiesTyped (TArray a) (MaxItems m) = fromIntegral (F.length a) <= m
165170satisfiesTyped (TArray a) (MinItems m) = fromIntegral (F.length a) >= m
166171satisfiesTyped (TArray a) UniqueItems = S.size (S.fromList $ F.toList a) == F.length a -- TODO: could be better #36
src/OpenAPI/Checker/Validate/Schema/Process.hs+5−1
@@ -245,7 +245,11 @@ processSchema sch@(extract -> Schema {..}) = do
245245 Just (Left rs) -> do
246246 f <- silently $ processRefSchema rs
247247 pure top {forArray = singletonFormula $ Items f rs}
248− Just (Right _) -> top <$ warn (NotSupported "array in items is not supported")
248+ Just (Right rss) -> do
249+ fsrs <- forM rss $ \rs -> do
250+ f <- silently $ processRefSchema rs
251+ pure (f, rs)
252+ pure top {forArray = singletonFormula $ TupleItems fsrs}
249253
250254 let maxItemsClause = case _schemaMaxItems of
251255 Nothing -> top
src/OpenAPI/Checker/Validate/Schema/Traced.hs+1
@@ -46,6 +46,7 @@ instance Steppable Schema (Referenced Schema) where
4646 | ItemsArrayStep Int
4747 | AdditionalPropertiesStep
4848 | NotStep
49+ | ImplicitTopSchema
4950 deriving stock (Eq, Ord, Show)
5051
5152instance Steppable (Referenced Schema) (Referenced Schema) where
test/golden/common/tuple-items/heterogeneous-component-mismatch/a.yamlnew file+28
@@ -0,0 +1,28 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+components:
23+ schemas:
24+ Test:
25+ type: array
26+ items:
27+ - type: number
28+ - type: string
test/golden/common/tuple-items/heterogeneous-component-mismatch/b.yamlnew file+28
@@ -0,0 +1,28 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+components:
23+ schemas:
24+ Test:
25+ type: array
26+ items:
27+ - type: number
28+ - type: object
test/golden/common/tuple-items/heterogeneous-component-mismatch/report.mdnew file+37
@@ -0,0 +1,37 @@
1+# Summary
2+
3+| [⚠️ Breaking changes](#breaking-changes) | [🙆 Non-breaking changes](#non-breaking-changes) | 🤷 Unsupported feature changes |
4+|------------------------------------------|-------------------------------------------------|-------------------------------|
5+| 2 | 2 | 0 |
6+
7+# <span id="breaking-changes"></span>⚠️ Breaking changes
8+
9+## **POST** /test
10+
11+### 📱➡️ JSON Request
12+
13+#### `$[1](String)`
14+
15+The type has been removed.
16+
17+### 📱⬅️ JSON Response – 200
18+
19+#### `$[1](Object)`
20+
21+The type has been added.
22+
23+# <span id="non-breaking-changes"></span>🙆 Non-breaking changes
24+
25+## **POST** /test
26+
27+### 📱➡️ JSON Request
28+
29+#### `$[1](Object)`
30+
31+The type has been added.
32+
33+### 📱⬅️ JSON Response – 200
34+
35+#### `$[1](String)`
36+
37+The type has been removed.
test/golden/common/tuple-items/heterogeneous-component-mismatch/trace-tree.yamlnew file+30
@@ -0,0 +1,30 @@
1+breakingChanges:
2+ AtPath "/test":
3+ InOperation PostMethod:
4+ InRequest:
5+ InPayload:
6+ PayloadSchema:
7+ OfType Array:
8+ InItem 1:
9+ OfType String: TypeBecomesEmpty
10+ WithStatusCode 200:
11+ ResponsePayload:
12+ PayloadSchema:
13+ OfType Array:
14+ InItem 1:
15+ OfType Object: TypeBecomesEmpty
16+nonBreakingChanges:
17+ AtPath "/test":
18+ InOperation PostMethod:
19+ InRequest:
20+ InPayload:
21+ PayloadSchema:
22+ OfType Array:
23+ InItem 1:
24+ OfType Object: TypeBecomesEmpty
25+ WithStatusCode 200:
26+ ResponsePayload:
27+ PayloadSchema:
28+ OfType Array:
29+ InItem 1:
30+ OfType String: TypeBecomesEmpty
test/golden/common/tuple-items/heterogeneous-length-mismatch/a.yamlnew file+29
@@ -0,0 +1,29 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+components:
23+ schemas:
24+ Test:
25+ type: array
26+ items:
27+ - type: number
28+ - type: string
29+ - type: object
test/golden/common/tuple-items/heterogeneous-length-mismatch/b.yamlnew file+28
@@ -0,0 +1,28 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+components:
23+ schemas:
24+ Test:
25+ type: array
26+ items:
27+ - type: number
28+ - type: object
test/golden/common/tuple-items/heterogeneous-length-mismatch/report.mdnew file+37
@@ -0,0 +1,37 @@
1+# Summary
2+
3+| [⚠️ Breaking changes](#breaking-changes) | [🙆 Non-breaking changes](#non-breaking-changes) | 🤷 Unsupported feature changes |
4+|------------------------------------------|-------------------------------------------------|-------------------------------|
5+| 2 | 2 | 0 |
6+
7+# <span id="breaking-changes"></span>⚠️ Breaking changes
8+
9+## **POST** /test
10+
11+### 📱➡️ JSON Request
12+
13+#### `$(Array)`
14+
15+Tuple length changed from 3 to 2.
16+
17+### 📱⬅️ JSON Response – 200
18+
19+#### `$(Array)`
20+
21+Tuple length changed from 2 to 3.
22+
23+# <span id="non-breaking-changes"></span>🙆 Non-breaking changes
24+
25+## **POST** /test
26+
27+### 📱➡️ JSON Request
28+
29+#### `$(Array)`
30+
31+Tuple length changed from 2 to 3.
32+
33+### 📱⬅️ JSON Response – 200
34+
35+#### `$(Array)`
36+
37+Tuple length changed from 3 to 2.
test/golden/common/tuple-items/heterogeneous-length-mismatch/trace-tree.yamlnew file+26
@@ -0,0 +1,26 @@
1+breakingChanges:
2+ AtPath "/test":
3+ InOperation PostMethod:
4+ InRequest:
5+ InPayload:
6+ PayloadSchema:
7+ OfType Array: TupleItemsLengthChanged (ProdCons {producer = 3, consumer
8+ = 2})
9+ WithStatusCode 200:
10+ ResponsePayload:
11+ PayloadSchema:
12+ OfType Array: TupleItemsLengthChanged (ProdCons {producer = 2, consumer
13+ = 3})
14+nonBreakingChanges:
15+ AtPath "/test":
16+ InOperation PostMethod:
17+ InRequest:
18+ InPayload:
19+ PayloadSchema:
20+ OfType Array: TupleItemsLengthChanged (ProdCons {producer = 2, consumer
21+ = 3})
22+ WithStatusCode 200:
23+ ResponsePayload:
24+ PayloadSchema:
25+ OfType Array: TupleItemsLengthChanged (ProdCons {producer = 3, consumer
26+ = 2})
test/golden/common/tuple-items/homogeneous-component-mismatch/a.yamlnew file+28
@@ -0,0 +1,28 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+components:
23+ schemas:
24+ Test:
25+ type: array
26+ items:
27+ - type: string
28+ - type: number
test/golden/common/tuple-items/homogeneous-component-mismatch/b.yamlnew file+29
@@ -0,0 +1,29 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+components:
23+ schemas:
24+ Test:
25+ type: array
26+ minItems: 2
27+ maxItems: 2
28+ items:
29+ type: number
test/golden/common/tuple-items/homogeneous-component-mismatch/report.mdnew file+53
@@ -0,0 +1,53 @@
1+# Summary
2+
3+| [⚠️ Breaking changes](#breaking-changes) | [🙆 Non-breaking changes](#non-breaking-changes) | 🤷 Unsupported feature changes |
4+|------------------------------------------|-------------------------------------------------|-------------------------------|
5+| 4 | 4 | 0 |
6+
7+# <span id="breaking-changes"></span>⚠️ Breaking changes
8+
9+## **POST** /test
10+
11+### 📱➡️ JSON Request
12+
13+#### `$(Array)`
14+
15+The array is no longer explicitly defined as a tuple.
16+
17+#### `$[0](String)`
18+
19+The type has been removed.
20+
21+### 📱⬅️ JSON Response – 200
22+
23+#### `$(Array)`
24+
25+The array is no longer explicitly defined as a tuple.
26+
27+#### `$[0](Number)`
28+
29+The type has been added.
30+
31+# <span id="non-breaking-changes"></span>🙆 Non-breaking changes
32+
33+## **POST** /test
34+
35+### 📱➡️ JSON Request
36+
37+#### `$(Array)`
38+
39+The array is no longer explicitly defined as a tuple.
40+
41+#### `$[0](Number)`
42+
43+The type has been added.
44+
45+### 📱⬅️ JSON Response – 200
46+
47+#### `$(Array)`
48+
49+The array is no longer explicitly defined as a tuple.
50+
51+#### `$[0](String)`
52+
53+The type has been removed.
test/golden/common/tuple-items/homogeneous-component-mismatch/trace-tree.yamlnew file+34
@@ -0,0 +1,34 @@
1+breakingChanges:
2+ AtPath "/test":
3+ InOperation PostMethod:
4+ InRequest:
5+ InPayload:
6+ PayloadSchema:
7+ OfType Array:
8+ - TupleToArray
9+ - InItem 0:
10+ OfType String: TypeBecomesEmpty
11+ WithStatusCode 200:
12+ ResponsePayload:
13+ PayloadSchema:
14+ OfType Array:
15+ - ArrayToTuple
16+ - InItem 0:
17+ OfType Number: TypeBecomesEmpty
18+nonBreakingChanges:
19+ AtPath "/test":
20+ InOperation PostMethod:
21+ InRequest:
22+ InPayload:
23+ PayloadSchema:
24+ OfType Array:
25+ - ArrayToTuple
26+ - InItem 0:
27+ OfType Number: TypeBecomesEmpty
28+ WithStatusCode 200:
29+ ResponsePayload:
30+ PayloadSchema:
31+ OfType Array:
32+ - TupleToArray
33+ - InItem 0:
34+ OfType String: TypeBecomesEmpty
test/golden/common/tuple-items/homogeneous-length-mismatch/a.yamlnew file+56
@@ -0,0 +1,56 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test1:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+ /test2:
23+ post:
24+ requestBody:
25+ content:
26+ application/json:
27+ schema:
28+ $ref: "#/components/schemas/Test"
29+ responses:
30+ '200':
31+ description: test
32+ content:
33+ application/json:
34+ schema:
35+ $ref: "#/components/schemas/Test"
36+ /test3:
37+ post:
38+ requestBody:
39+ content:
40+ application/json:
41+ schema:
42+ $ref: "#/components/schemas/Test"
43+ responses:
44+ '200':
45+ description: test
46+ content:
47+ application/json:
48+ schema:
49+ $ref: "#/components/schemas/Test"
50+components:
51+ schemas:
52+ Test:
53+ type: array
54+ items:
55+ - type: number
56+ - type: number
test/golden/common/tuple-items/homogeneous-length-mismatch/b.yamlnew file+67
@@ -0,0 +1,67 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test1:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test1"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test1"
22+ /test2:
23+ post:
24+ requestBody:
25+ content:
26+ application/json:
27+ schema:
28+ $ref: "#/components/schemas/Test2"
29+ responses:
30+ '200':
31+ description: test
32+ content:
33+ application/json:
34+ schema:
35+ $ref: "#/components/schemas/Test2"
36+ /test3:
37+ post:
38+ requestBody:
39+ content:
40+ application/json:
41+ schema:
42+ $ref: "#/components/schemas/Test3"
43+ responses:
44+ '200':
45+ description: test
46+ content:
47+ application/json:
48+ schema:
49+ $ref: "#/components/schemas/Test3"
50+components:
51+ schemas:
52+ Test1:
53+ type: array
54+ maxItems: 2
55+ items:
56+ type: number
57+ Test2:
58+ type: array
59+ minItems: 2
60+ items:
61+ type: number
62+ Test3:
63+ type: array
64+ minItems: 3
65+ maxItems: 3
66+ items:
67+ type: number
test/golden/common/tuple-items/homogeneous-length-mismatch/report.mdnew file+73
@@ -0,0 +1,73 @@
1+# Summary
2+
3+| [⚠️ Breaking changes](#breaking-changes) | [🙆 Non-breaking changes](#non-breaking-changes) | 🤷 Unsupported feature changes |
4+|------------------------------------------|-------------------------------------------------|-------------------------------|
5+| 5 | 5 | 0 |
6+
7+# <span id="breaking-changes"></span>⚠️ Breaking changes
8+
9+## **POST** /test1
10+
11+### 📱⬅️ JSON Response – 200
12+
13+#### `$(Array)`
14+
15+The array is no longer explicitly defined as a tuple.
16+
17+## **POST** /test2
18+
19+### 📱⬅️ JSON Response – 200
20+
21+#### `$(Array)`
22+
23+The array is no longer explicitly defined as a tuple.
24+
25+## **POST** /test3
26+
27+### 📱➡️ JSON Request
28+
29+#### `$(Array)`
30+
31+Minimum length of the array changed from 2 to 3.
32+
33+### 📱⬅️ JSON Response – 200
34+
35+#### `$(Array)`
36+
37+1. Tuple length changed from 3 to 2.
38+
39+2. The array is no longer explicitly defined as a tuple.
40+
41+# <span id="non-breaking-changes"></span>🙆 Non-breaking changes
42+
43+## **POST** /test1
44+
45+### 📱➡️ JSON Request
46+
47+#### `$(Array)`
48+
49+The array is no longer explicitly defined as a tuple.
50+
51+## **POST** /test2
52+
53+### 📱➡️ JSON Request
54+
55+#### `$(Array)`
56+
57+The array is no longer explicitly defined as a tuple.
58+
59+## **POST** /test3
60+
61+### 📱➡️ JSON Request
62+
63+#### `$(Array)`
64+
65+1. Tuple length changed from 3 to 2.
66+
67+2. The array is no longer explicitly defined as a tuple.
68+
69+### 📱⬅️ JSON Response – 200
70+
71+#### `$(Array)`
72+
73+Minimum length of the array changed from 2 to 3.
test/golden/common/tuple-items/homogeneous-length-mismatch/trace-tree.yamlnew file+52
@@ -0,0 +1,52 @@
1+breakingChanges:
2+ AtPath "/test3":
3+ InOperation PostMethod:
4+ InRequest:
5+ InPayload:
6+ PayloadSchema:
7+ OfType Array: MatchingMinItemsWeak (ProdCons {producer = 2, consumer =
8+ 3})
9+ WithStatusCode 200:
10+ ResponsePayload:
11+ PayloadSchema:
12+ OfType Array:
13+ - TupleItemsLengthChanged (ProdCons {producer = 3, consumer = 2})
14+ - ArrayToTuple
15+ AtPath "/test1":
16+ InOperation PostMethod:
17+ WithStatusCode 200:
18+ ResponsePayload:
19+ PayloadSchema:
20+ OfType Array: NoMatchingTupleItems
21+ AtPath "/test2":
22+ InOperation PostMethod:
23+ WithStatusCode 200:
24+ ResponsePayload:
25+ PayloadSchema:
26+ OfType Array: NoMatchingTupleItems
27+nonBreakingChanges:
28+ AtPath "/test3":
29+ InOperation PostMethod:
30+ InRequest:
31+ InPayload:
32+ PayloadSchema:
33+ OfType Array:
34+ - TupleItemsLengthChanged (ProdCons {producer = 3, consumer = 2})
35+ - ArrayToTuple
36+ WithStatusCode 200:
37+ ResponsePayload:
38+ PayloadSchema:
39+ OfType Array: MatchingMinItemsWeak (ProdCons {producer = 2, consumer =
40+ 3})
41+ AtPath "/test1":
42+ InOperation PostMethod:
43+ InRequest:
44+ InPayload:
45+ PayloadSchema:
46+ OfType Array: NoMatchingTupleItems
47+ AtPath "/test2":
48+ InOperation PostMethod:
49+ InRequest:
50+ InPayload:
51+ PayloadSchema:
52+ OfType Array: NoMatchingTupleItems
test/golden/common/tuple-items/homogeneous-vector/a.yamlnew file+28
@@ -0,0 +1,28 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+components:
23+ schemas:
24+ Test:
25+ type: array
26+ items:
27+ - type: number
28+ - type: number
test/golden/common/tuple-items/homogeneous-vector/b.yamlnew file+29
@@ -0,0 +1,29 @@
1+openapi: "3.0.0"
2+info:
3+ version: 1.0.0
4+ title: Test
5+servers:
6+ - url: http://localhost/
7+paths:
8+ /test:
9+ post:
10+ requestBody:
11+ content:
12+ application/json:
13+ schema:
14+ $ref: "#/components/schemas/Test"
15+ responses:
16+ '200':
17+ description: test
18+ content:
19+ application/json:
20+ schema:
21+ $ref: "#/components/schemas/Test"
22+components:
23+ schemas:
24+ Test:
25+ type: array
26+ minItems: 2
27+ maxItems: 2
28+ items:
29+ type: number
test/golden/common/tuple-items/homogeneous-vector/report.mdnew file+5
@@ -0,0 +1,5 @@
1+# Summary
2+
3+| ⚠️ Breaking changes | 🙆 Non-breaking changes | 🤷 Unsupported feature changes |
4+|---------------------|------------------------|-------------------------------|
5+| 0 | 0 | 0 |
test/golden/common/tuple-items/homogeneous-vector/trace-tree.yamlnew file+2
@@ -0,0 +1,2 @@
1+breakingChanges: {}
2+nonBreakingChanges: {}