diff --git a/BREAKING-CHANGES-EXAMPLES.md b/BREAKING-CHANGES-EXAMPLES.md index d0fc403c..1894b44c 100644 --- a/BREAKING-CHANGES-EXAMPLES.md +++ b/BREAKING-CHANGES-EXAMPLES.md @@ -1,10 +1,10 @@ # Examples of Breaking and Non-Breaking Changes These examples are automatically generated from unit tests. ## Examples of breaking changes -[adding 'allOf' subschema to the request body or request body property is breaking](checker/checker_breaking_test.go?plain=1#L694) +[adding 'allOf' subschema to the request body or request body property is breaking](checker/checker_breaking_test.go?plain=1#L693) [adding a new required property in request body is breaking](checker/checker_breaking_property_test.go?plain=1#L352) -[adding a pattern to a schema is breaking for recursive properties](checker/checker_breaking_test.go?plain=1#L475) -[adding a pattern to a schema is breaking](checker/checker_breaking_test.go?plain=1#L459) +[adding a pattern to a schema is breaking for recursive properties](checker/checker_breaking_test.go?plain=1#L474) +[adding a pattern to a schema is breaking](checker/checker_breaking_test.go?plain=1#L458) [adding a required request body is breaking](checker/checker_breaking_test.go?plain=1#L65) [changing a request body to enum is breaking](checker/checker_breaking_property_test.go?plain=1#L122) [changing a request body type and changing it to enum simultaneously is breaking](checker/checker_breaking_property_test.go?plain=1#L152) @@ -12,21 +12,21 @@ These examples are automatically generated from unit tests. [changing a required property in response body to optional and also deleting it is breaking](checker/checker_breaking_property_test.go?plain=1#L280) [changing a response body to nullable is breaking](checker/checker_breaking_property_test.go?plain=1#L216) [changing a response property to nullable is breaking](checker/checker_breaking_property_test.go?plain=1#L248) -[changing a response property to optional under AllOf, AnyOf or OneOf is breaking](checker/checker_breaking_property_test.go?plain=1#L645) +[changing a response property to optional under AllOf, AnyOf or OneOf is breaking](checker/checker_breaking_property_test.go?plain=1#L643) [changing an embedded response property to nullable is breaking](checker/checker_breaking_property_test.go?plain=1#L264) [changing an existing header param from optional to required is breaking](checker/checker_breaking_test.go?plain=1#L187) [changing an existing header param to enum is breaking](checker/checker_breaking_property_test.go?plain=1#L184) -[changing an existing property in request body anyOf to required is breaking](checker/checker_breaking_property_test.go?plain=1#L613) -[changing an existing property in request body items to required is breaking](checker/checker_breaking_property_test.go?plain=1#L597) +[changing an existing property in request body anyOf to required is breaking](checker/checker_breaking_property_test.go?plain=1#L611) +[changing an existing property in request body items to required is breaking](checker/checker_breaking_property_test.go?plain=1#L595) [changing an existing property in request body to enum is breaking](checker/checker_breaking_property_test.go?plain=1#L168) [changing an existing property in request body to required is breaking](checker/checker_breaking_property_test.go?plain=1#L336) [changing an existing property in request header to enum is breaking](checker/checker_breaking_property_test.go?plain=1#L200) [changing an existing property in request header to required is breaking](checker/checker_breaking_property_test.go?plain=1#L56) [changing an existing property in response body to optional is breaking](checker/checker_breaking_property_test.go?plain=1#L106) -[changing an existing property under another property in request body to required is breaking](checker/checker_breaking_property_test.go?plain=1#L629) +[changing an existing property under another property in request body to required is breaking](checker/checker_breaking_property_test.go?plain=1#L627) [changing an existing request body from optional to required is breaking](checker/checker_breaking_test.go?plain=1#L82) -[changing an existing required property in response body to not-write-only is breaking](checker/checker_breaking_property_test.go?plain=1#L562) -[changing an existing response header from required to optional is breaking](checker/checker_breaking_test.go?plain=1#L211) +[changing an existing required property in response body to not-write-only is breaking](checker/checker_breaking_property_test.go?plain=1#L560) +[changing an existing response header from required to optional is breaking](checker/checker_breaking_test.go?plain=1#L210) [changing max length in request from nil to any value is breaking](checker/checker_breaking_min_max_test.go?plain=1#L110) [changing max length in response from any value to nil is breaking](checker/checker_breaking_min_max_test.go?plain=1#L160) [changing request's body schema type from number to integer is breaking](checker/checker_breaking_request_type_changed_test.go?plain=1#L51) @@ -37,26 +37,26 @@ These examples are automatically generated from unit tests. [changing response's body schema type from number to string is breaking](checker/checker_breaking_response_type_changed_test.go?plain=1#L31) [changing response's body schema type from string to number is breaking](checker/checker_breaking_response_type_changed_test.go?plain=1#L11) [changing response's embedded property schema type from string/none to integer/int32 is breaking](checker/checker_breaking_response_type_changed_test.go?plain=1#L108) -[deleting a media-type from response is breaking](checker/checker_breaking_test.go?plain=1#L429) -[deleting a non-required non-write-only property in response body is breaking with warning](checker/checker_breaking_property_test.go?plain=1#L513) +[deleting a media-type from response is breaking](checker/checker_breaking_test.go?plain=1#L428) +[deleting a non-required non-write-only property in response body is breaking with warning](checker/checker_breaking_property_test.go?plain=1#L511) [deleting a path is breaking](checker/checker_breaking_test.go?plain=1#L43) -[deleting a path with some operations having sunset date in the future is breaking](checker/checker_deprecation_test.go?plain=1#L272) +[deleting a path with some operations having sunset date in the future is breaking](checker/checker_deprecation_test.go?plain=1#L271) [deleting a required property in request is breaking with warn](checker/checker_breaking_property_test.go?plain=1#L368) -[deleting a required property in response body is breaking](checker/checker_breaking_property_test.go?plain=1#L422) -[deleting a required property under AllOf in response body is breaking](checker/checker_breaking_property_test.go?plain=1#L452) +[deleting a required property in response body is breaking](checker/checker_breaking_property_test.go?plain=1#L420) +[deleting a required property under AllOf in response body is breaking](checker/checker_breaking_property_test.go?plain=1#L450) [deleting an embedded optional property in request is breaking with warn](checker/checker_breaking_property_test.go?plain=1#L385) [deleting an enum value is breaking](checker/checker_breaking_test.go?plain=1#L103) -[deleting an operation before sunset date is breaking](checker/checker_deprecation_test.go?plain=1#L34) +[deleting an operation before sunset date is breaking](checker/checker_deprecation_test.go?plain=1#L33) [deleting an operation is breaking](checker/checker_breaking_test.go?plain=1#L50) -[deleting an operation without sunset date is breaking](checker/checker_deprecation_test.go?plain=1#L51) -[deleting sunset header for a deprecated endpoint is breaking](checker/checker_deprecation_test.go?plain=1#L289) -[deprecating an operation with a deprecation policy and sunset date before required deprecation period is breaking](checker/checker_deprecation_test.go?plain=1#L217) -[deprecating an operation with a deprecation policy but without specifying sunset date is breaking](checker/checker_deprecation_test.go?plain=1#L83) +[deleting an operation without sunset date is breaking](checker/checker_deprecation_test.go?plain=1#L50) +[deleting sunset header for a deprecated endpoint is breaking](checker/checker_deprecation_test.go?plain=1#L288) +[deprecating an operation with a deprecation policy and sunset date before required deprecation period is breaking](checker/checker_deprecation_test.go?plain=1#L216) +[deprecating an operation with a deprecation policy but without specifying sunset date is breaking](checker/checker_deprecation_test.go?plain=1#L82) [increasing max length in response is breaking](checker/checker_breaking_min_max_test.go?plain=1#L93) [increasing min items in request is breaking](checker/checker_breaking_min_max_test.go?plain=1#L236) -[modifying a pattern in a schema is breaking](checker/checker_breaking_test.go?plain=1#L491) -[modifying a pattern in request parameter is breaking](checker/checker_breaking_test.go?plain=1#L507) -[modifying the default value of an optional request parameter is breaking](checker/checker_breaking_test.go?plain=1#L537) +[modifying a pattern in a schema is breaking](checker/checker_breaking_test.go?plain=1#L490) +[modifying a pattern in request parameter is breaking](checker/checker_breaking_test.go?plain=1#L506) +[modifying the default value of an optional request parameter is breaking](checker/checker_breaking_test.go?plain=1#L536) [new header, query and cookie required request default param is breaking](checker/check-new-request-non-path-default-parameter_test.go?plain=1#L11) [new required header param is breaking](checker/checker_breaking_test.go?plain=1#L171) [new required path param is breaking](checker/checker_breaking_test.go?plain=1#L155) @@ -65,30 +65,30 @@ These examples are automatically generated from unit tests. [reducing max length in request is breaking](checker/checker_breaking_min_max_test.go?plain=1#L12) [reducing min items in response is breaking](checker/checker_breaking_min_max_test.go?plain=1#L220) [reducing min length in response is breaking](checker/checker_breaking_min_max_test.go?plain=1#L62) -[removing 'allOf' subschema from the request body or request body property is breaking with warn](checker/checker_breaking_test.go?plain=1#L716) -[removing 'anyOf' schema from the request body or request body property is breaking](checker/checker_breaking_test.go?plain=1#L651) -[removing 'oneOf' schema from the request body or request body property is breaking](checker/checker_breaking_test.go?plain=1#L673) -[removing a media type from request body is breaking](checker/checker_breaking_test.go?plain=1#L635) -[removing a success status is breaking](checker/check-response-status-updated_test.go?plain=1#L89) -[removing an existing optional response header is breaking as warn](checker/checker_breaking_test.go?plain=1#L410) -[removing an existing required response header is breaking as error](checker/checker_breaking_test.go?plain=1#L227) -[removing an existing response with non-successful status is breaking (optional)](checker/checker_breaking_test.go?plain=1#L264) -[removing an existing response with successful status is breaking](checker/checker_breaking_test.go?plain=1#L246) -[removing an schema object from components is breaking (optional)](checker/checker_breaking_test.go?plain=1#L610) -[removing the default value of an optional request parameter is breaking](checker/checker_breaking_test.go?plain=1#L573) -[removing the path without a deprecation policy and without specifying sunset date is breaking if some APIs are not alpha stability level](checker/checker_deprecation_test.go?plain=1#L136) -[removing the path without a deprecation policy and without specifying sunset date is breaking if some APIs are not draft stability level](checker/checker_deprecation_test.go?plain=1#L190) -[removing/updating a property enum in response is breaking (optional)](checker/checker_breaking_test.go?plain=1#L324) -[removing/updating a tag is breaking (optional)](checker/checker_breaking_test.go?plain=1#L341) -[removing/updating an enum in request body is breaking (optional)](checker/checker_breaking_test.go?plain=1#L302) -[removing/updating an operation id is breaking (optional)](checker/checker_breaking_test.go?plain=1#L282) -[setting the default value of an optional request parameter is breaking](checker/checker_breaking_test.go?plain=1#L555) +[removing 'allOf' subschema from the request body or request body property is breaking with warn](checker/checker_breaking_test.go?plain=1#L715) +[removing 'anyOf' schema from the request body or request body property is breaking](checker/checker_breaking_test.go?plain=1#L650) +[removing 'oneOf' schema from the request body or request body property is breaking](checker/checker_breaking_test.go?plain=1#L672) +[removing a media type from request body is breaking](checker/checker_breaking_test.go?plain=1#L634) +[removing a success status is breaking](checker/check-response-status-updated_test.go?plain=1#L86) +[removing an existing optional response header is breaking as warn](checker/checker_breaking_test.go?plain=1#L409) +[removing an existing required response header is breaking as error](checker/checker_breaking_test.go?plain=1#L226) +[removing an existing response with non-successful status is breaking (optional)](checker/checker_breaking_test.go?plain=1#L263) +[removing an existing response with successful status is breaking](checker/checker_breaking_test.go?plain=1#L245) +[removing an schema object from components is breaking (optional)](checker/checker_breaking_test.go?plain=1#L609) +[removing the default value of an optional request parameter is breaking](checker/checker_breaking_test.go?plain=1#L572) +[removing the path without a deprecation policy and without specifying sunset date is breaking if some APIs are not alpha stability level](checker/checker_deprecation_test.go?plain=1#L135) +[removing the path without a deprecation policy and without specifying sunset date is breaking if some APIs are not draft stability level](checker/checker_deprecation_test.go?plain=1#L189) +[removing/updating a property enum in response is breaking (optional)](checker/checker_breaking_test.go?plain=1#L323) +[removing/updating a tag is breaking (optional)](checker/checker_breaking_test.go?plain=1#L340) +[removing/updating an enum in request body is breaking (optional)](checker/checker_breaking_test.go?plain=1#L301) +[removing/updating an operation id is breaking (optional)](checker/checker_breaking_test.go?plain=1#L281) +[setting the default value of an optional request parameter is breaking](checker/checker_breaking_test.go?plain=1#L554) ## Examples of non-breaking changes [adding a media-type to response is not breaking](checker/checker_not_breaking_test.go?plain=1#L185) -[adding a new required property in response body is not breaking](checker/checker_breaking_property_test.go?plain=1#L408) -[adding a new required property under AllOf in response body is not breaking](checker/checker_breaking_property_test.go?plain=1#L438) -[adding a new required read-only property in request body is not breaking](checker/checker_breaking_property_test.go?plain=1#L468) +[adding a new required property in response body is not breaking](checker/checker_breaking_property_test.go?plain=1#L406) +[adding a new required property under AllOf in response body is not breaking](checker/checker_breaking_property_test.go?plain=1#L436) +[adding a new required read-only property in request body is not breaking](checker/checker_breaking_property_test.go?plain=1#L466) [adding a non-existent required property in request body is not breaking](checker/checker_breaking_property_test.go?plain=1#L294) [adding a required property to response is not breaking](checker/checker_not_breaking_test.go?plain=1#L290) [adding a tag is not breaking](checker/checker_not_breaking_test.go?plain=1#L267) @@ -102,9 +102,9 @@ These examples are automatically generated from unit tests. [changing an existing property in request body to optional is not breaking](checker/checker_breaking_property_test.go?plain=1#L322) [changing an existing property in request header to optional is not breaking](checker/checker_breaking_property_test.go?plain=1#L82) [changing an existing property in response body to required is not breaking](checker/checker_breaking_property_test.go?plain=1#L308) -[changing an existing read-only property in request body to required is not breaking](checker/checker_breaking_property_test.go?plain=1#L482) -[changing an existing required property in response body to write-only is not breaking](checker/checker_breaking_property_test.go?plain=1#L548) -[changing an existing write-only property in response body to optional is not breaking](checker/checker_breaking_property_test.go?plain=1#L534) +[changing an existing read-only property in request body to required is not breaking](checker/checker_breaking_property_test.go?plain=1#L480) +[changing an existing required property in response body to write-only is not breaking](checker/checker_breaking_property_test.go?plain=1#L546) +[changing an existing write-only property in response body to optional is not breaking](checker/checker_breaking_property_test.go?plain=1#L532) [changing comments is not breaking](checker/checker_not_breaking_test.go?plain=1#L107) [changing extensions is not breaking](checker/checker_not_breaking_test.go?plain=1#L95) [changing max length in request from any value to nil is not breaking](checker/checker_breaking_min_max_test.go?plain=1#L144) @@ -114,21 +114,21 @@ These examples are automatically generated from unit tests. [changing response's body schema type from number to integer is not breaking](checker/checker_breaking_response_type_changed_test.go?plain=1#L51) [changing response's body schema type from number/none to integer/int32 is not breaking](checker/checker_breaking_response_type_changed_test.go?plain=1#L89) [changing servers is not breaking](checker/checker_not_breaking_test.go?plain=1#L253) -[deleting a path after sunset date of all contained operations is not breaking](checker/checker_deprecation_test.go?plain=1#L257) -[deleting a pattern from a schema is not breaking](checker/checker_breaking_test.go?plain=1#L445) -[deleting a required write-only property in response body is not breaking](checker/checker_breaking_property_test.go?plain=1#L496) +[deleting a path after sunset date of all contained operations is not breaking](checker/checker_deprecation_test.go?plain=1#L256) +[deleting a pattern from a schema is not breaking](checker/checker_breaking_test.go?plain=1#L444) +[deleting a required write-only property in response body is not breaking](checker/checker_breaking_property_test.go?plain=1#L494) [deleting a tag is not breaking](checker/checker_not_breaking_test.go?plain=1#L71) -[deleting an operation after sunset date is not breaking](checker/checker_deprecation_test.go?plain=1#L68) +[deleting an operation after sunset date is not breaking](checker/checker_deprecation_test.go?plain=1#L67) [deprecating a header is not breaking](checker/checker_not_breaking_test.go?plain=1#L227) [deprecating a parameter is not breaking](checker/checker_not_breaking_test.go?plain=1#L214) [deprecating a schema is not breaking](checker/checker_not_breaking_test.go?plain=1#L240) -[deprecating an operation with a deprecation policy and sunset date after required deprecation period is not breaking](checker/checker_deprecation_test.go?plain=1#L236) -[deprecating an operation without a deprecation policy and without specifying sunset date is not breaking for draft level](checker/checker_deprecation_test.go?plain=1#L154) -[deprecating an operation without a deprecation policy and without specifying sunset date is not breaking](checker/checker_deprecation_test.go?plain=1#L102) +[deprecating an operation with a deprecation policy and sunset date after required deprecation period is not breaking](checker/checker_deprecation_test.go?plain=1#L235) +[deprecating an operation without a deprecation policy and without specifying sunset date is not breaking for draft level](checker/checker_deprecation_test.go?plain=1#L153) +[deprecating an operation without a deprecation policy and without specifying sunset date is not breaking](checker/checker_deprecation_test.go?plain=1#L101) [increasing max length in request is not breaking](checker/checker_breaking_min_max_test.go?plain=1#L76) [increasing min items in response is not breaking](checker/checker_breaking_min_max_test.go?plain=1#L250) -[modifying a pattern to ".*" in a schema is not breaking](checker/checker_breaking_test.go?plain=1#L523) -[modifying the default value of a required request parameter is not breaking](checker/checker_breaking_test.go?plain=1#L591) +[modifying a pattern to ".*" in a schema is not breaking](checker/checker_breaking_test.go?plain=1#L522) +[modifying the default value of a required request parameter is not breaking](checker/checker_breaking_test.go?plain=1#L590) [new optional header param is not breaking](checker/checker_not_breaking_test.go?plain=1#L119) [new optional property in request header is not breaking](checker/checker_breaking_property_test.go?plain=1#L38) [new required response header param is not breaking](checker/checker_not_breaking_test.go?plain=1#L153) @@ -137,10 +137,10 @@ These examples are automatically generated from unit tests. [reducing max length in response is not breaking](checker/checker_breaking_min_max_test.go?plain=1#L31) [reducing min items in request is not breaking](checker/checker_breaking_min_max_test.go?plain=1#L206) [reducing min length in request is not breaking](checker/checker_breaking_min_max_test.go?plain=1#L48) -[removing an existing response with error status is not breaking](checker/checker_breaking_test.go?plain=1#L394) -[removing an existing response with unparseable status is not breaking](checker/checker_breaking_test.go?plain=1#L378) -[removing the path without a deprecation policy and without specifying sunset date is not breaking for alpha level](checker/checker_deprecation_test.go?plain=1#L117) -[removing the path without a deprecation policy and without specifying sunset date is not breaking for draft level](checker/checker_deprecation_test.go?plain=1#L171) +[removing an existing response with error status is not breaking](checker/checker_breaking_test.go?plain=1#L393) +[removing an existing response with unparseable status is not breaking](checker/checker_breaking_test.go?plain=1#L377) +[removing the path without a deprecation policy and without specifying sunset date is not breaking for alpha level](checker/checker_deprecation_test.go?plain=1#L116) +[removing the path without a deprecation policy and without specifying sunset date is not breaking for draft level](checker/checker_deprecation_test.go?plain=1#L170) [renaming a path parameter is not breaking](checker/checker_breaking_test.go?plain=1#L135) ## Examples of info-level changes for changelog @@ -158,96 +158,96 @@ These examples are automatically generated from unit tests. [adding a new optional request property](checker/check-request-property-updated_test.go?plain=1#L64) [adding a new required request property](checker/check-request-property-updated_test.go?plain=1#L11) [adding a new security component](checker/check-components-security-updated_test.go?plain=1#L74) -[adding a new security to the API endpoint](checker/check-api-security-updated_test.go?plain=1#L89) +[adding a new security to the API endpoint](checker/check-api-security-updated_test.go?plain=1#L85) [adding a new tag](checker/check-api-tag-updated_test.go?plain=1#L11) -[adding a non-success response status](checker/check-response-status-updated_test.go?plain=1#L37) +[adding a non-success response status](checker/check-response-status-updated_test.go?plain=1#L36) [adding a required property to response body is detected](checker/check-response-required-property-updated_test.go?plain=1#L11) -[adding a required write-only property to response body is detected](checker/check-response-required-property-updated_test.go?plain=1#L59) -[adding a security scope from an API global security](checker/check-api-security-updated_test.go?plain=1#L69) -[adding a security scope to an API endpoint security](checker/check-api-security-updated_test.go?plain=1#L158) +[adding a required write-only property to response body is detected](checker/check-response-required-property-updated_test.go?plain=1#L57) +[adding a security scope from an API global security](checker/check-api-security-updated_test.go?plain=1#L66) +[adding a security scope to an API endpoint security](checker/check-api-security-updated_test.go?plain=1#L148) [adding a success response status](checker/check-response-status-updated_test.go?plain=1#L11) [adding an enum value to a response property](checker/check-response-property-enum-value-added_test.go?plain=1#L11) -[adding an enum value to a response write-only property](checker/check-response-property-enum-value-added_test.go?plain=1#L36) +[adding an enum value to a response write-only property](checker/check-response-property-enum-value-added_test.go?plain=1#L37) [adding an enum value to request parameter](checker/check-request-parameter-enum-value-updated_test.go?plain=1#L34) -[adding an optional write-only property to a response](checker/check-response-optional-property-updated_test.go?plain=1#L34) -[adding discriminator to the request body or request body property](checker/check-request-discriminator-updated_test.go?plain=1#L11) -[adding discriminator to the response body or response property](checker/check-response-discriminator-updated_test.go?plain=1#L11) +[adding an optional write-only property to a response](checker/check-response-optional-property-updated_test.go?plain=1#L33) +[adding discriminator to the request body or request body property](checker/check-request-discriminator-updated_test.go?plain=1#L12) +[adding discriminator to the response body or response property](checker/check-response-discriminator-updated_test.go?plain=1#L12) [adding pattern to request parameters](checker/check-request-parameter-pattern-added-or-changed_test.go?plain=1#L35) -[adding request body default value or request property default value](checker/check-request-property-default-value-changed_test.go?plain=1#L58) -[adding request parameter default value](checker/check-request-parameters-default-value-changed_test.go?plain=1#L34) +[adding request body default value or request property default value](checker/check-request-property-default-value-changed_test.go?plain=1#L57) +[adding request parameter default value](checker/check-request-parameters-default-value-changed_test.go?plain=1#L33) [adding request property enum values](checker/check-request-property-enum-value-updated_test.go?plain=1#L37) [adding request property pattern](checker/check-request-property-pattern-added-or-changed_test.go?plain=1#L36) -[adding response body default value or response body property default value](checker/check-response-property-default-value-changed_test.go?plain=1#L66) -[adding response property pattern](checker/check-response-pattern-added-or-changed_test.go?plain=1#L37) +[adding response body default value or response body property default value](checker/check-response-property-default-value-changed_test.go?plain=1#L63) +[adding response property pattern](checker/check-response-pattern-added-or-changed_test.go?plain=1#L36) [adding two new request properties, one required, one optional](checker/check-request-property-updated_test.go?plain=1#L33) -[changing a response property schema format](checker/check-response-property-type-changed_test.go?plain=1#L59) -[changing a response property schema type](checker/check-response-property-type-changed_test.go?plain=1#L34) +[changing a response property schema format](checker/check-response-property-type-changed_test.go?plain=1#L57) +[changing a response property schema type](checker/check-response-property-type-changed_test.go?plain=1#L33) [changing a response schema type](checker/check-response-property-type-changed_test.go?plain=1#L11) -[changing an existing header param from required to optional](checker/checker_request_parameter_required_value_updated_test.go?plain=1#L35) +[changing an existing header param from required to optional](checker/checker_request_parameter_required_value_updated_test.go?plain=1#L34) [changing an existing header param to optional](checker/checker_not_breaking_test.go?plain=1#L133) [changing an existing request body from required to optional](checker/checker_not_breaking_test.go?plain=1#L53) -[changing discriminator mapping in the request body or request body property](checker/check-request-discriminator-updated_test.go?plain=1#L119) -[changing discriminator mapping in the response body or response property](checker/check-response-discriminator-updated_test.go?plain=1#L119) -[changing discriminator propertyName in the request body or request body property](checker/check-request-discriminator-updated_test.go?plain=1#L83) -[changing discriminator propertyName in the response body or response property](checker/check-response-discriminator-updated_test.go?plain=1#L83) +[changing discriminator mapping in the request body or request body property](checker/check-request-discriminator-updated_test.go?plain=1#L112) +[changing discriminator mapping in the response body or response property](checker/check-response-discriminator-updated_test.go?plain=1#L114) +[changing discriminator propertyName in the request body or request body property](checker/check-request-discriminator-updated_test.go?plain=1#L78) +[changing discriminator propertyName in the response body or response property](checker/check-response-discriminator-updated_test.go?plain=1#L80) [changing optional request property to not read-only](checker/check-request-property-write-only-read-only_test.go?plain=1#L86) [changing optional request property to not write-only](checker/check-request-property-write-only-read-only_test.go?plain=1#L36) [changing optional request property to read-only](checker/check-request-property-write-only-read-only_test.go?plain=1#L61) [changing optional request property to write-only](checker/check-request-property-write-only-read-only_test.go?plain=1#L11) -[changing optional response property to not read-only](checker/check-response-optional-property-write-only-read-only_test.go?plain=1#L88) -[changing optional response property to not write-only](checker/check-response-optional-property-write-only-read-only_test.go?plain=1#L37) -[changing optional response property to read-only](checker/check-response-optional-property-write-only-read-only_test.go?plain=1#L62) +[changing optional response property to not read-only](checker/check-response-optional-property-write-only-read-only_test.go?plain=1#L86) +[changing optional response property to not write-only](checker/check-response-optional-property-write-only-read-only_test.go?plain=1#L36) +[changing optional response property to read-only](checker/check-response-optional-property-write-only-read-only_test.go?plain=1#L61) [changing optional response property to required](checker/check-response-property-became-required_test.go?plain=1#L11) [changing optional response property to write-only](checker/check-response-optional-property-write-only-read-only_test.go?plain=1#L11) -[changing optional response write-only property to required](checker/check-response-property-became-required_test.go?plain=1#L33) +[changing optional response write-only property to required](checker/check-response-property-became-required_test.go?plain=1#L32) [changing pattern of request parameters](checker/check-request-parameter-pattern-added-or-changed_test.go?plain=1#L11) [changing request body and property types from array to object](checker/check-request-property-type-changed_test.go?plain=1#L84) [changing request body and property types from object to array](checker/check-request-property-type-changed_test.go?plain=1#L116) [changing request body default value](checker/check-request-property-default-value-changed_test.go?plain=1#L11) -[changing request body to not nullable](checker/check-request-property-became-not-nuallable_test.go?plain=1#L84) -[changing request body to nullable](checker/check-request-property-became-not-nuallable_test.go?plain=1#L58) +[changing request body to not nullable](checker/check-request-property-became-not-nuallable_test.go?plain=1#L80) +[changing request body to nullable](checker/check-request-property-became-not-nuallable_test.go?plain=1#L56) [changing request body type](checker/check-request-property-type-changed_test.go?plain=1#L11) -[changing request header parameter format](checker/check-request-parameters-type-changed_test.go?plain=1#L136) -[changing request header parameter type](checker/check-request-parameters-type-changed_test.go?plain=1#L61) +[changing request header parameter format](checker/check-request-parameters-type-changed_test.go?plain=1#L131) +[changing request header parameter type](checker/check-request-parameters-type-changed_test.go?plain=1#L59) [changing request parameter default value](checker/check-request-parameters-default-value-changed_test.go?plain=1#L11) [changing request parameter type to enum](checker/check-request-parameter-became-enum_test.go?plain=1#L11) -[changing request path parameter format](checker/check-request-parameters-type-changed_test.go?plain=1#L86) +[changing request path parameter format](checker/check-request-parameters-type-changed_test.go?plain=1#L83) [changing request path parameter type](checker/check-request-parameters-type-changed_test.go?plain=1#L11) -[changing request property default value](checker/check-request-property-default-value-changed_test.go?plain=1#L34) +[changing request property default value](checker/check-request-property-default-value-changed_test.go?plain=1#L33) [changing request property format](checker/check-request-property-type-changed_test.go?plain=1#L148) [changing request property pattern](checker/check-request-property-pattern-added-or-changed_test.go?plain=1#L11) [changing request property required value to false](checker/check-request-property-required-updated_test.go?plain=1#L34) [changing request property required value to true](checker/check-request-property-required-updated_test.go?plain=1#L11) [changing request property to not nullable](checker/check-request-property-became-not-nuallable_test.go?plain=1#L11) -[changing request property to nullable](checker/check-request-property-became-not-nuallable_test.go?plain=1#L34) +[changing request property to nullable](checker/check-request-property-became-not-nuallable_test.go?plain=1#L33) [changing request property type](checker/check-request-property-type-changed_test.go?plain=1#L61) -[changing request query parameter format](checker/check-request-parameters-type-changed_test.go?plain=1#L111) -[changing request query parameter type](checker/check-request-parameters-type-changed_test.go?plain=1#L36) -[changing request's body to optional](checker/check-request-body-required-value-updated_test.go?plain=1#L36) +[changing request query parameter format](checker/check-request-parameters-type-changed_test.go?plain=1#L107) +[changing request query parameter type](checker/check-request-parameters-type-changed_test.go?plain=1#L35) +[changing request's body to optional](checker/check-request-body-required-value-updated_test.go?plain=1#L34) [changing request's body to required is breaking](checker/check-request-body-required-value-updated_test.go?plain=1#L11) [changing required request property to not read-only](checker/check-request-property-write-only-read-only_test.go?plain=1#L186) [changing required request property to not write-only](checker/check-request-property-write-only-read-only_test.go?plain=1#L136) [changing required request property to read-only](checker/check-request-property-write-only-read-only_test.go?plain=1#L161) [changing required request property to write-only](checker/check-request-property-write-only-read-only_test.go?plain=1#L111) [changing required response property to not read-only](checker/check-response-required-property-write-only-read-only_test.go?plain=1#L89) -[changing required response property to not write-only](checker/check-response-required-property-write-only-read-only_test.go?plain=1#L37) +[changing required response property to not write-only](checker/check-response-required-property-write-only-read-only_test.go?plain=1#L36) [changing required response property to optional](checker/check-response-property-became-optional_test.go?plain=1#L11) -[changing required response property to read-only](checker/check-response-required-property-write-only-read-only_test.go?plain=1#L63) +[changing required response property to read-only](checker/check-response-required-property-write-only-read-only_test.go?plain=1#L64) [changing required response property to write-only](checker/check-response-required-property-write-only-read-only_test.go?plain=1#L11) -[changing response body default value](checker/check-response-property-default-value-changed_test.go?plain=1#L42) +[changing response body default value](checker/check-response-property-default-value-changed_test.go?plain=1#L40) [changing response body property default value](checker/check-response-property-default-value-changed_test.go?plain=1#L11) [changing response property pattern](checker/check-response-pattern-added-or-changed_test.go?plain=1#L11) [changing security component oauth's url](checker/check-components-security-updated_test.go?plain=1#L11) [changing security component token url](checker/check-components-security-updated_test.go?plain=1#L32) [changing security component type](checker/check-components-security-updated_test.go?plain=1#L53) -[changing write-only required response property to optional](checker/check-response-property-became-optional_test.go?plain=1#L33) +[changing write-only required response property to optional](checker/check-response-property-became-optional_test.go?plain=1#L32) [decreasing max length of request body](checker/check-request-property-max-length-updated_test.go?plain=1#L39) [decreasing max length of request property](checker/check-request-property-max-length-updated_test.go?plain=1#L67) -[decreasing maxItems of request parameters](checker/check-request-parameters-max-items-updated_test.go?plain=1#L34) -[decreasing maxLength of request parameters](checker/check-request-parameters-max-length-updated_test.go?plain=1#L33) +[decreasing maxItems of request parameters](checker/check-request-parameters-max-items-updated_test.go?plain=1#L33) +[decreasing maxLength of request parameters](checker/check-request-parameters-max-length-updated_test.go?plain=1#L32) [decreasing maximum value of request parameter](checker/check-request-parameters-max-updated_test.go?plain=1#L33) [decreasing minItems value of request parameter](checker/check-request-parameters-min-items-updated_test.go?plain=1#L33) -[decreasing minLength of request body](checker/check-request-property-min-length-updated_test.go?plain=1#L86) +[decreasing minLength of request body](checker/check-request-property-min-length-updated_test.go?plain=1#L83) [decreasing minLength of request property](checker/check-request-property-min-length-updated_test.go?plain=1#L11) [decreasing minLength value of request parameter](checker/check-request-parameters-min-length-updated_test.go?plain=1#L34) [decreasing minimum value of request parameter](checker/check-request-parameters-min-updated_test.go?plain=1#L33) @@ -261,8 +261,8 @@ These examples are automatically generated from unit tests. [increasing maxLength of request parameters](checker/check-request-parameters-max-length-updated_test.go?plain=1#L11) [increasing maximum value of request parameter](checker/check-request-parameters-max-updated_test.go?plain=1#L11) [increasing minItems value of request parameter](checker/check-request-parameters-min-items-updated_test.go?plain=1#L11) -[increasing minLength of request body](checker/check-request-property-min-length-updated_test.go?plain=1#L61) -[increasing minLength of request property](checker/check-request-property-min-length-updated_test.go?plain=1#L36) +[increasing minLength of request body](checker/check-request-property-min-length-updated_test.go?plain=1#L59) +[increasing minLength of request property](checker/check-request-property-min-length-updated_test.go?plain=1#L35) [increasing minLength value of request parameter](checker/check-request-parameters-min-length-updated_test.go?plain=1#L11) [increasing minimum value of request parameter](checker/check-request-parameters-min-updated_test.go?plain=1#L11) [increasing minimum value of request property](checker/check-request-property-min-updated_test.go?plain=1#L11) @@ -270,40 +270,40 @@ These examples are automatically generated from unit tests. [increasing request property maximum value](checker/check-request-property-max-updated_test.go?plain=1#L37) [new header, query and cookie request params](checker/check-new-request-non-path-parameter_test.go?plain=1#L11) [new paths or path operations](checker/check-api-added_test.go?plain=1#L11) -[path operations that became deprecated](checker/checker_deprecation_test.go?plain=1#L323) -[path operations that were re-activated](checker/checker_deprecation_test.go?plain=1#L345) -[removing 'allOf' subschema from the request body or request body property](checker/check-request-property-all-of-updated_test.go?plain=1#L47) -[removing 'allOf' subschema from the response body or response body property](checker/check-response-property-all-of-updated_test.go?plain=1#L47) -[removing 'anyOf' schema from the request body or request body property](checker/check-request-property-any-of-updated_test.go?plain=1#L47) -[removing 'anyOf' schema from the response body or response body property](checker/check-response-property-any-of-updated_test.go?plain=1#L47) -[removing 'oneOf' schema from the request body or request body property](checker/check-request-property-one-of-updated_test.go?plain=1#L47) -[removing 'oneOf' schema from the response body or response body property](checker/check-response-property-one-of-updated_test.go?plain=1#L57) -[removing a global security from the API](checker/check-api-security-updated_test.go?plain=1#L30) -[removing a new media type to response](checker/check-response-mediatype-updated_test.go?plain=1#L34) +[path operations that became deprecated](checker/checker_deprecation_test.go?plain=1#L322) +[path operations that were re-activated](checker/checker_deprecation_test.go?plain=1#L344) +[removing 'allOf' subschema from the request body or request body property](checker/check-request-property-all-of-updated_test.go?plain=1#L45) +[removing 'allOf' subschema from the response body or response body property](checker/check-response-property-all-of-updated_test.go?plain=1#L45) +[removing 'anyOf' schema from the request body or request body property](checker/check-request-property-any-of-updated_test.go?plain=1#L45) +[removing 'anyOf' schema from the response body or response body property](checker/check-response-property-any-of-updated_test.go?plain=1#L45) +[removing 'oneOf' schema from the request body or request body property](checker/check-request-property-one-of-updated_test.go?plain=1#L45) +[removing 'oneOf' schema from the response body or response body property](checker/check-response-property-one-of-updated_test.go?plain=1#L54) +[removing a global security from the API](checker/check-api-security-updated_test.go?plain=1#L29) +[removing a new media type to response](checker/check-response-mediatype-updated_test.go?plain=1#L33) [removing a new oauth security scope](checker/check-components-security-updated_test.go?plain=1#L133) [removing a new security component](checker/check-components-security-updated_test.go?plain=1#L93) -[removing a new security to the API endpoint](checker/check-api-security-updated_test.go?plain=1#L112) -[removing a non-success response status](checker/check-response-status-updated_test.go?plain=1#L63) +[removing a new security to the API endpoint](checker/check-api-security-updated_test.go?plain=1#L106) +[removing a non-success response status](checker/check-response-status-updated_test.go?plain=1#L61) [removing a required request property](checker/check-request-property-updated_test.go?plain=1#L87) -[removing a required write-only property that was required in response body is detected](checker/check-response-required-property-updated_test.go?plain=1#L85) -[removing a security scope from an API endpoint security](checker/check-api-security-updated_test.go?plain=1#L135) -[removing a security scope from an API global security](checker/check-api-security-updated_test.go?plain=1#L49) +[removing a required write-only property that was required in response body is detected](checker/check-response-required-property-updated_test.go?plain=1#L82) +[removing a security scope from an API endpoint security](checker/check-api-security-updated_test.go?plain=1#L127) +[removing a security scope from an API global security](checker/check-api-security-updated_test.go?plain=1#L47) [removing an enum value from a response property](checker/check-response-property-enum-value-removed_test.go?plain=1#L11) [removing an enum value from a response write-only property](checker/check-response-property-enum-value-removed_test.go?plain=1#L35) [removing an enum value from request parameter](checker/check-request-parameter-enum-value-updated_test.go?plain=1#L11) -[removing an existent property that was required in response body is detected](checker/check-response-required-property-updated_test.go?plain=1#L35) +[removing an existent property that was required in response body is detected](checker/check-response-required-property-updated_test.go?plain=1#L34) [removing an existing operation id](checker/check-api-operation-id-updated_test.go?plain=1#L11) -[removing an existing tag](checker/check-api-tag-updated_test.go?plain=1#L36) +[removing an existing tag](checker/check-api-tag-updated_test.go?plain=1#L35) [removing an optional write-only property from a response](checker/check-response-optional-property-updated_test.go?plain=1#L11) -[removing discriminator from the request body or request body property](checker/check-request-discriminator-updated_test.go?plain=1#L47) -[removing discriminator from the response body or response property](checker/check-response-discriminator-updated_test.go?plain=1#L47) -[removing media type from request body](checker/check-request-body-mediatype-updated_test.go?plain=1#L34) +[removing discriminator from the request body or request body property](checker/check-request-discriminator-updated_test.go?plain=1#L45) +[removing discriminator from the response body or response property](checker/check-response-discriminator-updated_test.go?plain=1#L46) +[removing media type from request body](checker/check-request-body-mediatype-updated_test.go?plain=1#L33) [removing pattern from request parameters](checker/check-request-parameter-pattern-added-or-changed_test.go?plain=1#L58) -[removing request body default value or request property default value](checker/check-request-property-default-value-changed_test.go?plain=1#L92) -[removing request parameter default value](checker/check-request-parameters-default-value-changed_test.go?plain=1#L59) +[removing request body default value or request property default value](checker/check-request-property-default-value-changed_test.go?plain=1#L90) +[removing request parameter default value](checker/check-request-parameters-default-value-changed_test.go?plain=1#L57) [removing request property enum values](checker/check-request-property-enum-value-updated_test.go?plain=1#L11) [removing request property pattern](checker/check-request-property-pattern-added-or-changed_test.go?plain=1#L59) -[removing response body default value or response body property default value](checker/check-response-property-default-value-changed_test.go?plain=1#L101) -[removing response property pattern](checker/check-response-pattern-added-or-changed_test.go?plain=1#L63) -[updating an existing operation id](checker/check-api-operation-id-updated_test.go?plain=1#L36) -[updating an existing tag](checker/check-api-tag-updated_test.go?plain=1#L62) +[removing response body default value or response body property default value](checker/check-response-property-default-value-changed_test.go?plain=1#L96) +[removing response property pattern](checker/check-response-pattern-added-or-changed_test.go?plain=1#L61) +[updating an existing operation id](checker/check-api-operation-id-updated_test.go?plain=1#L35) +[updating an existing tag](checker/check-api-tag-updated_test.go?plain=1#L60) diff --git a/checker/api_change.go b/checker/api_change.go index e4bfc6c5..2743fd7c 100644 --- a/checker/api_change.go +++ b/checker/api_change.go @@ -10,7 +10,7 @@ import ( // ApiChange represnts a change in the Paths Section of an OpenAPI spec type ApiChange struct { Id string `json:"id,omitempty" yaml:"id,omitempty"` - Text string `json:"text,omitempty" yaml:"text,omitempty"` + Args []any Comment string `json:"comment,omitempty" yaml:"comment,omitempty"` Level Level `json:"level" yaml:"level"` Operation string `json:"operation,omitempty" yaml:"operation,omitempty"` @@ -25,29 +25,42 @@ type ApiChange struct { SourceColumnEnd int `json:"-" yaml:"-"` } +func (c ApiChange) GetSection() string { + return "paths" +} + func (c ApiChange) IsBreaking() bool { return c.GetLevel().IsBreaking() } -func (c ApiChange) MatchIgnore(ignorePath, ignoreLine string) bool { +func (c ApiChange) MatchIgnore(ignorePath, ignoreLine string, l Localizer) bool { if ignorePath == "" { return false } + x := c.GetUncolorizedText(l) return ignorePath == strings.ToLower(c.Path) && strings.Contains(ignoreLine, strings.ToLower(c.Operation+" "+c.Path)) && - strings.Contains(ignoreLine, strings.ToLower(GetUncolorizedText(c))) + strings.Contains(ignoreLine, strings.ToLower(x)) } func (c ApiChange) GetId() string { return c.Id } -func (c ApiChange) GetText() string { - return c.Text +func (c ApiChange) GetText(l Localizer) string { + return l(c.Id, colorizedValues(c.Args)...) +} + +func (c ApiChange) GetArgs() []any { + return c.Args } -func (c ApiChange) GetComment() string { - return c.Comment +func (c ApiChange) GetUncolorizedText(l Localizer) string { + return l(c.Id, quotedValues(c.Args)...) +} + +func (c ApiChange) GetComment(l Localizer) string { + return l(c.Comment) } func (c ApiChange) GetLevel() Level { @@ -66,6 +79,10 @@ func (c ApiChange) GetPath() string { return c.Path } +func (c ApiChange) GetSource() string { + return c.Source +} + func (c ApiChange) GetSourceFile() string { return c.SourceFile } @@ -86,22 +103,30 @@ func (c ApiChange) GetSourceColumnEnd() int { return c.SourceColumnEnd } -func (c ApiChange) LocalizedError(l Localizer) string { - return fmt.Sprintf("%s %s %s, %s API %s %s %s [%s]. %s", c.Level, l("at"), c.Source, l("in"), c.Operation, c.Path, c.Text, c.Id, c.Comment) -} +func (c ApiChange) SingleLineError(l Localizer, colorMode ColorMode) string { + const format = "%s %s %s, %s API %s %s %s [%s]. %s" -func (c ApiChange) PrettyErrorText(l Localizer) string { - if IsPipedOutput() { - return c.LocalizedError(l) + if isColorEnabled(colorMode) { + return fmt.Sprintf(format, c.Level.PrettyString(), l("at"), c.Source, l("in"), color.InGreen(c.Operation), color.InGreen(c.Path), c.GetText(l), color.InYellow(c.Id), c.GetComment(l)) } - comment := "" - if c.Comment != "" { - comment = fmt.Sprintf("\n\t\t%s", c.Comment) + return fmt.Sprintf(format, c.Level.String(), l("at"), c.Source, l("in"), c.Operation, c.Path, c.GetUncolorizedText(l), c.Id, c.GetComment(l)) + +} + +func (c ApiChange) MultiLineError(l Localizer, colorMode ColorMode) string { + const format = "%s\t[%s] %s %s\t\n\t%s API %s %s\n\t\t%s%s" + + if isColorEnabled(colorMode) { + return fmt.Sprintf(format, c.Level.PrettyString(), color.InYellow(c.Id), l("at"), c.Source, l("in"), color.InGreen(c.Operation), color.InGreen(c.Path), c.GetText(l), multiLineComment(c.GetComment(l))) } - return fmt.Sprintf("%s\t[%s] %s %s\t\n\t%s API %s %s\n\t\t%s%s", c.Level.PrettyString(), color.InYellow(c.Id), l("at"), c.Source, l("in"), color.InGreen(c.Operation), color.InGreen(c.Path), c.Text, comment) + + return fmt.Sprintf(format, c.Level.String(), c.Id, l("at"), c.Source, l("in"), c.Operation, c.Path, c.GetUncolorizedText(l), multiLineComment(c.GetComment(l))) } -func (c ApiChange) Error() string { - return fmt.Sprintf("%s at %s, in API %s %s %s [%s]. %s", c.Level, c.Source, c.Operation, c.Path, c.Text, c.Id, c.Comment) +func multiLineComment(comment string) string { + if comment == "" { + return "" + } + return fmt.Sprintf("\n\t\t%s", comment) } diff --git a/checker/api_change_test.go b/checker/api_change_test.go index 56ec563b..988c4120 100644 --- a/checker/api_change_test.go +++ b/checker/api_change_test.go @@ -8,9 +8,9 @@ import ( ) var apiChange = checker.ApiChange{ - Id: "id", - Text: "text", - Comment: "comment", + Id: "change_id", + Args: []any{}, + Comment: "comment_id", Level: checker.ERR, Operation: "GET", OperationId: "123", @@ -24,29 +24,45 @@ var apiChange = checker.ApiChange{ } func TestApiChange(t *testing.T) { - require.Equal(t, "id", apiChange.GetId()) - require.Equal(t, "text", apiChange.GetText()) - require.Equal(t, "comment", apiChange.GetComment()) + require.Equal(t, "paths", apiChange.GetSection()) + require.Equal(t, "change_id", apiChange.GetId()) + require.Equal(t, "comment", apiChange.GetComment(MockLocalizer)) require.Equal(t, checker.ERR, apiChange.GetLevel()) require.Equal(t, "GET", apiChange.GetOperation()) require.Equal(t, "123", apiChange.GetOperationId()) require.Equal(t, "/test", apiChange.GetPath()) + require.Equal(t, "source", apiChange.GetSource()) require.Equal(t, "sourceFile", apiChange.GetSourceFile()) require.Equal(t, 1, apiChange.GetSourceLine()) require.Equal(t, 2, apiChange.GetSourceLineEnd()) require.Equal(t, 3, apiChange.GetSourceColumn()) require.Equal(t, 4, apiChange.GetSourceColumnEnd()) - require.Equal(t, "error at source, in API GET /test text [id]. comment", apiChange.LocalizedError(checker.NewDefaultLocalizer())) - require.Equal(t, "error at source, in API GET /test text [id]. comment", apiChange.Error()) + require.Equal(t, "error at source, in API GET /test This is a breaking change. [change_id]. comment", apiChange.SingleLineError(MockLocalizer, checker.ColorNever)) +} + +func MockLocalizer(originalKey string, args ...interface{}) string { + switch originalKey { + case "change_id": + return "This is a breaking change." + case "comment_id": + return "comment" + default: + return originalKey + } + } func TestApiChange_MatchIgnore(t *testing.T) { - require.True(t, apiChange.MatchIgnore("/test", "error at source, in api get /test text [id]. comment")) + require.True(t, apiChange.MatchIgnore("/test", "error at source, in api get /test this is a breaking change. [change_id]. comment", MockLocalizer)) } -func TestApiChange_PrettyPiped(t *testing.T) { - piped := true - save := checker.SetPipedOutput(&piped) - defer checker.SetPipedOutput(save) - require.Equal(t, "error at source, in API GET /test text [id]. comment", apiChange.PrettyErrorText(checker.NewDefaultLocalizer())) +func TestApiChange_MultiLineError(t *testing.T) { + require.Equal(t, "error\t[change_id] at source\t\n\tin API GET /test\n\t\tThis is a breaking change.\n\t\tcomment", apiChange.MultiLineError(MockLocalizer, checker.ColorNever)) +} + +func TestApiChange_MultiLineError_NoComment(t *testing.T) { + apiChangeNoComment := apiChange + apiChangeNoComment.Comment = "" + + require.Equal(t, "error\t[change_id] at source\t\n\tin API GET /test\n\t\tThis is a breaking change.", apiChangeNoComment.MultiLineError(MockLocalizer, checker.ColorNever)) } diff --git a/checker/api_change_unix_test.go b/checker/api_change_unix_test.go index 502e86a7..db0b163a 100644 --- a/checker/api_change_unix_test.go +++ b/checker/api_change_unix_test.go @@ -13,5 +13,9 @@ func TestApiChange_PrettyNotPipedUnix(t *testing.T) { piped := false save := checker.SetPipedOutput(&piped) defer checker.SetPipedOutput(save) - require.Equal(t, "\x1b[31merror\x1b[0m\t[\x1b[33mid\x1b[0m] at source\t\n\tin API \x1b[32mGET\x1b[0m \x1b[32m/test\x1b[0m\n\t\ttext\n\t\tcomment", apiChange.PrettyErrorText(checker.NewDefaultLocalizer())) + require.Equal(t, "\x1b[31merror\x1b[0m\t[\x1b[33mchange_id\x1b[0m] at source\t\n\tin API \x1b[32mGET\x1b[0m \x1b[32m/test\x1b[0m\n\t\tThis is a breaking change.\n\t\tcomment", apiChange.MultiLineError(MockLocalizer, checker.ColorAuto)) +} + +func TestApiChange_SingleLineError_WithColor(t *testing.T) { + require.Equal(t, "\x1b[31merror\x1b[0m at source, in API \x1b[32mGET\x1b[0m \x1b[32m/test\x1b[0m This is a breaking change. [\x1b[33mchange_id\x1b[0m]. comment", apiChange.SingleLineError(MockLocalizer, checker.ColorAlways)) } diff --git a/checker/api_change_windows_test.go b/checker/api_change_windows_test.go index bbd33189..332b27a5 100644 --- a/checker/api_change_windows_test.go +++ b/checker/api_change_windows_test.go @@ -11,5 +11,5 @@ func TestApiChange_PrettyNotPipedWindows(t *testing.T) { piped := false save := checker.SetPipedOutput(&piped) defer checker.SetPipedOutput(save) - require.Equal(t, "error\t[id] at source\t\n\tin API GET /test\n\t\ttext\n\t\tcomment", apiChange.PrettyErrorText(checker.NewDefaultLocalizer())) + require.Equal(t, "error\t[change_id] at source\t\n\tin API GET /test\n\t\tThis is a breaking change.\n\t\tcomment", apiChange.MultiLineError(MockLocalizer, checker.ColorAuto)) } diff --git a/checker/change.go b/checker/change.go index f12495e6..d478c13e 100644 --- a/checker/change.go +++ b/checker/change.go @@ -1,21 +1,24 @@ package checker type Change interface { + GetSection() string IsBreaking() bool GetId() string - GetText() string - GetComment() string + GetText(l Localizer) string + GetArgs() []any + GetUncolorizedText(l Localizer) string + GetComment(l Localizer) string GetLevel() Level GetOperation() string GetOperationId() string GetPath() string + GetSource() string GetSourceFile() string GetSourceLine() int GetSourceLineEnd() int GetSourceColumn() int GetSourceColumnEnd() int - MatchIgnore(ignorePath, ignoreLine string) bool - LocalizedError(l Localizer) string - PrettyErrorText(l Localizer) string - Error() string + MatchIgnore(ignorePath, ignoreLine string, l Localizer) bool + SingleLineError(l Localizer, colorMode ColorMode) string + MultiLineError(l Localizer, colorMode ColorMode) string } diff --git a/checker/change_utils.go b/checker/change_utils.go deleted file mode 100644 index 2900da17..00000000 --- a/checker/change_utils.go +++ /dev/null @@ -1,12 +0,0 @@ -package checker - -import ( - "strings" - - "github.com/TwiN/go-color" -) - -func GetUncolorizedText(c Change) string { - uncolorizedText := strings.ReplaceAll(c.GetText(), color.Bold, "") - return strings.ReplaceAll(uncolorizedText, color.Reset, "") -} diff --git a/checker/changes.go b/checker/changes.go index 1bd2492c..63f58044 100644 --- a/checker/changes.go +++ b/checker/changes.go @@ -37,11 +37,18 @@ func (changes Changes) Less(i, j int) bool { return iv.GetOperation() < jv.GetOperation() case iv.GetId() != jv.GetId(): return iv.GetId() < jv.GetId() - case iv.GetText() != jv.GetText(): - return iv.GetText() < jv.GetText() + case len(iv.GetArgs()) != len(jv.GetArgs()): + return len(iv.GetArgs()) < len(jv.GetArgs()) default: - return iv.GetComment() < jv.GetComment() + for i, arg := range iv.GetArgs() { + ia := interfaceToString(arg) + ja := interfaceToString(jv.GetArgs()[i]) + if ia != ja { + return ia < ja + } + } } + return true } func (changes Changes) Swap(i, j int) { diff --git a/checker/changes_by_endpoint.go b/checker/changes_by_endpoint.go deleted file mode 100644 index e3e0f079..00000000 --- a/checker/changes_by_endpoint.go +++ /dev/null @@ -1,27 +0,0 @@ -package checker - -type Endpoint struct { - Path string - Operation string -} - -type ChangesByEndpoint map[Endpoint]*Changes - -func GroupChanges(changes Changes) ChangesByEndpoint { - - apiChanges := ChangesByEndpoint{} - - for _, change := range changes { - switch change.(type) { - case ApiChange: - ep := Endpoint{Path: change.GetPath(), Operation: change.GetOperation()} - if c, ok := apiChanges[ep]; ok { - *c = append(*c, change) - } else { - apiChanges[ep] = &Changes{change} - } - } - } - - return apiChanges -} diff --git a/checker/changes_test.go b/checker/changes_test.go index d7c6084a..c170eaa2 100644 --- a/checker/changes_test.go +++ b/checker/changes_test.go @@ -11,26 +11,22 @@ import ( var changes = checker.Changes{ checker.ApiChange{ Id: "api-deleted", - Text: "API deleted", Level: checker.ERR, Operation: "GET", Path: "/test", }, checker.ApiChange{ Id: "api-added", - Text: "API added", Level: checker.INFO, Operation: "GET", Path: "/test", }, checker.ComponentChange{ Id: "component-added", - Text: "component added", Level: checker.INFO, }, checker.SecurityChange{ Id: "security-added", - Text: "security added", Level: checker.INFO, }, } @@ -51,7 +47,3 @@ func TestChanges_Count(t *testing.T) { require.Equal(t, 0, lc[checker.WARN]) require.Equal(t, 1, lc[checker.ERR]) } - -func TestChanges_Group(t *testing.T) { - require.Contains(t, checker.GroupChanges(changes), checker.Endpoint{Path: "/test", Operation: "GET"}) -} diff --git a/checker/check-added-required-request-body.go b/checker/check-added-required-request-body.go index 93a3071d..989019ca 100644 --- a/checker/check-added-required-request-body.go +++ b/checker/check-added-required-request-body.go @@ -8,7 +8,7 @@ const ( AddedRequiredRequestBodyId = "added-required-request-body" ) -func AddedRequiredRequestBodyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func AddedRequiredRequestBodyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -27,7 +27,6 @@ func AddedRequiredRequestBodyCheck(diffReport *diff.Diff, operationsSources *dif result = append(result, ApiChange{ Id: AddedRequiredRequestBodyId, Level: ERR, - Text: config.Localize(AddedRequiredRequestBodyId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-api-added.go b/checker/check-api-added.go index cdf59ba7..c7478ee3 100644 --- a/checker/check-api-added.go +++ b/checker/check-api-added.go @@ -9,7 +9,7 @@ const ( EndpointAddedId = "endpoint-added" ) -func APIAddedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APIAddedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -19,7 +19,6 @@ func APIAddedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSour result = append(result, ApiChange{ Id: EndpointAddedId, Level: INFO, - Text: config.Localize(EndpointAddedId), Operation: opName, OperationId: opConfig.OperationID, Path: path, diff --git a/checker/check-api-deprecation.go b/checker/check-api-deprecation.go index 55e11cea..2017eb9b 100644 --- a/checker/check-api-deprecation.go +++ b/checker/check-api-deprecation.go @@ -1,7 +1,6 @@ package checker import ( - "fmt" "time" "cloud.google.com/go/civil" @@ -16,7 +15,7 @@ const ( EndpointDeprecatedId = "endpoint-deprecated" ) -func APIDeprecationCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APIDeprecationCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +38,6 @@ func APIDeprecationCheck(diffReport *diff.Diff, operationsSources *diff.Operatio result = append(result, ApiChange{ Id: EndpointReactivatedId, Level: INFO, - Text: config.Localize(EndpointReactivatedId), Operation: operation, OperationId: op.OperationID, Path: path, @@ -53,7 +51,7 @@ func APIDeprecationCheck(diffReport *diff.Diff, operationsSources *diff.Operatio result = append(result, ApiChange{ Id: APIDeprecatedSunsetParseId, Level: ERR, - Text: config.Localize(APIDeprecatedSunsetParseId, rawDate, err), + Args: []any{rawDate, err}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -69,7 +67,7 @@ func APIDeprecationCheck(diffReport *diff.Diff, operationsSources *diff.Operatio result = append(result, ApiChange{ Id: ParseErrorId, Level: ERR, - Text: fmt.Sprintf("parsing error %s", err.Error()), + Args: []any{err.Error()}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -84,7 +82,7 @@ func APIDeprecationCheck(diffReport *diff.Diff, operationsSources *diff.Operatio result = append(result, ApiChange{ Id: APISunsetDateTooSmallId, Level: ERR, - Text: config.Localize(APISunsetDateTooSmallId, date, deprecationDays), + Args: []any{date, deprecationDays}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -97,7 +95,6 @@ func APIDeprecationCheck(diffReport *diff.Diff, operationsSources *diff.Operatio result = append(result, ApiChange{ Id: EndpointDeprecatedId, Level: INFO, - Text: config.Localize(EndpointDeprecatedId), Operation: operation, OperationId: op.OperationID, Path: path, diff --git a/checker/check-api-operation-id-updated.go b/checker/check-api-operation-id-updated.go index e1b79ee0..626e8baf 100644 --- a/checker/check-api-operation-id-updated.go +++ b/checker/check-api-operation-id-updated.go @@ -9,7 +9,7 @@ const ( APIOperationIdAddId = "api-operation-id-added" ) -func APIOperationIdUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APIOperationIdUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -29,17 +29,17 @@ func APIOperationIdUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.O source := (*operationsSources)[op] id := APIOperationIdRemovedId - text := config.Localize(id, ColorizedValue(operationItem.Base.OperationID), ColorizedValue(operationItem.Revision.OperationID)) + args := []any{operationItem.Base.OperationID, operationItem.Revision.OperationID} if operationItem.OperationIDDiff.From == nil || operationItem.OperationIDDiff.From == "" { id = APIOperationIdAddId op = pathItem.Revision.Operations()[operation] - text = config.Localize(id, ColorizedValue(operationItem.Revision.OperationID)) + args = []any{operationItem.Revision.OperationID} } result = append(result, ApiChange{ Id: id, Level: config.getLogLevel(id, INFO), - Text: text, + Args: args, Operation: operation, OperationId: op.OperationID, Path: path, diff --git a/checker/check-api-operation-id-updated_test.go b/checker/check-api-operation-id-updated_test.go index d59e65ce..c342cf2b 100644 --- a/checker/check-api-operation-id-updated_test.go +++ b/checker/check-api-operation-id-updated_test.go @@ -23,8 +23,7 @@ func TestOperationIdRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.APIOperationIdRemovedId, - Text: "api operation id 'createOneGroup' removed and replaced with ''", - Comment: "", + Args: []any{"createOneGroup", ""}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -48,14 +47,15 @@ func TestOperationIdUpdated(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.APIOperationIdRemovedId, - Text: "api operation id 'createOneGroup' removed and replaced with 'newOperationId'", - Comment: "", + Args: []any{"createOneGroup", "newOperationId"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", Source: "../data/checker/operation_id_removed_base.yaml", OperationId: "createOneGroup", }, errs[0]) + + require.Equal(t, "api operation id 'createOneGroup' removed and replaced with 'newOperationId'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // CL: adding a new operation id @@ -73,8 +73,7 @@ func TestOperationIdAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.APIOperationIdAddId, - Text: "api operation id 'NewOperationId' was added", - Comment: "", + Args: []any{"NewOperationId"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-api-removed.go b/checker/check-api-removed.go index f73225fb..9a8cab5a 100644 --- a/checker/check-api-removed.go +++ b/checker/check-api-removed.go @@ -15,7 +15,7 @@ const ( APIRemovedBeforeSunsetId = "api-removed-before-sunset" ) -func APIRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APIRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -32,7 +32,6 @@ func APIRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSo result = append(result, ApiChange{ Id: APIPathRemovedWithoutDeprecationId, Level: ERR, - Text: config.Localize(APIPathRemovedWithoutDeprecationId), Operation: operation, OperationId: op.OperationID, Path: path, @@ -46,7 +45,7 @@ func APIRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSo result = append(result, ApiChange{ Id: APIPathSunsetParseId, Level: ERR, - Text: config.Localize(APIDeprecatedSunsetParseId, rawDate, err), + Args: []any{rawDate, err}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -59,7 +58,7 @@ func APIRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSo result = append(result, ApiChange{ Id: APIPathRemovedBeforeSunsetId, Level: ERR, - Text: config.Localize(APIPathRemovedBeforeSunsetId, date), + Args: []any{date}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -80,7 +79,6 @@ func APIRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSo result = append(result, ApiChange{ Id: APIRemovedWithoutDeprecationId, Level: ERR, - Text: config.Localize(APIRemovedWithoutDeprecationId), Operation: operation, OperationId: op.OperationID, Path: path, @@ -94,7 +92,7 @@ func APIRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSo result = append(result, ApiChange{ Id: APIPathSunsetParseId, Level: ERR, - Text: config.Localize(APIDeprecatedSunsetParseId, rawDate, err), + Args: []any{rawDate, err}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -107,7 +105,7 @@ func APIRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSo result = append(result, ApiChange{ Id: APIRemovedBeforeSunsetId, Level: ERR, - Text: config.Localize(APIRemovedBeforeSunsetId, date), + Args: []any{date}, Operation: operation, OperationId: op.OperationID, Path: path, diff --git a/checker/check-api-security-updated.go b/checker/check-api-security-updated.go index e598a0c3..0a29c5ff 100644 --- a/checker/check-api-security-updated.go +++ b/checker/check-api-security-updated.go @@ -15,7 +15,7 @@ const ( APIGlobalSecurityScopeRemovedId = "api-global-security-scope-removed" ) -func checkGlobalSecurity(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func checkGlobalSecurity(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.SecurityDiff == nil { return result @@ -25,7 +25,7 @@ func checkGlobalSecurity(diffReport *diff.Diff, operationsSources *diff.Operatio result = append(result, SecurityChange{ Id: APIGlobalSecurityAddedCheckId, Level: INFO, - Text: config.Localize(APIGlobalSecurityAddedCheckId, ColorizedValue(addedSecurity)), + Args: []any{addedSecurity}, }) } @@ -33,7 +33,7 @@ func checkGlobalSecurity(diffReport *diff.Diff, operationsSources *diff.Operatio result = append(result, SecurityChange{ Id: APIGlobalSecurityRemovedCheckId, Level: INFO, - Text: config.Localize(APIGlobalSecurityRemovedCheckId, ColorizedValue(removedSecurity)), + Args: []any{removedSecurity}, }) } @@ -43,14 +43,14 @@ func checkGlobalSecurity(diffReport *diff.Diff, operationsSources *diff.Operatio result = append(result, SecurityChange{ Id: APIGlobalSecurityScopeAddedId, Level: INFO, - Text: config.Localize(APIGlobalSecurityScopeAddedId, ColorizedValue(addedScope), ColorizedValue(securitySchemeName)), + Args: []any{addedScope, securitySchemeName}, }) } for _, deletedScope := range updatedSecuritySchemeScopes.Deleted { result = append(result, SecurityChange{ Id: APIGlobalSecurityScopeRemovedId, Level: INFO, - Text: config.Localize(APIGlobalSecurityScopeRemovedId, ColorizedValue(deletedScope), ColorizedValue(securitySchemeName)), + Args: []any{deletedScope, securitySchemeName}, }) } } @@ -60,7 +60,7 @@ func checkGlobalSecurity(diffReport *diff.Diff, operationsSources *diff.Operatio } -func APISecurityUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APISecurityUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) result = append(result, checkGlobalSecurity(diffReport, operationsSources, config)...) @@ -88,7 +88,7 @@ func APISecurityUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.Oper result = append(result, ApiChange{ Id: APISecurityAddedCheckId, Level: INFO, - Text: config.Localize(APISecurityAddedCheckId, ColorizedValue(addedSecurity)), + Args: []any{addedSecurity}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -103,7 +103,7 @@ func APISecurityUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.Oper result = append(result, ApiChange{ Id: APISecurityRemovedCheckId, Level: INFO, - Text: config.Localize(APISecurityRemovedCheckId, ColorizedValue(deletedSecurity)), + Args: []any{deletedSecurity}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -120,7 +120,7 @@ func APISecurityUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.Oper result = append(result, ApiChange{ Id: APISecurityScopeAddedId, Level: INFO, - Text: config.Localize(APISecurityScopeAddedId, ColorizedValue(addedScope), ColorizedValue(securitySchemeName)), + Args: []any{addedScope, securitySchemeName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -131,7 +131,7 @@ func APISecurityUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.Oper result = append(result, ApiChange{ Id: APISecurityScopeRemovedId, Level: INFO, - Text: config.Localize(APISecurityScopeRemovedId, ColorizedValue(deletedScope), ColorizedValue(securitySchemeName)), + Args: []any{deletedScope, securitySchemeName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-api-security-updated_test.go b/checker/check-api-security-updated_test.go index dbe0b124..2c1d44a2 100644 --- a/checker/check-api-security-updated_test.go +++ b/checker/check-api-security-updated_test.go @@ -20,10 +20,9 @@ func TestAPIGlobalSecurityyAdded(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.APISecurityUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.SecurityChange{ - Id: checker.APIGlobalSecurityAddedCheckId, - Text: "the security scheme 'petstore_auth' was added to the API", - Comment: "", - Level: checker.INFO, + Id: checker.APIGlobalSecurityAddedCheckId, + Args: []any{"petstore_auth"}, + Level: checker.INFO, }, errs[0]) } @@ -39,10 +38,9 @@ func TestAPIGlobalSecurityyDeleted(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.APISecurityUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.SecurityChange{ - Id: checker.APIGlobalSecurityRemovedCheckId, - Text: "the security scheme 'petstore_auth' was removed from the API", - Comment: "", - Level: checker.INFO, + Id: checker.APIGlobalSecurityRemovedCheckId, + Args: []any{"petstore_auth"}, + Level: checker.INFO, }, errs[0]) } @@ -59,10 +57,9 @@ func TestAPIGlobalSecurityScopeRemoved(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.APISecurityUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.SecurityChange{ - Id: checker.APIGlobalSecurityScopeRemovedId, - Text: "the security scope 'read:pets' was removed from the global security scheme 'petstore_auth'", - Comment: "", - Level: checker.INFO, + Id: checker.APIGlobalSecurityScopeRemovedId, + Args: []any{"read:pets", "petstore_auth"}, + Level: checker.INFO, }, errs[0]) } @@ -79,10 +76,9 @@ func TestAPIGlobalSecurityScopeAdded(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.APISecurityUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.SecurityChange{ - Id: checker.APIGlobalSecurityScopeAddedId, - Text: "the security scope 'read:pets' was added to the global security scheme 'petstore_auth'", - Comment: "", - Level: checker.INFO, + Id: checker.APIGlobalSecurityScopeAddedId, + Args: []any{"read:pets", "petstore_auth"}, + Level: checker.INFO, }, errs[0]) } @@ -98,14 +94,12 @@ func TestAPISecurityAdded(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.APISecurityUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.APISecurityAddedCheckId, - Text: "the endpoint scheme security 'petstore_auth' was added to the API", - Comment: "", - Level: checker.INFO, - Operation: "POST", - Path: "/subscribe", - Source: "../data/checker/api_security_added_revision.yaml", - OperationId: "", + Id: checker.APISecurityAddedCheckId, + Args: []any{"petstore_auth"}, + Level: checker.INFO, + Operation: "POST", + Path: "/subscribe", + Source: "../data/checker/api_security_added_revision.yaml", }, errs[0]) } @@ -121,14 +115,12 @@ func TestAPISecurityDeleted(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.APISecurityUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.APISecurityRemovedCheckId, - Text: "the endpoint scheme security 'petstore_auth' was removed from the API", - Comment: "", - Level: checker.INFO, - Operation: "POST", - Path: "/subscribe", - Source: "../data/checker/api_security_added_base.yaml", - OperationId: "", + Id: checker.APISecurityRemovedCheckId, + Args: []any{"petstore_auth"}, + Level: checker.INFO, + Operation: "POST", + Path: "/subscribe", + Source: "../data/checker/api_security_added_base.yaml", }, errs[0]) } @@ -144,14 +136,12 @@ func TestAPISecurityScopeRemoved(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.APISecurityUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.APISecurityScopeRemovedId, - Text: "the security scope 'read:pets' was removed from the endpoint's security scheme 'petstore_auth'", - Comment: "", - Level: checker.INFO, - Operation: "POST", - Path: "/subscribe", - Source: "../data/checker/api_security_updated_revision.yaml", - OperationId: "", + Id: checker.APISecurityScopeRemovedId, + Args: []any{"read:pets", "petstore_auth"}, + Level: checker.INFO, + Operation: "POST", + Path: "/subscribe", + Source: "../data/checker/api_security_updated_revision.yaml", }, errs[0]) } @@ -167,13 +157,11 @@ func TestAPISecurityScopeAdded(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.APISecurityUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.APISecurityScopeAddedId, - Text: "the security scope 'read:pets' was added to the endpoint's security scheme 'petstore_auth'", - Comment: "", - Level: checker.INFO, - Operation: "POST", - Path: "/subscribe", - Source: "../data/checker/api_security_updated_base.yaml", - OperationId: "", + Id: checker.APISecurityScopeAddedId, + Args: []any{"read:pets", "petstore_auth"}, + Level: checker.INFO, + Operation: "POST", + Path: "/subscribe", + Source: "../data/checker/api_security_updated_base.yaml", }, errs[0]) } diff --git a/checker/check-api-sunset-changed.go b/checker/check-api-sunset-changed.go index cb671d4b..ec55690d 100644 --- a/checker/check-api-sunset-changed.go +++ b/checker/check-api-sunset-changed.go @@ -1,7 +1,6 @@ package checker import ( - "fmt" "time" "cloud.google.com/go/civil" @@ -13,7 +12,7 @@ const ( APISunsetDateChangedTooSmallId = "api-sunset-date-changed-too-small" ) -func APISunsetChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APISunsetChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -35,7 +34,6 @@ func APISunsetChangedCheck(diffReport *diff.Diff, operationsSources *diff.Operat result = append(result, ApiChange{ Id: APISunsetDeletedId, Level: ERR, - Text: config.Localize(APISunsetDeletedId), Operation: operation, OperationId: op.OperationID, Path: path, @@ -54,7 +52,7 @@ func APISunsetChangedCheck(diffReport *diff.Diff, operationsSources *diff.Operat result = append(result, ApiChange{ Id: APIDeprecatedSunsetParseId, Level: ERR, - Text: config.Localize(APIDeprecatedSunsetParseId, rawDate, err), + Args: []any{rawDate, err}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -68,7 +66,7 @@ func APISunsetChangedCheck(diffReport *diff.Diff, operationsSources *diff.Operat result = append(result, ApiChange{ Id: APIDeprecatedSunsetParseId, Level: ERR, - Text: config.Localize(APIDeprecatedSunsetParseId, rawDate, err), + Args: []any{rawDate, err}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -84,7 +82,7 @@ func APISunsetChangedCheck(diffReport *diff.Diff, operationsSources *diff.Operat result = append(result, ApiChange{ Id: ParseErrorId, Level: ERR, - Text: fmt.Sprintf("parsing error %s", err.Error()), + Args: []any{err.Error()}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -99,7 +97,7 @@ func APISunsetChangedCheck(diffReport *diff.Diff, operationsSources *diff.Operat result = append(result, ApiChange{ Id: APISunsetDateChangedTooSmallId, Level: ERR, - Text: config.Localize(APISunsetDateChangedTooSmallId, baseDate, date, baseDate, deprecationDays), + Args: []any{baseDate, date, baseDate, deprecationDays}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -119,7 +117,7 @@ const ( STABILITY_STABLE = "stable" ) -func getDeprecationDays(config Config, stability string) int { +func getDeprecationDays(config *Config, stability string) int { switch stability { case STABILITY_DRAFT: return 0 diff --git a/checker/check-api-tag-updated.go b/checker/check-api-tag-updated.go index 8ea10804..fdcefc39 100644 --- a/checker/check-api-tag-updated.go +++ b/checker/check-api-tag-updated.go @@ -9,7 +9,7 @@ const ( APITagAddedId = "api-tag-added" ) -func APITagUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APITagUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -32,7 +32,7 @@ func APITagUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.Operation result = append(result, ApiChange{ Id: APITagRemovedId, Level: config.getLogLevel(APITagRemovedId, INFO), - Text: config.Localize(APITagRemovedId, ColorizedValue(tag)), + Args: []any{tag}, Operation: operation, OperationId: op.OperationID, Path: path, @@ -45,15 +45,13 @@ func APITagUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.Operation result = append(result, ApiChange{ Id: APITagAddedId, Level: config.getLogLevel(APITagAddedId, INFO), - Text: config.Localize(APITagAddedId, ColorizedValue(tag)), + Args: []any{tag}, Operation: operation, OperationId: op.OperationID, Path: path, Source: source, }) - } - } } return result diff --git a/checker/check-api-tag-updated_test.go b/checker/check-api-tag-updated_test.go index 1fde27ab..6d7ea27c 100644 --- a/checker/check-api-tag-updated_test.go +++ b/checker/check-api-tag-updated_test.go @@ -23,8 +23,7 @@ func TestTagAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.APITagAddedId, - Text: "api tag 'newTag' added", - Comment: "", + Args: []any{"newTag"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -49,8 +48,7 @@ func TestTagRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.APITagRemovedId, - Text: "api tag 'Test' removed", - Comment: "", + Args: []any{"Test"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -78,8 +76,7 @@ func TestTagUpdated(t *testing.T) { if errs[cl].GetId() == checker.APITagRemovedId { require.Equal(t, checker.ApiChange{ Id: checker.APITagRemovedId, - Text: "api tag 'Test' removed", - Comment: "", + Args: []any{"Test"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -91,8 +88,7 @@ func TestTagUpdated(t *testing.T) { if errs[cl].GetId() == checker.APITagAddedId { require.Equal(t, checker.ApiChange{ Id: checker.APITagAddedId, - Text: "api tag 'newTag' added", - Comment: "", + Args: []any{"newTag"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-components-schemas-removed.go b/checker/check-components-schemas-removed.go index f6ac70f8..ea0d2334 100644 --- a/checker/check-components-schemas-removed.go +++ b/checker/check-components-schemas-removed.go @@ -9,7 +9,7 @@ const ( ComponentSchemas = "schemas" ) -func APIComponentsSchemaRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APIComponentsSchemaRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.ComponentsDiff.SchemasDiff == nil { return result @@ -19,7 +19,7 @@ func APIComponentsSchemaRemovedCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ComponentChange{ Id: APISchemasRemovedId, Level: config.getLogLevel(APISchemasRemovedId, INFO), - Text: config.Localize(APISchemasRemovedId, ColorizedValue(deletedSchema)), + Args: []any{deletedSchema}, Component: ComponentSchemas, }) } diff --git a/checker/check-components-security-updated.go b/checker/check-components-security-updated.go index 87022902..1eb5a328 100644 --- a/checker/check-components-security-updated.go +++ b/checker/check-components-security-updated.go @@ -17,7 +17,7 @@ const ( const ComponentSecuritySchemes = "securitySchemes" -func checkOAuthUpdates(updatedSecurity *diff.SecuritySchemeDiff, config Config, updatedSecurityName string) Changes { +func checkOAuthUpdates(updatedSecurity *diff.SecuritySchemeDiff, config *Config, updatedSecurityName string) Changes { result := make(Changes, 0) if updatedSecurity.OAuthFlowsDiff == nil { @@ -32,7 +32,7 @@ func checkOAuthUpdates(updatedSecurity *diff.SecuritySchemeDiff, config Config, result = append(result, ComponentChange{ Id: APIComponentsSecurityComponentOauthUrlUpdatedId, Level: INFO, - Text: config.Localize(APIComponentsSecurityComponentOauthUrlUpdatedId, ColorizedValue(updatedSecurityName), ColorizedValue(urlDiff.From), ColorizedValue(urlDiff.To)), + Args: []any{updatedSecurityName, urlDiff.From, urlDiff.To}, Component: ComponentSecuritySchemes, }) } @@ -41,7 +41,7 @@ func checkOAuthUpdates(updatedSecurity *diff.SecuritySchemeDiff, config Config, result = append(result, ComponentChange{ Id: APIComponentsSecurityOauthTokenUrlUpdatedId, Level: INFO, - Text: config.Localize(APIComponentsSecurityOauthTokenUrlUpdatedId, ColorizedValue(updatedSecurityName), ColorizedValue(tokenDiff.From), ColorizedValue(tokenDiff.To)), + Args: []any{updatedSecurityName, tokenDiff.From, tokenDiff.To}, Component: ComponentSecuritySchemes, }) } @@ -51,7 +51,7 @@ func checkOAuthUpdates(updatedSecurity *diff.SecuritySchemeDiff, config Config, result = append(result, ComponentChange{ Id: APIComponentSecurityOauthScopeAddedId, Level: INFO, - Text: config.Localize(APIComponentSecurityOauthScopeAddedId, ColorizedValue(updatedSecurityName), ColorizedValue(addedScope)), + Args: []any{updatedSecurityName, addedScope}, Component: ComponentSecuritySchemes, }) } @@ -60,7 +60,7 @@ func checkOAuthUpdates(updatedSecurity *diff.SecuritySchemeDiff, config Config, result = append(result, ComponentChange{ Id: APIComponentSecurityOauthScopeRemovedId, Level: INFO, - Text: config.Localize(APIComponentSecurityOauthScopeRemovedId, ColorizedValue(updatedSecurityName), ColorizedValue(removedScope)), + Args: []any{updatedSecurityName, removedScope}, Component: ComponentSecuritySchemes, }) } @@ -69,7 +69,7 @@ func checkOAuthUpdates(updatedSecurity *diff.SecuritySchemeDiff, config Config, result = append(result, ComponentChange{ Id: APIComponentSecurityOauthScopeUpdatedId, Level: INFO, - Text: config.Localize(APIComponentSecurityOauthScopeUpdatedId, ColorizedValue(updatedSecurityName), ColorizedValue(name), ColorizedValue(modifiedScope.From), ColorizedValue(modifiedScope.To)), + Args: []any{updatedSecurityName, name, modifiedScope.From, modifiedScope.To}, Component: ComponentSecuritySchemes, }) } @@ -79,7 +79,7 @@ func checkOAuthUpdates(updatedSecurity *diff.SecuritySchemeDiff, config Config, return result } -func APIComponentsSecurityUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func APIComponentsSecurityUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.ComponentsDiff.SecuritySchemesDiff == nil { return result @@ -89,7 +89,7 @@ func APIComponentsSecurityUpdatedCheck(diffReport *diff.Diff, operationsSources result = append(result, ComponentChange{ Id: APIComponentsSecurityAddedId, Level: INFO, - Text: config.Localize(APIComponentsSecurityAddedId, ColorizedValue(updatedSecurity)), + Args: []any{updatedSecurity}, Component: ComponentSecuritySchemes, }) } @@ -98,7 +98,7 @@ func APIComponentsSecurityUpdatedCheck(diffReport *diff.Diff, operationsSources result = append(result, ComponentChange{ Id: APIComponentsSecurityRemovedId, Level: INFO, - Text: config.Localize(APIComponentsSecurityRemovedId, ColorizedValue(updatedSecurity)), + Args: []any{updatedSecurity}, Component: ComponentSecuritySchemes, }) } @@ -110,7 +110,7 @@ func APIComponentsSecurityUpdatedCheck(diffReport *diff.Diff, operationsSources result = append(result, ComponentChange{ Id: APIComponentsSecurityTypeUpdatedId, Level: INFO, - Text: config.Localize(APIComponentsSecurityTypeUpdatedId, ColorizedValue(updatedSecurityName), ColorizedValue(updatedSecurity.TypeDiff.From), ColorizedValue(updatedSecurity.TypeDiff.To)), + Args: []any{updatedSecurityName, updatedSecurity.TypeDiff.From, updatedSecurity.TypeDiff.To}, Component: ComponentSecuritySchemes, }) } diff --git a/checker/check-components-security-updated_test.go b/checker/check-components-security-updated_test.go index 716fa1db..63d3b8d7 100644 --- a/checker/check-components-security-updated_test.go +++ b/checker/check-components-security-updated_test.go @@ -23,7 +23,7 @@ func TestComponentSecurityOauthURLUpdated(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ComponentChange{ Id: checker.APIComponentsSecurityComponentOauthUrlUpdatedId, - Text: "the component security scheme 'petstore_auth' oauth url changed from 'http://example.org/api/oauth/dialog' to 'http://example.new.org/api/oauth/dialog'", + Args: []any{"petstore_auth", "http://example.org/api/oauth/dialog", "http://example.new.org/api/oauth/dialog"}, Level: checker.INFO, Component: checker.ComponentSecuritySchemes, }, errs[0]) @@ -44,7 +44,7 @@ func TestComponentSecurityOauthTokenUpdated(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ComponentChange{ Id: checker.APIComponentsSecurityOauthTokenUrlUpdatedId, - Text: "the component security scheme 'petstore_auth' oauth token url changed from '' to 'http://example.new.org/api/oauth/dialog'", + Args: []any{"petstore_auth", "", "http://example.new.org/api/oauth/dialog"}, Level: checker.INFO, Component: checker.ComponentSecuritySchemes, }, errs[0]) @@ -65,7 +65,7 @@ func TestComponentSecurityTypeUpdated(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ComponentChange{ Id: checker.APIComponentsSecurityTypeUpdatedId, - Text: "the component security scheme 'petstore_auth' type changed from 'oauth2' to 'http'", + Args: []any{"petstore_auth", "oauth2", "http"}, Level: checker.INFO, Component: checker.ComponentSecuritySchemes, }, errs[0]) @@ -84,7 +84,7 @@ func TestComponentSecurityAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ComponentChange{ Id: checker.APIComponentsSecurityAddedId, - Text: "the component security scheme 'BasicAuth' was added", + Args: []any{"BasicAuth"}, Level: checker.INFO, Component: checker.ComponentSecuritySchemes, }, errs[0]) @@ -103,7 +103,7 @@ func TestComponentSecurityRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ComponentChange{ Id: checker.APIComponentsSecurityRemovedId, - Text: "the component security scheme 'BasicAuth' was removed", + Args: []any{"BasicAuth"}, Level: checker.INFO, Component: checker.ComponentSecuritySchemes, }, errs[0]) @@ -124,7 +124,7 @@ func TestComponentSecurityOauthScopeAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ComponentChange{ Id: checker.APIComponentSecurityOauthScopeAddedId, - Text: "the component security scheme 'petstore_auth' oauth scope 'admin:pets' was added", + Args: []any{"petstore_auth", "admin:pets"}, Level: checker.INFO, Component: checker.ComponentSecuritySchemes, }, errs[0]) @@ -146,8 +146,7 @@ func TestComponentSecurityOauthScopeRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ComponentChange{ Id: "api-security-component-oauth-scope-removed", - Text: "the component security scheme 'petstore_auth' oauth scope 'admin:pets' was removed", - Comment: "", + Args: []any{"petstore_auth", "admin:pets"}, Level: checker.INFO, Component: checker.ComponentSecuritySchemes, }, errs[0]) @@ -168,8 +167,7 @@ func TestComponentSecurityOauthScopeUpdated(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ComponentChange{ Id: "api-security-component-oauth-scope-changed", - Text: "the component security scheme 'petstore_auth' oauth scope 'read:pets' was updated from 'read your pets' to 'grants access to pets (deprecated)'", - Comment: "", + Args: []any{"petstore_auth", "read:pets", "read your pets", "grants access to pets (deprecated)"}, Level: checker.INFO, Component: checker.ComponentSecuritySchemes, }, errs[0]) diff --git a/checker/check-new-request-non-path-default-parameter.go b/checker/check-new-request-non-path-default-parameter.go index 164e5857..0e66d943 100644 --- a/checker/check-new-request-non-path-default-parameter.go +++ b/checker/check-new-request-non-path-default-parameter.go @@ -9,7 +9,7 @@ const ( NewOptionalRequestDefaultParameterToExistingPathId = "new-optional-request-default-parameter-to-existing-path" ) -func NewRequestNonPathDefaultParameterCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func NewRequestNonPathDefaultParameterCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil || len(diffReport.PathsDiff.Modified) == 0 { return result @@ -42,7 +42,7 @@ func NewRequestNonPathDefaultParameterCheck(diffReport *diff.Diff, operationsSou result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLoc), ColorizedValue(param.Value.Name)), + Args: []any{paramLoc, param.Value.Name}, Operation: operation, OperationId: operationItem.OperationID, Path: path, diff --git a/checker/check-new-request-non-path-default-parameter_test.go b/checker/check-new-request-non-path-default-parameter_test.go index 85df4e8d..0762755e 100644 --- a/checker/check-new-request-non-path-default-parameter_test.go +++ b/checker/check-new-request-non-path-default-parameter_test.go @@ -26,8 +26,7 @@ func TestNewRequestNonPathParameter_DetectsNewRequiredPathsAndNewOperations(t *t require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.NewRequiredRequestDefaultParameterToExistingPathId, - Text: "added the new required 'query' request parameter 'version' to all path's operations", - Comment: "", + Args: []any{"query", "version"}, Level: 3, Operation: "GET", OperationId: "getTest", @@ -35,19 +34,16 @@ func TestNewRequestNonPathParameter_DetectsNewRequiredPathsAndNewOperations(t *t Source: "../data/request_params/required-request-params.yaml", }, { - Id: checker.NewRequiredRequestDefaultParameterToExistingPathId, - Text: "added the new required 'query' request parameter 'version' to all path's operations", - Comment: "", - Level: 3, - Operation: "POST", - OperationId: "", - Path: "/api/test1", - Source: "../data/request_params/required-request-params.yaml", + Id: checker.NewRequiredRequestDefaultParameterToExistingPathId, + Args: []any{"query", "version"}, + Level: 3, + Operation: "POST", + Path: "/api/test1", + Source: "../data/request_params/required-request-params.yaml", }, { Id: checker.NewRequiredRequestDefaultParameterToExistingPathId, - Text: "added the new required 'query' request parameter 'id' to all path's operations", - Comment: "", + Args: []any{"query", "id"}, Level: 3, Operation: "GET", OperationId: "getTest", @@ -56,8 +52,7 @@ func TestNewRequestNonPathParameter_DetectsNewRequiredPathsAndNewOperations(t *t }, { Id: checker.NewRequiredRequestDefaultParameterToExistingPathId, - Text: "added the new required 'header' request parameter 'If-None-Match' to all path's operations", - Comment: "", + Args: []any{"header", "If-None-Match"}, Level: 3, Operation: "GET", OperationId: "getTest", @@ -66,8 +61,7 @@ func TestNewRequestNonPathParameter_DetectsNewRequiredPathsAndNewOperations(t *t }, { Id: checker.NewOptionalRequestDefaultParameterToExistingPathId, - Text: "added the new optional 'query' request parameter 'optionalQueryParam' to all path's operations", - Comment: "", + Args: []any{"query", "optionalQueryParam"}, Level: 1, Operation: "GET", OperationId: "getTest", @@ -75,19 +69,16 @@ func TestNewRequestNonPathParameter_DetectsNewRequiredPathsAndNewOperations(t *t Source: "../data/request_params/required-request-params.yaml", }, { - Id: checker.NewOptionalRequestDefaultParameterToExistingPathId, - Text: "added the new optional 'query' request parameter 'optionalQueryParam' to all path's operations", - Comment: "", - Level: 1, - Operation: "POST", - OperationId: "", - Path: "/api/test1", - Source: "../data/request_params/required-request-params.yaml", + Id: checker.NewOptionalRequestDefaultParameterToExistingPathId, + Args: []any{"query", "optionalQueryParam"}, + Level: 1, + Operation: "POST", + Path: "/api/test1", + Source: "../data/request_params/required-request-params.yaml", }, { Id: checker.NewOptionalRequestDefaultParameterToExistingPathId, - Text: "added the new optional 'header' request parameter 'optionalHeaderParam' to all path's operations", - Comment: "", + Args: []any{"header", "optionalHeaderParam"}, Level: 1, Operation: "GET", OperationId: "getTest", diff --git a/checker/check-new-request-non-path-parameter.go b/checker/check-new-request-non-path-parameter.go index 70140c34..eb28368d 100644 --- a/checker/check-new-request-non-path-parameter.go +++ b/checker/check-new-request-non-path-parameter.go @@ -9,7 +9,7 @@ const ( NewOptionalRequestParameterId = "new-optional-request-parameter" ) -func NewRequestNonPathParameterCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func NewRequestNonPathParameterCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -41,7 +41,7 @@ func NewRequestNonPathParameterCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-new-request-non-path-parameter_test.go b/checker/check-new-request-non-path-parameter_test.go index 0794cac2..1731b3bb 100644 --- a/checker/check-new-request-non-path-parameter_test.go +++ b/checker/check-new-request-non-path-parameter_test.go @@ -29,7 +29,7 @@ func TestNewRequestNonPathParameter_DetectsNewPathsAndNewOperations(t *testing.T require.Equal(t, "GET", e0.Operation) require.Equal(t, "/api/test1", e0.Path) require.Equal(t, checker.INFO, e0.Level) - require.Contains(t, e0.Text, "X-NewRequestHeaderParam") + require.Contains(t, e0.SingleLineError(checker.NewDefaultLocalizer(), checker.ColorNever), "X-NewRequestHeaderParam") require.IsType(t, checker.ApiChange{}, errs[1]) e1 := errs[1].(checker.ApiChange) @@ -37,7 +37,7 @@ func TestNewRequestNonPathParameter_DetectsNewPathsAndNewOperations(t *testing.T require.Equal(t, "GET", e1.Operation) require.Equal(t, "/api/test2", e1.Path) require.Equal(t, checker.INFO, e1.Level) - require.Contains(t, e1.Text, "newQueryParam") + require.Contains(t, e1.SingleLineError(checker.NewDefaultLocalizer(), checker.ColorNever), "newQueryParam") require.IsType(t, checker.ApiChange{}, errs[2]) e2 := errs[2].(checker.ApiChange) @@ -45,5 +45,5 @@ func TestNewRequestNonPathParameter_DetectsNewPathsAndNewOperations(t *testing.T require.Equal(t, "GET", e2.Operation) require.Equal(t, "/api/test3", e2.Path) require.Equal(t, checker.INFO, e2.Level) - require.Contains(t, e2.Text, "csrf-token") + require.Contains(t, e2.SingleLineError(checker.NewDefaultLocalizer(), checker.ColorNever), "csrf-token") } diff --git a/checker/check-new-requried-request-header-property.go b/checker/check-new-requried-request-header-property.go index b51cc559..6bbc9187 100644 --- a/checker/check-new-requried-request-header-property.go +++ b/checker/check-new-requried-request-header-property.go @@ -10,7 +10,7 @@ const ( NewRequiredRequestHeaderPropertyId = "new-required-request-header-property" ) -func NewRequiredRequestHeaderPropertyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func NewRequiredRequestHeaderPropertyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -46,7 +46,7 @@ func NewRequiredRequestHeaderPropertyCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: NewRequiredRequestHeaderPropertyId, Level: ERR, - Text: config.Localize(NewRequiredRequestHeaderPropertyId, ColorizedValue(paramName), ColorizedValue(propertyFullName(propertyPath, newPropertyName))), + Args: []any{paramName, propertyFullName(propertyPath, newPropertyName)}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-body-became-enum.go b/checker/check-request-body-became-enum.go index 863cc7bd..d674a46e 100644 --- a/checker/check-request-body-became-enum.go +++ b/checker/check-request-body-became-enum.go @@ -8,7 +8,7 @@ const ( RequestBodyBecameEnumId = "request-body-became-enum" ) -func RequestBodyBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestBodyBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,6 @@ func RequestBodyBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.O result = append(result, ApiChange{ Id: RequestBodyBecameEnumId, Level: ERR, - Text: config.Localize(RequestBodyBecameEnumId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-body-enum-deleted.go b/checker/check-request-body-enum-deleted.go index c056b9e1..4b86c722 100644 --- a/checker/check-request-body-enum-deleted.go +++ b/checker/check-request-body-enum-deleted.go @@ -8,7 +8,7 @@ const ( RequestBodyEnumValueRemovedId = "request-body-enum-value-removed" ) -func RequestBodyEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestBodyEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -44,7 +44,7 @@ func RequestBodyEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestBodyEnumValueRemovedId, Level: config.getLogLevel(RequestBodyEnumValueRemovedId, INFO), - Text: config.Localize(RequestBodyEnumValueRemovedId, ColorizedValue(enumVal)), + Args: []any{enumVal}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-body-mediatype-updated.go b/checker/check-request-body-mediatype-updated.go index 4f023615..65f134e8 100644 --- a/checker/check-request-body-mediatype-updated.go +++ b/checker/check-request-body-mediatype-updated.go @@ -9,7 +9,7 @@ const ( RequestBodyMediaTypeRemovedId = "request-body-media-type-removed" ) -func RequestBodyMediaTypeChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestBodyMediaTypeChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -31,7 +31,7 @@ func RequestBodyMediaTypeChangedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestBodyMediaTypeAddedId, Level: INFO, - Text: config.Localize(RequestBodyMediaTypeAddedId, mediaType), + Args: []any{mediaType}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -44,14 +44,13 @@ func RequestBodyMediaTypeChangedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestBodyMediaTypeRemovedId, Level: ERR, - Text: config.Localize(RequestBodyMediaTypeRemovedId, mediaType), + Args: []any{mediaType}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) } - } } return result diff --git a/checker/check-request-body-mediatype-updated_test.go b/checker/check-request-body-mediatype-updated_test.go index 29044890..a46a5124 100644 --- a/checker/check-request-body-mediatype-updated_test.go +++ b/checker/check-request-body-mediatype-updated_test.go @@ -21,8 +21,7 @@ func TestRequestBodyMediaTypeAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyMediaTypeAddedId, - Text: "added the media type application/json to the request body", - Comment: "", + Args: []any{"application/json"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -44,8 +43,7 @@ func TestRequestBodyMediaTypeRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyMediaTypeRemovedId, - Text: "removed the media type application/json from the request body", - Comment: "", + Args: []any{"application/json"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-body-required-value-updated.go b/checker/check-request-body-required-value-updated.go index 71f7c9e1..643a3384 100644 --- a/checker/check-request-body-required-value-updated.go +++ b/checker/check-request-body-required-value-updated.go @@ -9,7 +9,7 @@ const ( RequestBodyBecameRequiredId = "request-body-became-required" ) -func RequestBodyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestBodyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,6 @@ func RequestBodyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ApiChange{ Id: id, Level: logLevel, - Text: config.Localize(id), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-body-required-value-updated_test.go b/checker/check-request-body-required-value-updated_test.go index 441b5087..ebd6e206 100644 --- a/checker/check-request-body-required-value-updated_test.go +++ b/checker/check-request-body-required-value-updated_test.go @@ -23,8 +23,6 @@ func TestRequestBodyBecameRequired(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyBecameRequiredId, - Text: "request body became required", - Comment: "", Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -48,8 +46,6 @@ func TestRequestBodyBecameOptional(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyBecameOptionalId, - Text: "request body became optional", - Comment: "", Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-discriminator-updated.go b/checker/check-request-discriminator-updated.go index b3a2af01..00fa9fbf 100644 --- a/checker/check-request-discriminator-updated.go +++ b/checker/check-request-discriminator-updated.go @@ -19,7 +19,7 @@ const ( RequestPropertyDiscriminatorMappingChangedId = "request-property-discriminator-mapping-changed" ) -func RequestDiscriminatorUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestDiscriminatorUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -42,7 +42,7 @@ func RequestDiscriminatorUpdatedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: messageId, Level: INFO, - Text: config.Localize(messageId, a...), + Args: a, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -93,7 +93,7 @@ func processDiscriminatorDiffForRequest( if propertyName == "" { appendResultItem(messageIdPrefix + "-added") } else { - appendResultItem(messageIdPrefix+"-added", ColorizedValue(propertyName)) + appendResultItem(messageIdPrefix+"-added", propertyName) } return } @@ -101,7 +101,7 @@ func processDiscriminatorDiffForRequest( if propertyName == "" { appendResultItem(messageIdPrefix + "-removed") } else { - appendResultItem(messageIdPrefix+"-removed", ColorizedValue(propertyName)) + appendResultItem(messageIdPrefix+"-removed", propertyName) } return } @@ -109,13 +109,13 @@ func processDiscriminatorDiffForRequest( if discriminatorDiff.PropertyNameDiff != nil { if propertyName == "" { appendResultItem(messageIdPrefix+"-property-name-changed", - ColorizedValue(discriminatorDiff.PropertyNameDiff.From), - ColorizedValue(discriminatorDiff.PropertyNameDiff.To)) + discriminatorDiff.PropertyNameDiff.From, + discriminatorDiff.PropertyNameDiff.To) } else { appendResultItem(messageIdPrefix+"-property-name-changed", - ColorizedValue(propertyName), - ColorizedValue(discriminatorDiff.PropertyNameDiff.From), - ColorizedValue(discriminatorDiff.PropertyNameDiff.To)) + propertyName, + discriminatorDiff.PropertyNameDiff.From, + discriminatorDiff.PropertyNameDiff.To) } } @@ -123,37 +123,37 @@ func processDiscriminatorDiffForRequest( if len(discriminatorDiff.MappingDiff.Added) > 0 { if propertyName == "" { appendResultItem(messageIdPrefix+"-mapping-added", - ColorizedValue(discriminatorDiff.MappingDiff.Added)) + discriminatorDiff.MappingDiff.Added) } else { appendResultItem(messageIdPrefix+"-mapping-added", - ColorizedValue(discriminatorDiff.MappingDiff.Added), - ColorizedValue(propertyName)) + discriminatorDiff.MappingDiff.Added, + propertyName) } } if len(discriminatorDiff.MappingDiff.Deleted) > 0 { if propertyName == "" { appendResultItem(messageIdPrefix+"-mapping-deleted", - ColorizedValue(discriminatorDiff.MappingDiff.Deleted)) + discriminatorDiff.MappingDiff.Deleted) } else { appendResultItem(messageIdPrefix+"-mapping-deleted", - ColorizedValue(discriminatorDiff.MappingDiff.Deleted), - ColorizedValue(propertyName)) + discriminatorDiff.MappingDiff.Deleted, + propertyName) } } for k, v := range discriminatorDiff.MappingDiff.Modified { if propertyName == "" { appendResultItem(messageIdPrefix+"-mapping-changed", - ColorizedValue(k), - ColorizedValue(v.From), - ColorizedValue(v.To)) + k, + v.From, + v.To) } else { appendResultItem(messageIdPrefix+"-mapping-changed", - ColorizedValue(k), - ColorizedValue(v.From), - ColorizedValue(v.To), - ColorizedValue(propertyName)) + k, + v.From, + v.To, + propertyName) } } diff --git a/checker/check-request-discriminator-updated_test.go b/checker/check-request-discriminator-updated_test.go index aa529a1b..7c1c505e 100644 --- a/checker/check-request-discriminator-updated_test.go +++ b/checker/check-request-discriminator-updated_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tufin/oasdiff/checker" "github.com/tufin/oasdiff/diff" + "github.com/tufin/oasdiff/utils" ) // CL: adding discriminator to the request body or request body property @@ -24,8 +25,6 @@ func TestRequestDiscriminatorUpdatedCheckAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyDiscriminatorAddedId, - Text: "added request discriminator", - Comment: "", Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -34,8 +33,7 @@ func TestRequestDiscriminatorUpdatedCheckAdded(t *testing.T) { }, { Id: checker.RequestPropertyDiscriminatorAddedId, - Text: "added discriminator to '/oneOf[#/components/schemas/Dog]/breed' request property", - Comment: "", + Args: []any{"/oneOf[#/components/schemas/Dog]/breed"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -60,8 +58,6 @@ func TestRequestDiscriminatorUpdatedCheckRemoved(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyDiscriminatorRemovedId, - Text: "removed request discriminator", - Comment: "", Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -70,8 +66,7 @@ func TestRequestDiscriminatorUpdatedCheckRemoved(t *testing.T) { }, { Id: checker.RequestPropertyDiscriminatorRemovedId, - Text: "removed discriminator from '/oneOf[#/components/schemas/Dog]/breed' request property", - Comment: "", + Args: []any{"/oneOf[#/components/schemas/Dog]/breed"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -96,8 +91,7 @@ func TestRequestDiscriminatorUpdatedCheckPropertyNameChanging(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyDiscriminatorPropertyNameChangedId, - Text: "request discriminator property name changed from 'petType' to 'petType2'", - Comment: "", + Args: []any{"petType", "petType2"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -106,8 +100,7 @@ func TestRequestDiscriminatorUpdatedCheckPropertyNameChanging(t *testing.T) { }, { Id: checker.RequestPropertyDiscriminatorPropertyNameChangedId, - Text: "request discriminator property name changed for '/oneOf[#/components/schemas/Dog]/breed' request property from 'name' to 'name2'", - Comment: "", + Args: []any{"/oneOf[#/components/schemas/Dog]/breed", "name", "name2"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -132,8 +125,7 @@ func TestRequestDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyDiscriminatorMappingAddedId, - Text: "added '[cats]' mapping keys to the request discriminator", - Comment: "", + Args: []any{utils.StringList{"cats"}}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -142,8 +134,7 @@ func TestRequestDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { }, { Id: checker.RequestBodyDiscriminatorMappingDeletedId, - Text: "removed '[cat]' mapping keys from the request discriminator", - Comment: "", + Args: []any{utils.StringList{"cat"}}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -152,8 +143,7 @@ func TestRequestDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { }, { Id: checker.RequestPropertyDiscriminatorMappingAddedId, - Text: "added '[breed1Code]' discriminator mapping keys to the '/oneOf[#/components/schemas/Dog]/breed' request property", - Comment: "", + Args: []any{utils.StringList{"breed1Code"}, "/oneOf[#/components/schemas/Dog]/breed"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -162,8 +152,7 @@ func TestRequestDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { }, { Id: checker.RequestPropertyDiscriminatorMappingChangedId, - Text: "mapped value for discriminator key 'breed2' changed from '#/components/schemas/Breed2' to '#/components/schemas/Breed3' for '/oneOf[#/components/schemas/Dog]/breed' request property", - Comment: "", + Args: []any{"breed2", "#/components/schemas/Breed2", "#/components/schemas/Breed3", "/oneOf[#/components/schemas/Dog]/breed"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -172,8 +161,7 @@ func TestRequestDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { }, { Id: checker.RequestPropertyDiscriminatorMappingDeletedId, - Text: "removed '[breed1]' discriminator mapping keys from the '/oneOf[#/components/schemas/Dog]/breed' request property", - Comment: "", + Args: []any{utils.StringList{"breed1"}, "/oneOf[#/components/schemas/Dog]/breed"}, Level: checker.INFO, Operation: "POST", Path: "/pets", diff --git a/checker/check-request-header-property-became-enum.go b/checker/check-request-header-property-became-enum.go index 147f8f42..cc47f76a 100644 --- a/checker/check-request-header-property-became-enum.go +++ b/checker/check-request-header-property-became-enum.go @@ -8,7 +8,7 @@ const ( RequestHeaderPropertyBecameEnumId = "request-header-property-became-enum" ) -func RequestHeaderPropertyBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestHeaderPropertyBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,7 @@ func RequestHeaderPropertyBecameEnumCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestHeaderPropertyBecameEnumId, Level: ERR, - Text: config.Localize(RequestHeaderPropertyBecameEnumId, ColorizedValue(paramName)), + Args: []any{paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -58,7 +58,7 @@ func RequestHeaderPropertyBecameEnumCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestHeaderPropertyBecameEnumId, Level: ERR, - Text: config.Localize(RequestHeaderPropertyBecameEnumId, ColorizedValue(paramName), ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{paramName, propertyFullName(propertyPath, propertyName)}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-header-property-became-required.go b/checker/check-request-header-property-became-required.go index c07d8604..6e0d5104 100644 --- a/checker/check-request-header-property-became-required.go +++ b/checker/check-request-header-property-became-required.go @@ -8,7 +8,7 @@ const ( RequestHeaderPropertyBecameRequiredId = "request-header-property-became-required" ) -func RequestHeaderPropertyBecameRequiredCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestHeaderPropertyBecameRequiredCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -52,7 +52,7 @@ func RequestHeaderPropertyBecameRequiredCheck(diffReport *diff.Diff, operationsS result = append(result, ApiChange{ Id: RequestHeaderPropertyBecameRequiredId, Level: ERR, - Text: config.Localize(RequestHeaderPropertyBecameRequiredId, ColorizedValue(paramName), ColorizedValue(changedRequiredPropertyName)), + Args: []any{paramName, changedRequiredPropertyName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -78,7 +78,7 @@ func RequestHeaderPropertyBecameRequiredCheck(diffReport *diff.Diff, operationsS result = append(result, ApiChange{ Id: RequestHeaderPropertyBecameRequiredId, Level: ERR, - Text: config.Localize(RequestHeaderPropertyBecameRequiredId, ColorizedValue(paramName), ColorizedValue(propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName)))), + Args: []any{paramName, propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName))}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameter-became-enum.go b/checker/check-request-parameter-became-enum.go index acce1f87..c2ff7a3e 100644 --- a/checker/check-request-parameter-became-enum.go +++ b/checker/check-request-parameter-became-enum.go @@ -8,7 +8,7 @@ const ( RequestParameterBecameEnumId = "request-parameter-became-enum" ) -func RequestParameterBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,7 +38,7 @@ func RequestParameterBecameEnumCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ApiChange{ Id: RequestParameterBecameEnumId, Level: ERR, - Text: config.Localize(RequestParameterBecameEnumId, ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameter-became-enum_test.go b/checker/check-request-parameter-became-enum_test.go index 668ac53f..db9e4e31 100644 --- a/checker/check-request-parameter-became-enum_test.go +++ b/checker/check-request-parameter-became-enum_test.go @@ -21,8 +21,7 @@ func TestRequestParameterBecameEnum(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterBecameEnumId, - Text: "the 'path' request parameter 'groupId' was restricted to a list of enum values", - Comment: "", + Args: []any{"path", "groupId"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-parameter-enum-value-updated.go b/checker/check-request-parameter-enum-value-updated.go index 932380ad..a05e9b18 100644 --- a/checker/check-request-parameter-enum-value-updated.go +++ b/checker/check-request-parameter-enum-value-updated.go @@ -9,7 +9,7 @@ const ( RequestParameterEnumValueRemovedId = "request-parameter-enum-value-removed" ) -func RequestParameterEnumValueUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterEnumValueUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,7 @@ func RequestParameterEnumValueUpdatedCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: RequestParameterEnumValueRemovedId, Level: ERR, - Text: config.Localize(RequestParameterEnumValueRemovedId, ColorizedValue(enumVal), ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{enumVal, paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -50,7 +50,7 @@ func RequestParameterEnumValueUpdatedCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: RequestParameterEnumValueAddedId, Level: INFO, - Text: config.Localize(RequestParameterEnumValueAddedId, ColorizedValue(enumVal), ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{enumVal, paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameter-enum-value-updated_test.go b/checker/check-request-parameter-enum-value-updated_test.go index db426622..299b5be7 100644 --- a/checker/check-request-parameter-enum-value-updated_test.go +++ b/checker/check-request-parameter-enum-value-updated_test.go @@ -22,7 +22,7 @@ func TestRequestParameterEnumValueRemovedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterEnumValueRemovedId, - Text: "removed the enum value 'available' from the 'query' request parameter 'status'", + Args: []any{"available", "query", "status"}, Level: checker.ERR, Operation: "GET", Path: "/test", @@ -45,7 +45,7 @@ func TestRequestParameterEnumValueAddedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterEnumValueAddedId, - Text: "added the new enum value 'available' to the 'query' request parameter 'status'", + Args: []any{"available", "query", "status"}, Level: checker.INFO, Operation: "GET", Path: "/test", diff --git a/checker/check-request-parameter-pattern-added-or-changed.go b/checker/check-request-parameter-pattern-added-or-changed.go index a5989c89..b8398861 100644 --- a/checker/check-request-parameter-pattern-added-or-changed.go +++ b/checker/check-request-parameter-pattern-added-or-changed.go @@ -8,9 +8,10 @@ const ( RequestParameterPatternAddedId = "request-parameter-pattern-added" RequestParameterPatternRemovedId = "request-parameter-pattern-removed" RequestParameterPatternChangedId = "request-parameter-pattern-changed" + PatternChangedCommentId = "pattern-changed-warn-comment" ) -func RequestParameterPatternAddedOrChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterPatternAddedOrChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -41,8 +42,8 @@ func RequestParameterPatternAddedOrChangedCheck(diffReport *diff.Diff, operation result = append(result, ApiChange{ Id: RequestParameterPatternAddedId, Level: WARN, - Text: config.Localize(RequestParameterPatternAddedId, patternDiff.To, ColorizedValue(paramLocation), ColorizedValue(paramName)), - Comment: config.Localize("pattern-changed-warn-comment"), + Args: []any{patternDiff.To, paramLocation, paramName}, + Comment: PatternChangedCommentId, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -52,7 +53,7 @@ func RequestParameterPatternAddedOrChangedCheck(diffReport *diff.Diff, operation result = append(result, ApiChange{ Id: RequestParameterPatternRemovedId, Level: INFO, - Text: config.Localize(RequestParameterPatternRemovedId, patternDiff.From, ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{patternDiff.From, paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -60,7 +61,7 @@ func RequestParameterPatternAddedOrChangedCheck(diffReport *diff.Diff, operation }) } else { level := WARN - comment := config.Localize("pattern-changed-warn-comment") + comment := PatternChangedCommentId if patternDiff.To == ".*" { level = INFO comment = "" @@ -68,7 +69,7 @@ func RequestParameterPatternAddedOrChangedCheck(diffReport *diff.Diff, operation result = append(result, ApiChange{ Id: RequestParameterPatternChangedId, Level: level, - Text: config.Localize(RequestParameterPatternChangedId, ColorizedValue(paramLocation), ColorizedValue(paramName), patternDiff.From, patternDiff.To), + Args: []any{paramLocation, paramName, patternDiff.From, patternDiff.To}, Comment: comment, Operation: operation, OperationId: operationItem.Revision.OperationID, diff --git a/checker/check-request-parameter-pattern-added-or-changed_test.go b/checker/check-request-parameter-pattern-added-or-changed_test.go index 519b766a..3ba8d6bc 100644 --- a/checker/check-request-parameter-pattern-added-or-changed_test.go +++ b/checker/check-request-parameter-pattern-added-or-changed_test.go @@ -21,15 +21,15 @@ func TestRequestParameterPatternChanged(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.RequestParameterPatternAddedOrChangedCheck), d, osm, checker.WARN) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.RequestParameterPatternChangedId, - Text: "changed the pattern of the 'query' request parameter 'category' from '^\\w+$' to '^[\\w\\s]+$'", - Comment: "This is a warning because it is difficult to automatically analyze if the new pattern is a superset of the previous pattern (e.g. changed from '[0-9]+' to '[0-9]*')", - Level: checker.WARN, - Operation: "POST", - Path: "/test", - Source: "../data/checker/request_parameter_pattern_added_or_changed_base.yaml", - OperationId: "", + Id: checker.RequestParameterPatternChangedId, + Args: []any{"query", "category", "^\\w+$", "^[\\w\\s]+$"}, + Comment: checker.PatternChangedCommentId, + Level: checker.WARN, + Operation: "POST", + Path: "/test", + Source: "../data/checker/request_parameter_pattern_added_or_changed_base.yaml", }, errs[0]) + require.Equal(t, "This is a warning because it is difficult to automatically analyze if the new pattern is a superset of the previous pattern (e.g. changed from '[0-9]+' to '[0-9]*')", errs[0].GetComment(checker.NewDefaultLocalizer())) } // CL: adding pattern to request parameters @@ -44,15 +44,15 @@ func TestRequestParameterPatternAdded(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.RequestParameterPatternAddedOrChangedCheck), d, osm, checker.WARN) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.RequestParameterPatternAddedId, - Text: "added the pattern '^\\w+$' to the 'query' request parameter 'category'", - Comment: "This is a warning because it is difficult to automatically analyze if the new pattern is a superset of the previous pattern (e.g. changed from '[0-9]+' to '[0-9]*')", - Level: checker.WARN, - Operation: "POST", - Path: "/test", - Source: "../data/checker/request_parameter_pattern_added_or_changed_base.yaml", - OperationId: "", + Id: checker.RequestParameterPatternAddedId, + Args: []any{"^\\w+$", "query", "category"}, + Comment: checker.PatternChangedCommentId, + Level: checker.WARN, + Operation: "POST", + Path: "/test", + Source: "../data/checker/request_parameter_pattern_added_or_changed_base.yaml", }, errs[0]) + require.Equal(t, "This is a warning because it is difficult to automatically analyze if the new pattern is a superset of the previous pattern (e.g. changed from '[0-9]+' to '[0-9]*')", errs[0].GetComment(checker.NewDefaultLocalizer())) } // CL: removing pattern from request parameters @@ -67,12 +67,11 @@ func TestRequestParameterPatternRemoved(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.RequestParameterPatternAddedOrChangedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.RequestParameterPatternRemovedId, - Text: "removed the pattern '^\\w+$' from the 'query' request parameter 'category'", - Level: checker.INFO, - Operation: "POST", - Path: "/test", - Source: "../data/checker/request_parameter_pattern_added_or_changed_revision.yaml", - OperationId: "", + Id: checker.RequestParameterPatternRemovedId, + Args: []any{"^\\w+$", "query", "category"}, + Level: checker.INFO, + Operation: "POST", + Path: "/test", + Source: "../data/checker/request_parameter_pattern_added_or_changed_revision.yaml", }, errs[0]) } diff --git a/checker/check-request-parameter-removed.go b/checker/check-request-parameter-removed.go index ea5b7e16..81ceff41 100644 --- a/checker/check-request-parameter-removed.go +++ b/checker/check-request-parameter-removed.go @@ -8,7 +8,7 @@ const ( RequestParameterRemovedId = "request-parameter-removed" ) -func RequestParameterRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -27,7 +27,7 @@ func RequestParameterRemovedCheck(diffReport *diff.Diff, operationsSources *diff result = append(result, ApiChange{ Id: RequestParameterRemovedId, Level: WARN, - Text: config.Localize(RequestParameterRemovedId, ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameter-required-value-updated.go b/checker/check-request-parameter-required-value-updated.go index eeac6cf1..152c026b 100644 --- a/checker/check-request-parameter-required-value-updated.go +++ b/checker/check-request-parameter-required-value-updated.go @@ -9,7 +9,7 @@ const ( RequestParameterBecomeOptionalId = "request-parameter-became-optional" ) -func RequestParameterRequiredValueUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterRequiredValueUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -44,7 +44,7 @@ func RequestParameterRequiredValueUpdatedCheck(diffReport *diff.Diff, operations result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameter-x-extensible-enum-value-removed.go b/checker/check-request-parameter-x-extensible-enum-value-removed.go index dd0d3902..c3db9afa 100644 --- a/checker/check-request-parameter-x-extensible-enum-value-removed.go +++ b/checker/check-request-parameter-x-extensible-enum-value-removed.go @@ -2,7 +2,6 @@ package checker import ( "encoding/json" - "fmt" "github.com/tufin/oasdiff/diff" "golang.org/x/exp/slices" @@ -14,7 +13,7 @@ const ( RequestParameterXExtensibleEnumValueRemovedId = "request-parameter-x-extensible-enum-value-removed" ) -func RequestParameterXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -58,7 +57,7 @@ func RequestParameterXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, ope result = append(result, ApiChange{ Id: UnparsableParameterFromXExtensibleEnumId, Level: ERR, - Text: fmt.Sprintf("unparseable x-extensible-enum of the %s request parameter %s", ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,7 +70,7 @@ func RequestParameterXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, ope result = append(result, ApiChange{ Id: UnparsableParameterToXExtensibleEnumId, Level: ERR, - Text: fmt.Sprintf("unparseable x-extensible-enum of the %s request parameter %s", ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -91,7 +90,7 @@ func RequestParameterXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, ope result = append(result, ApiChange{ Id: RequestParameterXExtensibleEnumValueRemovedId, Level: ERR, - Text: config.Localize(RequestParameterXExtensibleEnumValueRemovedId, ColorizedValue(enumVal), ColorizedValue(paramLocation), ColorizedValue(paramName)), + Args: []any{enumVal, paramLocation, paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-default-value-changed.go b/checker/check-request-parameters-default-value-changed.go index f14215d5..14614519 100644 --- a/checker/check-request-parameters-default-value-changed.go +++ b/checker/check-request-parameters-default-value-changed.go @@ -10,7 +10,7 @@ const ( RequestParameterDefaultValueRemovedId = "request-parameter-default-value-removed" ) -func RequestParameterDefaultValueChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterDefaultValueChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -28,7 +28,7 @@ func RequestParameterDefaultValueChangedCheck(diffReport *diff.Diff, operationsS result = append(result, ApiChange{ Id: messageId, Level: ERR, - Text: config.Localize(messageId, a...), + Args: a, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -58,11 +58,11 @@ func RequestParameterDefaultValueChangedCheck(diffReport *diff.Diff, operationsS } if defaultValueDiff.From == nil { - appendResultItem(RequestParameterDefaultValueAddedId, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(defaultValueDiff.To)) + appendResultItem(RequestParameterDefaultValueAddedId, paramLocation, paramName, defaultValueDiff.To) } else if defaultValueDiff.To == nil { - appendResultItem(RequestParameterDefaultValueRemovedId, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(defaultValueDiff.From)) + appendResultItem(RequestParameterDefaultValueRemovedId, paramLocation, paramName, defaultValueDiff.From) } else { - appendResultItem(RequestParameterDefaultValueChangedId, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(defaultValueDiff.From), ColorizedValue(defaultValueDiff.To)) + appendResultItem(RequestParameterDefaultValueChangedId, paramLocation, paramName, defaultValueDiff.From, defaultValueDiff.To) } } } diff --git a/checker/check-request-parameters-default-value-changed_test.go b/checker/check-request-parameters-default-value-changed_test.go index c95a930a..4217a616 100644 --- a/checker/check-request-parameters-default-value-changed_test.go +++ b/checker/check-request-parameters-default-value-changed_test.go @@ -21,8 +21,7 @@ func TestRequestParameterDefaultValueChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterDefaultValueChangedId, - Text: "for the 'query' request parameter 'category', default value was changed from 'default_category' to 'updated_category'", - Comment: "", + Args: []any{"query", "category", "default_category", "updated_category"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -46,8 +45,7 @@ func TestRequestParameterDefaultValueAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterDefaultValueAddedId, - Text: "for the 'query' request parameter 'category', default value 'default_category' was added", - Comment: "", + Args: []any{"query", "category", "default_category"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -71,8 +69,7 @@ func TestRequestParameterDefaultValueRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterDefaultValueRemovedId, - Text: "for the 'query' request parameter 'category', default value 'default_category' was removed", - Comment: "", + Args: []any{"query", "category", "default_category"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-parameters-max-items-updated.go b/checker/check-request-parameters-max-items-updated.go index 2df1d8eb..a60184cc 100644 --- a/checker/check-request-parameters-max-items-updated.go +++ b/checker/check-request-parameters-max-items-updated.go @@ -9,7 +9,7 @@ const ( RequestParameterMaxItemsDecreasedId = "request-parameter-max-items-decreased" ) -func RequestParameterMaxItemsUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMaxItemsUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -48,7 +48,7 @@ func RequestParameterMaxItemsUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(maxItemsDiff.From), ColorizedValue(maxItemsDiff.To)), + Args: []any{paramLocation, paramName, maxItemsDiff.From, maxItemsDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-max-items-updated_test.go b/checker/check-request-parameters-max-items-updated_test.go index 963fb058..2c24bf70 100644 --- a/checker/check-request-parameters-max-items-updated_test.go +++ b/checker/check-request-parameters-max-items-updated_test.go @@ -21,8 +21,7 @@ func TestRequestParameterMaxItemsIncreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMaxItemsIncreasedId, - Text: "for the 'query' request parameter 'category', the maxItems was increased from '10' to '20'", - Comment: "", + Args: []any{"query", "category", uint64(10), uint64(20)}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -44,8 +43,7 @@ func TestRequestParameterMaxItemsDecreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMaxItemsDecreasedId, - Text: "for the 'query' request parameter 'category', the maxItems was decreased from '20' to '10'", - Comment: "", + Args: []any{"query", "category", uint64(20), uint64(10)}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-parameters-max-length-set.go b/checker/check-request-parameters-max-length-set.go index 37a60ef2..b3bf25f0 100644 --- a/checker/check-request-parameters-max-length-set.go +++ b/checker/check-request-parameters-max-length-set.go @@ -8,7 +8,7 @@ const ( RequestParameterMaxLengthSetId = "request-parameter-max-length-set" ) -func RequestParameterMaxLengthSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMaxLengthSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -40,8 +40,8 @@ func RequestParameterMaxLengthSetCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: RequestParameterMaxLengthSetId, Level: WARN, - Text: config.Localize(RequestParameterMaxLengthSetId, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(maxLengthDiff.To)), - Comment: config.Localize(comment(RequestParameterMaxLengthSetId)), + Args: []any{paramLocation, paramName, maxLengthDiff.To}, + Comment: commentId(RequestParameterMaxLengthSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-max-length-updated.go b/checker/check-request-parameters-max-length-updated.go index 47953c7a..da94c9dd 100644 --- a/checker/check-request-parameters-max-length-updated.go +++ b/checker/check-request-parameters-max-length-updated.go @@ -9,7 +9,7 @@ const ( RequestParameterMaxLengthIncreasedId = "request-parameter-max-length-increased" ) -func RequestParameterMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -48,7 +48,7 @@ func RequestParameterMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(maxLengthDiff.From), ColorizedValue(maxLengthDiff.To)), + Args: []any{paramLocation, paramName, maxLengthDiff.From, maxLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-max-length-updated_test.go b/checker/check-request-parameters-max-length-updated_test.go index 827eb4c6..88475c65 100644 --- a/checker/check-request-parameters-max-length-updated_test.go +++ b/checker/check-request-parameters-max-length-updated_test.go @@ -20,13 +20,12 @@ func TestRequestParameterMaxLengthIncreasedCheck(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.RequestParameterMaxLengthUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.RequestParameterMaxLengthIncreasedId, - Text: "for the 'query' request parameter 'category', the maxLength was increased from '10' to '15'", - Level: checker.INFO, - Operation: "POST", - Path: "/test", - Source: "../data/checker/request_parameter_max_length_updated_revision.yaml", - OperationId: "", + Id: checker.RequestParameterMaxLengthIncreasedId, + Args: []any{"query", "category", uint64(10), uint64(15)}, + Level: checker.INFO, + Operation: "POST", + Path: "/test", + Source: "../data/checker/request_parameter_max_length_updated_revision.yaml", }, errs[0]) } @@ -42,12 +41,11 @@ func TestRequestParameterMaxLengthDecreasedCheck(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.RequestParameterMaxLengthUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.RequestParameterMaxLengthDecreasedId, - Text: "for the 'query' request parameter 'category', the maxLength was decreased from '15' to '10'", - Level: checker.ERR, - Operation: "POST", - Path: "/test", - Source: "../data/checker/request_parameter_max_length_updated_base.yaml", - OperationId: "", + Id: checker.RequestParameterMaxLengthDecreasedId, + Args: []any{"query", "category", uint64(15), uint64(10)}, + Level: checker.ERR, + Operation: "POST", + Path: "/test", + Source: "../data/checker/request_parameter_max_length_updated_base.yaml", }, errs[0]) } diff --git a/checker/check-request-parameters-max-set.go b/checker/check-request-parameters-max-set.go index 213e64ff..2b7c0e27 100644 --- a/checker/check-request-parameters-max-set.go +++ b/checker/check-request-parameters-max-set.go @@ -8,7 +8,7 @@ const ( RequestParameterMaxSetId = "request-parameter-max-set" ) -func RequestParameterMaxSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMaxSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -40,8 +40,8 @@ func RequestParameterMaxSetCheck(diffReport *diff.Diff, operationsSources *diff. result = append(result, ApiChange{ Id: RequestParameterMaxSetId, Level: WARN, - Text: config.Localize(RequestParameterMaxSetId, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(maxDiff.To)), - Comment: config.Localize(comment(RequestParameterMaxSetId)), + Args: []any{paramLocation, paramName, maxDiff.To}, + Comment: commentId(RequestParameterMaxSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-max-updated.go b/checker/check-request-parameters-max-updated.go index 8f59bd4d..58910880 100644 --- a/checker/check-request-parameters-max-updated.go +++ b/checker/check-request-parameters-max-updated.go @@ -9,7 +9,7 @@ const ( RequestParameterMaxIncreasedId = "request-parameter-max-increased" ) -func RequestParameterMaxUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMaxUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -49,7 +49,7 @@ func RequestParameterMaxUpdatedCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(maxDiff.From), ColorizedValue(maxDiff.To)), + Args: []any{paramLocation, paramName, maxDiff.From, maxDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-max-updated_test.go b/checker/check-request-parameters-max-updated_test.go index 9159b8b6..b87f6a3a 100644 --- a/checker/check-request-parameters-max-updated_test.go +++ b/checker/check-request-parameters-max-updated_test.go @@ -21,7 +21,7 @@ func TestRequestParameterMaxIncreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMaxIncreasedId, - Text: "for the 'query' request parameter 'category', the max was increased from '5.00' to '10.00'", + Args: []any{"query", "category", 5.0, 10.0}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -43,7 +43,7 @@ func TestRequestParameterMaxDecreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMaxDecreasedId, - Text: "for the 'query' request parameter 'category', the max was decreased from '10.00' to '5.00'", + Args: []any{"query", "category", 10.0, 5.0}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-parameters-min-items-set.go b/checker/check-request-parameters-min-items-set.go index ae72cb15..ed22cf9a 100644 --- a/checker/check-request-parameters-min-items-set.go +++ b/checker/check-request-parameters-min-items-set.go @@ -8,7 +8,7 @@ const ( RequestParameterMinItemsSetId = "request-parameter-min-items-set" ) -func RequestParameterMinItemsSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMinItemsSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,8 +39,8 @@ func RequestParameterMinItemsSetCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestParameterMinItemsSetId, Level: WARN, - Text: config.Localize(RequestParameterMinItemsSetId, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(minItemsDiff.To)), - Comment: config.Localize(comment(RequestParameterMinItemsSetId)), + Args: []any{paramLocation, paramName, minItemsDiff.To}, + Comment: commentId(RequestParameterMinItemsSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-min-items-updated.go b/checker/check-request-parameters-min-items-updated.go index bb0e5776..ec0f35e4 100644 --- a/checker/check-request-parameters-min-items-updated.go +++ b/checker/check-request-parameters-min-items-updated.go @@ -9,7 +9,7 @@ const ( RequestParameterMinItemsDecreasedId = "request-parameter-min-items-decreased" ) -func RequestParameterMinItemsUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMinItemsUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -48,7 +48,7 @@ func RequestParameterMinItemsUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(minItemsDiff.From), ColorizedValue(minItemsDiff.To)), + Args: []any{paramLocation, paramName, minItemsDiff.From, minItemsDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-min-items-updated_test.go b/checker/check-request-parameters-min-items-updated_test.go index 3bf79639..bcfa1d85 100644 --- a/checker/check-request-parameters-min-items-updated_test.go +++ b/checker/check-request-parameters-min-items-updated_test.go @@ -21,7 +21,7 @@ func TestRequestParameterMinItemsIncreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMinItemsIncreasedId, - Text: "for the 'query' request parameter 'category', the minItems was increased from '2' to '3'", + Args: []any{"query", "category", uint64(2), uint64(3)}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -43,7 +43,7 @@ func TestRequestParameterMinItemsDecreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMinItemsDecreasedId, - Text: "for the 'query' request parameter 'category', the minItems was decreased from '3' to '2'", + Args: []any{"query", "category", uint64(3), uint64(2)}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-parameters-min-length-updated.go b/checker/check-request-parameters-min-length-updated.go index c8fb95b8..c8265ed2 100644 --- a/checker/check-request-parameters-min-length-updated.go +++ b/checker/check-request-parameters-min-length-updated.go @@ -9,7 +9,7 @@ const ( RequestParameterMinLengthDecreasedId = "request-parameter-min-length-decreased" ) -func RequestParameterMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -48,7 +48,7 @@ func RequestParameterMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(minLengthDiff.From), ColorizedValue(minLengthDiff.To)), + Args: []any{paramLocation, paramName, minLengthDiff.From, minLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-min-length-updated_test.go b/checker/check-request-parameters-min-length-updated_test.go index 6847adda..a8a66f60 100644 --- a/checker/check-request-parameters-min-length-updated_test.go +++ b/checker/check-request-parameters-min-length-updated_test.go @@ -22,7 +22,7 @@ func TestRequestParameterMinLengthIncreasedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMinLengthIncreasedId, - Text: "for the 'query' request parameter 'name', the minLength was increased from '3' to '5'", + Args: []any{"query", "name", uint64(3), uint64(5)}, Level: checker.ERR, Operation: "POST", Path: "/test", @@ -45,7 +45,7 @@ func TestRequestParameterMinLengthDecreasedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMinLengthDecreasedId, - Text: "for the 'query' request parameter 'name', the minLength was decreased from '5' to '3'", + Args: []any{"query", "name", uint64(5), uint64(3)}, Level: checker.INFO, Operation: "POST", Path: "/test", diff --git a/checker/check-request-parameters-min-set.go b/checker/check-request-parameters-min-set.go index 96385732..2b92d9e1 100644 --- a/checker/check-request-parameters-min-set.go +++ b/checker/check-request-parameters-min-set.go @@ -8,7 +8,7 @@ const ( RequestParameterMinSetId = "request-parameter-min-set" ) -func RequestParameterMinSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMinSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -40,8 +40,8 @@ func RequestParameterMinSetCheck(diffReport *diff.Diff, operationsSources *diff. result = append(result, ApiChange{ Id: RequestParameterMinSetId, Level: WARN, - Text: config.Localize(RequestParameterMinSetId, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(minDiff.To)), - Comment: config.Localize(comment(RequestParameterMinSetId)), + Args: []any{paramLocation, paramName, minDiff.To}, + Comment: commentId(RequestParameterMinSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-min-updated.go b/checker/check-request-parameters-min-updated.go index 935faa4f..a4514622 100644 --- a/checker/check-request-parameters-min-updated.go +++ b/checker/check-request-parameters-min-updated.go @@ -9,7 +9,7 @@ const ( RequestParameterMinDecreasedId = "request-parameter-min-decreased" ) -func RequestParameterMinUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterMinUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -48,7 +48,7 @@ func RequestParameterMinUpdatedCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(paramLocation), ColorizedValue(paramName), ColorizedValue(minDiff.From), ColorizedValue(minDiff.To)), + Args: []any{paramLocation, paramName, minDiff.From, minDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-min-updated_test.go b/checker/check-request-parameters-min-updated_test.go index 97147839..883ae36b 100644 --- a/checker/check-request-parameters-min-updated_test.go +++ b/checker/check-request-parameters-min-updated_test.go @@ -21,7 +21,7 @@ func TestRequestParameterMinIncreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMinIncreasedId, - Text: "for the 'path' request parameter 'groupId', the min was increased from '1.00' to '10.00'", + Args: []any{"path", "groupId", 1.0, 10.0}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -43,7 +43,7 @@ func TestRequestParameterMinDecreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterMinDecreasedId, - Text: "for the 'path' request parameter 'groupId', the min was decreased from '10.00' to '1.00'", + Args: []any{"path", "groupId", 10.0, 1.0}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-parameters-type-changed.go b/checker/check-request-parameters-type-changed.go index 2025f084..c19b47fa 100644 --- a/checker/check-request-parameters-type-changed.go +++ b/checker/check-request-parameters-type-changed.go @@ -8,7 +8,7 @@ const ( RequestParameterTypeChangedId = "request-parameter-type-changed" ) -func RequestParameterTypeChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestParameterTypeChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -74,7 +74,7 @@ func RequestParameterTypeChangedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestParameterTypeChangedId, Level: ERR, - Text: config.Localize(RequestParameterTypeChangedId, ColorizedValue(paramLocation), ColorizedValue(paramName), empty2none(typeDiff.From), empty2none(formatDiff.From), empty2none(typeDiff.To), empty2none(formatDiff.To)), + Args: []any{paramLocation, paramName, typeDiff.From, formatDiff.From, typeDiff.To, formatDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-parameters-type-changed_test.go b/checker/check-request-parameters-type-changed_test.go index 0ac39127..528e550b 100644 --- a/checker/check-request-parameters-type-changed_test.go +++ b/checker/check-request-parameters-type-changed_test.go @@ -23,8 +23,7 @@ func TestRequestPathParamTypeChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterTypeChangedId, - Text: "for the 'path' request parameter 'groupId', the type/format was changed from 'string'/'none' to 'int'/'none'", - Comment: "", + Args: []any{"path", "groupId", "string", "", "int", ""}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -48,8 +47,7 @@ func TestRequestQueryParamTypeChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterTypeChangedId, - Text: "for the 'query' request parameter 'token', the type/format was changed from 'string'/'uuid' to 'int'/'uuid'", - Comment: "", + Args: []any{"query", "token", "string", "uuid", "int", "uuid"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -73,8 +71,7 @@ func TestRequestQueryHeaderTypeChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterTypeChangedId, - Text: "for the 'header' request parameter 'X-Request-ID', the type/format was changed from 'string'/'uuid' to 'int'/'uuid'", - Comment: "", + Args: []any{"header", "X-Request-ID", "string", "uuid", "int", "uuid"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -98,8 +95,7 @@ func TestRequestPathParamFormatChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterTypeChangedId, - Text: "for the 'path' request parameter 'groupId', the type/format was changed from 'string'/'none' to 'string'/'uuid'", - Comment: "", + Args: []any{"path", "groupId", "string", "", "string", "uuid"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -123,8 +119,7 @@ func TestRequestQueryParamFormatChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterTypeChangedId, - Text: "for the 'query' request parameter 'token', the type/format was changed from 'string'/'uuid' to 'string'/'uri'", - Comment: "", + Args: []any{"query", "token", "string", "uuid", "string", "uri"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -148,8 +143,7 @@ func TestRequestQueryHeaderFormatChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterTypeChangedId, - Text: "for the 'header' request parameter 'X-Request-ID', the type/format was changed from 'string'/'uuid' to 'string'/'uri'", - Comment: "", + Args: []any{"header", "X-Request-ID", "string", "uuid", "string", "uri"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-path-parameter-added.go b/checker/check-request-path-parameter-added.go index 99cf53a4..166bdfbf 100644 --- a/checker/check-request-path-parameter-added.go +++ b/checker/check-request-path-parameter-added.go @@ -8,7 +8,7 @@ const ( NewRequestPathParameterId = "new-request-path-parameter" ) -func NewRequestPathParameterCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func NewRequestPathParameterCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -31,7 +31,7 @@ func NewRequestPathParameterCheck(diffReport *diff.Diff, operationsSources *diff result = append(result, ApiChange{ Id: NewRequestPathParameterId, Level: ERR, - Text: config.Localize(NewRequestPathParameterId, ColorizedValue(paramName)), + Args: []any{paramName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-all-of-updated.go b/checker/check-request-property-all-of-updated.go index fb8ff197..0c7c8519 100644 --- a/checker/check-request-property-all-of-updated.go +++ b/checker/check-request-property-all-of-updated.go @@ -11,7 +11,7 @@ const ( RequestPropertyAllOfRemovedId = "request-property-all-of-removed" ) -func RequestPropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,11 +38,9 @@ func RequestPropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if mediaTypeDiff.SchemaDiff.AllOfDiff != nil && len(mediaTypeDiff.SchemaDiff.AllOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: RequestBodyAllOfAddedId, - Level: ERR, - Text: config.Localize( - RequestBodyAllOfAddedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.AllOfDiff.Added.String())), + Id: RequestBodyAllOfAddedId, + Level: ERR, + Args: []any{mediaTypeDiff.SchemaDiff.AllOfDiff.Added.String()}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -52,11 +50,9 @@ func RequestPropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if mediaTypeDiff.SchemaDiff.AllOfDiff != nil && len(mediaTypeDiff.SchemaDiff.AllOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: RequestBodyAllOfRemovedId, - Level: WARN, - Text: config.Localize( - RequestBodyAllOfRemovedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.AllOfDiff.Deleted.String())), + Id: RequestBodyAllOfRemovedId, + Level: WARN, + Args: []any{mediaTypeDiff.SchemaDiff.AllOfDiff.Deleted.String()}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,14 +67,14 @@ func RequestPropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources * return } + propName := propertyFullName(propertyPath, propertyName) + if len(propertyDiff.AllOfDiff.Added) > 0 { result = append(result, ApiChange{ Id: RequestPropertyAllOfAddedId, Level: ERR, - Text: config.Localize( - RequestPropertyAllOfAddedId, - ColorizedValue(propertyDiff.AllOfDiff.Added.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName))), + + Args: []any{propertyDiff.AllOfDiff.Added.String(), propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -88,12 +84,9 @@ func RequestPropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if len(propertyDiff.AllOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: RequestPropertyAllOfRemovedId, - Level: WARN, - Text: config.Localize( - RequestPropertyAllOfRemovedId, - ColorizedValue(propertyDiff.AllOfDiff.Deleted.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName))), + Id: RequestPropertyAllOfRemovedId, + Level: WARN, + Args: []any{propertyDiff.AllOfDiff.Deleted.String(), propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-all-of-updated_test.go b/checker/check-request-property-all-of-updated_test.go index 1d80d74b..339e1fc4 100644 --- a/checker/check-request-property-all-of-updated_test.go +++ b/checker/check-request-property-all-of-updated_test.go @@ -24,8 +24,7 @@ func TestRequestPropertyAllOfAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyAllOfAddedId, - Text: "added 'Rabbit' to the request body 'allOf' list", - Comment: "", + Args: []any{"Rabbit"}, Level: checker.ERR, Operation: "POST", Path: "/pets", @@ -34,8 +33,7 @@ func TestRequestPropertyAllOfAdded(t *testing.T) { }, { Id: checker.RequestPropertyAllOfAddedId, - Text: "added 'Breed3' to the '/allOf[#/components/schemas/Dog]/breed' request property 'allOf' list", - Comment: "", + Args: []any{"Breed3", "/allOf[#/components/schemas/Dog]/breed"}, Level: checker.ERR, Operation: "POST", Path: "/pets", @@ -60,8 +58,7 @@ func TestRequestPropertyAllOfRemoved(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyAllOfRemovedId, - Text: "removed 'Rabbit' from the request body 'allOf' list", - Comment: "", + Args: []any{"Rabbit"}, Level: checker.WARN, Operation: "POST", Path: "/pets", @@ -70,8 +67,7 @@ func TestRequestPropertyAllOfRemoved(t *testing.T) { }, { Id: checker.RequestPropertyAllOfRemovedId, - Text: "removed 'Breed3' from the '/allOf[#/components/schemas/Dog]/breed' request property 'allOf' list", - Comment: "", + Args: []any{"Breed3", "/allOf[#/components/schemas/Dog]/breed"}, Level: checker.WARN, Operation: "POST", Path: "/pets", diff --git a/checker/check-request-property-any-of-updated.go b/checker/check-request-property-any-of-updated.go index 762609fe..2d6b89c5 100644 --- a/checker/check-request-property-any-of-updated.go +++ b/checker/check-request-property-any-of-updated.go @@ -11,7 +11,7 @@ const ( RequestPropertyAnyOfRemovedId = "request-property-any-of-removed" ) -func RequestPropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,11 +38,9 @@ func RequestPropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if mediaTypeDiff.SchemaDiff.AnyOfDiff != nil && len(mediaTypeDiff.SchemaDiff.AnyOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: RequestBodyAnyOfAddedId, - Level: INFO, - Text: config.Localize( - RequestBodyAnyOfAddedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.AnyOfDiff.Added.String())), + Id: RequestBodyAnyOfAddedId, + Level: INFO, + Args: []any{mediaTypeDiff.SchemaDiff.AnyOfDiff.Added.String()}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -52,11 +50,9 @@ func RequestPropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if mediaTypeDiff.SchemaDiff.AnyOfDiff != nil && len(mediaTypeDiff.SchemaDiff.AnyOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: RequestBodyAnyOfRemovedId, - Level: ERR, - Text: config.Localize( - RequestBodyAnyOfRemovedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.AnyOfDiff.Deleted.String())), + Id: RequestBodyAnyOfRemovedId, + Level: ERR, + Args: []any{mediaTypeDiff.SchemaDiff.AnyOfDiff.Deleted.String()}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,14 +67,13 @@ func RequestPropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources * return } + propName := propertyFullName(propertyPath, propertyName) + if len(propertyDiff.AnyOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: RequestPropertyAnyOfAddedId, - Level: INFO, - Text: config.Localize( - RequestPropertyAnyOfAddedId, - ColorizedValue(propertyDiff.AnyOfDiff.Added.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName))), + Id: RequestPropertyAnyOfAddedId, + Level: INFO, + Args: []any{propertyDiff.AnyOfDiff.Added.String(), propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -88,12 +83,9 @@ func RequestPropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if len(propertyDiff.AnyOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: RequestPropertyAnyOfRemovedId, - Level: ERR, - Text: config.Localize( - RequestPropertyAnyOfRemovedId, - ColorizedValue(propertyDiff.AnyOfDiff.Deleted.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName))), + Id: RequestPropertyAnyOfRemovedId, + Level: ERR, + Args: []any{propertyDiff.AnyOfDiff.Deleted.String(), propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-any-of-updated_test.go b/checker/check-request-property-any-of-updated_test.go index b981bb37..4b9a70d4 100644 --- a/checker/check-request-property-any-of-updated_test.go +++ b/checker/check-request-property-any-of-updated_test.go @@ -24,8 +24,7 @@ func TestRequestPropertyAnyOfAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyAnyOfAddedId, - Text: "added 'Rabbit' to the request body 'anyOf' list", - Comment: "", + Args: []any{"Rabbit"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -34,8 +33,7 @@ func TestRequestPropertyAnyOfAdded(t *testing.T) { }, { Id: checker.RequestPropertyAnyOfAddedId, - Text: "added 'Breed3' to the '/anyOf[#/components/schemas/Dog]/breed' request property 'anyOf' list", - Comment: "", + Args: []any{"Breed3", "/anyOf[#/components/schemas/Dog]/breed"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -60,8 +58,7 @@ func TestRequestPropertyAnyOfRemoved(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyAnyOfRemovedId, - Text: "removed 'Rabbit' from the request body 'anyOf' list", - Comment: "", + Args: []any{"Rabbit"}, Level: checker.ERR, Operation: "POST", Path: "/pets", @@ -70,8 +67,7 @@ func TestRequestPropertyAnyOfRemoved(t *testing.T) { }, { Id: checker.RequestPropertyAnyOfRemovedId, - Text: "removed 'Breed3' from the '/anyOf[#/components/schemas/Dog]/breed' request property 'anyOf' list", - Comment: "", + Args: []any{"Breed3", "/anyOf[#/components/schemas/Dog]/breed"}, Level: checker.ERR, Operation: "POST", Path: "/pets", diff --git a/checker/check-request-property-became-enum.go b/checker/check-request-property-became-enum.go index c5292c53..f6d8c577 100644 --- a/checker/check-request-property-became-enum.go +++ b/checker/check-request-property-became-enum.go @@ -8,7 +8,7 @@ const ( RequestPropertyBecameEnumId = "request-property-became-enum" ) -func RequestPropertyBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyBecameEnumCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -42,7 +42,7 @@ func RequestPropertyBecameEnumCheck(diffReport *diff.Diff, operationsSources *di result = append(result, ApiChange{ Id: RequestPropertyBecameEnumId, Level: ERR, - Text: config.Localize(RequestPropertyBecameEnumId, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propertyFullName(propertyPath, propertyName)}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-became-not-nuallable.go b/checker/check-request-property-became-not-nuallable.go index a272e579..7e411d98 100644 --- a/checker/check-request-property-became-not-nuallable.go +++ b/checker/check-request-property-became-not-nuallable.go @@ -11,7 +11,7 @@ const ( RequestPropertyBecomeNullableId = "request-property-became-nullable" ) -func RequestPropertyBecameNotNullableCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyBecameNotNullableCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -37,22 +37,22 @@ func RequestPropertyBecameNotNullableCheck(diffReport *diff.Diff, operationsSour if mediaTypeDiff.SchemaDiff.NullableDiff != nil { if mediaTypeDiff.SchemaDiff.NullableDiff.From == true { result = append(result, ApiChange{ - Id: RequestBodyBecomeNotNullableId, - Level: ERR, - Text: config.Localize(RequestBodyBecomeNotNullableId), - Operation: operation, - Path: path, - Source: source, + Id: RequestBodyBecomeNotNullableId, + Level: ERR, + Operation: operation, + Path: path, + Source: source, + OperationId: operationItem.Revision.OperationID, }) } else if mediaTypeDiff.SchemaDiff.NullableDiff.To == true { result = append(result, ApiChange{ - Id: RequestBodyBecomeNullableId, - Level: INFO, - Text: config.Localize(RequestBodyBecomeNullableId), - Operation: operation, - Path: path, - Source: source, + Id: RequestBodyBecomeNullableId, + Level: INFO, + Operation: operation, + Path: path, + Source: source, + OperationId: operationItem.Revision.OperationID, }) } @@ -65,24 +65,29 @@ func RequestPropertyBecameNotNullableCheck(diffReport *diff.Diff, operationsSour if nullableDiff == nil { return } + + propName := propertyFullName(propertyPath, propertyName) + if nullableDiff.From == true { result = append(result, ApiChange{ - Id: RequestPropertyBecomeNotNullableId, - Level: ERR, - Text: config.Localize(RequestPropertyBecomeNotNullableId, ColorizedValue(propertyFullName(propertyPath, propertyName))), - Operation: operation, - Path: path, - Source: source, + Id: RequestPropertyBecomeNotNullableId, + Level: ERR, + Args: []any{propName}, + Operation: operation, + Path: path, + Source: source, + OperationId: operationItem.Revision.OperationID, }) } else if nullableDiff.To == true { result = append(result, ApiChange{ - Id: RequestPropertyBecomeNullableId, - Level: INFO, - Text: config.Localize(RequestPropertyBecomeNullableId, ColorizedValue(propertyFullName(propertyPath, propertyName))), - Operation: operation, - Path: path, - Source: source, + Id: RequestPropertyBecomeNullableId, + Level: INFO, + Args: []any{propName}, + Operation: operation, + Path: path, + Source: source, + OperationId: operationItem.Revision.OperationID, }) } diff --git a/checker/check-request-property-became-not-nuallable_test.go b/checker/check-request-property-became-not-nuallable_test.go index 7cd76e01..32d82f99 100644 --- a/checker/check-request-property-became-not-nuallable_test.go +++ b/checker/check-request-property-became-not-nuallable_test.go @@ -21,8 +21,7 @@ func TestRequestPropertyBecameNotNullable(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyBecomeNotNullableId, - Text: "the request property 'name' became not nullable", - Comment: "", + Args: []any{"name"}, Level: checker.ERR, Operation: "POST", Path: "/products", @@ -44,8 +43,7 @@ func TestRequestPropertyBecameNullable(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyBecomeNullableId, - Text: "the request property 'name' became nullable", - Comment: "", + Args: []any{"name"}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -71,8 +69,6 @@ func TestRequestBodyBecameNullable(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyBecomeNullableId, - Text: "the request's body became nullable", - Comment: "", Level: checker.INFO, Operation: "POST", Path: "/products", @@ -97,8 +93,6 @@ func TestRequestBodyBecameNotNullable(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyBecomeNotNullableId, - Text: "the request's body became not nullable", - Comment: "", Level: checker.ERR, Operation: "POST", Path: "/products", diff --git a/checker/check-request-property-default-value-changed.go b/checker/check-request-property-default-value-changed.go index 4dc83e8e..6d61c79e 100644 --- a/checker/check-request-property-default-value-changed.go +++ b/checker/check-request-property-default-value-changed.go @@ -13,7 +13,7 @@ const ( RequestPropertyDefaultValueChangedId = "request-property-default-value-changed" ) -func RequestPropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -34,7 +34,7 @@ func RequestPropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsSo result = append(result, ApiChange{ Id: messageId, Level: INFO, - Text: config.Localize(messageId, a...), + Args: a, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -48,11 +48,11 @@ func RequestPropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsSo defaultValueDiff := mediaTypeDiff.SchemaDiff.DefaultDiff if defaultValueDiff.From == nil { - appendResultItem(RequestBodyDefaultValueAddedId, ColorizedValue(mediaType), empty2none(defaultValueDiff.To)) + appendResultItem(RequestBodyDefaultValueAddedId, mediaType, defaultValueDiff.To) } else if defaultValueDiff.To == nil { - appendResultItem(RequestBodyDefaultValueRemovedId, ColorizedValue(mediaType), empty2none(defaultValueDiff.From)) + appendResultItem(RequestBodyDefaultValueRemovedId, mediaType, defaultValueDiff.From) } else { - appendResultItem(RequestBodyDefaultValueChangedId, ColorizedValue(mediaType), empty2none(defaultValueDiff.From), empty2none(defaultValueDiff.To)) + appendResultItem(RequestBodyDefaultValueChangedId, mediaType, defaultValueDiff.From, defaultValueDiff.To) } } @@ -66,11 +66,11 @@ func RequestPropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsSo defaultValueDiff := propertyDiff.DefaultDiff if defaultValueDiff.From == nil { - appendResultItem(RequestPropertyDefaultValueAddedId, ColorizedValue(propertyName), empty2none(defaultValueDiff.To)) + appendResultItem(RequestPropertyDefaultValueAddedId, propertyName, defaultValueDiff.To) } else if defaultValueDiff.To == nil { - appendResultItem(RequestPropertyDefaultValueRemovedId, ColorizedValue(propertyName), empty2none(defaultValueDiff.From)) + appendResultItem(RequestPropertyDefaultValueRemovedId, propertyName, defaultValueDiff.From) } else { - appendResultItem(RequestPropertyDefaultValueChangedId, ColorizedValue(propertyName), empty2none(defaultValueDiff.From), empty2none(defaultValueDiff.To)) + appendResultItem(RequestPropertyDefaultValueChangedId, propertyName, defaultValueDiff.From, defaultValueDiff.To) } }) } diff --git a/checker/check-request-property-default-value-changed_test.go b/checker/check-request-property-default-value-changed_test.go index 19e0a8d7..83c3138c 100644 --- a/checker/check-request-property-default-value-changed_test.go +++ b/checker/check-request-property-default-value-changed_test.go @@ -21,8 +21,7 @@ func TestRequestBodyDefaultValueChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyDefaultValueChangedId, - Text: "the request body 'text/plain' default value changed from 'Default' to 'NewDefault'", - Comment: "", + Args: []any{"text/plain", "Default", "NewDefault"}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -46,7 +45,7 @@ func TestRequestPropertyDefaultValueChanged(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyDefaultValueChangedId, - Text: "the 'price' request property default value changed from '10.00' to '20.00'", + Args: []any{"price", 10.0, 20.0}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -71,8 +70,7 @@ func TestRequestBodyDefaultValueAdded(t *testing.T) { require.Len(t, errs, 2) require.ElementsMatch(t, []checker.ApiChange{{ Id: checker.RequestBodyDefaultValueAddedId, - Text: "the request body 'text/plain' default value 'Default' was added", - Comment: "", + Args: []any{"text/plain", "Default"}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -80,7 +78,7 @@ func TestRequestBodyDefaultValueAdded(t *testing.T) { OperationId: "createProduct", }, { Id: checker.RequestPropertyDefaultValueAddedId, - Text: "the 'price' request property default value '10.00' was added", + Args: []any{"price", 10.0}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -105,8 +103,7 @@ func TestRequestBodyDefaultValueRemoving(t *testing.T) { require.Len(t, errs, 2) require.ElementsMatch(t, []checker.ApiChange{{ Id: checker.RequestBodyDefaultValueRemovedId, - Text: "the request body 'text/plain' default value 'Default' was removed", - Comment: "", + Args: []any{"text/plain", "Default"}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -114,7 +111,7 @@ func TestRequestBodyDefaultValueRemoving(t *testing.T) { OperationId: "createProduct", }, { Id: checker.RequestPropertyDefaultValueRemovedId, - Text: "the 'price' request property default value '10.00' was removed", + Args: []any{"price", 10.0}, Level: checker.INFO, Operation: "POST", Path: "/products", diff --git a/checker/check-request-property-enum-value-updated.go b/checker/check-request-property-enum-value-updated.go index acc4288e..347e6308 100644 --- a/checker/check-request-property-enum-value-updated.go +++ b/checker/check-request-property-enum-value-updated.go @@ -9,7 +9,7 @@ const ( RequestPropertyEnumValueAddedId = "request-property-enum-value-added" ) -func RequestPropertyEnumValueUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyEnumValueUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -36,11 +36,13 @@ func RequestPropertyEnumValueUpdatedCheck(diffReport *diff.Diff, operationsSourc return } + propName := propertyFullName(propertyPath, propertyName) + for _, enumVal := range enumDiff.Deleted { result = append(result, ApiChange{ Id: RequestPropertyEnumValueRemovedId, - Level: ConditionalError(!propertyDiff.Revision.ReadOnly, INFO), - Text: config.Localize(RequestPropertyEnumValueRemovedId, ColorizedValue(enumVal), ColorizedValue(propertyFullName(propertyPath, propertyName))), + Level: conditionalError(!propertyDiff.Revision.ReadOnly, INFO), + Args: []any{enumVal, propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -52,7 +54,7 @@ func RequestPropertyEnumValueUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestPropertyEnumValueAddedId, Level: INFO, - Text: config.Localize(RequestPropertyEnumValueAddedId, ColorizedValue(enumVal), ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{enumVal, propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-enum-value-updated_test.go b/checker/check-request-property-enum-value-updated_test.go index 9ffbabc4..7b850c0d 100644 --- a/checker/check-request-property-enum-value-updated_test.go +++ b/checker/check-request-property-enum-value-updated_test.go @@ -26,7 +26,7 @@ func TestRequestPropertyEnumValueRemovedCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyEnumValueRemovedId, Level: checker.ERR, - Text: "removed the enum value 'bird' of the request property 'category'", + Args: []any{"bird", "category"}, Operation: "POST", OperationId: "updatePet", Path: "/pets", @@ -52,7 +52,7 @@ func TestRequestPropertyEnumValueAddedCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyEnumValueAddedId, Level: checker.INFO, - Text: "added the new 'bird' enum value to the request property 'category'", + Args: []any{"bird", "category"}, Operation: "POST", OperationId: "updatePet", Path: "/pets", diff --git a/checker/check-request-property-max-length-set.go b/checker/check-request-property-max-length-set.go index 3354e276..df86be95 100644 --- a/checker/check-request-property-max-length-set.go +++ b/checker/check-request-property-max-length-set.go @@ -9,7 +9,7 @@ const ( RequestPropertyMaxLengthSetId = "request-property-max-length-set" ) -func RequestPropertyMaxLengthSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMaxLengthSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -35,8 +35,8 @@ func RequestPropertyMaxLengthSetCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestBodyMaxLengthSetId, Level: WARN, - Text: config.Localize(RequestBodyMaxLengthSetId, ColorizedValue(maxLengthDiff.To)), - Comment: config.Localize(comment(RequestBodyMaxLengthSetId)), + Args: []any{maxLengthDiff.To}, + Comment: commentId(RequestBodyMaxLengthSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -63,8 +63,8 @@ func RequestPropertyMaxLengthSetCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestPropertyMaxLengthSetId, Level: WARN, - Text: config.Localize(RequestPropertyMaxLengthSetId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxLengthDiff.To)), - Comment: config.Localize(comment(RequestPropertyMaxLengthSetId)), + Args: []any{propertyFullName(propertyPath, propertyName), maxLengthDiff.To}, + Comment: commentId(RequestPropertyMaxLengthSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-max-length-updated.go b/checker/check-request-property-max-length-updated.go index 40ed43be..61c71686 100644 --- a/checker/check-request-property-max-length-updated.go +++ b/checker/check-request-property-max-length-updated.go @@ -11,7 +11,7 @@ const ( RequestPropertyMaxLengthIncreasedId = "request-property-max-length-increased" ) -func RequestPropertyMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,7 +38,7 @@ func RequestPropertyMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestBodyMaxLengthDecreasedId, Level: ERR, - Text: config.Localize(RequestBodyMaxLengthDecreasedId, ColorizedValue(maxLengthDiff.To)), + Args: []any{maxLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -48,7 +48,7 @@ func RequestPropertyMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestBodyMaxLengthIncreasedId, Level: INFO, - Text: config.Localize(RequestBodyMaxLengthIncreasedId, ColorizedValue(maxLengthDiff.From), ColorizedValue(maxLengthDiff.To)), + Args: []any{maxLengthDiff.From, maxLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -70,11 +70,13 @@ func RequestPropertyMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSourc return } + propName := propertyFullName(propertyPath, propertyName) + if IsDecreasedValue(maxLengthDiff) { result = append(result, ApiChange{ Id: RequestPropertyMaxLengthDecreasedId, - Level: ConditionalError(!propertyDiff.Revision.ReadOnly, INFO), - Text: config.Localize(RequestPropertyMaxLengthDecreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxLengthDiff.To)), + Level: conditionalError(!propertyDiff.Revision.ReadOnly, INFO), + Args: []any{propName, maxLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -84,7 +86,7 @@ func RequestPropertyMaxLengthUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestPropertyMaxLengthIncreasedId, Level: INFO, - Text: config.Localize(RequestPropertyMaxLengthIncreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxLengthDiff.From), ColorizedValue(maxLengthDiff.To)), + Args: []any{propName, maxLengthDiff.From, maxLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-max-length-updated_test.go b/checker/check-request-property-max-length-updated_test.go index fb1a6e14..436c2bc9 100644 --- a/checker/check-request-property-max-length-updated_test.go +++ b/checker/check-request-property-max-length-updated_test.go @@ -27,7 +27,7 @@ func TestRequestBodyMaxLengthDecreasedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyMaxLengthIncreasedId, - Text: "the request's body maxLength was increased from '50' to '100'", + Args: []any{maxLength, newMaxLength}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -55,7 +55,7 @@ func TestRequestBodyMaxLengthIncreasedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyMaxLengthDecreasedId, - Text: "the request's body maxLength was decreased to '50'", + Args: []any{newMaxLength}, Level: checker.ERR, Operation: "POST", Path: "/pets", @@ -82,7 +82,7 @@ func TestRequestPropertyMaxLengthDecreasedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyMaxLengthDecreasedId, - Text: "the 'description' request property's maxLength was decreased to '50'", + Args: []any{"description", newMaxLength}, Level: checker.ERR, Operation: "POST", Path: "/pets", @@ -109,7 +109,7 @@ func TestRequestPropertyMaxLengthIncreasedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyMaxLengthIncreasedId, - Text: "the 'description' request property's maxLength was increased from '50' to '100'", + Args: []any{"description", maxLength, newMaxLength}, Level: checker.INFO, Operation: "POST", Path: "/pets", diff --git a/checker/check-request-property-max-set.go b/checker/check-request-property-max-set.go index dd3aa332..21ecbd6a 100644 --- a/checker/check-request-property-max-set.go +++ b/checker/check-request-property-max-set.go @@ -9,7 +9,7 @@ const ( RequestPropertyMaxSetId = "request-property-max-set" ) -func RequestPropertyMaxSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMaxSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -35,8 +35,8 @@ func RequestPropertyMaxSetCheck(diffReport *diff.Diff, operationsSources *diff.O result = append(result, ApiChange{ Id: RequestBodyMaxSetId, Level: WARN, - Text: config.Localize(RequestBodyMaxSetId, ColorizedValue(maxDiff.To)), - Comment: config.Localize(comment(RequestBodyMaxSetId)), + Args: []any{maxDiff.To}, + Comment: commentId(RequestBodyMaxSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -63,8 +63,8 @@ func RequestPropertyMaxSetCheck(diffReport *diff.Diff, operationsSources *diff.O result = append(result, ApiChange{ Id: RequestPropertyMaxSetId, Level: WARN, - Text: config.Localize(RequestPropertyMaxSetId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxDiff.To)), - Comment: config.Localize(comment(RequestPropertyMaxSetId)), + Args: []any{propertyFullName(propertyPath, propertyName), maxDiff.To}, + Comment: commentId(RequestPropertyMaxSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-max-updated.go b/checker/check-request-property-max-updated.go index df94b1e6..86045dc9 100644 --- a/checker/check-request-property-max-updated.go +++ b/checker/check-request-property-max-updated.go @@ -11,7 +11,7 @@ const ( RequestPropertyMaxIncreasedId = "request-property-max-increased" ) -func RequestPropertyMaxDecreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMaxDecreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,7 +38,7 @@ func RequestPropertyMaxDecreasedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestBodyMaxDecreasedId, Level: ERR, - Text: config.Localize(RequestBodyMaxDecreasedId, ColorizedValue(maxDiff.To)), + Args: []any{maxDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -48,7 +48,7 @@ func RequestPropertyMaxDecreasedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestBodyMaxIncreasedId, Level: INFO, - Text: config.Localize(RequestBodyMaxIncreasedId, ColorizedValue(maxDiff.From), ColorizedValue(maxDiff.To)), + Args: []any{maxDiff.From, maxDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -69,11 +69,14 @@ func RequestPropertyMaxDecreasedCheck(diffReport *diff.Diff, operationsSources * maxDiff.To == nil { return } + + propName := propertyFullName(propertyPath, propertyName) + if IsDecreasedValue(maxDiff) { result = append(result, ApiChange{ Id: RequestPropertyMaxDecreasedId, - Level: ConditionalError(!propertyDiff.Revision.ReadOnly, INFO), - Text: config.Localize(RequestPropertyMaxDecreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxDiff.To)), + Level: conditionalError(!propertyDiff.Revision.ReadOnly, INFO), + Args: []any{propName, maxDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -83,7 +86,7 @@ func RequestPropertyMaxDecreasedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestPropertyMaxIncreasedId, Level: INFO, - Text: config.Localize(RequestPropertyMaxIncreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxDiff.From), ColorizedValue(maxDiff.To)), + Args: []any{propName, maxDiff.From, maxDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-max-updated_test.go b/checker/check-request-property-max-updated_test.go index e26edf4e..fc0eb815 100644 --- a/checker/check-request-property-max-updated_test.go +++ b/checker/check-request-property-max-updated_test.go @@ -26,7 +26,7 @@ func TestRequestPropertyMaxDecreasedCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyMaxDecreasedId, Level: checker.ERR, - Text: "the 'name' request property's max was decreased to '10.00'", + Args: []any{"name", 10.0}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_max_decreased_base.yaml", @@ -52,7 +52,7 @@ func TestRequestPropertyMaxIncreasingCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyMaxIncreasedId, Level: checker.INFO, - Text: "the 'name' request property's max was increased from '15.00' to '20.00'", + Args: []any{"name", 15.0, 20.0}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_max_decreased_base.yaml", @@ -80,7 +80,7 @@ func TestRequestBodyMaxIncreasingCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyMaxIncreasedId, Level: checker.INFO, - Text: "the request's body max was increased from '20.00' to '25.00'", + Args: []any{20.0, 25.0}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_max_decreased_base.yaml", @@ -108,7 +108,7 @@ func TestRequestBodyMaxDecreasedCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyMaxDecreasedId, Level: checker.ERR, - Text: "the request's body max was decreased to '20.00'", + Args: []any{20.0}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_max_decreased_base.yaml", diff --git a/checker/check-request-property-min-items-increased.go b/checker/check-request-property-min-items-increased.go index 0809b17e..4dd80fd2 100644 --- a/checker/check-request-property-min-items-increased.go +++ b/checker/check-request-property-min-items-increased.go @@ -9,7 +9,7 @@ const ( RequestPropertyMinItemsIncreasedId = "request-property-min-items-increased" ) -func RequestPropertyMinItemsIncreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMinItemsIncreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -36,7 +36,7 @@ func RequestPropertyMinItemsIncreasedCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: RequestBodyMinItemsIncreasedId, Level: ERR, - Text: config.Localize(RequestBodyMinItemsIncreasedId, ColorizedValue(minItemsDiff.To)), + Args: []any{minItemsDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -67,7 +67,7 @@ func RequestPropertyMinItemsIncreasedCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: RequestPropertyMinItemsIncreasedId, Level: ERR, - Text: config.Localize(RequestPropertyMinItemsIncreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minItemsDiff.To)), + Args: []any{propertyFullName(propertyPath, propertyName), minItemsDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-min-items-set.go b/checker/check-request-property-min-items-set.go index 836a88b7..270d65a1 100644 --- a/checker/check-request-property-min-items-set.go +++ b/checker/check-request-property-min-items-set.go @@ -9,7 +9,7 @@ const ( RequestPropertyMinItemsSetId = "request-property-min-items-set" ) -func RequestPropertyMinItemsSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMinItemsSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -35,8 +35,8 @@ func RequestPropertyMinItemsSetCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ApiChange{ Id: RequestBodyMinItemsSetId, Level: WARN, - Text: config.Localize(RequestBodyMinItemsSetId, ColorizedValue(minItemsDiff.To)), - Comment: config.Localize(comment(RequestBodyMinItemsSetId)), + Args: []any{minItemsDiff.To}, + Comment: commentId(RequestBodyMinItemsSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -63,8 +63,8 @@ func RequestPropertyMinItemsSetCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ApiChange{ Id: RequestPropertyMinItemsSetId, Level: WARN, - Text: config.Localize(RequestPropertyMinItemsSetId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minItemsDiff.To)), - Comment: config.Localize(comment(RequestPropertyMinItemsSetId)), + Args: []any{propertyFullName(propertyPath, propertyName), minItemsDiff.To}, + Comment: commentId(RequestPropertyMinItemsSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-min-length-updated.go b/checker/check-request-property-min-length-updated.go index 917f9b64..ec71365c 100644 --- a/checker/check-request-property-min-length-updated.go +++ b/checker/check-request-property-min-length-updated.go @@ -11,7 +11,7 @@ const ( RequestPropertyMinLengthDecreasedId = "request-property-min-length-decreased" ) -func RequestPropertyMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,7 +38,7 @@ func RequestPropertyMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestBodyMinLengthIncreasedId, Level: ERR, - Text: config.Localize(RequestBodyMinLengthIncreasedId, ColorizedValue(minLengthDiff.From), ColorizedValue(minLengthDiff.To)), + Args: []any{minLengthDiff.From, minLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -48,7 +48,7 @@ func RequestPropertyMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestBodyMinLengthDecreasedId, Level: INFO, - Text: config.Localize(RequestBodyMinLengthDecreasedId, ColorizedValue(minLengthDiff.From), ColorizedValue(minLengthDiff.To)), + Args: []any{minLengthDiff.From, minLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -70,11 +70,13 @@ func RequestPropertyMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSourc return } + propName := propertyFullName(propertyPath, propertyName) + if IsDecreasedValue(minLengthDiff) { result = append(result, ApiChange{ Id: RequestPropertyMinLengthDecreasedId, Level: INFO, - Text: config.Localize(RequestPropertyMinLengthDecreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minLengthDiff.From), ColorizedValue(minLengthDiff.To)), + Args: []any{propName, minLengthDiff.From, minLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -84,14 +86,13 @@ func RequestPropertyMinLengthUpdatedCheck(diffReport *diff.Diff, operationsSourc result = append(result, ApiChange{ Id: RequestPropertyMinLengthIncreasedId, Level: ERR, - Text: config.Localize(RequestPropertyMinLengthIncreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minLengthDiff.From), ColorizedValue(minLengthDiff.To)), + Args: []any{propName, minLengthDiff.From, minLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) } - }) } } diff --git a/checker/check-request-property-min-length-updated_test.go b/checker/check-request-property-min-length-updated_test.go index b1bad4b7..76f1c9b6 100644 --- a/checker/check-request-property-min-length-updated_test.go +++ b/checker/check-request-property-min-length-updated_test.go @@ -23,8 +23,7 @@ func TestRequestPropertyMinLengthDecreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyMinLengthDecreasedId, - Text: "the 'name' request property's minLength was decreased from '3' to '2'", - Comment: "", + Args: []any{"name", uint64(3), uint64(2)}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -48,8 +47,7 @@ func TestRequestPropertyMinLengthIncreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyMinLengthIncreasedId, - Text: "the 'name' request property's minLength was increased from '3' to '5'", - Comment: "", + Args: []any{"name", uint64(3), uint64(5)}, Level: checker.ERR, Operation: "POST", Path: "/products", @@ -73,8 +71,7 @@ func TestRequestBodyMinLengthIncreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyMinLengthIncreasedId, - Text: "the request's body minLength was increased from '10' to '100'", - Comment: "", + Args: []any{uint64(10), uint64(100)}, Level: checker.ERR, Operation: "POST", Path: "/products", @@ -98,8 +95,7 @@ func TestRequestBodyMinLengthDecreased(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyMinLengthDecreasedId, - Text: "the request's body minLength was decreased from '10' to '1'", - Comment: "", + Args: []any{uint64(10), uint64(1)}, Level: checker.INFO, Operation: "POST", Path: "/products", diff --git a/checker/check-request-property-min-set.go b/checker/check-request-property-min-set.go index 2de31112..4897c54c 100644 --- a/checker/check-request-property-min-set.go +++ b/checker/check-request-property-min-set.go @@ -9,7 +9,7 @@ const ( RequestPropertyMinSetId = "request-property-min-set" ) -func RequestPropertyMinSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMinSetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -35,8 +35,8 @@ func RequestPropertyMinSetCheck(diffReport *diff.Diff, operationsSources *diff.O result = append(result, ApiChange{ Id: RequestBodyMinSetId, Level: WARN, - Text: config.Localize(RequestBodyMinSetId, ColorizedValue(minDiff.To)), - Comment: config.Localize(comment(RequestBodyMinSetId)), + Args: []any{minDiff.To}, + Comment: commentId(RequestBodyMinSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -63,8 +63,8 @@ func RequestPropertyMinSetCheck(diffReport *diff.Diff, operationsSources *diff.O result = append(result, ApiChange{ Id: RequestPropertyMinSetId, Level: WARN, - Text: config.Localize(RequestPropertyMinSetId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minDiff.To)), - Comment: config.Localize(comment(RequestPropertyMinSetId)), + Args: []any{propertyFullName(propertyPath, propertyName), minDiff.To}, + Comment: commentId(RequestPropertyMinSetId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-min-updated.go b/checker/check-request-property-min-updated.go index 52a5bad3..1f0065bd 100644 --- a/checker/check-request-property-min-updated.go +++ b/checker/check-request-property-min-updated.go @@ -11,7 +11,7 @@ const ( RequestPropertyMinDecreasedId = "request-property-min-decreased" ) -func RequestPropertyMinIncreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyMinIncreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,7 +38,7 @@ func RequestPropertyMinIncreasedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestBodyMinIncreasedId, Level: ERR, - Text: config.Localize(RequestBodyMinIncreasedId, ColorizedValue(minDiff.To)), + Args: []any{minDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -48,7 +48,7 @@ func RequestPropertyMinIncreasedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestBodyMinDecreasedId, Level: INFO, - Text: config.Localize(RequestBodyMinDecreasedId, ColorizedValue(minDiff.From), ColorizedValue(minDiff.To)), + Args: []any{minDiff.From, minDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -69,11 +69,14 @@ func RequestPropertyMinIncreasedCheck(diffReport *diff.Diff, operationsSources * minDiff.To == nil { return } + + propName := propertyFullName(propertyPath, propertyName) + if IsIncreasedValue(minDiff) { result = append(result, ApiChange{ Id: RequestPropertyMinIncreasedId, - Level: ConditionalError(!propertyDiff.Revision.ReadOnly, INFO), - Text: config.Localize(RequestPropertyMinIncreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minDiff.To)), + Level: conditionalError(!propertyDiff.Revision.ReadOnly, INFO), + Args: []any{propName, minDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -83,14 +86,13 @@ func RequestPropertyMinIncreasedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: RequestPropertyMinDecreasedId, Level: INFO, - Text: config.Localize(RequestPropertyMinDecreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minDiff.From), ColorizedValue(minDiff.To)), + Args: []any{propName, minDiff.From, minDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) } - }) } } diff --git a/checker/check-request-property-min-updated_test.go b/checker/check-request-property-min-updated_test.go index ab234a84..544f6974 100644 --- a/checker/check-request-property-min-updated_test.go +++ b/checker/check-request-property-min-updated_test.go @@ -22,7 +22,7 @@ func TestRequestPropertyMinIncreasedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyMinIncreasedId, - Text: "the 'age' request property's min was increased to '15.00'", + Args: []any{"age", 15.0}, Level: checker.ERR, Operation: "POST", Path: "/pets", @@ -45,7 +45,7 @@ func TestRequestPropertyMinDecreasedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyMinDecreasedId, - Text: "the 'age' request property's min was decreased from '15.00' to '10.00'", + Args: []any{"age", 15.0, 10.0}, Level: checker.INFO, Operation: "POST", Path: "/pets", diff --git a/checker/check-request-property-one-of-updated.go b/checker/check-request-property-one-of-updated.go index 1cabcb82..6a41eeab 100644 --- a/checker/check-request-property-one-of-updated.go +++ b/checker/check-request-property-one-of-updated.go @@ -11,7 +11,7 @@ const ( RequestPropertyOneOfRemovedId = "request-property-one-of-removed" ) -func RequestPropertyOneOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyOneOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,11 +38,9 @@ func RequestPropertyOneOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if mediaTypeDiff.SchemaDiff.OneOfDiff != nil && len(mediaTypeDiff.SchemaDiff.OneOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: RequestBodyOneOfAddedId, - Level: INFO, - Text: config.Localize( - RequestBodyOneOfAddedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.OneOfDiff.Added.String())), + Id: RequestBodyOneOfAddedId, + Level: INFO, + Args: []any{mediaTypeDiff.SchemaDiff.OneOfDiff.Added.String()}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -52,11 +50,9 @@ func RequestPropertyOneOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if mediaTypeDiff.SchemaDiff.OneOfDiff != nil && len(mediaTypeDiff.SchemaDiff.OneOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: RequestBodyOneOfRemovedId, - Level: ERR, - Text: config.Localize( - RequestBodyOneOfRemovedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.OneOfDiff.Deleted.String())), + Id: RequestBodyOneOfRemovedId, + Level: ERR, + Args: []any{mediaTypeDiff.SchemaDiff.OneOfDiff.Deleted.String()}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,14 +67,13 @@ func RequestPropertyOneOfUpdatedCheck(diffReport *diff.Diff, operationsSources * return } + propName := propertyFullName(propertyPath, propertyName) + if len(propertyDiff.OneOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: RequestPropertyOneOfAddedId, - Level: INFO, - Text: config.Localize( - RequestPropertyOneOfAddedId, - ColorizedValue(propertyDiff.OneOfDiff.Added.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName))), + Id: RequestPropertyOneOfAddedId, + Level: INFO, + Args: []any{propertyDiff.OneOfDiff.Added.String(), propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -88,12 +83,9 @@ func RequestPropertyOneOfUpdatedCheck(diffReport *diff.Diff, operationsSources * if len(propertyDiff.OneOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: RequestPropertyOneOfRemovedId, - Level: ERR, - Text: config.Localize( - RequestPropertyOneOfRemovedId, - ColorizedValue(propertyDiff.OneOfDiff.Deleted.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName))), + Id: RequestPropertyOneOfRemovedId, + Level: ERR, + Args: []any{propertyDiff.OneOfDiff.Deleted.String(), propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-one-of-updated_test.go b/checker/check-request-property-one-of-updated_test.go index e18cd9d8..9be1145a 100644 --- a/checker/check-request-property-one-of-updated_test.go +++ b/checker/check-request-property-one-of-updated_test.go @@ -24,8 +24,7 @@ func TestRequestPropertyOneOfAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyOneOfAddedId, - Text: "added 'Rabbit' to the request body 'oneOf' list", - Comment: "", + Args: []any{"Rabbit"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -34,8 +33,7 @@ func TestRequestPropertyOneOfAdded(t *testing.T) { }, { Id: checker.RequestPropertyOneOfAddedId, - Text: "added 'Breed3' to the '/oneOf[#/components/schemas/Dog]/breed' request property 'oneOf' list", - Comment: "", + Args: []any{"Breed3", "/oneOf[#/components/schemas/Dog]/breed"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -60,8 +58,7 @@ func TestRequestPropertyOneOfRemoved(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.RequestBodyOneOfRemovedId, - Text: "removed 'Rabbit' from the request body 'oneOf' list", - Comment: "", + Args: []any{"Rabbit"}, Level: checker.ERR, Operation: "POST", Path: "/pets", @@ -70,8 +67,7 @@ func TestRequestPropertyOneOfRemoved(t *testing.T) { }, { Id: checker.RequestPropertyOneOfRemovedId, - Text: "removed 'Breed3' from the '/oneOf[#/components/schemas/Dog]/breed' request property 'oneOf' list", - Comment: "", + Args: []any{"Breed3", "/oneOf[#/components/schemas/Dog]/breed"}, Level: checker.ERR, Operation: "POST", Path: "/pets", diff --git a/checker/check-request-property-pattern-added-or-changed.go b/checker/check-request-property-pattern-added-or-changed.go index 2a1dd847..7ece1b47 100644 --- a/checker/check-request-property-pattern-added-or-changed.go +++ b/checker/check-request-property-pattern-added-or-changed.go @@ -10,7 +10,7 @@ const ( RequestPropertyPatternChangedId = "request-property-pattern-changed" ) -func RequestPropertyPatternUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyPatternUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -36,12 +36,13 @@ func RequestPropertyPatternUpdatedCheck(diffReport *diff.Diff, operationsSources } source := (*operationsSources)[operationItem.Revision] + propName := propertyFullName(propertyPath, propertyName) if patternDiff.To == "" { result = append(result, ApiChange{ Id: RequestPropertyPatternRemovedId, Level: INFO, - Text: config.Localize(RequestPropertyPatternRemovedId, patternDiff.From, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{patternDiff.From, propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -51,8 +52,8 @@ func RequestPropertyPatternUpdatedCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: RequestPropertyPatternAddedId, Level: WARN, - Text: config.Localize(RequestPropertyPatternAddedId, patternDiff.To, ColorizedValue(propertyFullName(propertyPath, propertyName))), - Comment: config.Localize("pattern-changed-warn-comment"), + Args: []any{patternDiff.To, propName}, + Comment: PatternChangedCommentId, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -60,7 +61,7 @@ func RequestPropertyPatternUpdatedCheck(diffReport *diff.Diff, operationsSources }) } else { level := WARN - comment := config.Localize("pattern-changed-warn-comment") + comment := PatternChangedCommentId if patternDiff.To == ".*" { level = INFO comment = "" @@ -68,7 +69,7 @@ func RequestPropertyPatternUpdatedCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: RequestPropertyPatternChangedId, Level: level, - Text: config.Localize(RequestPropertyPatternChangedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), patternDiff.From, patternDiff.To), + Args: []any{propName, patternDiff.From, patternDiff.To}, Comment: comment, Operation: operation, OperationId: operationItem.Revision.OperationID, diff --git a/checker/check-request-property-pattern-added-or-changed_test.go b/checker/check-request-property-pattern-added-or-changed_test.go index 28e971d4..a7a8b5ac 100644 --- a/checker/check-request-property-pattern-added-or-changed_test.go +++ b/checker/check-request-property-pattern-added-or-changed_test.go @@ -22,15 +22,15 @@ func TestRequestPropertyPatternChanged(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.RequestPropertyPatternUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.RequestPropertyPatternChangedId, - Text: "changed the pattern of the request property 'name' from '^\\w+$' to '^[\\w\\s]+$'", - Level: checker.WARN, - Operation: "POST", - Path: "/test", - Source: "../data/checker/request_property_pattern_added_or_changed_revision.yaml", - OperationId: "", - Comment: "This is a warning because it is difficult to automatically analyze if the new pattern is a superset of the previous pattern (e.g. changed from '[0-9]+' to '[0-9]*')", + Id: checker.RequestPropertyPatternChangedId, + Args: []any{"name", "^\\w+$", "^[\\w\\s]+$"}, + Level: checker.WARN, + Operation: "POST", + Path: "/test", + Source: "../data/checker/request_property_pattern_added_or_changed_revision.yaml", + Comment: checker.PatternChangedCommentId, }, errs[0]) + require.Equal(t, "This is a warning because it is difficult to automatically analyze if the new pattern is a superset of the previous pattern (e.g. changed from '[0-9]+' to '[0-9]*')", errs[0].GetComment(checker.NewDefaultLocalizer())) } // CL: adding request property pattern @@ -45,15 +45,15 @@ func TestRequestPropertyPatternAdded(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.RequestPropertyPatternUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.RequestPropertyPatternAddedId, - Text: "added the pattern '^\\w+$' to the request property 'name'", - Level: checker.WARN, - Operation: "POST", - Path: "/test", - Source: "../data/checker/request_property_pattern_added_or_changed_base.yaml", - OperationId: "", - Comment: "This is a warning because it is difficult to automatically analyze if the new pattern is a superset of the previous pattern (e.g. changed from '[0-9]+' to '[0-9]*')", + Id: checker.RequestPropertyPatternAddedId, + Args: []any{"^\\w+$", "name"}, + Level: checker.WARN, + Operation: "POST", + Path: "/test", + Source: "../data/checker/request_property_pattern_added_or_changed_base.yaml", + Comment: checker.PatternChangedCommentId, }, errs[0]) + require.Equal(t, "This is a warning because it is difficult to automatically analyze if the new pattern is a superset of the previous pattern (e.g. changed from '[0-9]+' to '[0-9]*')", errs[0].GetComment(checker.NewDefaultLocalizer())) } // CL: removing request property pattern @@ -68,12 +68,11 @@ func TestRequestPropertyPatternRemoved(t *testing.T) { errs := checker.CheckBackwardCompatibilityUntilLevel(singleCheckConfig(checker.RequestPropertyPatternUpdatedCheck), d, osm, checker.INFO) require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ - Id: checker.RequestPropertyPatternRemovedId, - Text: "removed the pattern '^\\w+$' from the request property 'name'", - Level: checker.INFO, - Operation: "POST", - Path: "/test", - Source: "../data/checker/request_property_pattern_added_or_changed_revision.yaml", - OperationId: "", + Id: checker.RequestPropertyPatternRemovedId, + Args: []any{"^\\w+$", "name"}, + Level: checker.INFO, + Operation: "POST", + Path: "/test", + Source: "../data/checker/request_property_pattern_added_or_changed_revision.yaml", }, errs[0]) } diff --git a/checker/check-request-property-required-updated.go b/checker/check-request-property-required-updated.go index 7f1de124..2d7bc9e6 100644 --- a/checker/check-request-property-required-updated.go +++ b/checker/check-request-property-required-updated.go @@ -9,7 +9,7 @@ const ( RequestPropertyBecameOptionalId = "request-property-became-optional" ) -func RequestPropertyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -48,7 +48,7 @@ func RequestPropertyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: RequestPropertyBecameRequiredId, Level: ERR, - Text: config.Localize(RequestPropertyBecameRequiredId, ColorizedValue(changedRequiredPropertyName)), + Args: []any{changedRequiredPropertyName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -70,14 +70,13 @@ func RequestPropertyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: RequestPropertyBecameOptionalId, Level: INFO, - Text: config.Localize(RequestPropertyBecameOptionalId, ColorizedValue(changedRequiredPropertyName)), + Args: []any{changedRequiredPropertyName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) } - } CheckModifiedPropertiesDiff( @@ -98,10 +97,11 @@ func RequestPropertyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSource // it is a new property, checked by the new-required-request-property check continue } + result = append(result, ApiChange{ Id: RequestPropertyBecameRequiredId, Level: ERR, - Text: config.Localize(RequestPropertyBecameRequiredId, ColorizedValue(propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName)))), + Args: []any{propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName))}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -120,10 +120,11 @@ func RequestPropertyRequiredUpdatedCheck(diffReport *diff.Diff, operationsSource // it is a new property, checked by the new-required-request-property check continue } + result = append(result, ApiChange{ Id: RequestPropertyBecameOptionalId, Level: INFO, - Text: config.Localize(RequestPropertyBecameOptionalId, ColorizedValue(propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName)))), + Args: []any{propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName))}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-required-updated_test.go b/checker/check-request-property-required-updated_test.go index 7d160eec..59528ba6 100644 --- a/checker/check-request-property-required-updated_test.go +++ b/checker/check-request-property-required-updated_test.go @@ -22,7 +22,7 @@ func TestRequestPropertyMarkedRequired(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyBecameRequiredId, - Text: "the request property 'name' became required", + Args: []any{"name"}, Level: checker.ERR, Operation: "POST", Path: "/products", @@ -45,7 +45,7 @@ func TestRequestPropertyMarkedOptional(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyBecameOptionalId, - Text: "the request property 'name' became optional", + Args: []any{"name"}, Level: checker.INFO, Operation: "POST", Path: "/products", diff --git a/checker/check-request-property-type-changed.go b/checker/check-request-property-type-changed.go index 8f7b38d0..3dc2e36c 100644 --- a/checker/check-request-property-type-changed.go +++ b/checker/check-request-property-type-changed.go @@ -9,7 +9,7 @@ const ( RequestPropertyTypeChangedId = "request-property-type-changed" ) -func RequestPropertyTypeChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyTypeChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,14 +38,13 @@ func RequestPropertyTypeChangedCheck(diffReport *diff.Diff, operationsSources *d result = append(result, ApiChange{ Id: RequestBodyTypeChangedId, - Level: ConditionalError(breakingTypeFormatChangedInRequestProperty(typeDiff, formatDiff, mediaType, schemaDiff), INFO), - Text: config.Localize(RequestBodyTypeChangedId, empty2none(typeDiff.From), empty2none(formatDiff.From), empty2none(typeDiff.To), empty2none(formatDiff.To)), + Level: conditionalError(breakingTypeFormatChangedInRequestProperty(typeDiff, formatDiff, mediaType, schemaDiff), INFO), + Args: []any{typeDiff.From, formatDiff.From, typeDiff.To, formatDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) - } } @@ -66,8 +65,8 @@ func RequestPropertyTypeChangedCheck(diffReport *diff.Diff, operationsSources *d typeDiff, formatDiff = fillEmptyTypeAndFormatDiffs(typeDiff, schemaDiff, formatDiff) result = append(result, ApiChange{ Id: RequestPropertyTypeChangedId, - Level: ConditionalError(breakingTypeFormatChangedInRequestProperty(typeDiff, formatDiff, mediaType, schemaDiff), INFO), - Text: config.Localize(RequestPropertyTypeChangedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), empty2none(typeDiff.From), empty2none(formatDiff.From), empty2none(typeDiff.To), empty2none(formatDiff.To)), + Level: conditionalError(breakingTypeFormatChangedInRequestProperty(typeDiff, formatDiff, mediaType, schemaDiff), INFO), + Args: []any{propertyFullName(propertyPath, propertyName), typeDiff.From, formatDiff.From, typeDiff.To, formatDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-type-changed_test.go b/checker/check-request-property-type-changed_test.go index 7af4c5ae..c6c3fbf8 100644 --- a/checker/check-request-property-type-changed_test.go +++ b/checker/check-request-property-type-changed_test.go @@ -25,7 +25,7 @@ func TestRequestBodyTypeChangedCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyTypeChangedId, Level: checker.ERR, - Text: "the request's body type/format changed from 'object'/'none' to 'array'/'none'", + Args: []any{"object", "", "array", ""}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_type_changed_base.yaml", @@ -50,7 +50,7 @@ func TestRequestBodyFormatChangedCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyTypeChangedId, Level: checker.ERR, - Text: "the request's body type/format changed from 'object'/'none' to 'object'/'uuid'", + Args: []any{"object", "", "object", "uuid"}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_type_changed_base.yaml", @@ -73,7 +73,7 @@ func TestRequestPropertyTypeChangedCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyTypeChangedId, Level: checker.ERR, - Text: "the 'age' request property type/format changed from 'integer'/'int32' to 'string'/'string'", + Args: []any{"age", "integer", "int32", "string", "string"}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_type_changed_revision.yaml", @@ -96,7 +96,7 @@ func TestRequestBodyAndPropertyTypesChangedCheckArrayToObject(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyTypeChangedId, Level: checker.ERR, - Text: "the 'colors' request property type/format changed from 'array'/'none' to 'object'/'none'", + Args: []any{"colors", "array", "", "object", ""}, Operation: "POST", Path: "/dogs", Source: "../data/checker/request_property_type_changed_revision_array_to_object.yaml", @@ -105,7 +105,7 @@ func TestRequestBodyAndPropertyTypesChangedCheckArrayToObject(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyTypeChangedId, Level: checker.ERR, - Text: "the request's body type/format changed from 'array'/'none' to 'object'/'none'", + Args: []any{"array", "", "object", ""}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_type_changed_revision_array_to_object.yaml", @@ -128,7 +128,7 @@ func TestRequestBodyAndPropertyTypesChangedCheckObjectToArray(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyTypeChangedId, Level: checker.ERR, - Text: "the 'colors' request property type/format changed from 'object'/'none' to 'array'/'none'", + Args: []any{"colors", "object", "", "array", ""}, Operation: "POST", Path: "/dogs", Source: "../data/checker/request_property_type_changed_base_array_to_object.yaml", @@ -137,7 +137,7 @@ func TestRequestBodyAndPropertyTypesChangedCheckObjectToArray(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestBodyTypeChangedId, Level: checker.ERR, - Text: "the request's body type/format changed from 'object'/'none' to 'array'/'none'", + Args: []any{"object", "", "array", ""}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_type_changed_base_array_to_object.yaml", @@ -162,7 +162,7 @@ func TestRequestPropertyFormatChangedCheck(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyTypeChangedId, Level: checker.ERR, - Text: "the 'age' request property type/format changed from 'integer'/'int32' to 'integer'/'uuid'", + Args: []any{"age", "integer", "int32", "integer", "uuid"}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_type_changed_base.yaml", @@ -187,7 +187,7 @@ func TestRequestPropertyFormatChangedCheckNonBreaking(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyTypeChangedId, Level: checker.INFO, - Text: "the 'age' request property type/format changed from 'integer'/'int32' to 'number'/'int32'", + Args: []any{"age", "integer", "int32", "number", "int32"}, Operation: "POST", Path: "/pets", Source: "../data/checker/request_property_type_changed_base.yaml", diff --git a/checker/check-request-property-updated.go b/checker/check-request-property-updated.go index 5021033d..b0d3c100 100644 --- a/checker/check-request-property-updated.go +++ b/checker/check-request-property-updated.go @@ -12,7 +12,7 @@ const ( NewOptionalRequestPropertyId = "new-optional-request-property" ) -func RequestPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -37,7 +37,7 @@ func RequestPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff. result = append(result, ApiChange{ Id: RequestPropertyRemovedId, Level: WARN, - Text: config.Localize(RequestPropertyRemovedId, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propertyFullName(propertyPath, propertyName)}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -52,11 +52,14 @@ func RequestPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff. if propertyItem.ReadOnly { return } + + propName := propertyFullName(propertyPath, propertyName) + if slices.Contains(parent.Revision.Required, propertyName) { result = append(result, ApiChange{ Id: NewRequiredRequestPropertyId, Level: ERR, - Text: config.Localize(NewRequiredRequestPropertyId, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -66,7 +69,7 @@ func RequestPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff. result = append(result, ApiChange{ Id: NewOptionalRequestPropertyId, Level: INFO, - Text: config.Localize(NewOptionalRequestPropertyId, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-updated_test.go b/checker/check-request-property-updated_test.go index 09a27c47..1f450409 100644 --- a/checker/check-request-property-updated_test.go +++ b/checker/check-request-property-updated_test.go @@ -21,7 +21,7 @@ func TestRequiredRequestPropertyAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.NewRequiredRequestPropertyId, - Text: "added the new required request property 'description'", + Args: []any{"description"}, Level: checker.ERR, Operation: "POST", Path: "/products", @@ -43,7 +43,7 @@ func TestRequiredRequestPropertiesAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.NewRequiredRequestPropertyId, - Text: "added the new required request property 'description'", + Args: []any{"description"}, Level: checker.ERR, Operation: "POST", Path: "/products", @@ -52,7 +52,7 @@ func TestRequiredRequestPropertiesAdded(t *testing.T) { }, { Id: checker.NewOptionalRequestPropertyId, - Text: "added the new optional request property 'info'", + Args: []any{"info"}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -75,7 +75,7 @@ func TestRequiredOptionalPropertyAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.NewOptionalRequestPropertyId, - Text: "added the new optional request property 'description'", + Args: []any{"description"}, Level: checker.INFO, Operation: "POST", Path: "/products", @@ -97,7 +97,7 @@ func TestRequiredRequestPropertyRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestPropertyRemovedId, - Text: "removed the request property 'description'", + Args: []any{"description"}, Level: checker.WARN, Operation: "POST", Path: "/products", diff --git a/checker/check-request-property-write-only-read-only.go b/checker/check-request-property-write-only-read-only.go index edbcec0f..726588bd 100644 --- a/checker/check-request-property-write-only-read-only.go +++ b/checker/check-request-property-write-only-read-only.go @@ -16,7 +16,7 @@ const ( RequestRequiredPropertyBecameNonReadOnlyCheckId = "request-required-property-became-not-read-only" ) -func RequestPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -51,15 +51,18 @@ func RequestPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSour return } + propName := propertyFullName(propertyPath, propertyName) + if slices.Contains(parent.Base.Required, propertyName) { id := RequestRequiredPropertyBecameNonWriteOnlyCheckId if writeOnlyDiff.To == true { id = RequestRequiredPropertyBecameWriteOnlyCheckId } + result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -75,7 +78,7 @@ func RequestPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -94,6 +97,9 @@ func RequestPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSour // removed properties processed by the RequestOptionalPropertyUpdatedCheck check return } + + propName := propertyFullName(propertyPath, propertyName) + if slices.Contains(parent.Base.Required, propertyName) { id := RequestRequiredPropertyBecameNonReadOnlyCheckId if readOnlyDiff.To == true { @@ -102,7 +108,7 @@ func RequestPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -118,7 +124,7 @@ func RequestPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSour result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propName}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-request-property-write-only-read-only_test.go b/checker/check-request-property-write-only-read-only_test.go index 596d6eea..ef78c760 100644 --- a/checker/check-request-property-write-only-read-only_test.go +++ b/checker/check-request-property-write-only-read-only_test.go @@ -24,7 +24,7 @@ func TestRequestOptionalPropertyBecameWriteOnly(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestOptionalPropertyBecameWriteOnlyCheckId, - Text: "the request optional property 'name' became write-only", + Args: []any{"name"}, Operation: "POST", Path: "/api/v1.0/groups", Level: checker.INFO, @@ -49,7 +49,7 @@ func TestRequestOptionalPropertyBecameNotWriteOnly(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestOptionalPropertyBecameNonWriteOnlyCheckId, - Text: "the request optional property 'name' became not write-only", + Args: []any{"name"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -74,7 +74,7 @@ func TestRequestOptionalPropertyBecameReadOnly(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestOptionalPropertyBecameReadOnlyCheckId, - Text: "the request optional property 'name' became read-only", + Args: []any{"name"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -99,7 +99,7 @@ func TestRequestOptionalPropertyBecameNonReadOnly(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestOptionalPropertyBecameNonReadOnlyCheckId, - Text: "the request optional property 'name' became not read-only", + Args: []any{"name"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -124,7 +124,7 @@ func TestRequestRequiredPropertyBecameWriteOnly(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestRequiredPropertyBecameWriteOnlyCheckId, - Text: "the request required property 'id' became write-only", + Args: []any{"id"}, Operation: "POST", Path: "/api/v1.0/groups", Level: checker.INFO, @@ -149,7 +149,7 @@ func TestRequestRequiredPropertyBecameNotWriteOnly(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestRequiredPropertyBecameNonWriteOnlyCheckId, - Text: "the request required property 'id' became not write-only", + Args: []any{"id"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -174,7 +174,7 @@ func TestRequestRequiredPropertyBecameReadOnly(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestRequiredPropertyBecameReadOnlyCheckId, - Text: "the request required property 'id' became read-only", + Args: []any{"id"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -199,7 +199,7 @@ func TestRequestRequiredPropertyBecameNonReadOnly(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestRequiredPropertyBecameNonReadOnlyCheckId, - Text: "the request required property 'id' became not read-only", + Args: []any{"id"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-request-property-x-extensible-enum-value-removed.go b/checker/check-request-property-x-extensible-enum-value-removed.go index 328b7cd6..ff78467d 100644 --- a/checker/check-request-property-x-extensible-enum-value-removed.go +++ b/checker/check-request-property-x-extensible-enum-value-removed.go @@ -2,7 +2,6 @@ package checker import ( "encoding/json" - "fmt" "github.com/tufin/oasdiff/diff" "golang.org/x/exp/slices" @@ -14,7 +13,7 @@ const ( RequestPropertyXExtensibleEnumValueRemovedId = "request-property-x-extensible-enum-value-removed" ) -func RequestPropertyXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func RequestPropertyXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -58,7 +57,7 @@ func RequestPropertyXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, oper result = append(result, ApiChange{ Id: UnparseablePropertyFromXExtensibleEnumId, Level: ERR, - Text: fmt.Sprintf("unparseable x-extensible-enum of the request property %s", ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propertyFullName(propertyPath, propertyName)}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,7 +70,7 @@ func RequestPropertyXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, oper result = append(result, ApiChange{ Id: UnparseablePropertyToXExtensibleEnumId, Level: ERR, - Text: fmt.Sprintf("unparseable x-extensible-enum of the request property %s", ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{propertyFullName(propertyPath, propertyName)}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -94,7 +93,7 @@ func RequestPropertyXExtensibleEnumValueRemovedCheck(diffReport *diff.Diff, oper result = append(result, ApiChange{ Id: RequestPropertyXExtensibleEnumValueRemovedId, Level: ERR, - Text: config.Localize(RequestPropertyXExtensibleEnumValueRemovedId, enumVal, ColorizedValue(propertyFullName(propertyPath, propertyName))), + Args: []any{enumVal, propertyFullName(propertyPath, propertyName)}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-discriminator-updated.go b/checker/check-response-discriminator-updated.go index f1fa6591..6b13f196 100644 --- a/checker/check-response-discriminator-updated.go +++ b/checker/check-response-discriminator-updated.go @@ -19,7 +19,7 @@ const ( ResponsePropertyDiscriminatorMappingChangedId = "response-property-discriminator-mapping-changed" ) -func ResponseDiscriminatorUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseDiscriminatorUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -40,7 +40,7 @@ func ResponseDiscriminatorUpdatedCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: messageId, Level: INFO, - Text: config.Localize(messageId, a...), + Args: a, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -100,7 +100,7 @@ func processDiscriminatorDiff( if propertyName == "" { appendResultItem(messageIdPrefix+"-added", responseStatus) } else { - appendResultItem(messageIdPrefix+"-added", ColorizedValue(propertyName), responseStatus) + appendResultItem(messageIdPrefix+"-added", propertyName, responseStatus) } return } @@ -108,7 +108,7 @@ func processDiscriminatorDiff( if propertyName == "" { appendResultItem(messageIdPrefix+"-removed", responseStatus) } else { - appendResultItem(messageIdPrefix+"-removed", ColorizedValue(propertyName), responseStatus) + appendResultItem(messageIdPrefix+"-removed", propertyName, responseStatus) } return } @@ -116,14 +116,14 @@ func processDiscriminatorDiff( if discriminatorDiff.PropertyNameDiff != nil { if propertyName == "" { appendResultItem(messageIdPrefix+"-property-name-changed", - ColorizedValue(discriminatorDiff.PropertyNameDiff.From), - ColorizedValue(discriminatorDiff.PropertyNameDiff.To), + discriminatorDiff.PropertyNameDiff.From, + discriminatorDiff.PropertyNameDiff.To, responseStatus) } else { appendResultItem(messageIdPrefix+"-property-name-changed", - ColorizedValue(propertyName), - ColorizedValue(discriminatorDiff.PropertyNameDiff.From), - ColorizedValue(discriminatorDiff.PropertyNameDiff.To), + propertyName, + discriminatorDiff.PropertyNameDiff.From, + discriminatorDiff.PropertyNameDiff.To, responseStatus) } } @@ -132,12 +132,12 @@ func processDiscriminatorDiff( if len(discriminatorDiff.MappingDiff.Added) > 0 { if propertyName == "" { appendResultItem(messageIdPrefix+"-mapping-added", - ColorizedValue(discriminatorDiff.MappingDiff.Added), + discriminatorDiff.MappingDiff.Added, responseStatus) } else { appendResultItem(messageIdPrefix+"-mapping-added", - ColorizedValue(discriminatorDiff.MappingDiff.Added), - ColorizedValue(propertyName), + discriminatorDiff.MappingDiff.Added, + propertyName, responseStatus) } } @@ -145,12 +145,12 @@ func processDiscriminatorDiff( if len(discriminatorDiff.MappingDiff.Deleted) > 0 { if propertyName == "" { appendResultItem(messageIdPrefix+"-mapping-deleted", - ColorizedValue(discriminatorDiff.MappingDiff.Deleted), + discriminatorDiff.MappingDiff.Deleted, responseStatus) } else { appendResultItem(messageIdPrefix+"-mapping-deleted", - ColorizedValue(discriminatorDiff.MappingDiff.Deleted), - ColorizedValue(propertyName), + discriminatorDiff.MappingDiff.Deleted, + propertyName, responseStatus) } } @@ -158,16 +158,16 @@ func processDiscriminatorDiff( for k, v := range discriminatorDiff.MappingDiff.Modified { if propertyName == "" { appendResultItem(messageIdPrefix+"-mapping-changed", - ColorizedValue(k), - ColorizedValue(v.From), - ColorizedValue(v.To), + k, + v.From, + v.To, responseStatus) } else { appendResultItem(messageIdPrefix+"-mapping-changed", - ColorizedValue(k), - ColorizedValue(v.From), - ColorizedValue(v.To), - ColorizedValue(propertyName), + k, + v.From, + v.To, + propertyName, responseStatus) } diff --git a/checker/check-response-discriminator-updated_test.go b/checker/check-response-discriminator-updated_test.go index 061ae651..2a5dbd37 100644 --- a/checker/check-response-discriminator-updated_test.go +++ b/checker/check-response-discriminator-updated_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tufin/oasdiff/checker" "github.com/tufin/oasdiff/diff" + "github.com/tufin/oasdiff/utils" ) // CL: adding discriminator to the response body or response property @@ -24,8 +25,7 @@ func TestResponseDiscriminatorUpdatedCheckAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyDiscriminatorAddedId, - Text: "added response discriminator for the response status 200", - Comment: "", + Args: []any{"200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -34,8 +34,7 @@ func TestResponseDiscriminatorUpdatedCheckAdded(t *testing.T) { }, { Id: checker.ResponsePropertyDiscriminatorAddedId, - Text: "added discriminator to '/oneOf[#/components/schemas/Dog]/breed' response property for the response status 200", - Comment: "", + Args: []any{"/oneOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -60,8 +59,7 @@ func TestResponseDiscriminatorUpdatedCheckRemoved(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyDiscriminatorRemovedId, - Text: "removed response discriminator for the response status 200", - Comment: "", + Args: []any{"200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -70,8 +68,7 @@ func TestResponseDiscriminatorUpdatedCheckRemoved(t *testing.T) { }, { Id: checker.ResponsePropertyDiscriminatorRemovedId, - Text: "removed discriminator from '/oneOf[#/components/schemas/Dog]/breed' response property for the response status 200", - Comment: "", + Args: []any{"/oneOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -96,8 +93,7 @@ func TestResponseDiscriminatorUpdatedCheckPropertyNameChanging(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyDiscriminatorPropertyNameChangedId, - Text: "response discriminator property name changed from 'petType' to 'petType2' for the response status 200", - Comment: "", + Args: []any{"petType", "petType2", "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -106,8 +102,7 @@ func TestResponseDiscriminatorUpdatedCheckPropertyNameChanging(t *testing.T) { }, { Id: checker.ResponsePropertyDiscriminatorPropertyNameChangedId, - Text: "response discriminator property name changed for '/oneOf[#/components/schemas/Dog]/breed' response property from 'name' to 'name2' for the response status 200", - Comment: "", + Args: []any{"/oneOf[#/components/schemas/Dog]/breed", "name", "name2", "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -132,8 +127,7 @@ func TestResponseDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyDiscriminatorMappingAddedId, - Text: "added '[cats]' mapping keys to the response discriminator for the response status 200", - Comment: "", + Args: []any{utils.StringList{"cats"}, "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -142,8 +136,7 @@ func TestResponseDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { }, { Id: checker.ResponseBodyDiscriminatorMappingDeletedId, - Text: "removed '[cat]' mapping keys from the response discriminator for the response status 200", - Comment: "", + Args: []any{utils.StringList{"cat"}, "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -152,8 +145,7 @@ func TestResponseDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { }, { Id: checker.ResponsePropertyDiscriminatorMappingAddedId, - Text: "added '[breed1Code]' discriminator mapping keys to the '/oneOf[#/components/schemas/Dog]/breed' response property for the response status 200", - Comment: "", + Args: []any{utils.StringList{"breed1Code"}, "/oneOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -162,8 +154,7 @@ func TestResponseDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { }, { Id: checker.ResponsePropertyDiscriminatorMappingChangedId, - Text: "mapped value for discriminator key 'breed2' changed from '#/components/schemas/Breed2' to '#/components/schemas/Breed3' for '/oneOf[#/components/schemas/Dog]/breed' response property for the response status 200", - Comment: "", + Args: []any{"breed2", "#/components/schemas/Breed2", "#/components/schemas/Breed3", "/oneOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", @@ -172,8 +163,7 @@ func TestResponseDiscriminatorUpdatedCheckMappingChanging(t *testing.T) { }, { Id: checker.ResponsePropertyDiscriminatorMappingDeletedId, - Text: "removed '[breed1]' discriminator mapping keys from the '/oneOf[#/components/schemas/Dog]/breed' response property for the response status 200", - Comment: "", + Args: []any{utils.StringList{"breed1"}, "/oneOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "POST", Path: "/pets", diff --git a/checker/check-response-header-became-optional.go b/checker/check-response-header-became-optional.go index 3fbb6714..557271f4 100644 --- a/checker/check-response-header-became-optional.go +++ b/checker/check-response-header-became-optional.go @@ -8,7 +8,7 @@ const ( ResponseHeaderBecameOptionalId = "response-header-became-optional" ) -func ResponseHeaderBecameOptionalCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseHeaderBecameOptionalCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -42,7 +42,7 @@ func ResponseHeaderBecameOptionalCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: ResponseHeaderBecameOptionalId, Level: ERR, - Text: config.Localize(ResponseHeaderBecameOptionalId, ColorizedValue(headerName), ColorizedValue(responseStatus)), + Args: []any{headerName, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-header-removed.go b/checker/check-response-header-removed.go index 33cb308b..100bda02 100644 --- a/checker/check-response-header-removed.go +++ b/checker/check-response-header-removed.go @@ -9,7 +9,7 @@ const ( OptionalResponseHeaderRemovedId = "optional-response-header-removed" ) -func ResponseHeaderRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseHeaderRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -40,7 +40,7 @@ func ResponseHeaderRemovedCheck(diffReport *diff.Diff, operationsSources *diff.O result = append(result, ApiChange{ Id: RequiredResponseHeaderRemovedId, Level: ERR, - Text: config.Localize(RequiredResponseHeaderRemovedId, ColorizedValue(headerName), ColorizedValue(responseStatus)), + Args: []any{headerName, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -50,7 +50,7 @@ func ResponseHeaderRemovedCheck(diffReport *diff.Diff, operationsSources *diff.O result = append(result, ApiChange{ Id: OptionalResponseHeaderRemovedId, Level: WARN, - Text: config.Localize(OptionalResponseHeaderRemovedId, ColorizedValue(headerName), ColorizedValue(responseStatus)), + Args: []any{headerName, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-mediatype-enum-value-removed.go b/checker/check-response-mediatype-enum-value-removed.go index fb0f33db..7b40c6f6 100644 --- a/checker/check-response-mediatype-enum-value-removed.go +++ b/checker/check-response-mediatype-enum-value-removed.go @@ -8,7 +8,7 @@ const ( ResponseMediaTypeEnumValueRemovedId = "response-mediatype-enum-value-removed" ) -func ResponseMediaTypeEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseMediaTypeEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -47,16 +47,14 @@ func ResponseMediaTypeEnumValueRemovedCheck(diffReport *diff.Diff, operationsSou result = append(result, ApiChange{ Id: ResponseMediaTypeEnumValueRemovedId, Level: config.getLogLevel(ResponseMediaTypeEnumValueRemovedId, ERR), - Text: config.Localize(ResponseMediaTypeEnumValueRemovedId, mediaType, ColorizedValue(enumVal)), + Args: []any{mediaType, enumVal}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) } - } - } } } diff --git a/checker/check-response-mediatype-updated.go b/checker/check-response-mediatype-updated.go index d8b10e9b..854051be 100644 --- a/checker/check-response-mediatype-updated.go +++ b/checker/check-response-mediatype-updated.go @@ -9,7 +9,7 @@ const ( ResponseMediaTypeAddedId = "response-media-type-added" ) -func ResponseMediaTypeUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseMediaTypeUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -37,7 +37,7 @@ func ResponseMediaTypeUpdatedCheck(diffReport *diff.Diff, operationsSources *dif result = append(result, ApiChange{ Id: ResponseMediaTypeRemovedId, Level: ERR, - Text: config.Localize(ResponseMediaTypeRemovedId, ColorizedValue(mediaType), ColorizedValue(responseStatus)), + Args: []any{mediaType, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -48,7 +48,7 @@ func ResponseMediaTypeUpdatedCheck(diffReport *diff.Diff, operationsSources *dif result = append(result, ApiChange{ Id: ResponseMediaTypeAddedId, Level: INFO, - Text: config.Localize(ResponseMediaTypeAddedId, ColorizedValue(mediaType), ColorizedValue(responseStatus)), + Args: []any{mediaType, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-mediatype-updated_test.go b/checker/check-response-mediatype-updated_test.go index c9179a3c..6d6c3cb6 100644 --- a/checker/check-response-mediatype-updated_test.go +++ b/checker/check-response-mediatype-updated_test.go @@ -21,8 +21,7 @@ func TestAddNewMediaType(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseMediaTypeAddedId, - Text: "added the media type 'application/xml' for the response with the status '200'", - Comment: "", + Args: []any{"application/xml", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -44,8 +43,7 @@ func TestDeleteNewMediaType(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseMediaTypeRemovedId, - Text: "removed the media type 'application/xml' for the response with the status '200'", - Comment: "", + Args: []any{"application/xml", "200"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-optional-property-updated.go b/checker/check-response-optional-property-updated.go index 46209697..57db9509 100644 --- a/checker/check-response-optional-property-updated.go +++ b/checker/check-response-optional-property-updated.go @@ -13,7 +13,7 @@ const ( ResponseOptionalWriteOnlyPropertyAddedId = "response-optional-write-only-property-added" ) -func ResponseOptionalPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseOptionalPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -50,10 +50,11 @@ func ResponseOptionalPropertyUpdatedCheck(diffReport *diff.Diff, operationsSourc // covered by response-required-property-removed return } + result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -72,17 +73,17 @@ func ResponseOptionalPropertyUpdatedCheck(diffReport *diff.Diff, operationsSourc // covered by response-required-property-added return } + result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) }) - } } } diff --git a/checker/check-response-optional-property-updated_test.go b/checker/check-response-optional-property-updated_test.go index a205ce60..6744865e 100644 --- a/checker/check-response-optional-property-updated_test.go +++ b/checker/check-response-optional-property-updated_test.go @@ -21,8 +21,7 @@ func TestResponseOptionalPropertyUpdatedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseOptionalPropertyRemovedId, - Text: "removed the optional property 'data/id' from the response with the '200' status", - Comment: "", + Args: []any{"data/id", "200"}, Level: checker.WARN, Operation: "POST", Path: "/api/v1.0/groups", @@ -45,8 +44,7 @@ func TestResponseOptionalPropertyAddedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseOptionalPropertyAddedId, - Text: "added the optional property 'data/id' to the response with the '200' status", - Comment: "", + Args: []any{"data/id", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -69,7 +67,7 @@ func TestResponseOptionalWriteOnlyPropertyRemovedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseOptionalWriteOnlyPropertyRemovedId, - Text: "removed the optional write-only property 'data/id' from the response with the '200' status", + Args: []any{"data/id", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -93,7 +91,7 @@ func TestResponseOptionalWriteOnlyPropertyAddedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseOptionalWriteOnlyPropertyAddedId, - Text: "added the optional write-only property 'data/id' to the response with the '200' status", + Args: []any{"data/id", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-optional-property-write-only-read-only.go b/checker/check-response-optional-property-write-only-read-only.go index ca0aabfb..31d7fd8b 100644 --- a/checker/check-response-optional-property-write-only-read-only.go +++ b/checker/check-response-optional-property-write-only-read-only.go @@ -12,7 +12,7 @@ const ( ResponseOptionalPropertyBecameNonReadOnlyId = "response-optional-property-became-not-read-only" ) -func ResponseOptionalPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseOptionalPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -65,7 +65,7 @@ func ResponseOptionalPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, opera result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -98,7 +98,7 @@ func ResponseOptionalPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, opera result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-optional-property-write-only-read-only_test.go b/checker/check-response-optional-property-write-only-read-only_test.go index d4345478..d72d0f1f 100644 --- a/checker/check-response-optional-property-write-only-read-only_test.go +++ b/checker/check-response-optional-property-write-only-read-only_test.go @@ -24,8 +24,7 @@ func TestResponseOptionalPropertyBecameWriteOnly(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseOptionalPropertyBecameWriteOnlyId, - Text: "the response optional property 'data/name' became write-only for the status '200'", - Comment: "", + Args: []any{"data/name", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -50,7 +49,7 @@ func TestResponseOptionalPropertyBecameNotWriteOnly(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseOptionalPropertyBecameNonWriteOnlyId, - Text: "the response optional property 'data/writeOnlyName' became not write-only for the status '200'", + Args: []any{"data/writeOnlyName", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -75,8 +74,7 @@ func TestResponseOptionalPropertyBecameReadOnly(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseOptionalPropertyBecameReadOnlyId, - Text: "the response optional property 'data/id' became read-only for the status '200'", - Comment: "", + Args: []any{"data/id", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -102,8 +100,7 @@ func TestResponseOptionalPropertyBecameNonReadOnly(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseOptionalPropertyBecameNonReadOnlyId, - Text: "the response optional property 'data/id' became not read-only for the status '200'", - Comment: "", + Args: []any{"data/id", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-pattern-added-or-changed.go b/checker/check-response-pattern-added-or-changed.go index ea8f7686..f245322d 100644 --- a/checker/check-response-pattern-added-or-changed.go +++ b/checker/check-response-pattern-added-or-changed.go @@ -10,7 +10,7 @@ const ( ResponsePropertyPatternRemovedId = "response-property-pattern-removed" ) -func ResponsePatternAddedOrChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePatternAddedOrChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -46,27 +46,27 @@ func ResponsePatternAddedOrChangedCheck(diffReport *diff.Diff, operationsSources return } + propName := propertyFullName(propertyPath, propertyName) + id := ResponsePropertyPatternChangedId - text := config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(patternDiff.From), ColorizedValue(patternDiff.To), ColorizedValue(responseStatus)) + args := []any{propName, patternDiff.From, patternDiff.To, responseStatus} if patternDiff.To == "" || patternDiff.To == nil { id = ResponsePropertyPatternRemovedId - text = config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(patternDiff.From), ColorizedValue(responseStatus)) - + args = []any{propName, patternDiff.From, responseStatus} } else if patternDiff.From == "" || patternDiff.From == nil { id = ResponsePropertyPatternAddedId - text = config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(patternDiff.To), ColorizedValue(responseStatus)) + args = []any{propName, patternDiff.To, responseStatus} } result = append(result, ApiChange{ Id: id, Level: INFO, - Text: text, + Args: args, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) - }) } } diff --git a/checker/check-response-pattern-added-or-changed_test.go b/checker/check-response-pattern-added-or-changed_test.go index c795fd73..7815326e 100644 --- a/checker/check-response-pattern-added-or-changed_test.go +++ b/checker/check-response-pattern-added-or-changed_test.go @@ -24,8 +24,7 @@ func TestResponsePropertyPatternChanged(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyPatternChangedId, - Text: "the 'data/created' response's property pattern was changed from '^[a-z]+$' to '^(?:([a-z]+-)*([a-z]+)?)$' for the status '200'", - Comment: "", + Args: []any{"data/created", "^[a-z]+$", "^(?:([a-z]+-)*([a-z]+)?)$", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -50,8 +49,7 @@ func TestResponsePropertyPatternAdded(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyPatternAddedId, - Text: "the 'data/created' response's property pattern '^[a-z]+$' was added for the status '200'", - Comment: "", + Args: []any{"data/created", "^[a-z]+$", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -76,8 +74,7 @@ func TestResponsePropertyPatternRemoved(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyPatternRemovedId, - Text: "the 'data/created' response's property pattern '^[a-z]+$' was removed for the status '200'", - Comment: "", + Args: []any{"data/created", "^[a-z]+$", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-property-all-of-updated.go b/checker/check-response-property-all-of-updated.go index f4bc8e8a..2fca83e5 100644 --- a/checker/check-response-property-all-of-updated.go +++ b/checker/check-response-property-all-of-updated.go @@ -11,7 +11,7 @@ const ( ResponsePropertyAllOfRemovedId = "response-property-all-of-removed" ) -func ResponsePropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -41,12 +41,9 @@ func ResponsePropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources if mediaTypeDiff.SchemaDiff.AllOfDiff != nil && len(mediaTypeDiff.SchemaDiff.AllOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: ResponseBodyAllOfAddedId, - Level: INFO, - Text: config.Localize( - ResponseBodyAllOfAddedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.AllOfDiff.Added.String()), - responseStatus), + Id: ResponseBodyAllOfAddedId, + Level: INFO, + Args: []any{mediaTypeDiff.SchemaDiff.AllOfDiff.Added.String(), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -56,12 +53,9 @@ func ResponsePropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources if mediaTypeDiff.SchemaDiff.AllOfDiff != nil && len(mediaTypeDiff.SchemaDiff.AllOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: ResponseBodyAllOfRemovedId, - Level: INFO, - Text: config.Localize( - ResponseBodyAllOfRemovedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.AllOfDiff.Deleted.String()), - responseStatus), + Id: ResponseBodyAllOfRemovedId, + Level: INFO, + Args: []any{mediaTypeDiff.SchemaDiff.AllOfDiff.Deleted.String(), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -77,14 +71,11 @@ func ResponsePropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources } if len(propertyDiff.AllOfDiff.Added) > 0 { + result = append(result, ApiChange{ - Id: ResponsePropertyAllOfAddedId, - Level: INFO, - Text: config.Localize( - ResponsePropertyAllOfAddedId, - ColorizedValue(propertyDiff.AllOfDiff.Added.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName)), - responseStatus), + Id: ResponsePropertyAllOfAddedId, + Level: INFO, + Args: []any{propertyDiff.AllOfDiff.Added.String(), propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -93,14 +84,11 @@ func ResponsePropertyAllOfUpdatedCheck(diffReport *diff.Diff, operationsSources } if len(propertyDiff.AllOfDiff.Deleted) > 0 { + result = append(result, ApiChange{ - Id: ResponsePropertyAllOfRemovedId, - Level: INFO, - Text: config.Localize( - ResponsePropertyAllOfRemovedId, - ColorizedValue(propertyDiff.AllOfDiff.Deleted.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName)), - responseStatus), + Id: ResponsePropertyAllOfRemovedId, + Level: INFO, + Args: []any{propertyDiff.AllOfDiff.Deleted.String(), propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-all-of-updated_test.go b/checker/check-response-property-all-of-updated_test.go index 5c6687c3..33a2b078 100644 --- a/checker/check-response-property-all-of-updated_test.go +++ b/checker/check-response-property-all-of-updated_test.go @@ -24,8 +24,7 @@ func TestResponsePropertyAllOfAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyAllOfAddedId, - Text: "added 'Rabbit' to the response body 'allOf' list for the response status 200", - Comment: "", + Args: []any{"Rabbit", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -34,8 +33,7 @@ func TestResponsePropertyAllOfAdded(t *testing.T) { }, { Id: checker.ResponsePropertyAllOfAddedId, - Text: "added 'Breed3' to the '/allOf[#/components/schemas/Dog]/breed' response property 'allOf' list for the response status 200", - Comment: "", + Args: []any{"Breed3", "/allOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -60,8 +58,7 @@ func TestResponsePropertyAllOfRemoved(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyAllOfRemovedId, - Text: "removed 'Rabbit' from the response body 'allOf' list for the response status 200", - Comment: "", + Args: []any{"Rabbit", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -70,8 +67,7 @@ func TestResponsePropertyAllOfRemoved(t *testing.T) { }, { Id: checker.ResponsePropertyAllOfRemovedId, - Text: "removed 'Breed3' from the '/allOf[#/components/schemas/Dog]/breed' response property 'allOf' list for the response status 200", - Comment: "", + Args: []any{"Breed3", "/allOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", diff --git a/checker/check-response-property-any-of-updated.go b/checker/check-response-property-any-of-updated.go index 7195ff76..b7279672 100644 --- a/checker/check-response-property-any-of-updated.go +++ b/checker/check-response-property-any-of-updated.go @@ -11,7 +11,7 @@ const ( ResponsePropertyAnyOfRemovedId = "response-property-any-of-removed" ) -func ResponsePropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -41,12 +41,9 @@ func ResponsePropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources if mediaTypeDiff.SchemaDiff.AnyOfDiff != nil && len(mediaTypeDiff.SchemaDiff.AnyOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: ResponseBodyAnyOfAddedId, - Level: INFO, - Text: config.Localize( - ResponseBodyAnyOfAddedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.AnyOfDiff.Added.String()), - responseStatus), + Id: ResponseBodyAnyOfAddedId, + Level: INFO, + Args: []any{mediaTypeDiff.SchemaDiff.AnyOfDiff.Added.String(), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -56,12 +53,9 @@ func ResponsePropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources if mediaTypeDiff.SchemaDiff.AnyOfDiff != nil && len(mediaTypeDiff.SchemaDiff.AnyOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: ResponseBodyAnyOfRemovedId, - Level: INFO, - Text: config.Localize( - ResponseBodyAnyOfRemovedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.AnyOfDiff.Deleted.String()), - responseStatus), + Id: ResponseBodyAnyOfRemovedId, + Level: INFO, + Args: []any{mediaTypeDiff.SchemaDiff.AnyOfDiff.Deleted.String(), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -77,14 +71,11 @@ func ResponsePropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources } if len(propertyDiff.AnyOfDiff.Added) > 0 { + result = append(result, ApiChange{ - Id: ResponsePropertyAnyOfAddedId, - Level: INFO, - Text: config.Localize( - ResponsePropertyAnyOfAddedId, - ColorizedValue(propertyDiff.AnyOfDiff.Added.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName)), - responseStatus), + Id: ResponsePropertyAnyOfAddedId, + Level: INFO, + Args: []any{propertyDiff.AnyOfDiff.Added.String(), propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -93,14 +84,11 @@ func ResponsePropertyAnyOfUpdatedCheck(diffReport *diff.Diff, operationsSources } if len(propertyDiff.AnyOfDiff.Deleted) > 0 { + result = append(result, ApiChange{ - Id: ResponsePropertyAnyOfRemovedId, - Level: INFO, - Text: config.Localize( - ResponsePropertyAnyOfRemovedId, - ColorizedValue(propertyDiff.AnyOfDiff.Deleted.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName)), - responseStatus), + Id: ResponsePropertyAnyOfRemovedId, + Level: INFO, + Args: []any{propertyDiff.AnyOfDiff.Deleted.String(), propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-any-of-updated_test.go b/checker/check-response-property-any-of-updated_test.go index 560fca43..9babf275 100644 --- a/checker/check-response-property-any-of-updated_test.go +++ b/checker/check-response-property-any-of-updated_test.go @@ -24,8 +24,7 @@ func TestResponsePropertyAnyOfAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyAnyOfAddedId, - Text: "added 'Rabbit' to the response body 'anyOf' list for the response status 200", - Comment: "", + Args: []any{"Rabbit", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -34,8 +33,7 @@ func TestResponsePropertyAnyOfAdded(t *testing.T) { }, { Id: checker.ResponsePropertyAnyOfAddedId, - Text: "added 'Breed3' to the '/anyOf[#/components/schemas/Dog]/breed' response property 'anyOf' list for the response status 200", - Comment: "", + Args: []any{"Breed3", "/anyOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -60,8 +58,7 @@ func TestResponsePropertyAnyOfRemoved(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyAnyOfRemovedId, - Text: "removed 'Rabbit' from the response body 'anyOf' list for the response status 200", - Comment: "", + Args: []any{"Rabbit", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -70,8 +67,7 @@ func TestResponsePropertyAnyOfRemoved(t *testing.T) { }, { Id: checker.ResponsePropertyAnyOfRemovedId, - Text: "removed 'Breed3' from the '/anyOf[#/components/schemas/Dog]/breed' response property 'anyOf' list for the response status 200", - Comment: "", + Args: []any{"Breed3", "/anyOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", diff --git a/checker/check-response-property-became-nuallable.go b/checker/check-response-property-became-nuallable.go index 9262da8e..b1aa8865 100644 --- a/checker/check-response-property-became-nuallable.go +++ b/checker/check-response-property-became-nuallable.go @@ -9,7 +9,7 @@ const ( ResponseBodyBecameNullableId = "response-body-became-nullable" ) -func ResponsePropertyBecameNullableCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyBecameNullableCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -41,7 +41,6 @@ func ResponsePropertyBecameNullableCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: ResponseBodyBecameNullableId, Level: ERR, - Text: config.Localize(ResponseBodyBecameNullableId), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -63,7 +62,7 @@ func ResponsePropertyBecameNullableCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: ResponsePropertyBecameNullableId, Level: ERR, - Text: config.Localize(ResponsePropertyBecameNullableId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-became-optional.go b/checker/check-response-property-became-optional.go index ebc92692..8acd8b24 100644 --- a/checker/check-response-property-became-optional.go +++ b/checker/check-response-property-became-optional.go @@ -9,7 +9,7 @@ const ( ResponseWriteOnlyPropertyBecameOptionalId = "response-write-only-property-became-optional" ) -func ResponsePropertyBecameOptionalCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyBecameOptionalCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -53,7 +53,7 @@ func ResponsePropertyBecameOptionalCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(changedRequiredPropertyName), ColorizedValue(responseStatus)), + Args: []any{changedRequiredPropertyName, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -84,10 +84,11 @@ func ResponsePropertyBecameOptionalCheck(diffReport *diff.Diff, operationsSource // removed properties processed by the ResponseRequiredPropertyUpdatedCheck check continue } + result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName))), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName)), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-became-optional_test.go b/checker/check-response-property-became-optional_test.go index b91a6f2f..a42b918e 100644 --- a/checker/check-response-property-became-optional_test.go +++ b/checker/check-response-property-became-optional_test.go @@ -20,8 +20,7 @@ func TestResponsePropertyBecameOptionalCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyBecameOptionalId, - Text: "the response property 'data/name' became optional for the status '200'", - Comment: "", + Args: []any{"data/name", "200"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -45,8 +44,7 @@ func TestResponseWriteOnlyPropertyBecameOptionalCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseWriteOnlyPropertyBecameOptionalId, - Text: "the response write-only property 'data/name' became optional for the status '200'", - Comment: "", + Args: []any{"data/name", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-property-became-required.go b/checker/check-response-property-became-required.go index 30f59094..990830f4 100644 --- a/checker/check-response-property-became-required.go +++ b/checker/check-response-property-became-required.go @@ -9,7 +9,7 @@ const ( ResponseWriteOnlyPropertyBecameRequiredId = "response-write-only-property-became-required" ) -func ResponsePropertyBecameRequiredCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyBecameRequiredCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -51,7 +51,7 @@ func ResponsePropertyBecameRequiredCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(changedRequiredPropertyName), ColorizedValue(responseStatus)), + Args: []any{changedRequiredPropertyName, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -79,10 +79,11 @@ func ResponsePropertyBecameRequiredCheck(diffReport *diff.Diff, operationsSource // removed properties processed by the ResponseRequiredPropertyUpdatedCheck check continue } + result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName))), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyFullName(propertyName, changedRequiredPropertyName)), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-became-required_test.go b/checker/check-response-property-became-required_test.go index 0c9d00fd..ae4671c5 100644 --- a/checker/check-response-property-became-required_test.go +++ b/checker/check-response-property-became-required_test.go @@ -20,8 +20,7 @@ func TestResponsePropertyBecameRequiredlCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyBecameRequiredId, - Text: "the response property 'data/name' became required for the status '200'", - Comment: "", + Args: []any{"data/name", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -45,8 +44,7 @@ func TestResponseWriteOnlyPropertyBecameRequiredCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseWriteOnlyPropertyBecameRequiredId, - Text: "the response write-only property 'data/name' became required for the status '200'", - Comment: "", + Args: []any{"data/name", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-property-default-value-changed.go b/checker/check-response-property-default-value-changed.go index 5663eb20..bee3bee1 100644 --- a/checker/check-response-property-default-value-changed.go +++ b/checker/check-response-property-default-value-changed.go @@ -13,7 +13,7 @@ const ( ResponsePropertyDefaultValueChangedId = "response-property-default-value-changed" ) -func ResponsePropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -32,7 +32,7 @@ func ResponsePropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsS result = append(result, ApiChange{ Id: messageId, Level: INFO, - Text: config.Localize(messageId, a...), + Args: a, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -51,11 +51,11 @@ func ResponsePropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsS if mediaTypeDiff.SchemaDiff != nil && mediaTypeDiff.SchemaDiff.DefaultDiff != nil { defaultValueDiff := mediaTypeDiff.SchemaDiff.DefaultDiff if defaultValueDiff.From == nil { - appendResultItem(ResponseBodyDefaultValueAddedId, ColorizedValue(mediaType), ColorizedValue(defaultValueDiff.To), ColorizedValue(responseStatus)) + appendResultItem(ResponseBodyDefaultValueAddedId, mediaType, defaultValueDiff.To, responseStatus) } else if defaultValueDiff.To == nil { - appendResultItem(ResponseBodyDefaultValueRemovedId, ColorizedValue(mediaType), ColorizedValue(defaultValueDiff.From), ColorizedValue(responseStatus)) + appendResultItem(ResponseBodyDefaultValueRemovedId, mediaType, defaultValueDiff.From, responseStatus) } else { - appendResultItem(ResponseBodyDefaultValueChangedId, ColorizedValue(mediaType), empty2none(defaultValueDiff.From), empty2none(defaultValueDiff.To), ColorizedValue(responseStatus)) + appendResultItem(ResponseBodyDefaultValueChangedId, mediaType, defaultValueDiff.From, defaultValueDiff.To, responseStatus) } } @@ -68,11 +68,11 @@ func ResponsePropertyDefaultValueChangedCheck(diffReport *diff.Diff, operationsS defaultValueDiff := propertyDiff.DefaultDiff if defaultValueDiff.From == nil { - appendResultItem(ResponsePropertyDefaultValueAddedId, ColorizedValue(propertyName), empty2none(defaultValueDiff.To), ColorizedValue(responseStatus)) + appendResultItem(ResponsePropertyDefaultValueAddedId, propertyName, defaultValueDiff.To, responseStatus) } else if defaultValueDiff.To == nil { - appendResultItem(ResponsePropertyDefaultValueRemovedId, ColorizedValue(propertyName), empty2none(defaultValueDiff.From), ColorizedValue(responseStatus)) + appendResultItem(ResponsePropertyDefaultValueRemovedId, propertyName, defaultValueDiff.From, responseStatus) } else { - appendResultItem(ResponsePropertyDefaultValueChangedId, ColorizedValue(propertyName), empty2none(defaultValueDiff.From), empty2none(defaultValueDiff.To), ColorizedValue(responseStatus)) + appendResultItem(ResponsePropertyDefaultValueChangedId, propertyName, defaultValueDiff.From, defaultValueDiff.To, responseStatus) } }) } diff --git a/checker/check-response-property-default-value-changed_test.go b/checker/check-response-property-default-value-changed_test.go index e2192369..34570c67 100644 --- a/checker/check-response-property-default-value-changed_test.go +++ b/checker/check-response-property-default-value-changed_test.go @@ -20,8 +20,7 @@ func TestResponsePropertyDefaultValueUpdatedCheck(t *testing.T) { require.Len(t, errs, 2) require.ElementsMatch(t, []checker.ApiChange{{ Id: checker.ResponsePropertyDefaultValueChangedId, - Text: "the 'created' response's property default value changed from '2020-01-01T00:00:00Z' to '2020-02-01T00:00:00Z' for the status '200'", - Comment: "", + Args: []any{"created", "2020-01-01T00:00:00Z", "2020-02-01T00:00:00Z", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -29,8 +28,7 @@ func TestResponsePropertyDefaultValueUpdatedCheck(t *testing.T) { OperationId: "createOneGroup", }, { Id: checker.ResponsePropertyDefaultValueChangedId, - Text: "the 'enabled' response's property default value changed from 'false' to 'true' for the status '200'", - Comment: "", + Args: []any{"enabled", false, true, "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -53,8 +51,7 @@ func TestResponseSchemaDefaultValueUpdatedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseBodyDefaultValueChangedId, - Text: "the response body 'text/plain' default value changed from 'Error' to 'new default value' for the status '404'", - Comment: "", + Args: []any{"text/plain", "Error", "new default value", "404"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -79,8 +76,7 @@ func TestResponsePropertyDefaultValueAddedCheck(t *testing.T) { require.Len(t, errs, 2) require.ElementsMatch(t, []checker.ApiChange{{ Id: checker.ResponseBodyDefaultValueAddedId, - Text: "the response body 'text/plain' default value 'Error' was added for the status '404'", - Comment: "", + Args: []any{"text/plain", "Error", "404"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -88,8 +84,7 @@ func TestResponsePropertyDefaultValueAddedCheck(t *testing.T) { OperationId: "createOneGroup", }, { Id: checker.ResponsePropertyDefaultValueAddedId, - Text: "the 'created' response's property default value '2020-01-01T00:00:00Z' was added for the status '200'", - Comment: "", + Args: []any{"created", "2020-01-01T00:00:00Z", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -114,8 +109,7 @@ func TestResponsePropertyDefaultValueRemovedCheck(t *testing.T) { require.Len(t, errs, 2) require.ElementsMatch(t, []checker.ApiChange{{ Id: checker.ResponseBodyDefaultValueRemovedId, - Text: "the response body 'text/plain' default value 'Error' was removed for the status '404'", - Comment: "", + Args: []any{"text/plain", "Error", "404"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -123,8 +117,7 @@ func TestResponsePropertyDefaultValueRemovedCheck(t *testing.T) { OperationId: "createOneGroup", }, { Id: checker.ResponsePropertyDefaultValueRemovedId, - Text: "the 'created' response's property default value '2020-01-01T00:00:00Z' was removed for the status '200'", - Comment: "", + Args: []any{"created", "2020-01-01T00:00:00Z", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-property-enum-value-added.go b/checker/check-response-property-enum-value-added.go index 8e1ba2c5..ef6c4e8d 100644 --- a/checker/check-response-property-enum-value-added.go +++ b/checker/check-response-property-enum-value-added.go @@ -9,7 +9,7 @@ const ( ResponseWriteOnlyPropertyEnumValueAddedId = "response-write-only-property-enum-value-added" ) -func ResponsePropertyEnumValueAddedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyEnumValueAddedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -41,7 +41,7 @@ func ResponsePropertyEnumValueAddedCheck(diffReport *diff.Diff, operationsSource id := ResponsePropertyEnumValueAddedId level := WARN - comment := config.Localize(comment(ResponsePropertyEnumValueAddedId)) + comment := commentId(ResponsePropertyEnumValueAddedId) if propertyDiff.Revision.WriteOnly { // Document write-only enum update @@ -54,7 +54,7 @@ func ResponsePropertyEnumValueAddedCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, enumVal, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{enumVal, propertyFullName(propertyPath, propertyName), responseStatus}, Comment: comment, Operation: operation, OperationId: operationItem.Revision.OperationID, diff --git a/checker/check-response-property-enum-value-added_test.go b/checker/check-response-property-enum-value-added_test.go index caa16fa7..0b7251cc 100644 --- a/checker/check-response-property-enum-value-added_test.go +++ b/checker/check-response-property-enum-value-added_test.go @@ -23,14 +23,15 @@ func TestResponsePropertyEnumValueAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyEnumValueAddedId, - Text: "added the new 'Test' enum value to the 'data/typeEnum' response property for the response status '200'", - Comment: "Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.", + Args: []any{"Test", "data/typeEnum", "200"}, + Comment: checker.ResponsePropertyEnumValueAddedId + "-comment", Level: checker.WARN, Operation: "POST", Path: "/api/v1.0/groups", Source: "../data/checker/response_property_enum_added_base.yaml", OperationId: "createOneGroup", }, errs[0]) + require.Equal(t, "Adding new enum values to response could be unexpected for clients, use x-extensible-enum instead.", errs[0].GetComment(checker.NewDefaultLocalizer())) } // CL: adding an enum value to a response write-only property @@ -48,7 +49,7 @@ func TestResponseWriteOnlyPropertyEnumValueAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseWriteOnlyPropertyEnumValueAddedId, - Text: "added the new 'Test' enum value to the 'data/writeOnlyEnum' response write-only property for the response status '200'", + Args: []any{"Test", "data/writeOnlyEnum", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-property-enum-value-removed.go b/checker/check-response-property-enum-value-removed.go index 6710fae4..763a437d 100644 --- a/checker/check-response-property-enum-value-removed.go +++ b/checker/check-response-property-enum-value-removed.go @@ -8,7 +8,7 @@ const ( ResponsePropertyEnumValueRemovedId = "response-property-enum-value-removed" ) -func ResponseParameterEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseParameterEnumValueRemovedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -42,7 +42,7 @@ func ResponseParameterEnumValueRemovedCheck(diffReport *diff.Diff, operationsSou result = append(result, ApiChange{ Id: ResponsePropertyEnumValueRemovedId, Level: config.getLogLevel(ResponsePropertyEnumValueRemovedId, INFO), - Text: config.Localize(ResponsePropertyEnumValueRemovedId, enumVal, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{enumVal, propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -51,7 +51,6 @@ func ResponseParameterEnumValueRemovedCheck(diffReport *diff.Diff, operationsSou } }) } - } } } diff --git a/checker/check-response-property-enum-value-removed_test.go b/checker/check-response-property-enum-value-removed_test.go index 96b4fccb..dea06c61 100644 --- a/checker/check-response-property-enum-value-removed_test.go +++ b/checker/check-response-property-enum-value-removed_test.go @@ -23,7 +23,7 @@ func TestResponsePropertyEnumValueRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyEnumValueRemovedId, - Text: "removed the 'TYPE2' enum value from the 'data/typeEnum' response property for the response status '200'", + Args: []any{"TYPE2", "data/typeEnum", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -47,7 +47,7 @@ func TestResponseWriteOnlyPropertyEnumValueRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyEnumValueRemovedId, - Text: "removed the 'TYPE2' enum value from the 'data/writeOnlyEnum' response property for the response status '200'", + Args: []any{"TYPE2", "data/writeOnlyEnum", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-property-max-increased.go b/checker/check-response-property-max-increased.go index bb990bf3..ae90a6cf 100644 --- a/checker/check-response-property-max-increased.go +++ b/checker/check-response-property-max-increased.go @@ -9,7 +9,7 @@ const ( ResponsePropertyMaxIncreasedId = "response-property-max-increased" ) -func ResponsePropertyMaxIncreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyMaxIncreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,7 @@ func ResponsePropertyMaxIncreasedCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: ResponseBodyMaxIncreasedId, Level: ERR, - Text: config.Localize(ResponseBodyMaxIncreasedId, ColorizedValue(maxDiff.From), ColorizedValue(maxDiff.To)), + Args: []any{maxDiff.From, maxDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,7 +71,7 @@ func ResponsePropertyMaxIncreasedCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: ResponsePropertyMaxIncreasedId, Level: ERR, - Text: config.Localize(ResponsePropertyMaxIncreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxDiff.From), ColorizedValue(maxDiff.To), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), maxDiff.From, maxDiff.To, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-max-length-increased.go b/checker/check-response-property-max-length-increased.go index f92e6a6a..1a8975b6 100644 --- a/checker/check-response-property-max-length-increased.go +++ b/checker/check-response-property-max-length-increased.go @@ -9,7 +9,7 @@ const ( ResponsePropertyMaxLengthIncreasedId = "response-property-max-length-increased" ) -func ResponsePropertyMaxLengthIncreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyMaxLengthIncreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,7 @@ func ResponsePropertyMaxLengthIncreasedCheck(diffReport *diff.Diff, operationsSo result = append(result, ApiChange{ Id: ResponseBodyMaxLengthIncreasedId, Level: ERR, - Text: config.Localize(ResponseBodyMaxLengthIncreasedId, ColorizedValue(maxLengthDiff.From), ColorizedValue(maxLengthDiff.To)), + Args: []any{maxLengthDiff.From, maxLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,7 +71,7 @@ func ResponsePropertyMaxLengthIncreasedCheck(diffReport *diff.Diff, operationsSo result = append(result, ApiChange{ Id: ResponsePropertyMaxLengthIncreasedId, Level: ERR, - Text: config.Localize(ResponsePropertyMaxLengthIncreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxLengthDiff.From), ColorizedValue(maxLengthDiff.To), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), maxLengthDiff.From, maxLengthDiff.To, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -79,9 +79,7 @@ func ResponsePropertyMaxLengthIncreasedCheck(diffReport *diff.Diff, operationsSo }) }) } - } - } } return result diff --git a/checker/check-response-property-max-length-unset.go b/checker/check-response-property-max-length-unset.go index cc7e8d61..2bea6917 100644 --- a/checker/check-response-property-max-length-unset.go +++ b/checker/check-response-property-max-length-unset.go @@ -9,7 +9,7 @@ const ( ResponsePropertyMaxLengthUnsetId = "response-property-max-length-unset" ) -func ResponsePropertyMaxLengthUnsetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyMaxLengthUnsetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,7 +38,7 @@ func ResponsePropertyMaxLengthUnsetCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: ResponseBodyMaxLengthUnsetId, Level: ERR, - Text: config.Localize(ResponseBodyMaxLengthUnsetId, ColorizedValue(maxLengthDiff.From)), + Args: []any{maxLengthDiff.From}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -65,7 +65,7 @@ func ResponsePropertyMaxLengthUnsetCheck(diffReport *diff.Diff, operationsSource result = append(result, ApiChange{ Id: ResponsePropertyMaxLengthUnsetId, Level: ERR, - Text: config.Localize(ResponsePropertyMaxLengthUnsetId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(maxLengthDiff.From), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), maxLengthDiff.From, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-min-decreased.go b/checker/check-response-property-min-decreased.go index 74fabdd8..572cc80b 100644 --- a/checker/check-response-property-min-decreased.go +++ b/checker/check-response-property-min-decreased.go @@ -9,7 +9,7 @@ const ( ResponsePropertyMinDecreasedId = "response-property-min-decreased" ) -func ResponsePropertyMinDecreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyMinDecreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,7 @@ func ResponsePropertyMinDecreasedCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: ResponseBodyMinDecreasedId, Level: ERR, - Text: config.Localize(ResponseBodyMinDecreasedId, ColorizedValue(minDiff.From), ColorizedValue(minDiff.To)), + Args: []any{minDiff.From, minDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,7 +71,7 @@ func ResponsePropertyMinDecreasedCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: ResponsePropertyMinDecreasedId, Level: ERR, - Text: config.Localize(ResponsePropertyMinDecreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minDiff.From), ColorizedValue(minDiff.To), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), minDiff.From, minDiff.To, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-min-items-decreased.go b/checker/check-response-property-min-items-decreased.go index d9fc7672..58318c86 100644 --- a/checker/check-response-property-min-items-decreased.go +++ b/checker/check-response-property-min-items-decreased.go @@ -9,7 +9,7 @@ const ( ResponsePropertyMinItemsDecreasedId = "response-property-min-items-decreased" ) -func ResponsePropertyMinItemsDecreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyMinItemsDecreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,7 @@ func ResponsePropertyMinItemsDecreasedCheck(diffReport *diff.Diff, operationsSou result = append(result, ApiChange{ Id: ResponseBodyMinItemsDecreasedId, Level: ERR, - Text: config.Localize(ResponseBodyMinItemsDecreasedId, ColorizedValue(minItemsDiff.From), ColorizedValue(minItemsDiff.To)), + Args: []any{minItemsDiff.From, minItemsDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,7 +71,7 @@ func ResponsePropertyMinItemsDecreasedCheck(diffReport *diff.Diff, operationsSou result = append(result, ApiChange{ Id: ResponsePropertyMinItemsDecreasedId, Level: ERR, - Text: config.Localize(ResponsePropertyMinItemsDecreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minItemsDiff.From), ColorizedValue(minItemsDiff.To), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), minItemsDiff.From, minItemsDiff.To, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-min-items-unset.go b/checker/check-response-property-min-items-unset.go index 29b88ca1..bc7f1fff 100644 --- a/checker/check-response-property-min-items-unset.go +++ b/checker/check-response-property-min-items-unset.go @@ -9,7 +9,7 @@ const ( ResponsePropertyMinItemsUnsetId = "response-property-min-items-unset" ) -func ResponsePropertyMinItemsUnsetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyMinItemsUnsetCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -38,7 +38,7 @@ func ResponsePropertyMinItemsUnsetCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: ResponseBodyMinItemsUnsetId, Level: ERR, - Text: config.Localize(ResponseBodyMinItemsUnsetId, ColorizedValue(minItemsDiff.From)), + Args: []any{minItemsDiff.From}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -65,7 +65,7 @@ func ResponsePropertyMinItemsUnsetCheck(diffReport *diff.Diff, operationsSources result = append(result, ApiChange{ Id: ResponsePropertyMinItemsUnsetId, Level: ERR, - Text: config.Localize(ResponsePropertyMinItemsUnsetId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minItemsDiff.From), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), minItemsDiff.From, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-min-length-decreased.go b/checker/check-response-property-min-length-decreased.go index e8d961ea..1c72ba14 100644 --- a/checker/check-response-property-min-length-decreased.go +++ b/checker/check-response-property-min-length-decreased.go @@ -9,7 +9,7 @@ const ( ResponsePropertyMinLengthDecreasedId = "response-property-min-length-decreased" ) -func ResponsePropertyMinLengthDecreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyMinLengthDecreasedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -39,7 +39,7 @@ func ResponsePropertyMinLengthDecreasedCheck(diffReport *diff.Diff, operationsSo result = append(result, ApiChange{ Id: ResponseBodyMinLengthDecreasedId, Level: ERR, - Text: config.Localize(ResponseBodyMinLengthDecreasedId, ColorizedValue(minLengthDiff.From), ColorizedValue(minLengthDiff.To)), + Args: []any{minLengthDiff.From, minLengthDiff.To}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,7 +71,7 @@ func ResponsePropertyMinLengthDecreasedCheck(diffReport *diff.Diff, operationsSo result = append(result, ApiChange{ Id: ResponsePropertyMinLengthDecreasedId, Level: ERR, - Text: config.Localize(ResponsePropertyMinLengthDecreasedId, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(minLengthDiff.From), ColorizedValue(minLengthDiff.To), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), minLengthDiff.From, minLengthDiff.To, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-one-of-updated.go b/checker/check-response-property-one-of-updated.go index 346122c2..9ac92048 100644 --- a/checker/check-response-property-one-of-updated.go +++ b/checker/check-response-property-one-of-updated.go @@ -11,7 +11,7 @@ const ( ResponsePropertyOneOfRemovedId = "response-property-one-of-removed" ) -func ResponsePropertyOneOfUpdated(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyOneOfUpdated(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -41,12 +41,9 @@ func ResponsePropertyOneOfUpdated(diffReport *diff.Diff, operationsSources *diff if mediaTypeDiff.SchemaDiff.OneOfDiff != nil && len(mediaTypeDiff.SchemaDiff.OneOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: ResponseBodyOneOfAddedId, - Level: INFO, - Text: config.Localize( - ResponseBodyOneOfAddedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.OneOfDiff.Added.String()), - responseStatus), + Id: ResponseBodyOneOfAddedId, + Level: INFO, + Args: []any{mediaTypeDiff.SchemaDiff.OneOfDiff.Added.String(), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -56,12 +53,9 @@ func ResponsePropertyOneOfUpdated(diffReport *diff.Diff, operationsSources *diff if mediaTypeDiff.SchemaDiff.OneOfDiff != nil && len(mediaTypeDiff.SchemaDiff.OneOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: ResponseBodyOneOfRemovedId, - Level: INFO, - Text: config.Localize( - ResponseBodyOneOfRemovedId, - ColorizedValue(mediaTypeDiff.SchemaDiff.OneOfDiff.Deleted.String()), - responseStatus), + Id: ResponseBodyOneOfRemovedId, + Level: INFO, + Args: []any{mediaTypeDiff.SchemaDiff.OneOfDiff.Deleted.String(), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -76,15 +70,13 @@ func ResponsePropertyOneOfUpdated(diffReport *diff.Diff, operationsSources *diff return } + propName := propertyFullName(propertyPath, propertyName) + if len(propertyDiff.OneOfDiff.Added) > 0 { result = append(result, ApiChange{ - Id: ResponsePropertyOneOfAddedId, - Level: INFO, - Text: config.Localize( - ResponsePropertyOneOfAddedId, - ColorizedValue(propertyDiff.OneOfDiff.Added.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName)), - responseStatus), + Id: ResponsePropertyOneOfAddedId, + Level: INFO, + Args: []any{propertyDiff.OneOfDiff.Added.String(), propName, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -94,13 +86,9 @@ func ResponsePropertyOneOfUpdated(diffReport *diff.Diff, operationsSources *diff if len(propertyDiff.OneOfDiff.Deleted) > 0 { result = append(result, ApiChange{ - Id: ResponsePropertyOneOfRemovedId, - Level: INFO, - Text: config.Localize( - ResponsePropertyOneOfRemovedId, - ColorizedValue(propertyDiff.OneOfDiff.Deleted.String()), - ColorizedValue(propertyFullName(propertyPath, propertyName)), - responseStatus), + Id: ResponsePropertyOneOfRemovedId, + Level: INFO, + Args: []any{propertyDiff.OneOfDiff.Deleted.String(), propName, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-one-of-updated_test.go b/checker/check-response-property-one-of-updated_test.go index f6de2216..7fd7b352 100644 --- a/checker/check-response-property-one-of-updated_test.go +++ b/checker/check-response-property-one-of-updated_test.go @@ -24,8 +24,7 @@ func TestResponsePropertyOneOfAdded(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyOneOfAddedId, - Text: "added 'Rabbit' to the response body 'oneOf' list for the response status 200", - Comment: "", + Args: []any{"Rabbit", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -34,8 +33,7 @@ func TestResponsePropertyOneOfAdded(t *testing.T) { }, { Id: checker.ResponsePropertyOneOfAddedId, - Text: "added 'Breed3' to the '/oneOf[#/components/schemas/Dog]/breed' response property 'oneOf' list for the response status 200", - Comment: "", + Args: []any{"Breed3", "/oneOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -44,8 +42,7 @@ func TestResponsePropertyOneOfAdded(t *testing.T) { }, { Id: checker.ResponsePropertyOneOfAddedId, - Text: "added 'RevisionSchema[1]:Dark brown types' to the '/oneOf[#/components/schemas/Fox]/breed' response property 'oneOf' list for the response status 200", - Comment: "", + Args: []any{"RevisionSchema[1]:Dark brown types", "/oneOf[#/components/schemas/Fox]/breed", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -70,8 +67,7 @@ func TestResponsePropertyOneOfRemoved(t *testing.T) { require.ElementsMatch(t, []checker.ApiChange{ { Id: checker.ResponseBodyOneOfRemovedId, - Text: "removed 'Rabbit' from the response body 'oneOf' list for the response status 200", - Comment: "", + Args: []any{"Rabbit", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -80,8 +76,7 @@ func TestResponsePropertyOneOfRemoved(t *testing.T) { }, { Id: checker.ResponsePropertyOneOfRemovedId, - Text: "removed 'Breed3' from the '/oneOf[#/components/schemas/Dog]/breed' response property 'oneOf' list for the response status 200", - Comment: "", + Args: []any{"Breed3", "/oneOf[#/components/schemas/Dog]/breed", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", @@ -90,8 +85,7 @@ func TestResponsePropertyOneOfRemoved(t *testing.T) { }, { Id: checker.ResponsePropertyOneOfRemovedId, - Text: "removed 'BaseSchema[1]:Dark brown types' from the '/oneOf[#/components/schemas/Fox]/breed' response property 'oneOf' list for the response status 200", - Comment: "", + Args: []any{"BaseSchema[1]:Dark brown types", "/oneOf[#/components/schemas/Fox]/breed", "200"}, Level: checker.INFO, Operation: "GET", Path: "/pets", diff --git a/checker/check-response-property-type-changed.go b/checker/check-response-property-type-changed.go index f54ac631..c69b0c3c 100644 --- a/checker/check-response-property-type-changed.go +++ b/checker/check-response-property-type-changed.go @@ -11,7 +11,7 @@ const ( ResponsePropertyTypeChangedId = "response-property-type-changed" ) -func ResponsePropertyTypeChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponsePropertyTypeChangedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -43,7 +43,7 @@ func ResponsePropertyTypeChangedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: ResponseBodyTypeChangedId, Level: ERR, - Text: config.Localize(ResponseBodyTypeChangedId, empty2none(typeDiff.From), empty2none(formatDiff.From), empty2none(typeDiff.To), empty2none(formatDiff.To), ColorizedValue(responseStatus)), + Args: []any{typeDiff.From, formatDiff.From, typeDiff.To, formatDiff.To, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -68,7 +68,7 @@ func ResponsePropertyTypeChangedCheck(diffReport *diff.Diff, operationsSources * result = append(result, ApiChange{ Id: ResponsePropertyTypeChangedId, Level: ERR, - Text: config.Localize(ResponsePropertyTypeChangedId, empty2none(typeDiff.From), empty2none(formatDiff.From), empty2none(typeDiff.To), empty2none(formatDiff.To), ColorizedValue(responseStatus)), + Args: []any{typeDiff.From, formatDiff.From, typeDiff.To, formatDiff.To, responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-property-type-changed_test.go b/checker/check-response-property-type-changed_test.go index 29dbe015..3d30c9b2 100644 --- a/checker/check-response-property-type-changed_test.go +++ b/checker/check-response-property-type-changed_test.go @@ -21,8 +21,7 @@ func TestResponseSchemaTypeChangedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseBodyTypeChangedId, - Text: "the response's body type/format changed from 'string'/'none' to 'object'/'none' for status '200'", - Comment: "", + Args: []any{"string", "", "object", "", "200"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -46,8 +45,7 @@ func TestResponsePropertyTypeChangedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyTypeChangedId, - Text: "the response's property type/format changed from 'string'/'none' to 'integer'/'none' for status '200'", - Comment: "", + Args: []any{"string", "", "integer", "", "200"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -71,8 +69,7 @@ func TestResponsePropertyFormatChangedCheck(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponsePropertyTypeChangedId, - Text: "the response's property type/format changed from 'string'/'hostname' to 'string'/'uuid' for status '200'", - Comment: "", + Args: []any{"string", "hostname", "string", "uuid", "200"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-required-property-updated.go b/checker/check-response-required-property-updated.go index 5e9ecad6..52e59d1a 100644 --- a/checker/check-response-required-property-updated.go +++ b/checker/check-response-required-property-updated.go @@ -13,7 +13,7 @@ const ( ResponseRequiredWriteOnlyPropertyAddedId = "response-required-write-only-property-added" ) -func ResponseRequiredPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseRequiredPropertyUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -50,10 +50,11 @@ func ResponseRequiredPropertyUpdatedCheck(diffReport *diff.Diff, operationsSourc // Covered by response-optional-property-removed return } + result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -71,10 +72,11 @@ func ResponseRequiredPropertyUpdatedCheck(diffReport *diff.Diff, operationsSourc // Covered by response-optional-property-added return } + result = append(result, ApiChange{ Id: id, Level: INFO, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-required-property-updated_test.go b/checker/check-response-required-property-updated_test.go index 40bd4dd2..60921aa3 100644 --- a/checker/check-response-required-property-updated_test.go +++ b/checker/check-response-required-property-updated_test.go @@ -22,8 +22,7 @@ func TestResponseRequiredPropertyAdded(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseRequiredPropertyAddedId, - Text: "added the required property 'data/new' to the response with the '200' status", - Comment: "", + Args: []any{"data/new", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -46,8 +45,7 @@ func TestResponseRequiredPropertyRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseRequiredPropertyRemovedId, - Text: "removed the required property 'data/new' from the response with the '200' status", - Comment: "", + Args: []any{"data/new", "200"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", @@ -72,8 +70,7 @@ func TestResponseRequiredWriteOnlyPropertyAdded(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseRequiredWriteOnlyPropertyAddedId, - Text: "added the required write-only property 'data/new' to the response with the '200' status", - Comment: "", + Args: []any{"data/new", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -97,8 +94,7 @@ func TestResponseRequiredWriteOnlyPropertyRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseRequiredWriteOnlyPropertyRemovedId, - Text: "removed the required write-only property 'data/new' from the response with the '200' status", - Comment: "", + Args: []any{"data/new", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-required-property-write-only-read-only.go b/checker/check-response-required-property-write-only-read-only.go index b9bd4ec4..ebb5035b 100644 --- a/checker/check-response-required-property-write-only-read-only.go +++ b/checker/check-response-required-property-write-only-read-only.go @@ -12,7 +12,7 @@ const ( ResponseRequiredPropertyBecameNonReadOnlyId = "response-required-property-became-not-read-only" ) -func ResponseRequiredPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseRequiredPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -58,7 +58,7 @@ func ResponseRequiredPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, opera id := ResponseRequiredPropertyBecameNonWriteOnlyId level := WARN - comment := config.Localize(comment(ResponseRequiredPropertyBecameNonWriteOnlyId)) + comment := commentId(ResponseRequiredPropertyBecameNonWriteOnlyId) if writeOnlyDiff.To == true { id = ResponseRequiredPropertyBecameWriteOnlyId @@ -69,7 +69,7 @@ func ResponseRequiredPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, opera result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Comment: comment, Operation: operation, OperationId: operationItem.Revision.OperationID, @@ -105,7 +105,7 @@ func ResponseRequiredPropertyWriteOnlyReadOnlyCheck(diffReport *diff.Diff, opera result = append(result, ApiChange{ Id: id, Level: level, - Text: config.Localize(id, ColorizedValue(propertyFullName(propertyPath, propertyName)), ColorizedValue(responseStatus)), + Args: []any{propertyFullName(propertyPath, propertyName), responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, diff --git a/checker/check-response-required-property-write-only-read-only_test.go b/checker/check-response-required-property-write-only-read-only_test.go index bb753499..9fdbf26b 100644 --- a/checker/check-response-required-property-write-only-read-only_test.go +++ b/checker/check-response-required-property-write-only-read-only_test.go @@ -24,8 +24,7 @@ func TestResponseRequiredPropertyBecameWriteOnly(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: "response-required-property-became-write-only", - Text: "the response required property 'data/name' became write-only for the status '200'", - Comment: "", + Args: []any{"data/name", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -50,14 +49,16 @@ func TestResponseRequiredPropertyBecameNotWriteOnly(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseRequiredPropertyBecameNonWriteOnlyId, - Text: "the response required property 'data/writeOnlyName' became not write-only for the status '200'", - Comment: "It is valid only if the property was always returned before the specification has been changed", + Args: []any{"data/writeOnlyName", "200"}, + Comment: checker.ResponseRequiredPropertyBecameNonWriteOnlyId + "-comment", Level: checker.WARN, Operation: "POST", Path: "/api/v1.0/groups", Source: "../data/checker/response_required_property_write_only_read_only_base.yaml", OperationId: "createOneGroup", }, errs[0]) + require.Equal(t, "It is valid only if the property was always returned before the specification has been changed", errs[0].GetComment(checker.NewDefaultLocalizer())) + require.Equal(t, "the response required property 'data/writeOnlyName' became not write-only for the status '200'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // CL: changing required response property to read-only @@ -76,8 +77,7 @@ func TestResponseRequiredPropertyBecameReadOnly(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseRequiredPropertyBecameReadOnlyId, - Text: "the response required property 'data/id' became read-only for the status '200'", - Comment: "", + Args: []any{"data/id", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -103,8 +103,7 @@ func TestResponseRequiredPropertyBecameNonReadOnly(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.ResponseRequiredPropertyBecameNonReadOnlyId, - Text: "the response required property 'data/id' became not read-only for the status '200'", - Comment: "", + Args: []any{"data/id", "200"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/check-response-status-updated.go b/checker/check-response-status-updated.go index cd098f4b..6c8c49a5 100644 --- a/checker/check-response-status-updated.go +++ b/checker/check-response-status-updated.go @@ -14,7 +14,7 @@ const ( ResponseNonSuccessStatusAddedId = "response-non-success-status-added" ) -func ResponseSuccessStatusUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseSuccessStatusUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { success := func(status int) bool { return status >= 200 && status <= 299 } @@ -22,7 +22,7 @@ func ResponseSuccessStatusUpdatedCheck(diffReport *diff.Diff, operationsSources return responseStatusUpdated(diffReport, operationsSources, config, success, ResponseSuccessStatusRemovedId, ERR) } -func ResponseNonSuccessStatusUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes { +func ResponseNonSuccessStatusUpdatedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes { notSuccess := func(status int) bool { return status < 200 || status > 299 } @@ -30,7 +30,7 @@ func ResponseNonSuccessStatusUpdatedCheck(diffReport *diff.Diff, operationsSourc return responseStatusUpdated(diffReport, operationsSources, config, notSuccess, ResponseNonSuccessStatusRemovedId, INFO) } -func responseStatusUpdated(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config, filter func(int) bool, id string, defaultLevel Level) Changes { +func responseStatusUpdated(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config, filter func(int) bool, id string, defaultLevel Level) Changes { result := make(Changes, 0) if diffReport.PathsDiff == nil { return result @@ -57,14 +57,13 @@ func responseStatusUpdated(diffReport *diff.Diff, operationsSources *diff.Operat result = append(result, ApiChange{ Id: id, Level: config.getLogLevel(id, defaultLevel), - Text: config.Localize(id, ColorizedValue(responseStatus)), + Args: []any{responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) } - } for _, responseStatus := range operationItem.ResponsesDiff.Added { @@ -78,16 +77,14 @@ func responseStatusUpdated(diffReport *diff.Diff, operationsSources *diff.Operat result = append(result, ApiChange{ Id: addedId, Level: config.getLogLevel(addedId, INFO), - Text: config.Localize(addedId, ColorizedValue(responseStatus)), + Args: []any{responseStatus}, Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, Source: source, }) } - } - } } return result diff --git a/checker/check-response-status-updated_test.go b/checker/check-response-status-updated_test.go index 34964259..f6559f7a 100644 --- a/checker/check-response-status-updated_test.go +++ b/checker/check-response-status-updated_test.go @@ -24,8 +24,7 @@ func TestResponseSuccessStatusAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseSuccessStatusAddedId, - Text: "added the success response with the status '201'", - Comment: "", + Args: []any{"201"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -50,8 +49,7 @@ func TestResponseNonSuccessStatusAdded(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseNonSuccessStatusAddedId, - Text: "added the non-success response with the status '400'", - Comment: "", + Args: []any{"400"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -76,8 +74,7 @@ func TestResponseNonSuccessStatusRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseNonSuccessStatusRemovedId, - Text: "removed the non-success response with the status '409'", - Comment: "", + Args: []any{"409"}, Level: checker.INFO, Operation: "POST", Path: "/api/v1.0/groups", @@ -102,8 +99,7 @@ func TestResponseSuccessStatusRemoved(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.ResponseSuccessStatusRemovedId, - Text: "removed the success response with the status '200'", - Comment: "", + Args: []any{"200"}, Level: checker.ERR, Operation: "POST", Path: "/api/v1.0/groups", diff --git a/checker/checker.go b/checker/checker.go index 60c4ea52..c09952d3 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -4,7 +4,6 @@ package checker import ( "encoding/json" "fmt" - "os" "sort" "github.com/getkin/kin-openapi/openapi3" @@ -15,46 +14,20 @@ const ( APIStabilityDecreasedId = "api-stability-decreased" ) -type BackwardCompatibilityCheck func(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes +type BackwardCompatibilityCheck func(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes -type BackwardCompatibilityRule struct { - Id string - Level Level - Description string - Required bool - Handler BackwardCompatibilityCheck `json:"-" yaml:"-"` -} - -var pipedOutput *bool - -func SetPipedOutput(val *bool) *bool { - save := pipedOutput - pipedOutput = val - return save -} - -func IsPipedOutput() bool { - if pipedOutput != nil { - return *pipedOutput - } - fi, _ := os.Stdout.Stat() - a := (fi.Mode() & os.ModeCharDevice) == 0 - pipedOutput = &a - return *pipedOutput -} - -func CheckBackwardCompatibility(config Config, diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap) Changes { +func CheckBackwardCompatibility(config *Config, diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap) Changes { return CheckBackwardCompatibilityUntilLevel(config, diffReport, operationsSources, WARN) } -func CheckBackwardCompatibilityUntilLevel(config Config, diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, level Level) Changes { +func CheckBackwardCompatibilityUntilLevel(config *Config, diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, level Level) Changes { result := make(Changes, 0) if diffReport == nil { return result } - result = removeDraftAndAlphaOperationsDiffs(diffReport, result, operationsSources) + result = removeDraftAndAlphaOperationsDiffs(config, diffReport, result, operationsSources) for _, check := range config.Checks { if check == nil { @@ -75,7 +48,7 @@ func CheckBackwardCompatibilityUntilLevel(config Config, diffReport *diff.Diff, return filteredResult } -func removeDraftAndAlphaOperationsDiffs(diffReport *diff.Diff, result Changes, operationsSources *diff.OperationsSourcesMap) Changes { +func removeDraftAndAlphaOperationsDiffs(config *Config, diffReport *diff.Diff, result Changes, operationsSources *diff.OperationsSourcesMap) Changes { if diffReport.PathsDiff == nil { return result } @@ -88,7 +61,7 @@ func removeDraftAndAlphaOperationsDiffs(diffReport *diff.Diff, result Changes, o baseStability, err := getStabilityLevel(pathDiff.Base[path].Operations()[operation].Extensions) source := (*operationsSources)[pathDiff.Base[path].Operations()[operation]] if err != nil { - result = newParsingError(result, err, operation, operationItem, path, source) + result = newParsingError(config, result, err, operation, operationItem, path, source) continue } if !(baseStability == STABILITY_DRAFT || baseStability == STABILITY_ALPHA) { @@ -115,7 +88,7 @@ func removeDraftAndAlphaOperationsDiffs(diffReport *diff.Diff, result Changes, o baseStability, err := getStabilityLevel(operationItem.Extensions) source := (*operationsSources)[pathDiff.Base.Operations()[operation]] if err != nil { - result = newParsingError(result, err, operation, operationItem, path, source) + result = newParsingError(config, result, err, operation, operationItem, path, source) continue } if !(baseStability == STABILITY_DRAFT || baseStability == STABILITY_ALPHA) { @@ -132,8 +105,8 @@ func removeDraftAndAlphaOperationsDiffs(diffReport *diff.Diff, result Changes, o source := (*operationsSources)[pathDiff.Base.Operations()[operation]] result = append(result, ApiChange{ Id: ParseErrorId, + Args: []any{err.Error()}, Level: ERR, - Text: fmt.Sprintf("parsing error %s", err.Error()), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -146,8 +119,8 @@ func removeDraftAndAlphaOperationsDiffs(diffReport *diff.Diff, result Changes, o source := (*operationsSources)[pathDiff.Revision.Operations()[operation]] result = append(result, ApiChange{ Id: ParseErrorId, + Args: []any{err.Error()}, Level: ERR, - Text: fmt.Sprintf("parsing error %s", err.Error()), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -162,8 +135,8 @@ func removeDraftAndAlphaOperationsDiffs(diffReport *diff.Diff, result Changes, o revisionStability == "" && baseStability != "" { result = append(result, ApiChange{ Id: APIStabilityDecreasedId, + Args: []any{baseStability, revisionStability}, Level: ERR, - Text: fmt.Sprintf("stability level decreased from '%s' to '%s'", baseStability, revisionStability), Operation: operation, OperationId: operationItem.Revision.OperationID, Path: path, @@ -179,7 +152,8 @@ func removeDraftAndAlphaOperationsDiffs(diffReport *diff.Diff, result Changes, o return result } -func newParsingError(result Changes, +func newParsingError(config *Config, + result Changes, err error, operation string, operationItem *openapi3.Operation, @@ -187,8 +161,8 @@ func newParsingError(result Changes, source string) Changes { result = append(result, ApiChange{ Id: ParseErrorId, + Args: []any{err.Error()}, Level: ERR, - Text: fmt.Sprintf("parsing error %s", err.Error()), Operation: operation, OperationId: operationItem.OperationID, Path: path, diff --git a/checker/checker_breaking_property_test.go b/checker/checker_breaking_property_test.go index c4b0935c..7884da3d 100644 --- a/checker/checker_breaking_property_test.go +++ b/checker/checker_breaking_property_test.go @@ -394,14 +394,12 @@ func TestBreaking_ReqBodyDeleteRequiredProperty2(t *testing.T) { require.NoError(t, err) errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Contains(t, errs, checker.ApiChange{ - Id: checker.RequestPropertyRemovedId, - Text: "removed the request property 'roleAssignments/items/role'", - Comment: "", - Level: checker.WARN, - Operation: "POST", - OperationId: "", - Path: "/api/roleMappings", - Source: "../data/required-properties/request-property-items-2.yaml", + Id: checker.RequestPropertyRemovedId, + Args: []any{"roleAssignments/items/role"}, + Level: checker.WARN, + Operation: "POST", + Path: "/api/roleMappings", + Source: "../data/required-properties/request-property-items-2.yaml", }) } diff --git a/checker/checker_breaking_request_type_changed_test.go b/checker/checker_breaking_request_type_changed_test.go index 588b6894..1cf169ac 100644 --- a/checker/checker_breaking_request_type_changed_test.go +++ b/checker/checker_breaking_request_type_changed_test.go @@ -25,7 +25,7 @@ func TestBreaking_ReqTypeStringToNumber(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.RequestBodyTypeChangedId, errs[0].GetId()) - require.Equal(t, "the request's body type/format changed from 'string'/'none' to 'number'/'none'", errs[0].GetText()) + require.Equal(t, "the request's body type/format changed from 'string'/'' to 'number'/''", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: changing request's body schema type from number to string is breaking @@ -45,7 +45,7 @@ func TestBreaking_ReqTypeNumberToString(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.RequestBodyTypeChangedId, errs[0].GetId()) - require.Equal(t, "the request's body type/format changed from 'number'/'none' to 'string'/'none'", errs[0].GetText()) + require.Equal(t, "the request's body type/format changed from 'number'/'' to 'string'/''", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: changing request's body schema type from number to integer is breaking @@ -65,7 +65,7 @@ func TestBreaking_ReqTypeNumberToInteger(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.RequestBodyTypeChangedId, errs[0].GetId()) - require.Equal(t, "the request's body type/format changed from 'number'/'none' to 'integer'/'none'", errs[0].GetText()) + require.Equal(t, "the request's body type/format changed from 'number'/'' to 'integer'/''", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: changing request's body schema type from integer to number is not breaking @@ -104,5 +104,5 @@ func TestBreaking_ReqTypeNumberToInt32(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.RequestBodyTypeChangedId, errs[0].GetId()) - require.Equal(t, "the request's body type/format changed from 'number'/'none' to 'integer'/'int32'", errs[0].GetText()) + require.Equal(t, "the request's body type/format changed from 'number'/'' to 'integer'/'int32'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } diff --git a/checker/checker_breaking_response_type_changed_test.go b/checker/checker_breaking_response_type_changed_test.go index a9a9e2eb..2dbe4ea8 100644 --- a/checker/checker_breaking_response_type_changed_test.go +++ b/checker/checker_breaking_response_type_changed_test.go @@ -25,7 +25,7 @@ func TestBreaking_RespTypeStringToNumber(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.ResponseBodyTypeChangedId, errs[0].GetId()) - require.Equal(t, "the response's body type/format changed from 'string'/'none' to 'number'/'none' for status '200'", errs[0].GetText()) + require.Equal(t, "the response's body type/format changed from 'string'/'' to 'number'/'' for status '200'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: changing response's body schema type from number to string is breaking @@ -45,7 +45,7 @@ func TestBreaking_RespTypeNumberToString(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.ResponseBodyTypeChangedId, errs[0].GetId()) - require.Equal(t, "the response's body type/format changed from 'number'/'none' to 'string'/'none' for status '200'", errs[0].GetText()) + require.Equal(t, "the response's body type/format changed from 'number'/'' to 'string'/'' for status '200'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: changing response's body schema type from number to integer is not breaking @@ -83,7 +83,7 @@ func TestBreaking_RespTypeIntegerToNumber(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.ResponseBodyTypeChangedId, errs[0].GetId()) - require.Equal(t, "the response's body type/format changed from 'integer'/'none' to 'number'/'none' for status '200'", errs[0].GetText()) + require.Equal(t, "the response's body type/format changed from 'integer'/'' to 'number'/'' for status '200'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: changing response's body schema type from number/none to integer/int32 is not breaking @@ -118,5 +118,5 @@ func TestBreaking_RespTypeChanged(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, "response-property-type-changed", errs[0].GetId()) - require.Equal(t, "the response's property type/format changed from 'string'/'none' to 'integer'/'int32' for status '200'", errs[0].GetText()) + require.Equal(t, "the response's property type/format changed from 'string'/'' to 'integer'/'int32' for status '200'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } diff --git a/checker/checker_breaking_test.go b/checker/checker_breaking_test.go index 3e0f080b..4381cb46 100644 --- a/checker/checker_breaking_test.go +++ b/checker/checker_breaking_test.go @@ -199,8 +199,7 @@ func TestBreaking_HeaderParamRequiredEnabled(t *testing.T) { require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterBecomeRequiredId, - Text: "the 'header' request parameter 'network-policies' became required", - Comment: "", + Args: []any{"header", "network-policies"}, Level: checker.ERR, Operation: "GET", Path: "/api/{domain}/{project}/install-command", @@ -549,7 +548,7 @@ func TestBreaking_ModifyRequiredOptionalParamDefaultValue(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.RequestParameterDefaultValueChangedId, errs[0].GetId()) - require.Equal(t, "for the 'header' request parameter 'network-policies', default value was changed from 'X' to 'Y'", errs[0].GetText()) + require.Equal(t, "for the 'header' request parameter 'network-policies', default value was changed from 'X' to 'Y'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: setting the default value of an optional request parameter is breaking @@ -567,7 +566,7 @@ func TestBreaking_SettingOptionalParamDefaultValue(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, checker.RequestParameterDefaultValueAddedId, errs[0].GetId()) - require.Equal(t, "for the 'header' request parameter 'network-policies', default value 'Y' was added", errs[0].GetText()) + require.Equal(t, "for the 'header' request parameter 'network-policies', default value 'Y' was added", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: removing the default value of an optional request parameter is breaking @@ -585,7 +584,7 @@ func TestBreaking_RemovingOptionalParamDefaultValue(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Len(t, errs, 1) require.Equal(t, "request-parameter-default-value-removed", errs[0].GetId()) - require.Equal(t, "for the 'header' request parameter 'network-policies', default value 'Y' was removed", errs[0].GetText()) + require.Equal(t, "for the 'header' request parameter 'network-policies', default value 'Y' was removed", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: modifying the default value of a required request parameter is not breaking @@ -627,9 +626,9 @@ func TestBreaking_SchemaRemoved(t *testing.T) { } require.NotEmpty(t, errs) require.Equal(t, checker.APISchemasRemovedId, errs[0].GetId()) - require.Equal(t, "removed the schema 'network-policies'", errs[0].GetText()) + require.Equal(t, "removed the schema 'network-policies'", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) require.Equal(t, checker.APISchemasRemovedId, errs[1].GetId()) - require.Equal(t, "removed the schema 'rules'", errs[1].GetText()) + require.Equal(t, "removed the schema 'rules'", errs[1].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: removing a media type from request body is breaking @@ -645,7 +644,7 @@ func TestBreaking_RequestBodyMediaTypeRemoved(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.NotEmpty(t, errs) require.Equal(t, "request-body-media-type-removed", errs[0].GetId()) - require.Equal(t, "removed the media type application/json from the request body", errs[0].GetText()) + require.Equal(t, "removed the media type 'application/json' from the request body", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: removing 'anyOf' schema from the request body or request body property is breaking @@ -663,11 +662,11 @@ func TestBreaking_RequestPropertyAnyOfRemoved(t *testing.T) { require.Equal(t, checker.RequestBodyAnyOfRemovedId, errs[0].GetId()) require.Equal(t, checker.ERR, errs[0].GetLevel()) - require.Equal(t, "removed 'Rabbit' from the request body 'anyOf' list", errs[0].GetText()) + require.Equal(t, "removed 'Rabbit' from the request body 'anyOf' list", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) require.Equal(t, checker.RequestPropertyAnyOfRemovedId, errs[1].GetId()) require.Equal(t, checker.ERR, errs[1].GetLevel()) - require.Equal(t, "removed 'Breed3' from the '/anyOf[#/components/schemas/Dog]/breed' request property 'anyOf' list", errs[1].GetText()) + require.Equal(t, "removed 'Breed3' from the '/anyOf[#/components/schemas/Dog]/breed' request property 'anyOf' list", errs[1].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: removing 'oneOf' schema from the request body or request body property is breaking @@ -684,11 +683,11 @@ func TestBreaking_RequestPropertyOneOfRemoved(t *testing.T) { require.Len(t, errs, 2) require.Equal(t, checker.RequestBodyOneOfRemovedId, errs[0].GetId()) require.Equal(t, checker.ERR, errs[0].GetLevel()) - require.Equal(t, "removed 'Rabbit' from the request body 'oneOf' list", errs[0].GetText()) + require.Equal(t, "removed 'Rabbit' from the request body 'oneOf' list", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) require.Equal(t, checker.RequestPropertyOneOfRemovedId, errs[1].GetId()) require.Equal(t, checker.ERR, errs[1].GetLevel()) - require.Equal(t, "removed 'Breed3' from the '/oneOf[#/components/schemas/Dog]/breed' request property 'oneOf' list", errs[1].GetText()) + require.Equal(t, "removed 'Breed3' from the '/oneOf[#/components/schemas/Dog]/breed' request property 'oneOf' list", errs[1].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: adding 'allOf' subschema to the request body or request body property is breaking @@ -706,11 +705,11 @@ func TestBreaking_RequestPropertyAllOfAdded(t *testing.T) { require.Equal(t, checker.RequestBodyAllOfAddedId, errs[0].GetId()) require.Equal(t, checker.ERR, errs[0].GetLevel()) - require.Equal(t, "added 'Rabbit' to the request body 'allOf' list", errs[0].GetText()) + require.Equal(t, "added 'Rabbit' to the request body 'allOf' list", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) require.Equal(t, checker.RequestPropertyAllOfAddedId, errs[1].GetId()) require.Equal(t, checker.ERR, errs[1].GetLevel()) - require.Equal(t, "added 'Breed3' to the '/allOf[#/components/schemas/Dog]/breed' request property 'allOf' list", errs[1].GetText()) + require.Equal(t, "added 'Breed3' to the '/allOf[#/components/schemas/Dog]/breed' request property 'allOf' list", errs[1].GetUncolorizedText(checker.NewDefaultLocalizer())) } // BC: removing 'allOf' subschema from the request body or request body property is breaking with warn @@ -728,9 +727,9 @@ func TestBreaking_RequestPropertyAllOfRemoved(t *testing.T) { require.Equal(t, checker.RequestBodyAllOfRemovedId, errs[0].GetId()) require.Equal(t, checker.WARN, errs[0].GetLevel()) - require.Equal(t, "removed 'Rabbit' from the request body 'allOf' list", errs[0].GetText()) + require.Equal(t, "removed 'Rabbit' from the request body 'allOf' list", errs[0].GetUncolorizedText(checker.NewDefaultLocalizer())) require.Equal(t, checker.RequestPropertyAllOfRemovedId, errs[1].GetId()) require.Equal(t, checker.WARN, errs[1].GetLevel()) - require.Equal(t, "removed 'Breed3' from the '/allOf[#/components/schemas/Dog]/breed' request property 'allOf' list", errs[1].GetText()) + require.Equal(t, "removed 'Breed3' from the '/allOf[#/components/schemas/Dog]/breed' request property 'allOf' list", errs[1].GetUncolorizedText(checker.NewDefaultLocalizer())) } diff --git a/checker/checker_deprecation_test.go b/checker/checker_deprecation_test.go index d749b932..ade2d0c1 100644 --- a/checker/checker_deprecation_test.go +++ b/checker/checker_deprecation_test.go @@ -22,12 +22,11 @@ func getDeprecationFile(file string) string { return fmt.Sprintf("../data/deprecation/%s", file) } -func singleCheckConfig(c checker.BackwardCompatibilityCheck) checker.Config { - return checker.Config{ +func singleCheckConfig(c checker.BackwardCompatibilityCheck) *checker.Config { + return &checker.Config{ Checks: []checker.BackwardCompatibilityCheck{c}, MinSunsetBetaDays: 31, MinSunsetStableDays: 180, - Localize: checker.NewDefaultLocalizer(), } } diff --git a/checker/checker_request_parameter_required_value_updated_test.go b/checker/checker_request_parameter_required_value_updated_test.go index 70e3dd55..2aca29dd 100644 --- a/checker/checker_request_parameter_required_value_updated_test.go +++ b/checker/checker_request_parameter_required_value_updated_test.go @@ -23,8 +23,7 @@ func TestBreaking_HeaderParamBecameRequired(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterBecomeRequiredId, - Text: "the 'header' request parameter 'network-policies' became required", - Comment: "", + Args: []any{"header", "network-policies"}, Level: checker.ERR, Operation: "GET", Path: "/api/{domain}/{project}/install-command", @@ -46,8 +45,7 @@ func TestBreaking_HeaderParamBecameOptional(t *testing.T) { require.Len(t, errs, 1) require.Equal(t, checker.ApiChange{ Id: checker.RequestParameterBecomeOptionalId, - Text: "the 'header' request parameter 'network-policies' became optional", - Comment: "", + Args: []any{"header", "network-policies"}, Level: checker.INFO, Operation: "GET", Path: "/api/{domain}/{project}/install-command", diff --git a/checker/checks-utils.go b/checker/checks-utils.go index 3ca8dbb5..d0dae204 100644 --- a/checker/checks-utils.go +++ b/checker/checks-utils.go @@ -4,15 +4,18 @@ import ( "fmt" "strings" - "github.com/TwiN/go-color" "github.com/getkin/kin-openapi/openapi3" "github.com/tufin/oasdiff/diff" ) -func comment(id string) string { +func commentId(id string) string { return id + "-comment" } +func descriptionId(id string) string { + return id + "-description" +} + func propertyFullName(propertyPath string, propertyNames ...string) string { propertyFullName := strings.Join(propertyNames, "/") if propertyPath != "" { @@ -21,14 +24,6 @@ func propertyFullName(propertyPath string, propertyNames ...string) string { return propertyFullName } -func ColorizedValue(arg interface{}) string { - str := interfaceToString(arg) - if IsPipedOutput() { - return fmt.Sprintf("'%s'", str) - } - return color.InBold(fmt.Sprintf("'%s'", str)) -} - func interfaceToString(arg interface{}) string { if arg == nil { return "undefined" @@ -234,10 +229,3 @@ func IsDecreased(from interface{}, to interface{}) bool { } return false } - -func empty2none(a interface{}) interface{} { - if a == nil || a == "" { - return ColorizedValue("none") - } - return ColorizedValue(a) -} diff --git a/checker/colorize.go b/checker/colorize.go new file mode 100644 index 00000000..d8b4a556 --- /dev/null +++ b/checker/colorize.go @@ -0,0 +1,58 @@ +package checker + +import ( + "fmt" + + "github.com/TwiN/go-color" +) + +type ColorMode int + +const ( + ColorAlways ColorMode = iota + ColorNever + ColorAuto + ColorInvalid +) + +func NewColorMode(color string) (ColorMode, error) { + switch color { + case "always": + return ColorAlways, nil + case "never": + return ColorNever, nil + case "auto": + return ColorAuto, nil + default: + return ColorInvalid, fmt.Errorf("invalid color mode: %s", color) + } +} + +func isColorEnabled(colorMode ColorMode) bool { + switch colorMode { + case ColorAlways: + return true + case ColorNever: + return false + case ColorAuto: + return !isPipedOutput() + default: + return false + } +} + +func colorizedValues(args []any) []any { + result := make([]any, len(args)) + for i, arg := range args { + result[i] = color.InBold(fmt.Sprintf("'%s'", interfaceToString(arg))) + } + return result +} + +func quotedValues(args []any) []any { + result := make([]any, len(args)) + for i, arg := range args { + result[i] = fmt.Sprintf("'%s'", interfaceToString(arg)) + } + return result +} diff --git a/checker/colorize_test.go b/checker/colorize_test.go new file mode 100644 index 00000000..9ca29bd3 --- /dev/null +++ b/checker/colorize_test.go @@ -0,0 +1,32 @@ +package checker_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/tufin/oasdiff/checker" +) + +func TestColorMode_Always(t *testing.T) { + colorMode, err := checker.NewColorMode("always") + require.NoError(t, err) + require.Equal(t, colorMode, checker.ColorAlways) +} + +func TestColorMode_Never(t *testing.T) { + colorMode, err := checker.NewColorMode("never") + require.NoError(t, err) + require.Equal(t, colorMode, checker.ColorNever) +} + +func TestColorMode_Auto(t *testing.T) { + colorMode, err := checker.NewColorMode("auto") + require.NoError(t, err) + require.Equal(t, colorMode, checker.ColorAuto) +} + +func TestColorMode_Invalid(t *testing.T) { + colorMode, err := checker.NewColorMode("invalid") + require.Error(t, err) + require.Equal(t, colorMode, checker.ColorInvalid) +} diff --git a/checker/component_change.go b/checker/component_change.go index 6a9c0736..f9ebc90d 100644 --- a/checker/component_change.go +++ b/checker/component_change.go @@ -10,10 +10,9 @@ import ( // ComponentChange represnts a change in the Components Section: https://swagger.io/docs/specification/components/ type ComponentChange struct { Id string `json:"id,omitempty" yaml:"id,omitempty"` - Text string `json:"text,omitempty" yaml:"text,omitempty"` + Args []any `json:"-" yaml:"-"` Comment string `json:"comment,omitempty" yaml:"comment,omitempty"` Level Level `json:"level" yaml:"level"` - Source string `json:"source,omitempty" yaml:"source,omitempty"` Component string `json:"component,omitempty" yaml:"component,omitempty"` SourceFile string `json:"-" yaml:"-"` @@ -23,12 +22,16 @@ type ComponentChange struct { SourceColumnEnd int `json:"-" yaml:"-"` } +func (c ComponentChange) GetSection() string { + return "components" +} + func (c ComponentChange) IsBreaking() bool { return c.GetLevel().IsBreaking() } -func (c ComponentChange) MatchIgnore(ignorePath, ignoreLine string) bool { - return strings.Contains(ignoreLine, strings.ToLower(GetUncolorizedText(c))) && +func (c ComponentChange) MatchIgnore(ignorePath, ignoreLine string, l Localizer) bool { + return strings.Contains(ignoreLine, strings.ToLower(c.GetUncolorizedText(l))) && strings.Contains(ignoreLine, "components") } @@ -36,12 +39,20 @@ func (c ComponentChange) GetId() string { return c.Id } -func (c ComponentChange) GetText() string { - return c.Text +func (c ComponentChange) GetText(l Localizer) string { + return l(c.Id, colorizedValues(c.Args)...) +} + +func (c ComponentChange) GetArgs() []any { + return c.Args } -func (c ComponentChange) GetComment() string { - return c.Comment +func (c ComponentChange) GetUncolorizedText(l Localizer) string { + return l(c.Id, quotedValues(c.Args)...) +} + +func (c ComponentChange) GetComment(l Localizer) string { + return l(c.Comment) } func (c ComponentChange) GetLevel() Level { @@ -60,6 +71,10 @@ func (ComponentChange) GetPath() string { return "" } +func (c ComponentChange) GetSource() string { + return "" +} + func (c ComponentChange) GetSourceFile() string { return c.SourceFile } @@ -80,22 +95,20 @@ func (c ComponentChange) GetSourceColumnEnd() int { return c.SourceColumnEnd } -func (c ComponentChange) LocalizedError(l Localizer) string { - return fmt.Sprintf("%s, %s components/%s %s [%s]. %s", c.Level, l("in"), c.Component, c.Text, c.Id, c.Comment) -} +func (c ComponentChange) SingleLineError(l Localizer, colorMode ColorMode) string { + const format = "%s, %s components/%s %s [%s]. %s" -func (c ComponentChange) PrettyErrorText(l Localizer) string { - if IsPipedOutput() { - return c.LocalizedError(l) + if isColorEnabled(colorMode) { + return fmt.Sprintf(format, c.Level.PrettyString(), l("in"), c.Component, c.GetText(l), color.InYellow(c.Id), c.GetComment(l)) } - - comment := "" - if c.Comment != "" { - comment = fmt.Sprintf("\n\t\t%s", c.Comment) - } - return fmt.Sprintf("%s\t[%s] \t\n\t%s components/%s\n\t\t%s%s", c.Level.PrettyString(), color.InYellow(c.Id), l("in"), c.Component, c.Text, comment) + return fmt.Sprintf(format, c.Level.String(), l("in"), c.Component, c.GetUncolorizedText(l), c.Id, c.GetComment(l)) } -func (c ComponentChange) Error() string { - return fmt.Sprintf("%s, in components/%s %s [%s]. %s", c.Level, c.Component, c.Text, c.Id, c.Comment) +func (c ComponentChange) MultiLineError(l Localizer, colorMode ColorMode) string { + const format = "%s\t[%s] \t\n\t%s components/%s\n\t\t%s%s" + + if isColorEnabled(colorMode) { + return fmt.Sprintf(format, c.Level.PrettyString(), color.InYellow(c.Id), l("in"), c.Component, c.GetText(l), multiLineComment(c.GetComment(l))) + } + return fmt.Sprintf(format, c.Level.String(), c.Id, l("in"), c.Component, c.GetUncolorizedText(l), multiLineComment(c.GetComment(l))) } diff --git a/checker/component_change_test.go b/checker/component_change_test.go index c05516d8..8467ef34 100644 --- a/checker/component_change_test.go +++ b/checker/component_change_test.go @@ -8,11 +8,9 @@ import ( ) var componentChange = checker.ComponentChange{ - Id: "id", - Text: "text", + Id: "change_id", Comment: "comment", Level: checker.ERR, - Source: "source", Component: "component", SourceFile: "sourceFile", SourceLine: 1, @@ -22,25 +20,27 @@ var componentChange = checker.ComponentChange{ } func TestComponentChange(t *testing.T) { - require.Equal(t, "comment", componentChange.GetComment()) + require.Equal(t, "components", componentChange.GetSection()) + require.Equal(t, "comment", componentChange.GetComment(MockLocalizer)) require.Equal(t, "", componentChange.GetOperationId()) + require.Equal(t, "", componentChange.GetSource()) require.Equal(t, "sourceFile", componentChange.GetSourceFile()) require.Equal(t, 1, componentChange.GetSourceLine()) require.Equal(t, 2, componentChange.GetSourceLineEnd()) require.Equal(t, 3, componentChange.GetSourceColumn()) require.Equal(t, 4, componentChange.GetSourceColumnEnd()) - require.Equal(t, "error, in components/component text [id]. comment", componentChange.LocalizedError(checker.NewDefaultLocalizer())) - require.Equal(t, "error, in components/component text [id]. comment", componentChange.PrettyErrorText(checker.NewDefaultLocalizer())) - require.Equal(t, "error, in components/component text [id]. comment", componentChange.Error()) + require.Equal(t, "error, in components/component This is a breaking change. [change_id]. comment", componentChange.SingleLineError(MockLocalizer, checker.ColorNever)) + require.Equal(t, "error, in components/component This is a breaking change. [change_id]. comment", componentChange.SingleLineError(MockLocalizer, checker.ColorNever)) } func TestComponentChange_MatchIgnore(t *testing.T) { - require.True(t, componentChange.MatchIgnore("", "error, in components/component text [id]. comment")) + require.True(t, componentChange.MatchIgnore("", "error, in components/component this is a breaking change. [change_id]. comment", MockLocalizer)) } -func TestComponentChange_PrettyPiped(t *testing.T) { - piped := true - save := checker.SetPipedOutput(&piped) - defer checker.SetPipedOutput(save) - require.Equal(t, "error, in components/component text [id]. comment", componentChange.PrettyErrorText(checker.NewDefaultLocalizer())) +func TestComponentChange_SingleLineError(t *testing.T) { + require.Equal(t, "error, in components/component This is a breaking change. [change_id]. comment", componentChange.SingleLineError(MockLocalizer, checker.ColorNever)) +} + +func TestComponentChange_MultiLineError_NoColor(t *testing.T) { + require.Equal(t, "error, in components/component This is a breaking change. [change_id]. comment", componentChange.SingleLineError(MockLocalizer, checker.ColorNever)) } diff --git a/checker/component_change_unix_test.go b/checker/component_change_unix_test.go index 28862210..8505c2d6 100644 --- a/checker/component_change_unix_test.go +++ b/checker/component_change_unix_test.go @@ -9,9 +9,19 @@ import ( "github.com/tufin/oasdiff/checker" ) -func TestComponentChange_PrettyNotPipedUnix(t *testing.T) { +func TestComponentChange_SetPipedOutput_NotPiped_Unix(t *testing.T) { piped := false save := checker.SetPipedOutput(&piped) defer checker.SetPipedOutput(save) - require.Equal(t, "\x1b[31merror\x1b[0m\t[\x1b[33mid\x1b[0m] \t\n\tin components/component\n\t\ttext\n\t\tcomment", componentChange.PrettyErrorText(checker.NewDefaultLocalizer())) + require.Equal(t, "\x1b[31merror\x1b[0m\t[\x1b[33mchange_id\x1b[0m] \t\n\tin components/component\n\t\tThis is a breaking change.\n\t\tcomment", componentChange.MultiLineError(MockLocalizer, checker.ColorAuto)) +} + +func TestComponentChange_SetPipedOutput_NilPiped_Unix(t *testing.T) { + save := checker.SetPipedOutput(nil) + defer checker.SetPipedOutput(save) + require.Equal(t, "error\t[change_id] \t\n\tin components/component\n\t\tThis is a breaking change.\n\t\tcomment", componentChange.MultiLineError(MockLocalizer, checker.ColorAuto)) +} + +func TestComponentChange_SingleLineError_WithColor(t *testing.T) { + require.Equal(t, "\x1b[31merror\x1b[0m, in components/component This is a breaking change. [\x1b[33mchange_id\x1b[0m]. comment", componentChange.SingleLineError(MockLocalizer, checker.ColorAlways)) } diff --git a/checker/component_change_windows_test.go b/checker/component_change_windows_test.go index 8c26fe13..953dcdc5 100644 --- a/checker/component_change_windows_test.go +++ b/checker/component_change_windows_test.go @@ -11,5 +11,5 @@ func TestComponentChange_PrettyNotPipedWindows(t *testing.T) { piped := false save := checker.SetPipedOutput(&piped) defer checker.SetPipedOutput(save) - require.Equal(t, "error\t[id] \t\n\tin components/component\n\t\ttext\n\t\tcomment", componentChange.PrettyErrorText(checker.NewDefaultLocalizer())) + require.Equal(t, "error\t[change_id] \t\n\tin components/component\n\t\tThis is a breaking change.\n\t\tcomment", componentChange.MultiLineError(MockLocalizer, checker.ColorAuto)) } diff --git a/checker/config.go b/checker/config.go index 1566a32f..2e787293 100644 --- a/checker/config.go +++ b/checker/config.go @@ -1,39 +1,9 @@ package checker -import ( - "fmt" - - "github.com/tufin/oasdiff/checker/localizations" -) - -type Localizer func(key string, args ...interface{}) string - -func NewDefaultLocalizer() Localizer { - return NewLocalizer(localizations.LangDefault) -} - -func NewLocalizer(locale string) Localizer { - locales := localizations.New(locale, localizations.LangDefault) - - return func(originalKey string, args ...interface{}) string { - key := "messages." + originalKey - pattern := locales.Get(key) - - // if key not found, return original key - // TODO: improve localizations to return error when key not found - if pattern == key { - return originalKey - } - - return fmt.Sprintf(pattern, args...) - } -} - type Config struct { Checks []BackwardCompatibilityCheck MinSunsetBetaDays int MinSunsetStableDays int - Localize Localizer LogLevelOverrides map[string]Level } @@ -43,11 +13,3 @@ func (c *Config) getLogLevel(checkerId string, defaultLevel Level) Level { } return defaultLevel } - -func ConditionalError(isConditionSatisfied bool, defaultLevel Level) Level { - if isConditionSatisfied { - return ERR - } - - return defaultLevel -} diff --git a/checker/default_checks.go b/checker/default_checks.go index 07d875cc..1dd9bd37 100644 --- a/checker/default_checks.go +++ b/checker/default_checks.go @@ -6,11 +6,11 @@ import ( "github.com/tufin/oasdiff/utils" ) -func GetDefaultChecks() Config { +func GetDefaultChecks() *Config { return GetChecks(utils.StringList{}) } -func GetChecks(includeChecks utils.StringList) Config { +func GetChecks(includeChecks utils.StringList) *Config { return getBackwardCompatibilityCheckConfig(allChecks(), LevelOverrides(includeChecks), BetaDeprecationDays, StableDeprecationDays) } @@ -25,22 +25,21 @@ func LevelOverrides(includeChecks utils.StringList) map[string]Level { return result } -func GetAllChecks(includeChecks utils.StringList, deprecationDaysBeta int, deprecationDaysStable int) Config { +func GetAllChecks(includeChecks utils.StringList, deprecationDaysBeta int, deprecationDaysStable int) *Config { return getBackwardCompatibilityCheckConfig(allChecks(), LevelOverrides(includeChecks), deprecationDaysBeta, deprecationDaysStable) } -func getBackwardCompatibilityCheckConfig(checks []BackwardCompatibilityCheck, levelOverrides map[string]Level, minSunsetBetaDays int, minSunsetStableDays int) Config { - return Config{ +func getBackwardCompatibilityCheckConfig(checks []BackwardCompatibilityCheck, levelOverrides map[string]Level, minSunsetBetaDays int, minSunsetStableDays int) *Config { + return &Config{ Checks: checks, LogLevelOverrides: levelOverrides, MinSunsetBetaDays: minSunsetBetaDays, MinSunsetStableDays: minSunsetStableDays, - Localize: NewDefaultLocalizer(), } } func optionalChecks() map[string]BackwardCompatibilityCheck { - optionalRules := GetOptionalRules(NewDefaultLocalizer()) + optionalRules := GetOptionalRules() result := make(map[string]BackwardCompatibilityCheck, len(optionalRules)) for _, rule := range optionalRules { @@ -66,7 +65,7 @@ func defaultChecks() []BackwardCompatibilityCheck { result := []BackwardCompatibilityCheck{} m := utils.StringSet{} - for _, rule := range GetRequiredRules(NewDefaultLocalizer()) { + for _, rule := range GetRequiredRules() { pStr := fmt.Sprintf("%v", rule.Handler) if !m.Contains(pStr) { m.Add(pStr) diff --git a/checker/ignore.go b/checker/ignore.go index f7383c6f..12760849 100644 --- a/checker/ignore.go +++ b/checker/ignore.go @@ -24,7 +24,7 @@ func ignoreLinePath(ignoreLine string) string { return ignoreComponents[pathIndex] } -func ProcessIgnoredBackwardCompatibilityErrors(level Level, errs Changes, ignoreFile string) (Changes, error) { +func ProcessIgnoredBackwardCompatibilityErrors(level Level, errs Changes, ignoreFile string, l Localizer) (Changes, error) { result := make(Changes, 0) ignore, err := os.Open(ignoreFile) @@ -44,7 +44,7 @@ func ProcessIgnoredBackwardCompatibilityErrors(level Level, errs Changes, ignore continue } - if err.MatchIgnore(ignorePath, ignoreLine) { + if err.MatchIgnore(ignorePath, ignoreLine, l) { ignoredErrs[errIndex] = true } } diff --git a/checker/ignore_test.go b/checker/ignore_test.go index d0d3cfd1..4c80fe46 100644 --- a/checker/ignore_test.go +++ b/checker/ignore_test.go @@ -18,7 +18,7 @@ func TestIgnore(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Equal(t, 6, len(errs)) - errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example.txt") + errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example.txt", checker.NewDefaultLocalizer()) require.NoError(t, err) require.Equal(t, 5, len(errs)) } @@ -32,7 +32,7 @@ func TestIgnoreSubpath(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Equal(t, 3, len(errs)) - errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example-2.txt") + errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example-2.txt", checker.NewDefaultLocalizer()) require.NoError(t, err) require.Equal(t, 0, len(errs)) } @@ -46,7 +46,7 @@ func TestIgnoreOnlyIncludedSubpaths(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), d, osm) require.Equal(t, 2, len(errs)) // detect new and newest were deleted - errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example-3.txt") + errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example-3.txt", checker.NewDefaultLocalizer()) require.NoError(t, err) require.Equal(t, 1, len(errs)) require.IsType(t, checker.ApiChange{}, errs[0]) @@ -63,7 +63,7 @@ func TestIgnoreComponent(t *testing.T) { errs := checker.CheckBackwardCompatibility(checker.GetChecks(utils.StringList{checker.APISchemasRemovedId}), d, osm) require.Equal(t, 8, len(errs)) - errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example.txt") + errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example.txt", checker.NewDefaultLocalizer()) require.NoError(t, err) require.Equal(t, 5, len(errs)) } diff --git a/checker/level.go b/checker/level.go index f51810a2..a80ecd69 100644 --- a/checker/level.go +++ b/checker/level.go @@ -26,6 +26,13 @@ func NewLevel(level string) (Level, error) { return INFO, fmt.Errorf("invalid level %s", level) } +func (level Level) StringCond(colorMode ColorMode) string { + if isColorEnabled(colorMode) { + return level.PrettyString() + } + return level.String() +} + func (level Level) String() string { switch level { case ERR: @@ -39,15 +46,7 @@ func (level Level) String() string { } } -func (level Level) IsBreaking() bool { - return level == ERR || level == WARN -} - func (level Level) PrettyString() string { - if IsPipedOutput() { - return level.String() - } - levelName := level.String() switch level { case ERR: @@ -60,3 +59,15 @@ func (level Level) PrettyString() string { return color.InGray(levelName) } } + +func (level Level) IsBreaking() bool { + return level == ERR || level == WARN +} + +func conditionalError(isConditionSatisfied bool, defaultLevel Level) Level { + if isConditionSatisfied { + return ERR + } + + return defaultLevel +} diff --git a/checker/localizer.go b/checker/localizer.go new file mode 100644 index 00000000..547bc9de --- /dev/null +++ b/checker/localizer.go @@ -0,0 +1,30 @@ +package checker + +import ( + "fmt" + + "github.com/tufin/oasdiff/checker/localizations" +) + +type Localizer func(key string, args ...interface{}) string + +func NewDefaultLocalizer() Localizer { + return NewLocalizer(localizations.LangDefault) +} + +func NewLocalizer(locale string) Localizer { + locales := localizations.New(locale, localizations.LangDefault) + + return func(originalKey string, args ...interface{}) string { + key := "messages." + originalKey + pattern := locales.Get(key) + + // if key not found, return original key + // TODO: improve localizations to return error when key not found + if pattern == key { + return originalKey + } + + return fmt.Sprintf(pattern, args...) + } +} diff --git a/checker/piped_output.go b/checker/piped_output.go new file mode 100644 index 00000000..e2736d68 --- /dev/null +++ b/checker/piped_output.go @@ -0,0 +1,22 @@ +package checker + +import "os" + +var pipedOutput *bool + +func SetPipedOutput(val *bool) *bool { + save := pipedOutput + pipedOutput = val + return save +} + +func isPipedOutput() bool { + if pipedOutput != nil { + return *pipedOutput + } + + fi, _ := os.Stdout.Stat() + a := (fi.Mode() & os.ModeCharDevice) == 0 + pipedOutput = &a + return *pipedOutput +} diff --git a/checker/rules.go b/checker/rules.go index 06ce91a4..5fdef989 100644 --- a/checker/rules.go +++ b/checker/rules.go @@ -1,369 +1,373 @@ package checker -func getDescription(l Localizer, id string) string { - return l(id + "-description") +type BackwardCompatibilityRule struct { + Id string + Level Level + Description string + Required bool + Handler BackwardCompatibilityCheck `json:"-" yaml:"-"` } -func newBackwardCompatibilityRule(l Localizer, id string, level Level, required bool, handler BackwardCompatibilityCheck) BackwardCompatibilityRule { +func newBackwardCompatibilityRule(id string, level Level, required bool, handler BackwardCompatibilityCheck) BackwardCompatibilityRule { return BackwardCompatibilityRule{ Id: id, Level: level, - Description: getDescription(l, id), + Description: descriptionId(id), Required: required, Handler: handler, } } -func GetAllRules(l Localizer) []BackwardCompatibilityRule { +func GetAllRules() []BackwardCompatibilityRule { return []BackwardCompatibilityRule{ // APIAddedCheck - newBackwardCompatibilityRule(l, EndpointAddedId, INFO, true, APIAddedCheck), + newBackwardCompatibilityRule(EndpointAddedId, INFO, true, APIAddedCheck), // APIComponentsSecurityUpdatedCheck - newBackwardCompatibilityRule(l, APIComponentsSecurityRemovedId, INFO, true, APIComponentsSecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIComponentsSecurityAddedId, INFO, true, APIComponentsSecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIComponentsSecurityComponentOauthUrlUpdatedId, INFO, true, APIComponentsSecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIComponentsSecurityTypeUpdatedId, INFO, true, APIComponentsSecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIComponentsSecurityOauthTokenUrlUpdatedId, INFO, true, APIComponentsSecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIComponentSecurityOauthScopeAddedId, INFO, true, APIComponentsSecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIComponentSecurityOauthScopeRemovedId, INFO, true, APIComponentsSecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIComponentSecurityOauthScopeUpdatedId, INFO, true, APIComponentsSecurityUpdatedCheck), + newBackwardCompatibilityRule(APIComponentsSecurityRemovedId, INFO, true, APIComponentsSecurityUpdatedCheck), + newBackwardCompatibilityRule(APIComponentsSecurityAddedId, INFO, true, APIComponentsSecurityUpdatedCheck), + newBackwardCompatibilityRule(APIComponentsSecurityComponentOauthUrlUpdatedId, INFO, true, APIComponentsSecurityUpdatedCheck), + newBackwardCompatibilityRule(APIComponentsSecurityTypeUpdatedId, INFO, true, APIComponentsSecurityUpdatedCheck), + newBackwardCompatibilityRule(APIComponentsSecurityOauthTokenUrlUpdatedId, INFO, true, APIComponentsSecurityUpdatedCheck), + newBackwardCompatibilityRule(APIComponentSecurityOauthScopeAddedId, INFO, true, APIComponentsSecurityUpdatedCheck), + newBackwardCompatibilityRule(APIComponentSecurityOauthScopeRemovedId, INFO, true, APIComponentsSecurityUpdatedCheck), + newBackwardCompatibilityRule(APIComponentSecurityOauthScopeUpdatedId, INFO, true, APIComponentsSecurityUpdatedCheck), // APISecurityUpdatedCheck - newBackwardCompatibilityRule(l, APISecurityRemovedCheckId, INFO, true, APISecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APISecurityAddedCheckId, INFO, true, APISecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APISecurityScopeAddedId, INFO, true, APISecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APISecurityScopeRemovedId, INFO, true, APISecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIGlobalSecurityRemovedCheckId, INFO, true, APISecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIGlobalSecurityAddedCheckId, INFO, true, APISecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIGlobalSecurityScopeAddedId, INFO, true, APISecurityUpdatedCheck), - newBackwardCompatibilityRule(l, APIGlobalSecurityScopeRemovedId, INFO, true, APISecurityUpdatedCheck), + newBackwardCompatibilityRule(APISecurityRemovedCheckId, INFO, true, APISecurityUpdatedCheck), + newBackwardCompatibilityRule(APISecurityAddedCheckId, INFO, true, APISecurityUpdatedCheck), + newBackwardCompatibilityRule(APISecurityScopeAddedId, INFO, true, APISecurityUpdatedCheck), + newBackwardCompatibilityRule(APISecurityScopeRemovedId, INFO, true, APISecurityUpdatedCheck), + newBackwardCompatibilityRule(APIGlobalSecurityRemovedCheckId, INFO, true, APISecurityUpdatedCheck), + newBackwardCompatibilityRule(APIGlobalSecurityAddedCheckId, INFO, true, APISecurityUpdatedCheck), + newBackwardCompatibilityRule(APIGlobalSecurityScopeAddedId, INFO, true, APISecurityUpdatedCheck), + newBackwardCompatibilityRule(APIGlobalSecurityScopeRemovedId, INFO, true, APISecurityUpdatedCheck), // Stability Descreased Check is run as part of CheckBackwardCompatibility - newBackwardCompatibilityRule(l, APIStabilityDecreasedId, ERR, true, nil), + newBackwardCompatibilityRule(APIStabilityDecreasedId, ERR, true, nil), // APIDeprecationCheck - newBackwardCompatibilityRule(l, EndpointReactivatedId, INFO, true, APIDeprecationCheck), - newBackwardCompatibilityRule(l, APIDeprecatedSunsetParseId, ERR, true, APIDeprecationCheck), - newBackwardCompatibilityRule(l, ParseErrorId, ERR, true, APIDeprecationCheck), - newBackwardCompatibilityRule(l, APISunsetDateTooSmallId, ERR, true, APIDeprecationCheck), - newBackwardCompatibilityRule(l, EndpointDeprecatedId, INFO, true, APIDeprecationCheck), + newBackwardCompatibilityRule(EndpointReactivatedId, INFO, true, APIDeprecationCheck), + newBackwardCompatibilityRule(APIDeprecatedSunsetParseId, ERR, true, APIDeprecationCheck), + newBackwardCompatibilityRule(ParseErrorId, ERR, true, APIDeprecationCheck), + newBackwardCompatibilityRule(APISunsetDateTooSmallId, ERR, true, APIDeprecationCheck), + newBackwardCompatibilityRule(EndpointDeprecatedId, INFO, true, APIDeprecationCheck), // APIRemovedCheck - newBackwardCompatibilityRule(l, APIPathRemovedWithoutDeprecationId, ERR, true, APIRemovedCheck), - newBackwardCompatibilityRule(l, APIPathSunsetParseId, ERR, true, APIRemovedCheck), - newBackwardCompatibilityRule(l, APIPathRemovedBeforeSunsetId, ERR, true, APIRemovedCheck), - newBackwardCompatibilityRule(l, APIRemovedWithoutDeprecationId, ERR, true, APIRemovedCheck), - newBackwardCompatibilityRule(l, APIRemovedBeforeSunsetId, ERR, true, APIRemovedCheck), + newBackwardCompatibilityRule(APIPathRemovedWithoutDeprecationId, ERR, true, APIRemovedCheck), + newBackwardCompatibilityRule(APIPathSunsetParseId, ERR, true, APIRemovedCheck), + newBackwardCompatibilityRule(APIPathRemovedBeforeSunsetId, ERR, true, APIRemovedCheck), + newBackwardCompatibilityRule(APIRemovedWithoutDeprecationId, ERR, true, APIRemovedCheck), + newBackwardCompatibilityRule(APIRemovedBeforeSunsetId, ERR, true, APIRemovedCheck), // APISunsetChangedCheck - newBackwardCompatibilityRule(l, APISunsetDeletedId, ERR, true, APISunsetChangedCheck), - newBackwardCompatibilityRule(l, APISunsetDateChangedTooSmallId, ERR, true, APISunsetChangedCheck), + newBackwardCompatibilityRule(APISunsetDeletedId, ERR, true, APISunsetChangedCheck), + newBackwardCompatibilityRule(APISunsetDateChangedTooSmallId, ERR, true, APISunsetChangedCheck), // AddedRequiredRequestBodyCheck - newBackwardCompatibilityRule(l, AddedRequiredRequestBodyId, ERR, true, AddedRequiredRequestBodyCheck), + newBackwardCompatibilityRule(AddedRequiredRequestBodyId, ERR, true, AddedRequiredRequestBodyCheck), // NewRequestNonPathDefaultParameterCheck - newBackwardCompatibilityRule(l, NewRequiredRequestDefaultParameterToExistingPathId, ERR, true, NewRequestNonPathDefaultParameterCheck), - newBackwardCompatibilityRule(l, NewOptionalRequestDefaultParameterToExistingPathId, INFO, true, NewRequestNonPathDefaultParameterCheck), + newBackwardCompatibilityRule(NewRequiredRequestDefaultParameterToExistingPathId, ERR, true, NewRequestNonPathDefaultParameterCheck), + newBackwardCompatibilityRule(NewOptionalRequestDefaultParameterToExistingPathId, INFO, true, NewRequestNonPathDefaultParameterCheck), // NewRequestNonPathParameterCheck - newBackwardCompatibilityRule(l, NewRequiredRequestParameterId, ERR, true, NewRequestNonPathParameterCheck), - newBackwardCompatibilityRule(l, NewOptionalRequestParameterId, INFO, true, NewRequestNonPathParameterCheck), + newBackwardCompatibilityRule(NewRequiredRequestParameterId, ERR, true, NewRequestNonPathParameterCheck), + newBackwardCompatibilityRule(NewOptionalRequestParameterId, INFO, true, NewRequestNonPathParameterCheck), // NewRequestPathParameterCheck - newBackwardCompatibilityRule(l, NewRequestPathParameterId, ERR, true, NewRequestPathParameterCheck), + newBackwardCompatibilityRule(NewRequestPathParameterId, ERR, true, NewRequestPathParameterCheck), // NewRequiredRequestHeaderPropertyCheck - newBackwardCompatibilityRule(l, NewRequiredRequestHeaderPropertyId, ERR, true, NewRequiredRequestHeaderPropertyCheck), + newBackwardCompatibilityRule(NewRequiredRequestHeaderPropertyId, ERR, true, NewRequiredRequestHeaderPropertyCheck), // RequestBodyBecameEnumCheck - newBackwardCompatibilityRule(l, RequestBodyBecameEnumId, ERR, true, RequestBodyBecameEnumCheck), + newBackwardCompatibilityRule(RequestBodyBecameEnumId, ERR, true, RequestBodyBecameEnumCheck), // RequestBodyMediaTypeChangedCheck - newBackwardCompatibilityRule(l, RequestBodyMediaTypeAddedId, INFO, true, RequestBodyMediaTypeChangedCheck), - newBackwardCompatibilityRule(l, RequestBodyMediaTypeRemovedId, ERR, true, RequestBodyMediaTypeChangedCheck), + newBackwardCompatibilityRule(RequestBodyMediaTypeAddedId, INFO, true, RequestBodyMediaTypeChangedCheck), + newBackwardCompatibilityRule(RequestBodyMediaTypeRemovedId, ERR, true, RequestBodyMediaTypeChangedCheck), // RequestBodyRequiredUpdatedCheck - newBackwardCompatibilityRule(l, RequestBodyBecameOptionalId, INFO, true, RequestBodyRequiredUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyBecameRequiredId, ERR, true, RequestBodyRequiredUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyBecameOptionalId, INFO, true, RequestBodyRequiredUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyBecameRequiredId, ERR, true, RequestBodyRequiredUpdatedCheck), // RequestDiscriminatorUpdatedCheck - newBackwardCompatibilityRule(l, RequestBodyDiscriminatorAddedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyDiscriminatorRemovedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyDiscriminatorPropertyNameChangedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyDiscriminatorMappingAddedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyDiscriminatorMappingDeletedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyDiscriminatorMappingChangedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDiscriminatorAddedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDiscriminatorRemovedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDiscriminatorPropertyNameChangedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDiscriminatorMappingAddedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDiscriminatorMappingDeletedId, INFO, true, RequestDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDiscriminatorMappingChangedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyDiscriminatorAddedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyDiscriminatorRemovedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyDiscriminatorPropertyNameChangedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyDiscriminatorMappingAddedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyDiscriminatorMappingDeletedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyDiscriminatorMappingChangedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyDiscriminatorAddedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyDiscriminatorRemovedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyDiscriminatorPropertyNameChangedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyDiscriminatorMappingAddedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyDiscriminatorMappingDeletedId, INFO, true, RequestDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyDiscriminatorMappingChangedId, INFO, true, RequestDiscriminatorUpdatedCheck), // RequestHeaderPropertyBecameEnumCheck - newBackwardCompatibilityRule(l, RequestHeaderPropertyBecameEnumId, ERR, true, RequestHeaderPropertyBecameEnumCheck), + newBackwardCompatibilityRule(RequestHeaderPropertyBecameEnumId, ERR, true, RequestHeaderPropertyBecameEnumCheck), // RequestHeaderPropertyBecameRequiredCheck - newBackwardCompatibilityRule(l, RequestHeaderPropertyBecameRequiredId, ERR, true, RequestHeaderPropertyBecameRequiredCheck), + newBackwardCompatibilityRule(RequestHeaderPropertyBecameRequiredId, ERR, true, RequestHeaderPropertyBecameRequiredCheck), // RequestParameterBecameEnumCheck - newBackwardCompatibilityRule(l, RequestParameterBecameEnumId, ERR, true, RequestParameterBecameEnumCheck), + newBackwardCompatibilityRule(RequestParameterBecameEnumId, ERR, true, RequestParameterBecameEnumCheck), // RequestParameterDefaultValueChangedCheck - newBackwardCompatibilityRule(l, RequestParameterDefaultValueChangedId, ERR, true, RequestParameterDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, RequestParameterDefaultValueAddedId, ERR, true, RequestParameterDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, RequestParameterDefaultValueRemovedId, ERR, true, RequestParameterDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestParameterDefaultValueChangedId, ERR, true, RequestParameterDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestParameterDefaultValueAddedId, ERR, true, RequestParameterDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestParameterDefaultValueRemovedId, ERR, true, RequestParameterDefaultValueChangedCheck), // RequestParameterEnumValueUpdatedCheck - newBackwardCompatibilityRule(l, RequestParameterEnumValueAddedId, INFO, true, RequestParameterEnumValueUpdatedCheck), - newBackwardCompatibilityRule(l, RequestParameterEnumValueRemovedId, ERR, true, RequestParameterEnumValueUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterEnumValueAddedId, INFO, true, RequestParameterEnumValueUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterEnumValueRemovedId, ERR, true, RequestParameterEnumValueUpdatedCheck), // RequestParameterMaxItemsUpdatedCheck - newBackwardCompatibilityRule(l, RequestParameterMaxItemsIncreasedId, INFO, true, RequestParameterMaxItemsUpdatedCheck), - newBackwardCompatibilityRule(l, RequestParameterMaxItemsDecreasedId, ERR, true, RequestParameterMaxItemsUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMaxItemsIncreasedId, INFO, true, RequestParameterMaxItemsUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMaxItemsDecreasedId, ERR, true, RequestParameterMaxItemsUpdatedCheck), // RequestParameterMaxLengthSetCheck - newBackwardCompatibilityRule(l, RequestParameterMaxLengthSetId, WARN, true, RequestParameterMaxLengthSetCheck), + newBackwardCompatibilityRule(RequestParameterMaxLengthSetId, WARN, true, RequestParameterMaxLengthSetCheck), // RequestParameterMaxLengthUpdatedCheck - newBackwardCompatibilityRule(l, RequestParameterMaxLengthIncreasedId, INFO, true, RequestParameterMaxLengthUpdatedCheck), - newBackwardCompatibilityRule(l, RequestParameterMaxLengthDecreasedId, ERR, true, RequestParameterMaxLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMaxLengthIncreasedId, INFO, true, RequestParameterMaxLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMaxLengthDecreasedId, ERR, true, RequestParameterMaxLengthUpdatedCheck), // RequestParameterMaxSetCheck - newBackwardCompatibilityRule(l, RequestParameterMaxSetId, WARN, true, RequestParameterMaxSetCheck), + newBackwardCompatibilityRule(RequestParameterMaxSetId, WARN, true, RequestParameterMaxSetCheck), // RequestParameterMaxUpdatedCheck - newBackwardCompatibilityRule(l, RequestParameterMaxIncreasedId, INFO, true, RequestParameterMaxUpdatedCheck), - newBackwardCompatibilityRule(l, RequestParameterMaxDecreasedId, ERR, true, RequestParameterMaxUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMaxIncreasedId, INFO, true, RequestParameterMaxUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMaxDecreasedId, ERR, true, RequestParameterMaxUpdatedCheck), // RequestParameterMinItemsSetCheck - newBackwardCompatibilityRule(l, RequestParameterMinItemsSetId, WARN, true, RequestParameterMinItemsSetCheck), + newBackwardCompatibilityRule(RequestParameterMinItemsSetId, WARN, true, RequestParameterMinItemsSetCheck), // RequestParameterMinItemsUpdatedCheck - newBackwardCompatibilityRule(l, RequestParameterMinItemsIncreasedId, ERR, true, RequestParameterMinItemsUpdatedCheck), - newBackwardCompatibilityRule(l, RequestParameterMinItemsDecreasedId, INFO, true, RequestParameterMinItemsUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMinItemsIncreasedId, ERR, true, RequestParameterMinItemsUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMinItemsDecreasedId, INFO, true, RequestParameterMinItemsUpdatedCheck), // RequestParameterMinLengthUpdatedCheck - newBackwardCompatibilityRule(l, RequestParameterMinLengthIncreasedId, ERR, true, RequestParameterMinLengthUpdatedCheck), - newBackwardCompatibilityRule(l, RequestParameterMinLengthDecreasedId, INFO, true, RequestParameterMinLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMinLengthIncreasedId, ERR, true, RequestParameterMinLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMinLengthDecreasedId, INFO, true, RequestParameterMinLengthUpdatedCheck), // RequestParameterMinSetCheck - newBackwardCompatibilityRule(l, RequestParameterMinSetId, WARN, true, RequestParameterMinSetCheck), + newBackwardCompatibilityRule(RequestParameterMinSetId, WARN, true, RequestParameterMinSetCheck), // RequestParameterMinUpdatedCheck - newBackwardCompatibilityRule(l, RequestParameterMinIncreasedId, ERR, true, RequestParameterMinUpdatedCheck), - newBackwardCompatibilityRule(l, RequestParameterMinDecreasedId, INFO, true, RequestParameterMinUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMinIncreasedId, ERR, true, RequestParameterMinUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterMinDecreasedId, INFO, true, RequestParameterMinUpdatedCheck), // RequestParameterPatternAddedOrChangedCheck - newBackwardCompatibilityRule(l, RequestParameterPatternAddedId, WARN, true, RequestParameterPatternAddedOrChangedCheck), - newBackwardCompatibilityRule(l, RequestParameterPatternRemovedId, INFO, true, RequestParameterPatternAddedOrChangedCheck), - newBackwardCompatibilityRule(l, RequestParameterPatternChangedId, WARN, true, RequestParameterPatternAddedOrChangedCheck), + newBackwardCompatibilityRule(RequestParameterPatternAddedId, WARN, true, RequestParameterPatternAddedOrChangedCheck), + newBackwardCompatibilityRule(RequestParameterPatternRemovedId, INFO, true, RequestParameterPatternAddedOrChangedCheck), + newBackwardCompatibilityRule(RequestParameterPatternChangedId, WARN, true, RequestParameterPatternAddedOrChangedCheck), // RequestParameterRemovedCheck - newBackwardCompatibilityRule(l, RequestParameterRemovedId, WARN, true, RequestParameterRemovedCheck), + newBackwardCompatibilityRule(RequestParameterRemovedId, WARN, true, RequestParameterRemovedCheck), // RequestParameterRequiredValueUpdatedCheck - newBackwardCompatibilityRule(l, RequestParameterBecomeRequiredId, ERR, true, RequestParameterRequiredValueUpdatedCheck), - newBackwardCompatibilityRule(l, RequestParameterBecomeOptionalId, INFO, true, RequestParameterRequiredValueUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterBecomeRequiredId, ERR, true, RequestParameterRequiredValueUpdatedCheck), + newBackwardCompatibilityRule(RequestParameterBecomeOptionalId, INFO, true, RequestParameterRequiredValueUpdatedCheck), // RequestParameterTypeChangedCheck - newBackwardCompatibilityRule(l, RequestParameterTypeChangedId, ERR, true, RequestParameterTypeChangedCheck), + newBackwardCompatibilityRule(RequestParameterTypeChangedId, ERR, true, RequestParameterTypeChangedCheck), // RequestParameterXExtensibleEnumValueRemovedCheck - newBackwardCompatibilityRule(l, UnparsableParameterFromXExtensibleEnumId, ERR, true, RequestParameterXExtensibleEnumValueRemovedCheck), - newBackwardCompatibilityRule(l, UnparsableParameterToXExtensibleEnumId, ERR, true, RequestParameterXExtensibleEnumValueRemovedCheck), - newBackwardCompatibilityRule(l, RequestParameterXExtensibleEnumValueRemovedId, ERR, true, RequestParameterXExtensibleEnumValueRemovedCheck), + newBackwardCompatibilityRule(UnparsableParameterFromXExtensibleEnumId, ERR, true, RequestParameterXExtensibleEnumValueRemovedCheck), + newBackwardCompatibilityRule(UnparsableParameterToXExtensibleEnumId, ERR, true, RequestParameterXExtensibleEnumValueRemovedCheck), + newBackwardCompatibilityRule(RequestParameterXExtensibleEnumValueRemovedId, ERR, true, RequestParameterXExtensibleEnumValueRemovedCheck), // RequestPropertyAllOfUpdatedCheck - newBackwardCompatibilityRule(l, RequestBodyAllOfAddedId, ERR, true, RequestPropertyAllOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyAllOfRemovedId, WARN, true, RequestPropertyAllOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyAllOfAddedId, ERR, true, RequestPropertyAllOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyAllOfRemovedId, WARN, true, RequestPropertyAllOfUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyAllOfAddedId, ERR, true, RequestPropertyAllOfUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyAllOfRemovedId, WARN, true, RequestPropertyAllOfUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyAllOfAddedId, ERR, true, RequestPropertyAllOfUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyAllOfRemovedId, WARN, true, RequestPropertyAllOfUpdatedCheck), // RequestPropertyAnyOfUpdatedCheck - newBackwardCompatibilityRule(l, RequestBodyAnyOfAddedId, INFO, true, RequestPropertyAnyOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyAnyOfRemovedId, ERR, true, RequestPropertyAnyOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyAnyOfAddedId, INFO, true, RequestPropertyAnyOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyAnyOfRemovedId, ERR, true, RequestPropertyAnyOfUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyAnyOfAddedId, INFO, true, RequestPropertyAnyOfUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyAnyOfRemovedId, ERR, true, RequestPropertyAnyOfUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyAnyOfAddedId, INFO, true, RequestPropertyAnyOfUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyAnyOfRemovedId, ERR, true, RequestPropertyAnyOfUpdatedCheck), // RequestPropertyBecameEnumCheck - newBackwardCompatibilityRule(l, RequestPropertyBecameEnumId, ERR, true, RequestPropertyBecameEnumCheck), + newBackwardCompatibilityRule(RequestPropertyBecameEnumId, ERR, true, RequestPropertyBecameEnumCheck), // RequestPropertyBecameNotNullableCheck - newBackwardCompatibilityRule(l, RequestBodyBecomeNotNullableId, ERR, true, RequestPropertyBecameNotNullableCheck), - newBackwardCompatibilityRule(l, RequestBodyBecomeNullableId, INFO, true, RequestPropertyBecameNotNullableCheck), - newBackwardCompatibilityRule(l, RequestPropertyBecomeNotNullableId, ERR, true, RequestPropertyBecameNotNullableCheck), - newBackwardCompatibilityRule(l, RequestPropertyBecomeNullableId, INFO, true, RequestPropertyBecameNotNullableCheck), + newBackwardCompatibilityRule(RequestBodyBecomeNotNullableId, ERR, true, RequestPropertyBecameNotNullableCheck), + newBackwardCompatibilityRule(RequestBodyBecomeNullableId, INFO, true, RequestPropertyBecameNotNullableCheck), + newBackwardCompatibilityRule(RequestPropertyBecomeNotNullableId, ERR, true, RequestPropertyBecameNotNullableCheck), + newBackwardCompatibilityRule(RequestPropertyBecomeNullableId, INFO, true, RequestPropertyBecameNotNullableCheck), // RequestPropertyDefaultValueChangedCheck - newBackwardCompatibilityRule(l, RequestBodyDefaultValueAddedId, INFO, true, RequestPropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, RequestBodyDefaultValueRemovedId, INFO, true, RequestPropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, RequestBodyDefaultValueChangedId, INFO, true, RequestPropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDefaultValueAddedId, INFO, true, RequestPropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDefaultValueRemovedId, INFO, true, RequestPropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, RequestPropertyDefaultValueChangedId, INFO, true, RequestPropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestBodyDefaultValueAddedId, INFO, true, RequestPropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestBodyDefaultValueRemovedId, INFO, true, RequestPropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestBodyDefaultValueChangedId, INFO, true, RequestPropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestPropertyDefaultValueAddedId, INFO, true, RequestPropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestPropertyDefaultValueRemovedId, INFO, true, RequestPropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(RequestPropertyDefaultValueChangedId, INFO, true, RequestPropertyDefaultValueChangedCheck), // RequestPropertyEnumValueUpdatedCheck - newBackwardCompatibilityRule(l, RequestPropertyEnumValueRemovedId, ERR, true, RequestPropertyEnumValueUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyEnumValueAddedId, INFO, true, RequestPropertyEnumValueUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyEnumValueRemovedId, ERR, true, RequestPropertyEnumValueUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyEnumValueAddedId, INFO, true, RequestPropertyEnumValueUpdatedCheck), // RequestPropertyMaxDecreasedCheck - newBackwardCompatibilityRule(l, RequestBodyMaxDecreasedId, ERR, true, RequestPropertyMaxDecreasedCheck), - newBackwardCompatibilityRule(l, RequestBodyMaxIncreasedId, INFO, true, RequestPropertyMaxDecreasedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMaxDecreasedId, ERR, true, RequestPropertyMaxDecreasedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMaxIncreasedId, INFO, true, RequestPropertyMaxDecreasedCheck), + newBackwardCompatibilityRule(RequestBodyMaxDecreasedId, ERR, true, RequestPropertyMaxDecreasedCheck), + newBackwardCompatibilityRule(RequestBodyMaxIncreasedId, INFO, true, RequestPropertyMaxDecreasedCheck), + newBackwardCompatibilityRule(RequestPropertyMaxDecreasedId, ERR, true, RequestPropertyMaxDecreasedCheck), + newBackwardCompatibilityRule(RequestPropertyMaxIncreasedId, INFO, true, RequestPropertyMaxDecreasedCheck), // RequestPropertyMaxLengthSetCheck - newBackwardCompatibilityRule(l, RequestBodyMaxLengthSetId, WARN, true, RequestPropertyMaxLengthSetCheck), - newBackwardCompatibilityRule(l, RequestPropertyMaxLengthSetId, WARN, true, RequestPropertyMaxLengthSetCheck), + newBackwardCompatibilityRule(RequestBodyMaxLengthSetId, WARN, true, RequestPropertyMaxLengthSetCheck), + newBackwardCompatibilityRule(RequestPropertyMaxLengthSetId, WARN, true, RequestPropertyMaxLengthSetCheck), // RequestPropertyMaxLengthUpdatedCheck - newBackwardCompatibilityRule(l, RequestBodyMaxLengthDecreasedId, ERR, true, RequestPropertyMaxLengthUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyMaxLengthIncreasedId, INFO, true, RequestPropertyMaxLengthUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMaxLengthDecreasedId, ERR, true, RequestPropertyMaxLengthUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMaxLengthIncreasedId, INFO, true, RequestPropertyMaxLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyMaxLengthDecreasedId, ERR, true, RequestPropertyMaxLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyMaxLengthIncreasedId, INFO, true, RequestPropertyMaxLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyMaxLengthDecreasedId, ERR, true, RequestPropertyMaxLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyMaxLengthIncreasedId, INFO, true, RequestPropertyMaxLengthUpdatedCheck), // RequestPropertyMaxSetCheck - newBackwardCompatibilityRule(l, RequestBodyMaxSetId, WARN, true, RequestPropertyMaxSetCheck), - newBackwardCompatibilityRule(l, RequestPropertyMaxSetId, WARN, true, RequestPropertyMaxSetCheck), + newBackwardCompatibilityRule(RequestBodyMaxSetId, WARN, true, RequestPropertyMaxSetCheck), + newBackwardCompatibilityRule(RequestPropertyMaxSetId, WARN, true, RequestPropertyMaxSetCheck), // RequestPropertyMinIncreasedCheck - newBackwardCompatibilityRule(l, RequestBodyMinIncreasedId, ERR, true, RequestPropertyMinIncreasedCheck), - newBackwardCompatibilityRule(l, RequestBodyMinDecreasedId, INFO, true, RequestPropertyMinIncreasedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMinIncreasedId, ERR, true, RequestPropertyMinIncreasedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMinDecreasedId, INFO, true, RequestPropertyMinIncreasedCheck), + newBackwardCompatibilityRule(RequestBodyMinIncreasedId, ERR, true, RequestPropertyMinIncreasedCheck), + newBackwardCompatibilityRule(RequestBodyMinDecreasedId, INFO, true, RequestPropertyMinIncreasedCheck), + newBackwardCompatibilityRule(RequestPropertyMinIncreasedId, ERR, true, RequestPropertyMinIncreasedCheck), + newBackwardCompatibilityRule(RequestPropertyMinDecreasedId, INFO, true, RequestPropertyMinIncreasedCheck), // RequestPropertyMinItemsIncreasedCheck - newBackwardCompatibilityRule(l, RequestBodyMinItemsIncreasedId, ERR, true, RequestPropertyMinItemsIncreasedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMinItemsIncreasedId, ERR, true, RequestPropertyMinItemsIncreasedCheck), + newBackwardCompatibilityRule(RequestBodyMinItemsIncreasedId, ERR, true, RequestPropertyMinItemsIncreasedCheck), + newBackwardCompatibilityRule(RequestPropertyMinItemsIncreasedId, ERR, true, RequestPropertyMinItemsIncreasedCheck), // RequestPropertyMinItemsSetCheck - newBackwardCompatibilityRule(l, RequestBodyMinItemsSetId, WARN, true, RequestPropertyMinItemsSetCheck), - newBackwardCompatibilityRule(l, RequestPropertyMinItemsSetId, WARN, true, RequestPropertyMinItemsSetCheck), + newBackwardCompatibilityRule(RequestBodyMinItemsSetId, WARN, true, RequestPropertyMinItemsSetCheck), + newBackwardCompatibilityRule(RequestPropertyMinItemsSetId, WARN, true, RequestPropertyMinItemsSetCheck), // RequestPropertyMinLengthUpdatedCheck - newBackwardCompatibilityRule(l, RequestBodyMinLengthIncreasedId, ERR, true, RequestPropertyMinLengthUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyMinLengthDecreasedId, INFO, true, RequestPropertyMinLengthUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMinLengthIncreasedId, ERR, true, RequestPropertyMinLengthUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyMinLengthDecreasedId, INFO, true, RequestPropertyMinLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyMinLengthIncreasedId, ERR, true, RequestPropertyMinLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyMinLengthDecreasedId, INFO, true, RequestPropertyMinLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyMinLengthIncreasedId, ERR, true, RequestPropertyMinLengthUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyMinLengthDecreasedId, INFO, true, RequestPropertyMinLengthUpdatedCheck), // RequestPropertyMinSetCheck - newBackwardCompatibilityRule(l, RequestBodyMinSetId, WARN, true, RequestPropertyMinSetCheck), - newBackwardCompatibilityRule(l, RequestPropertyMinSetId, WARN, true, RequestPropertyMinSetCheck), + newBackwardCompatibilityRule(RequestBodyMinSetId, WARN, true, RequestPropertyMinSetCheck), + newBackwardCompatibilityRule(RequestPropertyMinSetId, WARN, true, RequestPropertyMinSetCheck), // RequestPropertyOneOfUpdatedCheck - newBackwardCompatibilityRule(l, RequestBodyOneOfAddedId, INFO, true, RequestPropertyOneOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestBodyOneOfRemovedId, ERR, true, RequestPropertyOneOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyOneOfAddedId, INFO, true, RequestPropertyOneOfUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyOneOfRemovedId, ERR, true, RequestPropertyOneOfUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyOneOfAddedId, INFO, true, RequestPropertyOneOfUpdatedCheck), + newBackwardCompatibilityRule(RequestBodyOneOfRemovedId, ERR, true, RequestPropertyOneOfUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyOneOfAddedId, INFO, true, RequestPropertyOneOfUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyOneOfRemovedId, ERR, true, RequestPropertyOneOfUpdatedCheck), // RequestPropertyPatternUpdatedCheck - newBackwardCompatibilityRule(l, RequestPropertyPatternRemovedId, INFO, true, RequestPropertyPatternUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyPatternAddedId, WARN, true, RequestPropertyPatternUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyPatternChangedId, WARN, true, RequestPropertyPatternUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyPatternRemovedId, INFO, true, RequestPropertyPatternUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyPatternAddedId, WARN, true, RequestPropertyPatternUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyPatternChangedId, WARN, true, RequestPropertyPatternUpdatedCheck), // RequestPropertyRequiredUpdatedCheck - newBackwardCompatibilityRule(l, RequestPropertyBecameRequiredId, ERR, true, RequestPropertyRequiredUpdatedCheck), - newBackwardCompatibilityRule(l, RequestPropertyBecameOptionalId, INFO, true, RequestPropertyRequiredUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyBecameRequiredId, ERR, true, RequestPropertyRequiredUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyBecameOptionalId, INFO, true, RequestPropertyRequiredUpdatedCheck), // RequestPropertyTypeChangedCheck - newBackwardCompatibilityRule(l, RequestBodyTypeChangedId, ERR, true, RequestPropertyTypeChangedCheck), - newBackwardCompatibilityRule(l, RequestPropertyTypeChangedId, INFO, true, RequestPropertyTypeChangedCheck), + newBackwardCompatibilityRule(RequestBodyTypeChangedId, ERR, true, RequestPropertyTypeChangedCheck), + newBackwardCompatibilityRule(RequestPropertyTypeChangedId, INFO, true, RequestPropertyTypeChangedCheck), // RequestPropertyUpdatedCheck - newBackwardCompatibilityRule(l, RequestPropertyRemovedId, WARN, true, RequestPropertyUpdatedCheck), - newBackwardCompatibilityRule(l, NewRequiredRequestPropertyId, ERR, true, RequestPropertyUpdatedCheck), - newBackwardCompatibilityRule(l, NewOptionalRequestPropertyId, INFO, true, RequestPropertyUpdatedCheck), + newBackwardCompatibilityRule(RequestPropertyRemovedId, WARN, true, RequestPropertyUpdatedCheck), + newBackwardCompatibilityRule(NewRequiredRequestPropertyId, ERR, true, RequestPropertyUpdatedCheck), + newBackwardCompatibilityRule(NewOptionalRequestPropertyId, INFO, true, RequestPropertyUpdatedCheck), // RequestPropertyWriteOnlyReadOnlyCheck - newBackwardCompatibilityRule(l, RequestOptionalPropertyBecameNonWriteOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, RequestOptionalPropertyBecameWriteOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, RequestOptionalPropertyBecameReadOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, RequestOptionalPropertyBecameNonReadOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, RequestRequiredPropertyBecameNonWriteOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, RequestRequiredPropertyBecameWriteOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, RequestRequiredPropertyBecameReadOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, RequestRequiredPropertyBecameNonReadOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(RequestOptionalPropertyBecameNonWriteOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(RequestOptionalPropertyBecameWriteOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(RequestOptionalPropertyBecameReadOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(RequestOptionalPropertyBecameNonReadOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(RequestRequiredPropertyBecameNonWriteOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(RequestRequiredPropertyBecameWriteOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(RequestRequiredPropertyBecameReadOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(RequestRequiredPropertyBecameNonReadOnlyCheckId, INFO, true, RequestPropertyWriteOnlyReadOnlyCheck), // RequestPropertyXExtensibleEnumValueRemovedCheck - newBackwardCompatibilityRule(l, UnparseablePropertyFromXExtensibleEnumId, ERR, true, RequestPropertyXExtensibleEnumValueRemovedCheck), - newBackwardCompatibilityRule(l, UnparseablePropertyToXExtensibleEnumId, ERR, true, RequestPropertyXExtensibleEnumValueRemovedCheck), - newBackwardCompatibilityRule(l, RequestPropertyXExtensibleEnumValueRemovedId, ERR, true, RequestPropertyXExtensibleEnumValueRemovedCheck), + newBackwardCompatibilityRule(UnparseablePropertyFromXExtensibleEnumId, ERR, true, RequestPropertyXExtensibleEnumValueRemovedCheck), + newBackwardCompatibilityRule(UnparseablePropertyToXExtensibleEnumId, ERR, true, RequestPropertyXExtensibleEnumValueRemovedCheck), + newBackwardCompatibilityRule(RequestPropertyXExtensibleEnumValueRemovedId, ERR, true, RequestPropertyXExtensibleEnumValueRemovedCheck), // ResponseDiscriminatorUpdatedCheck - newBackwardCompatibilityRule(l, ResponseBodyDiscriminatorAddedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseBodyDiscriminatorRemovedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseBodyDiscriminatorPropertyNameChangedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseBodyDiscriminatorMappingAddedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseBodyDiscriminatorMappingDeletedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseBodyDiscriminatorMappingChangedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDiscriminatorAddedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDiscriminatorRemovedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDiscriminatorPropertyNameChangedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDiscriminatorMappingAddedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDiscriminatorMappingDeletedId, INFO, true, ResponseDiscriminatorUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDiscriminatorMappingChangedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyDiscriminatorAddedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyDiscriminatorRemovedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyDiscriminatorPropertyNameChangedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyDiscriminatorMappingAddedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyDiscriminatorMappingDeletedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyDiscriminatorMappingChangedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyDiscriminatorAddedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyDiscriminatorRemovedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyDiscriminatorPropertyNameChangedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyDiscriminatorMappingAddedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyDiscriminatorMappingDeletedId, INFO, true, ResponseDiscriminatorUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyDiscriminatorMappingChangedId, INFO, true, ResponseDiscriminatorUpdatedCheck), // ResponseHeaderBecameOptionalCheck - newBackwardCompatibilityRule(l, ResponseHeaderBecameOptionalId, ERR, true, ResponseHeaderBecameOptionalCheck), + newBackwardCompatibilityRule(ResponseHeaderBecameOptionalId, ERR, true, ResponseHeaderBecameOptionalCheck), // ResponseHeaderRemovedCheck - newBackwardCompatibilityRule(l, RequiredResponseHeaderRemovedId, ERR, true, ResponseHeaderRemovedCheck), - newBackwardCompatibilityRule(l, OptionalResponseHeaderRemovedId, WARN, true, ResponseHeaderRemovedCheck), + newBackwardCompatibilityRule(RequiredResponseHeaderRemovedId, ERR, true, ResponseHeaderRemovedCheck), + newBackwardCompatibilityRule(OptionalResponseHeaderRemovedId, WARN, true, ResponseHeaderRemovedCheck), // ResponseMediaTypeUpdatedCheck - newBackwardCompatibilityRule(l, ResponseMediaTypeRemovedId, ERR, true, ResponseMediaTypeUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseMediaTypeAddedId, INFO, true, ResponseMediaTypeUpdatedCheck), + newBackwardCompatibilityRule(ResponseMediaTypeRemovedId, ERR, true, ResponseMediaTypeUpdatedCheck), + newBackwardCompatibilityRule(ResponseMediaTypeAddedId, INFO, true, ResponseMediaTypeUpdatedCheck), // ResponseOptionalPropertyUpdatedCheck - newBackwardCompatibilityRule(l, ResponseOptionalPropertyRemovedId, WARN, true, ResponseOptionalPropertyUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseOptionalWriteOnlyPropertyRemovedId, INFO, true, ResponseOptionalPropertyUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseOptionalPropertyAddedId, INFO, true, ResponseOptionalPropertyUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseOptionalWriteOnlyPropertyAddedId, INFO, true, ResponseOptionalPropertyUpdatedCheck), + newBackwardCompatibilityRule(ResponseOptionalPropertyRemovedId, WARN, true, ResponseOptionalPropertyUpdatedCheck), + newBackwardCompatibilityRule(ResponseOptionalWriteOnlyPropertyRemovedId, INFO, true, ResponseOptionalPropertyUpdatedCheck), + newBackwardCompatibilityRule(ResponseOptionalPropertyAddedId, INFO, true, ResponseOptionalPropertyUpdatedCheck), + newBackwardCompatibilityRule(ResponseOptionalWriteOnlyPropertyAddedId, INFO, true, ResponseOptionalPropertyUpdatedCheck), // ResponseOptionalPropertyWriteOnlyReadOnlyCheck - newBackwardCompatibilityRule(l, ResponseOptionalPropertyBecameNonWriteOnlyId, INFO, true, ResponseOptionalPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, ResponseOptionalPropertyBecameWriteOnlyId, INFO, true, ResponseOptionalPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, ResponseOptionalPropertyBecameReadOnlyId, INFO, true, ResponseOptionalPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, ResponseOptionalPropertyBecameNonReadOnlyId, INFO, true, ResponseOptionalPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(ResponseOptionalPropertyBecameNonWriteOnlyId, INFO, true, ResponseOptionalPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(ResponseOptionalPropertyBecameWriteOnlyId, INFO, true, ResponseOptionalPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(ResponseOptionalPropertyBecameReadOnlyId, INFO, true, ResponseOptionalPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(ResponseOptionalPropertyBecameNonReadOnlyId, INFO, true, ResponseOptionalPropertyWriteOnlyReadOnlyCheck), // ResponsePatternAddedOrChangedCheck - newBackwardCompatibilityRule(l, ResponsePropertyPatternAddedId, INFO, true, ResponsePatternAddedOrChangedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyPatternChangedId, INFO, true, ResponsePatternAddedOrChangedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyPatternRemovedId, INFO, true, ResponsePatternAddedOrChangedCheck), + newBackwardCompatibilityRule(ResponsePropertyPatternAddedId, INFO, true, ResponsePatternAddedOrChangedCheck), + newBackwardCompatibilityRule(ResponsePropertyPatternChangedId, INFO, true, ResponsePatternAddedOrChangedCheck), + newBackwardCompatibilityRule(ResponsePropertyPatternRemovedId, INFO, true, ResponsePatternAddedOrChangedCheck), // ResponsePropertyAllOfUpdatedCheck - newBackwardCompatibilityRule(l, ResponseBodyAllOfAddedId, INFO, true, ResponsePropertyAllOfUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseBodyAllOfRemovedId, INFO, true, ResponsePropertyAllOfUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyAllOfAddedId, INFO, true, ResponsePropertyAllOfUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyAllOfRemovedId, INFO, true, ResponsePropertyAllOfUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyAllOfAddedId, INFO, true, ResponsePropertyAllOfUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyAllOfRemovedId, INFO, true, ResponsePropertyAllOfUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyAllOfAddedId, INFO, true, ResponsePropertyAllOfUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyAllOfRemovedId, INFO, true, ResponsePropertyAllOfUpdatedCheck), // ResponsePropertyAnyOfUpdatedCheck - newBackwardCompatibilityRule(l, ResponseBodyAnyOfAddedId, INFO, true, ResponsePropertyAnyOfUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseBodyAnyOfRemovedId, INFO, true, ResponsePropertyAnyOfUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyAnyOfAddedId, INFO, true, ResponsePropertyAnyOfUpdatedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyAnyOfRemovedId, INFO, true, ResponsePropertyAnyOfUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyAnyOfAddedId, INFO, true, ResponsePropertyAnyOfUpdatedCheck), + newBackwardCompatibilityRule(ResponseBodyAnyOfRemovedId, INFO, true, ResponsePropertyAnyOfUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyAnyOfAddedId, INFO, true, ResponsePropertyAnyOfUpdatedCheck), + newBackwardCompatibilityRule(ResponsePropertyAnyOfRemovedId, INFO, true, ResponsePropertyAnyOfUpdatedCheck), // ResponsePropertyBecameNullableCheck - newBackwardCompatibilityRule(l, ResponsePropertyBecameNullableId, ERR, true, ResponsePropertyBecameNullableCheck), - newBackwardCompatibilityRule(l, ResponseBodyBecameNullableId, ERR, true, ResponsePropertyBecameNullableCheck), + newBackwardCompatibilityRule(ResponsePropertyBecameNullableId, ERR, true, ResponsePropertyBecameNullableCheck), + newBackwardCompatibilityRule(ResponseBodyBecameNullableId, ERR, true, ResponsePropertyBecameNullableCheck), // ResponsePropertyBecameOptionalCheck - newBackwardCompatibilityRule(l, ResponsePropertyBecameOptionalId, ERR, true, ResponsePropertyBecameOptionalCheck), - newBackwardCompatibilityRule(l, ResponseWriteOnlyPropertyBecameOptionalId, ERR, true, ResponsePropertyBecameOptionalCheck), + newBackwardCompatibilityRule(ResponsePropertyBecameOptionalId, ERR, true, ResponsePropertyBecameOptionalCheck), + newBackwardCompatibilityRule(ResponseWriteOnlyPropertyBecameOptionalId, ERR, true, ResponsePropertyBecameOptionalCheck), // ResponsePropertyBecameRequiredCheck - newBackwardCompatibilityRule(l, ResponsePropertyBecameRequiredId, INFO, true, ResponsePropertyBecameRequiredCheck), - newBackwardCompatibilityRule(l, ResponseWriteOnlyPropertyBecameRequiredId, INFO, true, ResponsePropertyBecameRequiredCheck), + newBackwardCompatibilityRule(ResponsePropertyBecameRequiredId, INFO, true, ResponsePropertyBecameRequiredCheck), + newBackwardCompatibilityRule(ResponseWriteOnlyPropertyBecameRequiredId, INFO, true, ResponsePropertyBecameRequiredCheck), // ResponsePropertyDefaultValueChangedCheck - newBackwardCompatibilityRule(l, ResponseBodyDefaultValueAddedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, ResponseBodyDefaultValueRemovedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, ResponseBodyDefaultValueChangedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDefaultValueAddedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDefaultValueRemovedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyDefaultValueChangedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(ResponseBodyDefaultValueAddedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(ResponseBodyDefaultValueRemovedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(ResponseBodyDefaultValueChangedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(ResponsePropertyDefaultValueAddedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(ResponsePropertyDefaultValueRemovedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), + newBackwardCompatibilityRule(ResponsePropertyDefaultValueChangedId, INFO, true, ResponsePropertyDefaultValueChangedCheck), // ResponsePropertyEnumValueAddedCheck - newBackwardCompatibilityRule(l, ResponsePropertyEnumValueAddedId, WARN, true, ResponsePropertyEnumValueAddedCheck), - newBackwardCompatibilityRule(l, ResponseWriteOnlyPropertyEnumValueAddedId, INFO, true, ResponsePropertyEnumValueAddedCheck), + newBackwardCompatibilityRule(ResponsePropertyEnumValueAddedId, WARN, true, ResponsePropertyEnumValueAddedCheck), + newBackwardCompatibilityRule(ResponseWriteOnlyPropertyEnumValueAddedId, INFO, true, ResponsePropertyEnumValueAddedCheck), // ResponsePropertyMaxIncreasedCheck - newBackwardCompatibilityRule(l, ResponseBodyMaxIncreasedId, ERR, true, ResponsePropertyMaxIncreasedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyMaxIncreasedId, ERR, true, ResponsePropertyMaxIncreasedCheck), + newBackwardCompatibilityRule(ResponseBodyMaxIncreasedId, ERR, true, ResponsePropertyMaxIncreasedCheck), + newBackwardCompatibilityRule(ResponsePropertyMaxIncreasedId, ERR, true, ResponsePropertyMaxIncreasedCheck), // ResponsePropertyMaxLengthIncreasedCheck - newBackwardCompatibilityRule(l, ResponseBodyMaxLengthIncreasedId, ERR, true, ResponsePropertyMaxLengthIncreasedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyMaxLengthIncreasedId, ERR, true, ResponsePropertyMaxLengthIncreasedCheck), + newBackwardCompatibilityRule(ResponseBodyMaxLengthIncreasedId, ERR, true, ResponsePropertyMaxLengthIncreasedCheck), + newBackwardCompatibilityRule(ResponsePropertyMaxLengthIncreasedId, ERR, true, ResponsePropertyMaxLengthIncreasedCheck), // ResponsePropertyMaxLengthUnsetCheck - newBackwardCompatibilityRule(l, ResponseBodyMaxLengthUnsetId, ERR, true, ResponsePropertyMaxLengthUnsetCheck), - newBackwardCompatibilityRule(l, ResponsePropertyMaxLengthUnsetId, ERR, true, ResponsePropertyMaxLengthUnsetCheck), + newBackwardCompatibilityRule(ResponseBodyMaxLengthUnsetId, ERR, true, ResponsePropertyMaxLengthUnsetCheck), + newBackwardCompatibilityRule(ResponsePropertyMaxLengthUnsetId, ERR, true, ResponsePropertyMaxLengthUnsetCheck), // ResponsePropertyMinDecreasedCheck - newBackwardCompatibilityRule(l, ResponseBodyMinDecreasedId, ERR, true, ResponsePropertyMinDecreasedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyMinDecreasedId, ERR, true, ResponsePropertyMinDecreasedCheck), + newBackwardCompatibilityRule(ResponseBodyMinDecreasedId, ERR, true, ResponsePropertyMinDecreasedCheck), + newBackwardCompatibilityRule(ResponsePropertyMinDecreasedId, ERR, true, ResponsePropertyMinDecreasedCheck), // ResponsePropertyMinItemsDecreasedCheck - newBackwardCompatibilityRule(l, ResponseBodyMinItemsDecreasedId, ERR, true, ResponsePropertyMinItemsDecreasedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyMinItemsDecreasedId, ERR, true, ResponsePropertyMinItemsDecreasedCheck), + newBackwardCompatibilityRule(ResponseBodyMinItemsDecreasedId, ERR, true, ResponsePropertyMinItemsDecreasedCheck), + newBackwardCompatibilityRule(ResponsePropertyMinItemsDecreasedId, ERR, true, ResponsePropertyMinItemsDecreasedCheck), // ResponsePropertyMinItemsUnsetCheck - newBackwardCompatibilityRule(l, ResponseBodyMinItemsUnsetId, ERR, true, ResponsePropertyMinItemsUnsetCheck), - newBackwardCompatibilityRule(l, ResponsePropertyMinItemsUnsetId, ERR, true, ResponsePropertyMinItemsUnsetCheck), + newBackwardCompatibilityRule(ResponseBodyMinItemsUnsetId, ERR, true, ResponsePropertyMinItemsUnsetCheck), + newBackwardCompatibilityRule(ResponsePropertyMinItemsUnsetId, ERR, true, ResponsePropertyMinItemsUnsetCheck), // ResponsePropertyMinLengthDecreasedCheck - newBackwardCompatibilityRule(l, ResponseBodyMinLengthDecreasedId, ERR, true, ResponsePropertyMinLengthDecreasedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyMinLengthDecreasedId, ERR, true, ResponsePropertyMinLengthDecreasedCheck), + newBackwardCompatibilityRule(ResponseBodyMinLengthDecreasedId, ERR, true, ResponsePropertyMinLengthDecreasedCheck), + newBackwardCompatibilityRule(ResponsePropertyMinLengthDecreasedId, ERR, true, ResponsePropertyMinLengthDecreasedCheck), // ResponsePropertyOneOfUpdated - newBackwardCompatibilityRule(l, ResponseBodyOneOfAddedId, INFO, true, ResponsePropertyOneOfUpdated), - newBackwardCompatibilityRule(l, ResponseBodyOneOfRemovedId, INFO, true, ResponsePropertyOneOfUpdated), - newBackwardCompatibilityRule(l, ResponsePropertyOneOfAddedId, INFO, true, ResponsePropertyOneOfUpdated), - newBackwardCompatibilityRule(l, ResponsePropertyOneOfRemovedId, INFO, true, ResponsePropertyOneOfUpdated), + newBackwardCompatibilityRule(ResponseBodyOneOfAddedId, INFO, true, ResponsePropertyOneOfUpdated), + newBackwardCompatibilityRule(ResponseBodyOneOfRemovedId, INFO, true, ResponsePropertyOneOfUpdated), + newBackwardCompatibilityRule(ResponsePropertyOneOfAddedId, INFO, true, ResponsePropertyOneOfUpdated), + newBackwardCompatibilityRule(ResponsePropertyOneOfRemovedId, INFO, true, ResponsePropertyOneOfUpdated), // ResponsePropertyTypeChangedCheck - newBackwardCompatibilityRule(l, ResponseBodyTypeChangedId, ERR, true, ResponsePropertyTypeChangedCheck), - newBackwardCompatibilityRule(l, ResponsePropertyTypeChangedId, ERR, true, ResponsePropertyTypeChangedCheck), + newBackwardCompatibilityRule(ResponseBodyTypeChangedId, ERR, true, ResponsePropertyTypeChangedCheck), + newBackwardCompatibilityRule(ResponsePropertyTypeChangedId, ERR, true, ResponsePropertyTypeChangedCheck), // ResponseRequiredPropertyUpdatedCheck - newBackwardCompatibilityRule(l, ResponseRequiredPropertyRemovedId, ERR, true, ResponseRequiredPropertyUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseRequiredWriteOnlyPropertyRemovedId, INFO, true, ResponseRequiredPropertyUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseRequiredPropertyAddedId, ERR, true, ResponseRequiredPropertyUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseRequiredWriteOnlyPropertyAddedId, INFO, true, ResponseRequiredPropertyUpdatedCheck), + newBackwardCompatibilityRule(ResponseRequiredPropertyRemovedId, ERR, true, ResponseRequiredPropertyUpdatedCheck), + newBackwardCompatibilityRule(ResponseRequiredWriteOnlyPropertyRemovedId, INFO, true, ResponseRequiredPropertyUpdatedCheck), + newBackwardCompatibilityRule(ResponseRequiredPropertyAddedId, ERR, true, ResponseRequiredPropertyUpdatedCheck), + newBackwardCompatibilityRule(ResponseRequiredWriteOnlyPropertyAddedId, INFO, true, ResponseRequiredPropertyUpdatedCheck), // ResponseRequiredPropertyWriteOnlyReadOnlyCheck - newBackwardCompatibilityRule(l, ResponseRequiredPropertyBecameNonWriteOnlyId, WARN, true, ResponseRequiredPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, ResponseRequiredPropertyBecameWriteOnlyId, INFO, true, ResponseRequiredPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, ResponseRequiredPropertyBecameReadOnlyId, INFO, true, ResponseRequiredPropertyWriteOnlyReadOnlyCheck), - newBackwardCompatibilityRule(l, ResponseRequiredPropertyBecameNonReadOnlyId, INFO, true, ResponseRequiredPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(ResponseRequiredPropertyBecameNonWriteOnlyId, WARN, true, ResponseRequiredPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(ResponseRequiredPropertyBecameWriteOnlyId, INFO, true, ResponseRequiredPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(ResponseRequiredPropertyBecameReadOnlyId, INFO, true, ResponseRequiredPropertyWriteOnlyReadOnlyCheck), + newBackwardCompatibilityRule(ResponseRequiredPropertyBecameNonReadOnlyId, INFO, true, ResponseRequiredPropertyWriteOnlyReadOnlyCheck), // ResponseSuccessStatusUpdatedCheck - newBackwardCompatibilityRule(l, ResponseSuccessStatusRemovedId, ERR, true, ResponseSuccessStatusUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseSuccessStatusAddedId, ERR, true, ResponseSuccessStatusUpdatedCheck), + newBackwardCompatibilityRule(ResponseSuccessStatusRemovedId, ERR, true, ResponseSuccessStatusUpdatedCheck), + newBackwardCompatibilityRule(ResponseSuccessStatusAddedId, ERR, true, ResponseSuccessStatusUpdatedCheck), // ResponseNonSuccessStatusUpdatedCheck - newBackwardCompatibilityRule(l, ResponseNonSuccessStatusRemovedId, ERR, false, ResponseNonSuccessStatusUpdatedCheck), - newBackwardCompatibilityRule(l, ResponseNonSuccessStatusAddedId, INFO, false, ResponseNonSuccessStatusUpdatedCheck), + newBackwardCompatibilityRule(ResponseNonSuccessStatusRemovedId, ERR, false, ResponseNonSuccessStatusUpdatedCheck), + newBackwardCompatibilityRule(ResponseNonSuccessStatusAddedId, INFO, false, ResponseNonSuccessStatusUpdatedCheck), // APIOperationIdUpdatedCheck - newBackwardCompatibilityRule(l, APIOperationIdRemovedId, ERR, false, APIOperationIdUpdatedCheck), - newBackwardCompatibilityRule(l, APIOperationIdAddId, INFO, false, APIOperationIdUpdatedCheck), + newBackwardCompatibilityRule(APIOperationIdRemovedId, ERR, false, APIOperationIdUpdatedCheck), + newBackwardCompatibilityRule(APIOperationIdAddId, INFO, false, APIOperationIdUpdatedCheck), // APITagUpdatedCheck - newBackwardCompatibilityRule(l, APITagRemovedId, ERR, false, APITagUpdatedCheck), - newBackwardCompatibilityRule(l, APITagAddedId, INFO, false, APITagUpdatedCheck), + newBackwardCompatibilityRule(APITagRemovedId, ERR, false, APITagUpdatedCheck), + newBackwardCompatibilityRule(APITagAddedId, INFO, false, APITagUpdatedCheck), // APIComponentsSchemaRemovedCheck - newBackwardCompatibilityRule(l, APISchemasRemovedId, ERR, false, APIComponentsSchemaRemovedCheck), + newBackwardCompatibilityRule(APISchemasRemovedId, ERR, false, APIComponentsSchemaRemovedCheck), // ResponseParameterEnumValueRemovedCheck - newBackwardCompatibilityRule(l, ResponsePropertyEnumValueRemovedId, ERR, false, ResponseParameterEnumValueRemovedCheck), + newBackwardCompatibilityRule(ResponsePropertyEnumValueRemovedId, ERR, false, ResponseParameterEnumValueRemovedCheck), // ResponseMediaTypeEnumValueRemovedCheck - newBackwardCompatibilityRule(l, ResponseMediaTypeEnumValueRemovedId, ERR, false, ResponseMediaTypeEnumValueRemovedCheck), + newBackwardCompatibilityRule(ResponseMediaTypeEnumValueRemovedId, ERR, false, ResponseMediaTypeEnumValueRemovedCheck), // RequestBodyEnumValueRemovedCheck - newBackwardCompatibilityRule(l, RequestBodyEnumValueRemovedId, ERR, false, RequestBodyEnumValueRemovedCheck), + newBackwardCompatibilityRule(RequestBodyEnumValueRemovedId, ERR, false, RequestBodyEnumValueRemovedCheck), } } -func GetOptionalRules(l Localizer) []BackwardCompatibilityRule { +func GetOptionalRules() []BackwardCompatibilityRule { result := []BackwardCompatibilityRule{} - for _, rule := range GetAllRules(l) { + for _, rule := range GetAllRules() { if rule.Required { continue } @@ -378,10 +382,10 @@ func GetOptionalRules(l Localizer) []BackwardCompatibilityRule { return result } -func GetRequiredRules(l Localizer) []BackwardCompatibilityRule { +func GetRequiredRules() []BackwardCompatibilityRule { result := []BackwardCompatibilityRule{} - for _, rule := range GetAllRules(l) { + for _, rule := range GetAllRules() { if rule.Required { result = append(result, rule) } diff --git a/checker/security_change.go b/checker/security_change.go index c4164a47..a9806f24 100644 --- a/checker/security_change.go +++ b/checker/security_change.go @@ -10,10 +10,9 @@ import ( // SecurityChange represents a change in the Security Section (not to be confised with components/securitySchemes) type SecurityChange struct { Id string `json:"id,omitempty" yaml:"id,omitempty"` - Text string `json:"text,omitempty" yaml:"text,omitempty"` + Args []any `json:"-" yaml:"-"` Comment string `json:"comment,omitempty" yaml:"comment,omitempty"` Level Level `json:"level" yaml:"level"` - Source string `json:"source,omitempty" yaml:"source,omitempty"` SourceFile string `json:"-" yaml:"-"` SourceLine int `json:"-" yaml:"-"` @@ -22,12 +21,16 @@ type SecurityChange struct { SourceColumnEnd int `json:"-" yaml:"-"` } +func (c SecurityChange) GetSection() string { + return "security" +} + func (c SecurityChange) IsBreaking() bool { return c.GetLevel().IsBreaking() } -func (c SecurityChange) MatchIgnore(ignorePath, ignoreLine string) bool { - return strings.Contains(ignoreLine, strings.ToLower(GetUncolorizedText(c))) && +func (c SecurityChange) MatchIgnore(ignorePath, ignoreLine string, l Localizer) bool { + return strings.Contains(ignoreLine, strings.ToLower(c.GetUncolorizedText(l))) && strings.Contains(ignoreLine, "security") } @@ -35,12 +38,20 @@ func (c SecurityChange) GetId() string { return c.Id } -func (c SecurityChange) GetText() string { - return c.Text +func (c SecurityChange) GetText(l Localizer) string { + return l(c.Id, colorizedValues(c.Args)...) +} + +func (c SecurityChange) GetArgs() []any { + return c.Args } -func (c SecurityChange) GetComment() string { - return c.Comment +func (c SecurityChange) GetUncolorizedText(l Localizer) string { + return l(c.Id, quotedValues(c.Args)...) +} + +func (c SecurityChange) GetComment(l Localizer) string { + return l(c.Comment) } func (c SecurityChange) GetLevel() Level { @@ -59,6 +70,10 @@ func (SecurityChange) GetPath() string { return "" } +func (c SecurityChange) GetSource() string { + return "" +} + func (c SecurityChange) GetSourceFile() string { return c.SourceFile } @@ -79,22 +94,21 @@ func (c SecurityChange) GetSourceColumnEnd() int { return c.SourceColumnEnd } -func (c SecurityChange) LocalizedError(l Localizer) string { - return fmt.Sprintf("%s, %s security %s [%s]. %s", c.Level, l("in"), c.Text, c.Id, c.Comment) -} +func (c SecurityChange) SingleLineError(l Localizer, colorMode ColorMode) string { + const format = "%s, %s security %s [%s]. %s" -func (c SecurityChange) PrettyErrorText(l Localizer) string { - if IsPipedOutput() { - return c.LocalizedError(l) + if isColorEnabled(colorMode) { + return fmt.Sprintf(format, c.Level.PrettyString(), l("in"), c.GetText(l), color.InYellow(c.Id), c.GetComment(l)) } + return fmt.Sprintf(format, c.Level.String(), l("in"), c.GetUncolorizedText(l), c.Id, c.GetComment(l)) +} + +func (c SecurityChange) MultiLineError(l Localizer, colorMode ColorMode) string { + const format = "%s\t[%s] \t\n\t%s security\n\t\t%s%s" - comment := "" - if c.Comment != "" { - comment = fmt.Sprintf("\n\t\t%s", c.Comment) + if isColorEnabled(colorMode) { + return fmt.Sprintf(format, c.Level.PrettyString(), color.InYellow(c.Id), l("in"), c.GetText(l), multiLineComment(c.GetComment(l))) } - return fmt.Sprintf("%s\t[%s] \t\n\t%s security\n\t\t%s%s", c.Level.PrettyString(), color.InYellow(c.Id), l("in"), c.Text, comment) -} -func (c SecurityChange) Error() string { - return fmt.Sprintf("%s, in security %s [%s]. %s", c.Level, c.Text, c.Id, c.Comment) + return fmt.Sprintf(format, c.Level.String(), c.Id, l("in"), c.GetUncolorizedText(l), multiLineComment(c.GetComment(l))) } diff --git a/checker/security_change_test.go b/checker/security_change_test.go index 639ca04a..bd9c1db3 100644 --- a/checker/security_change_test.go +++ b/checker/security_change_test.go @@ -8,11 +8,10 @@ import ( ) var securityChange = checker.SecurityChange{ - Id: "id", - Text: "text", + Id: "change_id", Comment: "comment", Level: checker.ERR, - Source: "source", + Args: []any{1}, SourceFile: "sourceFile", SourceLine: 1, SourceLineEnd: 2, @@ -21,24 +20,27 @@ var securityChange = checker.SecurityChange{ } func TestSecurityChange(t *testing.T) { - require.Equal(t, "comment", securityChange.GetComment()) + require.Equal(t, "security", securityChange.GetSection()) + require.Equal(t, "comment", securityChange.GetComment(MockLocalizer)) require.Equal(t, "", securityChange.GetOperationId()) + require.Equal(t, "", securityChange.GetSource()) + require.Equal(t, []any{1}, securityChange.GetArgs()) require.Equal(t, "sourceFile", securityChange.GetSourceFile()) require.Equal(t, 1, securityChange.GetSourceLine()) require.Equal(t, 2, securityChange.GetSourceLineEnd()) require.Equal(t, 3, securityChange.GetSourceColumn()) require.Equal(t, 4, securityChange.GetSourceColumnEnd()) - require.Equal(t, "error, in security text [id]. comment", securityChange.LocalizedError(checker.NewDefaultLocalizer())) - require.Equal(t, "error, in security text [id]. comment", securityChange.Error()) + require.Equal(t, "error, in security This is a breaking change. [change_id]. comment", securityChange.SingleLineError(MockLocalizer, checker.ColorNever)) } func TestSecurityChange_MatchIgnore(t *testing.T) { - require.True(t, securityChange.MatchIgnore("", "error, in security text [id]. comment")) + require.True(t, securityChange.MatchIgnore("", "error, in security this is a breaking change. [change_id]. comment", MockLocalizer)) } -func TestSecurityChange_PrettyPiped(t *testing.T) { - piped := true - save := checker.SetPipedOutput(&piped) - defer checker.SetPipedOutput(save) - require.Equal(t, "error, in security text [id]. comment", securityChange.PrettyErrorText(checker.NewDefaultLocalizer())) +func TestSecurityChange_SingleLineError(t *testing.T) { + require.Equal(t, "error, in security This is a breaking change. [change_id]. comment", securityChange.SingleLineError(MockLocalizer, checker.ColorNever)) +} + +func TestSecurityChange_MultiLineError_NoColor(t *testing.T) { + require.Equal(t, "error\t[change_id] \t\n\tin security\n\t\tThis is a breaking change.\n\t\tcomment", securityChange.MultiLineError(MockLocalizer, checker.ColorNever)) } diff --git a/checker/security_change_unix_test.go b/checker/security_change_unix_test.go index 0cada8ac..5fb461c4 100644 --- a/checker/security_change_unix_test.go +++ b/checker/security_change_unix_test.go @@ -13,5 +13,9 @@ func TestSecurityChange_PrettyNotPipedUnix(t *testing.T) { piped := false save := checker.SetPipedOutput(&piped) defer checker.SetPipedOutput(save) - require.Equal(t, "\x1b[31merror\x1b[0m\t[\x1b[33mid\x1b[0m] \t\n\tin security\n\t\ttext\n\t\tcomment", securityChange.PrettyErrorText(checker.NewDefaultLocalizer())) + require.Equal(t, "\x1b[31merror\x1b[0m\t[\x1b[33mchange_id\x1b[0m] \t\n\tin security\n\t\tThis is a breaking change.\n\t\tcomment", securityChange.MultiLineError(MockLocalizer, checker.ColorAuto)) +} + +func TestSecurityChange_SingleLineError_WithColor(t *testing.T) { + require.Equal(t, "\x1b[31merror\x1b[0m, in security This is a breaking change. [\x1b[33mchange_id\x1b[0m]. comment", securityChange.SingleLineError(MockLocalizer, checker.ColorAlways)) } diff --git a/checker/security_change_windows_test.go b/checker/security_change_windows_test.go index 7fe90b05..13eac960 100644 --- a/checker/security_change_windows_test.go +++ b/checker/security_change_windows_test.go @@ -11,5 +11,5 @@ func TestSecurityChange_PrettyNotPipedWindows(t *testing.T) { piped := false save := checker.SetPipedOutput(&piped) defer checker.SetPipedOutput(save) - require.Equal(t, "error\t[id] \t\n\tin security\n\t\ttext\n\t\tcomment", securityChange.PrettyErrorText(checker.NewDefaultLocalizer())) + require.Equal(t, "error\t[change_id] \t\n\tin security\n\t\tThis is a breaking change.\n\t\tcomment", securityChange.MultiLineError(MockLocalizer, checker.ColorAuto)) } diff --git a/diff/example_test.go b/diff/example_test.go index c587d010..9fa9daf0 100644 --- a/diff/example_test.go +++ b/diff/example_test.go @@ -88,19 +88,17 @@ func ExampleGetPathsDiff() { return } - c := checker.GetDefaultChecks() - c.Localize = checker.NewDefaultLocalizer() - errs := checker.CheckBackwardCompatibility(c, diffRes, operationsSources) + errs := checker.CheckBackwardCompatibility(checker.GetDefaultChecks(), diffRes, operationsSources) // process configuration file for ignoring errors - errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example.txt") + errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, "../data/ignore-err-example.txt", checker.NewDefaultLocalizer()) if err != nil { fmt.Fprintf(os.Stderr, "ignore errors failed with %v", err) return } // process configuration file for ignoring warnings - errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.WARN, errs, "../data/ignore-warn-example.txt") + errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.WARN, errs, "../data/ignore-warn-example.txt", checker.NewDefaultLocalizer()) if err != nil { fmt.Fprintf(os.Stderr, "ignore warnings failed with %v", err) return @@ -108,10 +106,11 @@ func ExampleGetPathsDiff() { // pretty print breaking changes errors if len(errs) > 0 { + localizer := checker.NewDefaultLocalizer() count := errs.GetLevelCount() - fmt.Print(c.Localize("total-errors", len(errs), count[checker.ERR], "error", count[checker.WARN], "warning")) + fmt.Print(localizer("total-errors", len(errs), count[checker.ERR], "error", count[checker.WARN], "warning")) for _, bcerr := range errs { - fmt.Printf("%s\n\n", strings.TrimRight(bcerr.PrettyErrorText(c.Localize), " ")) + fmt.Printf("%s\n\n", strings.TrimRight(bcerr.SingleLineError(localizer, checker.ColorNever), " ")) } } diff --git a/formatters/changes.go b/formatters/changes.go new file mode 100644 index 00000000..7b130fd4 --- /dev/null +++ b/formatters/changes.go @@ -0,0 +1,38 @@ +package formatters + +import ( + "github.com/tufin/oasdiff/checker" +) + +type Change struct { + Id string `json:"id,omitempty" yaml:"id,omitempty"` + Text string `json:"text,omitempty" yaml:"text,omitempty"` + Comment string `json:"comment,omitempty" yaml:"comment,omitempty"` + Level checker.Level `json:"level" yaml:"level"` + Operation string `json:"operation,omitempty" yaml:"operation,omitempty"` + OperationId string `json:"operationId,omitempty" yaml:"operationId,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Source string `json:"source,omitempty" yaml:"source,omitempty"` + Section string `json:"section,omitempty" yaml:"section,omitempty"` + IsBreaking bool `json:"-" yaml:"-"` +} + +type Changes []Change + +func NewChanges(originalChanges checker.Changes, l checker.Localizer) Changes { + changes := make(Changes, len(originalChanges)) + for i, change := range originalChanges { + changes[i] = Change{ + Section: change.GetSection(), + Id: change.GetId(), + Text: change.GetUncolorizedText(l), + Comment: change.GetComment(l), + Level: change.GetLevel(), + Operation: change.GetOperation(), + OperationId: change.GetOperationId(), + Path: change.GetPath(), + Source: change.GetSource(), + } + } + return changes +} diff --git a/formatters/changes_by_endpoint.go b/formatters/changes_by_endpoint.go new file mode 100644 index 00000000..89e73c65 --- /dev/null +++ b/formatters/changes_by_endpoint.go @@ -0,0 +1,35 @@ +package formatters + +import "github.com/tufin/oasdiff/checker" + +type Endpoint struct { + Path string + Operation string +} + +type ChangesByEndpoint map[Endpoint]*Changes + +func GroupChanges(changes checker.Changes, l checker.Localizer) ChangesByEndpoint { + + apiChanges := ChangesByEndpoint{} + + for _, change := range changes { + switch change.(type) { + case checker.ApiChange: + ep := Endpoint{Path: change.GetPath(), Operation: change.GetOperation()} + if c, ok := apiChanges[ep]; ok { + *c = append(*c, Change{ + IsBreaking: change.IsBreaking(), + Text: change.GetUncolorizedText(l), + }) + } else { + apiChanges[ep] = &Changes{Change{ + IsBreaking: change.IsBreaking(), + Text: change.GetUncolorizedText(l), + }} + } + } + } + + return apiChanges +} diff --git a/formatters/changes_by_endpoint_test.go b/formatters/changes_by_endpoint_test.go new file mode 100644 index 00000000..dcdcd4f6 --- /dev/null +++ b/formatters/changes_by_endpoint_test.go @@ -0,0 +1,36 @@ +package formatters_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/tufin/oasdiff/checker" + "github.com/tufin/oasdiff/formatters" +) + +var changes = checker.Changes{ + checker.ApiChange{ + Id: "api-deleted", + Level: checker.ERR, + Operation: "GET", + Path: "/test", + }, + checker.ApiChange{ + Id: "api-added", + Level: checker.INFO, + Operation: "GET", + Path: "/test", + }, + checker.ComponentChange{ + Id: "component-added", + Level: checker.INFO, + }, + checker.SecurityChange{ + Id: "security-added", + Level: checker.INFO, + }, +} + +func TestChanges_Group(t *testing.T) { + require.Contains(t, formatters.GroupChanges(changes, checker.NewDefaultLocalizer()), formatters.Endpoint{Path: "/test", Operation: "GET"}) +} diff --git a/formatters/format_githubactions.go b/formatters/format_githubactions.go index b5767b94..23d4461e 100644 --- a/formatters/format_githubactions.go +++ b/formatters/format_githubactions.go @@ -18,6 +18,7 @@ var githubActionsSeverity = map[checker.Level]string{ type GitHubActionsFormatter struct { notImplementedFormatter + Localizer checker.Localizer } func (f GitHubActionsFormatter) RenderBreakingChanges(changes checker.Changes, opts RenderOpts) ([]byte, error) { @@ -55,7 +56,7 @@ func (f GitHubActionsFormatter) RenderBreakingChanges(changes checker.Changes, o } // all annotated messages must be one-line, due to GitHub Actions limitations - message := StripANSIEscapeCodes([]byte(strings.ReplaceAll(change.GetText(), "\n", "%0A"))) + message := strings.ReplaceAll(change.GetUncolorizedText(f.Localizer), "\n", "%0A") buf.WriteString(fmt.Sprintf("::%s %s::%s\n", githubActionsSeverity[change.GetLevel()], strings.Join(params, ","), message)) } diff --git a/formatters/format_githubactions_test.go b/formatters/format_githubactions_test.go index 58ca2714..acb68503 100644 --- a/formatters/format_githubactions_test.go +++ b/formatters/format_githubactions_test.go @@ -5,81 +5,78 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/tufin/oasdiff/checker" "github.com/tufin/oasdiff/formatters" ) +var gitHubFormatter = formatters.GitHubActionsFormatter{ + Localizer: MockLocalizer, +} + +func TestGithubActionsLookup(t *testing.T) { + f, err := formatters.Lookup(string(formatters.FormatGithubActions), formatters.DefaultFormatterOpts()) + require.NoError(t, err) + require.IsType(t, formatters.GitHubActionsFormatter{}, f) +} + func TestGitHubActionsFormatter_RenderBreakingChanges_OneFailure(t *testing.T) { - // prepare formatter and test changes - formatter := formatters.GitHubActionsFormatter{} testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, } // check output - output, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + output, err := gitHubFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) assert.NoError(t, err) expectedOutput := "::error title=change_id::This is a breaking change.\n" assert.Equal(t, expectedOutput, string(output)) } func TestGitHubActionsFormatter_RenderBreakingChanges_MultipleLevels(t *testing.T) { - // prepare formatter and test changes - formatter := formatters.GitHubActionsFormatter{} testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, checker.ComponentChange{ - Id: "change_id", - Text: "This is a warning.", + Id: "warning_id", Level: checker.WARN, }, checker.ComponentChange{ - Id: "change_id", - Text: "This is a notice.", + Id: "notice_id", Level: checker.INFO, }, } // check output - output, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + output, err := gitHubFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) assert.NoError(t, err) - expectedOutput := "::error title=change_id::This is a breaking change.\n::warning title=change_id::This is a warning.\n::notice title=change_id::This is a notice.\n" + expectedOutput := "::error title=change_id::This is a breaking change.\n::warning title=warning_id::This is a warning.\n::notice title=notice_id::This is a notice.\n" assert.Equal(t, expectedOutput, string(output)) } func TestGitHubActionsFormatter_RenderBreakingChanges_MultilineText(t *testing.T) { - // prepare formatter and test changes - formatter := formatters.GitHubActionsFormatter{} testChanges := checker.Changes{ checker.ComponentChange{ - Id: "change_id", - Text: "This is a breaking change.\nThis is a second line.", + Id: "change_two_lines_id", Level: checker.ERR, }, } // check output - output, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + output, err := gitHubFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) assert.NoError(t, err) - expectedOutput := "::error title=change_id::This is a breaking change.%0AThis is a second line.\n" + expectedOutput := "::error title=change_two_lines_id::This is a breaking change.%0AThis is a second line.\n" assert.Equal(t, expectedOutput, string(output)) } func TestGitHubActionsFormatter_RenderBreakingChanges_FileLocation(t *testing.T) { - // prepare formatter and test changes - formatter := formatters.GitHubActionsFormatter{} testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, SourceFile: "openapi.json", SourceLine: 20, @@ -90,7 +87,7 @@ func TestGitHubActionsFormatter_RenderBreakingChanges_FileLocation(t *testing.T) } // check output - output, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + output, err := gitHubFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) assert.NoError(t, err) expectedOutput := "::error title=change_id,file=openapi.json,col=6,endColumn=11,line=21,endLine=26::This is a breaking change.\n" assert.Equal(t, expectedOutput, string(output)) @@ -103,36 +100,30 @@ func TestGitHubActionsFormatter_RenderBreakingChanges_JobOutputParameters(t *tes defer os.Remove(tempFile.Name()) _ = os.Setenv("GITHUB_OUTPUT", tempFile.Name()) - // prepare formatter and test changes - formatter := formatters.GitHubActionsFormatter{} testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, checker.ComponentChange{ Id: "change_id", - Text: "This is a second breaking change.", Level: checker.ERR, }, checker.ComponentChange{ - Id: "change_id", - Text: "This is a warning.", + Id: "warning_id", Level: checker.WARN, }, checker.ComponentChange{ - Id: "change_id", - Text: "This is a notice.", + Id: "notice_id", Level: checker.INFO, }, } // check output - output, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + output, err := gitHubFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) assert.NoError(t, err) _ = os.Unsetenv("GITHUB_OUTPUT") - expectedOutput := "::error title=change_id::This is a breaking change.\n::error title=change_id::This is a second breaking change.\n::warning title=change_id::This is a warning.\n::notice title=change_id::This is a notice.\n" + expectedOutput := "::error title=change_id::This is a breaking change.\n::error title=change_id::This is a breaking change.\n::warning title=warning_id::This is a warning.\n::notice title=notice_id::This is a notice.\n" assert.Equal(t, expectedOutput, string(output)) // check job output parameters (NOTE: order of parameters is not guaranteed) @@ -144,21 +135,19 @@ func TestGitHubActionsFormatter_RenderBreakingChanges_JobOutputParameters(t *tes } func TestGitHubActionsFormatterr_NotImplemented(t *testing.T) { - formatter := formatters.GitHubActionsFormatter{} - var err error - _, err = formatter.RenderDiff(nil, formatters.RenderOpts{}) + _, err = gitHubFormatter.RenderDiff(nil, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderSummary(nil, formatters.RenderOpts{}) + _, err = gitHubFormatter.RenderSummary(nil, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderChangelog(nil, formatters.RenderOpts{}, nil) + _, err = gitHubFormatter.RenderChangelog(nil, formatters.NewRenderOpts(), nil) assert.Error(t, err) - _, err = formatter.RenderChecks(nil, formatters.RenderOpts{}) + _, err = gitHubFormatter.RenderChecks(nil, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderFlatten(nil, formatters.RenderOpts{}) + _, err = gitHubFormatter.RenderFlatten(nil, formatters.NewRenderOpts()) assert.Error(t, err) } diff --git a/formatters/format_html.go b/formatters/format_html.go index e0407f9f..c638c7ee 100644 --- a/formatters/format_html.go +++ b/formatters/format_html.go @@ -15,6 +15,7 @@ import ( type HTMLFormatter struct { notImplementedFormatter + Localizer checker.Localizer } func (f HTMLFormatter) RenderDiff(diff *diff.Diff, opts RenderOpts) ([]byte, error) { @@ -30,7 +31,7 @@ func (f HTMLFormatter) RenderDiff(diff *diff.Diff, opts RenderOpts) ([]byte, err var changelog string type TemplateData struct { - APIChanges checker.ChangesByEndpoint + APIChanges ChangesByEndpoint BaseVersion string RevisionVersion string } @@ -39,7 +40,7 @@ func (f HTMLFormatter) RenderChangelog(changes checker.Changes, opts RenderOpts, tmpl := template.Must(template.New("changelog").Parse(changelog)) var out bytes.Buffer - if err := tmpl.Execute(&out, TemplateData{checker.GroupChanges(changes), specInfoPair.GetBaseVersion(), specInfoPair.GetRevisionVersion()}); err != nil { + if err := tmpl.Execute(&out, TemplateData{GroupChanges(changes, f.Localizer), specInfoPair.GetBaseVersion(), specInfoPair.GetRevisionVersion()}); err != nil { return nil, err } diff --git a/formatters/format_html_test.go b/formatters/format_html_test.go index 19aac6f5..9c93b444 100644 --- a/formatters/format_html_test.go +++ b/formatters/format_html_test.go @@ -1,6 +1,7 @@ package formatters_test import ( + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -9,45 +10,67 @@ import ( "github.com/tufin/oasdiff/formatters" ) -func TestHtmlFormatter_RenderDiff(t *testing.T) { - formatter := formatters.HTMLFormatter{} +func MockLocalizer(id string, args ...interface{}) string { + switch id { + case "change_id": + return "This is a breaking change." + case "warning_id": + return "This is a warning." + case "notice_id": + return "This is a notice." + case "change_two_lines_id": + return "This is a breaking change.\nThis is a second line." + case "total-errors": + return fmt.Sprintf("%d breaking changes: %d %s, %d %s\n", args...) + case "total-changes": + return fmt.Sprintf("%d changes: %d %s, %d %s, %d %s\n", args...) + default: + return id + } +} - out, err := formatter.RenderDiff(nil, formatters.RenderOpts{}) +var htmlFormatter = formatters.HTMLFormatter{ + Localizer: MockLocalizer, +} + +func TestHtmlLookup(t *testing.T) { + f, err := formatters.Lookup(string(formatters.FormatHTML), formatters.DefaultFormatterOpts()) + require.NoError(t, err) + require.IsType(t, formatters.HTMLFormatter{}, f) +} + +func TestHtmlFormatter_RenderDiff(t *testing.T) { + out, err := htmlFormatter.RenderDiff(nil, formatters.NewRenderOpts()) require.NoError(t, err) require.Equal(t, string(out), "

No changes

\n") } func TestHtmlFormatter_RenderChangelog(t *testing.T) { - formatter := formatters.HTMLFormatter{} - testChanges := checker.Changes{ checker.ApiChange{ Path: "/test", Operation: "GET", Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, } - out, err := formatter.RenderChangelog(testChanges, formatters.RenderOpts{}, nil) + out, err := htmlFormatter.RenderChangelog(testChanges, formatters.NewRenderOpts(), nil) require.NoError(t, err) require.NotEmpty(t, string(out)) } func TestHtmlFormatter_NotImplemented(t *testing.T) { - formatter := formatters.HTMLFormatter{} - var err error - _, err = formatter.RenderBreakingChanges(checker.Changes{}, formatters.RenderOpts{}) + _, err = htmlFormatter.RenderBreakingChanges(checker.Changes{}, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderChecks(formatters.Checks{}, formatters.RenderOpts{}) + _, err = htmlFormatter.RenderChecks(formatters.Checks{}, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderFlatten(nil, formatters.RenderOpts{}) + _, err = htmlFormatter.RenderFlatten(nil, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderSummary(nil, formatters.RenderOpts{}) + _, err = htmlFormatter.RenderSummary(nil, formatters.NewRenderOpts()) assert.Error(t, err) } diff --git a/formatters/format_json.go b/formatters/format_json.go index 4a790f55..184aeb21 100644 --- a/formatters/format_json.go +++ b/formatters/format_json.go @@ -12,6 +12,7 @@ import ( ) type JSONFormatter struct { + Localizer checker.Localizer } func (f JSONFormatter) RenderDiff(diff *diff.Diff, opts RenderOpts) ([]byte, error) { @@ -23,11 +24,11 @@ func (f JSONFormatter) RenderSummary(diff *diff.Diff, opts RenderOpts) ([]byte, } func (f JSONFormatter) RenderBreakingChanges(changes checker.Changes, opts RenderOpts) ([]byte, error) { - return printJSON(changes) + return printJSON(NewChanges(changes, f.Localizer)) } func (f JSONFormatter) RenderChangelog(changes checker.Changes, opts RenderOpts, specInfoPair *load.SpecInfoPair) ([]byte, error) { - return printJSON(changes) + return printJSON(NewChanges(changes, f.Localizer)) } func (f JSONFormatter) RenderChecks(checks Checks, opts RenderOpts) ([]byte, error) { @@ -52,5 +53,5 @@ func printJSON(output interface{}) ([]byte, error) { return nil, fmt.Errorf("failed to marshal JSON: %w", err) } - return StripANSIEscapeCodes(bytes), nil + return bytes, nil } diff --git a/formatters/format_json_test.go b/formatters/format_json_test.go index 52ddd7a9..cd440114 100644 --- a/formatters/format_json_test.go +++ b/formatters/format_json_test.go @@ -8,41 +8,43 @@ import ( "github.com/tufin/oasdiff/formatters" ) -func TestJsonFormatter_RenderBreakingChanges(t *testing.T) { - formatter := formatters.JSONFormatter{} +var jsonFormatter = formatters.JSONFormatter{ + Localizer: MockLocalizer, +} + +func TestJsonLookup(t *testing.T) { + f, err := formatters.Lookup(string(formatters.FormatJSON), formatters.DefaultFormatterOpts()) + require.NoError(t, err) + require.IsType(t, formatters.JSONFormatter{}, f) +} +func TestJsonFormatter_RenderBreakingChanges(t *testing.T) { testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, } - out, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + out, err := jsonFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) require.NoError(t, err) - require.Equal(t, string(out), "[{\"id\":\"change_id\",\"text\":\"This is a breaking change.\",\"level\":3}]") + require.Equal(t, "[{\"id\":\"change_id\",\"text\":\"This is a breaking change.\",\"level\":3,\"section\":\"components\"}]", string(out)) } func TestJsonFormatter_RenderChangelog(t *testing.T) { - formatter := formatters.JSONFormatter{} - testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, } - out, err := formatter.RenderChangelog(testChanges, formatters.RenderOpts{}, nil) + out, err := jsonFormatter.RenderChangelog(testChanges, formatters.NewRenderOpts(), nil) require.NoError(t, err) - require.Equal(t, string(out), "[{\"id\":\"change_id\",\"text\":\"This is a breaking change.\",\"level\":3}]") + require.Equal(t, "[{\"id\":\"change_id\",\"text\":\"This is a breaking change.\",\"level\":3,\"section\":\"components\"}]", string(out)) } func TestJsonFormatter_RenderChecks(t *testing.T) { - formatter := formatters.JSONFormatter{} - checks := formatters.Checks{ { Id: "change_id", @@ -52,31 +54,25 @@ func TestJsonFormatter_RenderChecks(t *testing.T) { }, } - out, err := formatter.RenderChecks(checks, formatters.RenderOpts{}) + out, err := jsonFormatter.RenderChecks(checks, formatters.NewRenderOpts()) require.NoError(t, err) - require.Equal(t, string(out), "[{\"id\":\"change_id\",\"level\":\"info\",\"description\":\"This is a breaking change.\",\"reuired\":true}]") + require.Equal(t, "[{\"id\":\"change_id\",\"level\":\"info\",\"description\":\"This is a breaking change.\",\"reuired\":true}]", string(out)) } func TestJsonFormatter_RenderDiff(t *testing.T) { - formatter := formatters.JSONFormatter{} - - out, err := formatter.RenderDiff(nil, formatters.RenderOpts{}) + out, err := jsonFormatter.RenderDiff(nil, formatters.NewRenderOpts()) require.NoError(t, err) require.Empty(t, string(out)) } func TestJsonFormatter_RenderFlatten(t *testing.T) { - formatter := formatters.JSONFormatter{} - - out, err := formatter.RenderFlatten(nil, formatters.RenderOpts{}) + out, err := jsonFormatter.RenderFlatten(nil, formatters.NewRenderOpts()) require.NoError(t, err) require.Empty(t, string(out)) } func TestJsonFormatter_RenderSummary(t *testing.T) { - formatter := formatters.JSONFormatter{} - - out, err := formatter.RenderSummary(nil, formatters.RenderOpts{}) + out, err := jsonFormatter.RenderSummary(nil, formatters.NewRenderOpts()) require.NoError(t, err) - require.Equal(t, string(out), `{"diff":false}`) + require.Equal(t, `{"diff":false}`, string(out)) } diff --git a/formatters/format_junit.go b/formatters/format_junit.go index e97d7935..21701c4a 100644 --- a/formatters/format_junit.go +++ b/formatters/format_junit.go @@ -37,6 +37,7 @@ type JUnitFailure struct { type JUnitFormatter struct { notImplementedFormatter + Localizer checker.Localizer } func (f JUnitFormatter) RenderBreakingChanges(changes checker.Changes, opts RenderOpts) ([]byte, error) { @@ -57,7 +58,7 @@ func (f JUnitFormatter) RenderBreakingChanges(changes checker.Changes, opts Rend Time: "0", Failure: &JUnitFailure{ Message: "Breaking change detected", - CDATA: StripANSIEscapeCodesStr(change.GetText()), + CDATA: change.GetUncolorizedText(f.Localizer), }, } testSuite.TestCases = append(testSuite.TestCases, testCase) diff --git a/formatters/format_junit_test.go b/formatters/format_junit_test.go index 5bf0c2f0..e65260ba 100644 --- a/formatters/format_junit_test.go +++ b/formatters/format_junit_test.go @@ -4,23 +4,31 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/tufin/oasdiff/checker" "github.com/tufin/oasdiff/formatters" ) +var jUnitFormatter = formatters.JUnitFormatter{ + Localizer: MockLocalizer, +} + +func TestJUnitLineLookup(t *testing.T) { + f, err := formatters.Lookup(string(formatters.FormatJUnit), formatters.DefaultFormatterOpts()) + require.NoError(t, err) + require.IsType(t, formatters.JUnitFormatter{}, f) +} + func TestJUnitFormatter_RenderBreakingChanges_OneFailure(t *testing.T) { - // prepare formatter and test changes - formatter := formatters.JUnitFormatter{} testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, } // check output - output, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + output, err := jUnitFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) assert.NoError(t, err) expectedOutput := ` @@ -34,12 +42,10 @@ func TestJUnitFormatter_RenderBreakingChanges_OneFailure(t *testing.T) { } func TestJUnitFormatter_RenderBreakingChanges_Success(t *testing.T) { - // prepare formatter and test changes - formatter := formatters.JUnitFormatter{} testChanges := checker.Changes{} // check output - output, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + output, err := jUnitFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) assert.NoError(t, err) expectedOutput := ` @@ -51,21 +57,20 @@ func TestJUnitFormatter_RenderBreakingChanges_Success(t *testing.T) { } func TestJUnitFormatter_NotImplemented(t *testing.T) { - formatter := formatters.GitHubActionsFormatter{} var err error - _, err = formatter.RenderDiff(nil, formatters.RenderOpts{}) + _, err = jUnitFormatter.RenderDiff(nil, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderSummary(nil, formatters.RenderOpts{}) + _, err = jUnitFormatter.RenderSummary(nil, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderChangelog(nil, formatters.RenderOpts{}, nil) + _, err = jUnitFormatter.RenderChangelog(nil, formatters.NewRenderOpts(), nil) assert.Error(t, err) - _, err = formatter.RenderChecks(nil, formatters.RenderOpts{}) + _, err = jUnitFormatter.RenderChecks(nil, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderFlatten(nil, formatters.RenderOpts{}) + _, err = jUnitFormatter.RenderFlatten(nil, formatters.NewRenderOpts()) assert.Error(t, err) } diff --git a/formatters/format_singleline.go b/formatters/format_singleline.go new file mode 100644 index 00000000..a669de30 --- /dev/null +++ b/formatters/format_singleline.go @@ -0,0 +1,92 @@ +package formatters + +import ( + "bytes" + "fmt" + "text/tabwriter" + + "github.com/tufin/oasdiff/checker" + "github.com/tufin/oasdiff/diff" + "github.com/tufin/oasdiff/load" + "github.com/tufin/oasdiff/report" +) + +type SingleLineFormatter struct { + notImplementedFormatter + Localizer checker.Localizer +} + +func (f SingleLineFormatter) RenderDiff(diff *diff.Diff, opts RenderOpts) ([]byte, error) { + return []byte(report.GetTextReportAsString(diff)), nil +} + +func (f SingleLineFormatter) RenderBreakingChanges(changes checker.Changes, opts RenderOpts) ([]byte, error) { + result := bytes.NewBuffer(nil) + + if len(changes) > 0 { + _, _ = fmt.Fprint(result, getBreakingTitle(changes, f.Localizer, opts.ColorMode)) + } + + for _, c := range changes { + _, _ = fmt.Fprintf(result, "%s\n\n", c.SingleLineError(f.Localizer, opts.ColorMode)) + } + + return result.Bytes(), nil +} + +func (f SingleLineFormatter) RenderChangelog(changes checker.Changes, opts RenderOpts, specInfoPair *load.SpecInfoPair) ([]byte, error) { + result := bytes.NewBuffer(nil) + + if len(changes) > 0 { + _, _ = fmt.Fprint(result, getChangelogTitle(changes, f.Localizer, opts.ColorMode)) + } + + for _, c := range changes { + _, _ = fmt.Fprintf(result, "%s\n\n", c.SingleLineError(f.Localizer, opts.ColorMode)) + } + + return result.Bytes(), nil +} + +func (f SingleLineFormatter) RenderChecks(checks Checks, opts RenderOpts) ([]byte, error) { + result := bytes.NewBuffer(nil) + + w := tabwriter.NewWriter(result, 1, 1, 1, ' ', 0) + _, _ = fmt.Fprintln(w, "ID\tDESCRIPTION\tLEVEL") + for _, check := range checks { + _, _ = fmt.Fprintln(w, check.Id+"\t"+f.Localizer(check.Description)+"\t"+check.Level) + } + _ = w.Flush() + + return result.Bytes(), nil +} + +func (f SingleLineFormatter) SupportedOutputs() []Output { + return []Output{OutputBreaking, OutputChangelog} +} + +func getBreakingTitle(changes checker.Changes, l checker.Localizer, colorMode checker.ColorMode) string { + count := changes.GetLevelCount() + return l( + "total-errors", + len(changes), + count[checker.ERR], + checker.ERR.StringCond(colorMode), + count[checker.WARN], + checker.WARN.StringCond(colorMode), + ) +} + +func getChangelogTitle(changes checker.Changes, l checker.Localizer, colorMode checker.ColorMode) string { + count := changes.GetLevelCount() + return l( + "total-changes", + len(changes), + count[checker.ERR], + checker.ERR.StringCond(colorMode), + count[checker.WARN], + checker.WARN.StringCond(colorMode), + count[checker.INFO], + checker.INFO.StringCond(colorMode), + ) +} diff --git a/formatters/format_singleline_test.go b/formatters/format_singleline_test.go new file mode 100644 index 00000000..ec175c0f --- /dev/null +++ b/formatters/format_singleline_test.go @@ -0,0 +1,79 @@ +package formatters_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tufin/oasdiff/checker" + "github.com/tufin/oasdiff/formatters" +) + +var singleLineFormatter = formatters.SingleLineFormatter{ + Localizer: MockLocalizer, +} + +func TestSingleLineLookup(t *testing.T) { + f, err := formatters.Lookup(string(formatters.FormatSingleLine), formatters.DefaultFormatterOpts()) + require.NoError(t, err) + require.IsType(t, formatters.SingleLineFormatter{}, f) +} + +func TestSingleLineFormatter_RenderBreakingChanges(t *testing.T) { + testChanges := checker.Changes{ + checker.ComponentChange{ + Id: "change_id", + Level: checker.ERR, + Component: "test", + }, + } + + out, err := singleLineFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) + require.NoError(t, err) + require.Equal(t, "1 breaking changes: 1 error, 0 warning\nerror, in components/test This is a breaking change. [change_id]. \n\n", string(out)) +} + +func TestSingleLineFormatter_RenderChangelog(t *testing.T) { + testChanges := checker.Changes{ + checker.ComponentChange{ + Id: "change_id", + Level: checker.ERR, + Component: "test", + }, + } + + out, err := singleLineFormatter.RenderChangelog(testChanges, formatters.NewRenderOpts(), nil) + require.NoError(t, err) + require.Equal(t, "1 changes: 1 error, 0 warning, 0 info\nerror, in components/test This is a breaking change. [change_id]. \n\n", string(out)) +} + +func TestSingleLineFormatter_RenderChecks(t *testing.T) { + checks := formatters.Checks{ + { + Id: "change_id", + Level: "info", + Description: "This is a breaking change.", + Required: true, + }, + } + + out, err := singleLineFormatter.RenderChecks(checks, formatters.NewRenderOpts()) + require.NoError(t, err) + require.Equal(t, string(out), "ID DESCRIPTION LEVEL\nchange_id This is a breaking change. info\n") +} + +func TestSingleLineFormatter_RenderDiff(t *testing.T) { + out, err := singleLineFormatter.RenderDiff(nil, formatters.NewRenderOpts()) + require.NoError(t, err) + require.Equal(t, string(out), "No changes\n") +} + +func TestSingleLineFormatter_NotImplemented(t *testing.T) { + var err error + + _, err = singleLineFormatter.RenderFlatten(nil, formatters.NewRenderOpts()) + assert.Error(t, err) + + _, err = singleLineFormatter.RenderSummary(nil, formatters.NewRenderOpts()) + assert.Error(t, err) +} diff --git a/formatters/format_text.go b/formatters/format_text.go index 5476db08..6e2fbc8b 100644 --- a/formatters/format_text.go +++ b/formatters/format_text.go @@ -24,21 +24,11 @@ func (f TEXTFormatter) RenderBreakingChanges(changes checker.Changes, opts Rende result := bytes.NewBuffer(nil) if len(changes) > 0 { - count := changes.GetLevelCount() - title := f.Localizer( - "total-errors", - len(changes), - count[checker.ERR], - checker.ERR.PrettyString(), - count[checker.WARN], - checker.WARN.PrettyString(), - ) - - _, _ = fmt.Fprint(result, title) + _, _ = fmt.Fprint(result, getBreakingTitle(changes, f.Localizer, opts.ColorMode)) } for _, c := range changes { - _, _ = fmt.Fprintf(result, "%s\n\n", c.PrettyErrorText(f.Localizer)) + _, _ = fmt.Fprintf(result, "%s\n\n", c.MultiLineError(f.Localizer, opts.ColorMode)) } return result.Bytes(), nil @@ -48,23 +38,11 @@ func (f TEXTFormatter) RenderChangelog(changes checker.Changes, opts RenderOpts, result := bytes.NewBuffer(nil) if len(changes) > 0 { - count := changes.GetLevelCount() - title := f.Localizer( - "total-changes", - len(changes), - count[checker.ERR], - checker.ERR.PrettyString(), - count[checker.WARN], - checker.WARN.PrettyString(), - count[checker.INFO], - checker.INFO.PrettyString(), - ) - - _, _ = fmt.Fprint(result, title) + _, _ = fmt.Fprint(result, getChangelogTitle(changes, f.Localizer, opts.ColorMode)) } for _, c := range changes { - _, _ = fmt.Fprintf(result, "%s\n\n", c.PrettyErrorText(f.Localizer)) + _, _ = fmt.Fprintf(result, "%s\n\n", c.MultiLineError(f.Localizer, opts.ColorMode)) } return result.Bytes(), nil @@ -76,7 +54,7 @@ func (f TEXTFormatter) RenderChecks(checks Checks, opts RenderOpts) ([]byte, err w := tabwriter.NewWriter(result, 1, 1, 1, ' ', 0) _, _ = fmt.Fprintln(w, "ID\tDESCRIPTION\tLEVEL") for _, check := range checks { - _, _ = fmt.Fprintln(w, check.Id+"\t"+check.Description+"\t"+check.Level) + _, _ = fmt.Fprintln(w, check.Id+"\t"+f.Localizer(check.Description)+"\t"+check.Level) } _ = w.Flush() diff --git a/formatters/format_text_test.go b/formatters/format_text_test.go index 661394fb..f97ded03 100644 --- a/formatters/format_text_test.go +++ b/formatters/format_text_test.go @@ -6,56 +6,48 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tufin/oasdiff/checker" - "github.com/tufin/oasdiff/checker/localizations" "github.com/tufin/oasdiff/formatters" ) -func TestTextFormatter_RenderBreakingChanges(t *testing.T) { - formatter, err := formatters.Lookup("text", formatters.FormatterOpts{ - Language: localizations.LangDefault, - }) +var textFormatter = formatters.TEXTFormatter{ + Localizer: MockLocalizer, +} + +func TestTextLookup(t *testing.T) { + f, err := formatters.Lookup(string(formatters.FormatText), formatters.DefaultFormatterOpts()) require.NoError(t, err) + require.IsType(t, formatters.TEXTFormatter{}, f) +} +func TestTextFormatter_RenderBreakingChanges(t *testing.T) { testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, Component: "test", }, } - out, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + out, err := textFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) require.NoError(t, err) - require.Equal(t, string(out), "1 breaking changes: 1 error, 0 warning\nerror, in components/test This is a breaking change. [change_id]. \n\n") + require.Equal(t, "1 breaking changes: 1 error, 0 warning\nerror\t[change_id] \t\n\tin components/test\n\t\tThis is a breaking change.\n\n", string(out)) } func TestTextFormatter_RenderChangelog(t *testing.T) { - formatter, err := formatters.Lookup("text", formatters.FormatterOpts{ - Language: localizations.LangDefault, - }) - require.NoError(t, err) - testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, Component: "test", }, } - out, err := formatter.RenderChangelog(testChanges, formatters.RenderOpts{}, nil) + out, err := textFormatter.RenderChangelog(testChanges, formatters.NewRenderOpts(), nil) require.NoError(t, err) - require.Equal(t, string(out), "1 changes: 1 error, 0 warning, 0 info\nerror, in components/test This is a breaking change. [change_id]. \n\n") + require.Equal(t, "1 changes: 1 error, 0 warning, 0 info\nerror\t[change_id] \t\n\tin components/test\n\t\tThis is a breaking change.\n\n", string(out)) } func TestTextFormatter_RenderChecks(t *testing.T) { - formatter, err := formatters.Lookup("text", formatters.FormatterOpts{ - Language: localizations.LangDefault, - }) - require.NoError(t, err) - checks := formatters.Checks{ { Id: "change_id", @@ -65,31 +57,23 @@ func TestTextFormatter_RenderChecks(t *testing.T) { }, } - out, err := formatter.RenderChecks(checks, formatters.RenderOpts{}) + out, err := textFormatter.RenderChecks(checks, formatters.NewRenderOpts()) require.NoError(t, err) require.Equal(t, string(out), "ID DESCRIPTION LEVEL\nchange_id This is a breaking change. info\n") } func TestTextFormatter_RenderDiff(t *testing.T) { - formatter, err := formatters.Lookup("text", formatters.FormatterOpts{ - Language: localizations.LangDefault, - }) - require.NoError(t, err) - - out, err := formatter.RenderDiff(nil, formatters.RenderOpts{}) + out, err := textFormatter.RenderDiff(nil, formatters.NewRenderOpts()) require.NoError(t, err) require.Equal(t, string(out), "No changes\n") } func TestTextFormatter_NotImplemented(t *testing.T) { - formatter, err := formatters.Lookup("text", formatters.FormatterOpts{ - Language: localizations.LangDefault, - }) - require.NoError(t, err) + var err error - _, err = formatter.RenderFlatten(nil, formatters.RenderOpts{}) + _, err = textFormatter.RenderFlatten(nil, formatters.NewRenderOpts()) assert.Error(t, err) - _, err = formatter.RenderSummary(nil, formatters.RenderOpts{}) + _, err = textFormatter.RenderSummary(nil, formatters.NewRenderOpts()) assert.Error(t, err) } diff --git a/formatters/format_yaml.go b/formatters/format_yaml.go index 57f78901..94ad3013 100644 --- a/formatters/format_yaml.go +++ b/formatters/format_yaml.go @@ -12,6 +12,7 @@ import ( ) type YAMLFormatter struct { + Localizer checker.Localizer } func (f YAMLFormatter) RenderDiff(diff *diff.Diff, opts RenderOpts) ([]byte, error) { @@ -23,11 +24,11 @@ func (f YAMLFormatter) RenderSummary(diff *diff.Diff, opts RenderOpts) ([]byte, } func (f YAMLFormatter) RenderBreakingChanges(changes checker.Changes, opts RenderOpts) ([]byte, error) { - return printYAML(changes) + return printYAML(NewChanges(changes, f.Localizer)) } func (f YAMLFormatter) RenderChangelog(changes checker.Changes, opts RenderOpts, specInfoPair *load.SpecInfoPair) ([]byte, error) { - return printYAML(changes) + return printYAML(NewChanges(changes, f.Localizer)) } func (f YAMLFormatter) RenderChecks(checks Checks, opts RenderOpts) ([]byte, error) { @@ -52,5 +53,5 @@ func printYAML(output interface{}) ([]byte, error) { return nil, fmt.Errorf("failed to marshal YAML: %w", err) } - return StripANSIEscapeCodes(bytes), nil + return bytes, nil } diff --git a/formatters/format_yaml_test.go b/formatters/format_yaml_test.go index b90c404e..c1c0e6b9 100644 --- a/formatters/format_yaml_test.go +++ b/formatters/format_yaml_test.go @@ -8,41 +8,43 @@ import ( "github.com/tufin/oasdiff/formatters" ) -func TestYamlFormatter_RenderBreakingChanges(t *testing.T) { - formatter := formatters.YAMLFormatter{} +var yamlFormatter = formatters.YAMLFormatter{ + Localizer: MockLocalizer, +} + +func TestYamlLookup(t *testing.T) { + f, err := formatters.Lookup(string(formatters.FormatYAML), formatters.DefaultFormatterOpts()) + require.NoError(t, err) + require.IsType(t, formatters.YAMLFormatter{}, f) +} +func TestYamlFormatter_RenderBreakingChanges(t *testing.T) { testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, } - out, err := formatter.RenderBreakingChanges(testChanges, formatters.RenderOpts{}) + out, err := yamlFormatter.RenderBreakingChanges(testChanges, formatters.NewRenderOpts()) require.NoError(t, err) - require.Equal(t, string(out), "- id: change_id\n text: This is a breaking change.\n level: 3\n") + require.Equal(t, "- id: change_id\n text: This is a breaking change.\n level: 3\n section: components\n", string(out)) } func TestYamlFormatter_RenderChangelog(t *testing.T) { - formatter := formatters.YAMLFormatter{} - testChanges := checker.Changes{ checker.ComponentChange{ Id: "change_id", - Text: "This is a breaking change.", Level: checker.ERR, }, } - out, err := formatter.RenderChangelog(testChanges, formatters.RenderOpts{}, nil) + out, err := yamlFormatter.RenderChangelog(testChanges, formatters.NewRenderOpts(), nil) require.NoError(t, err) - require.Equal(t, string(out), "- id: change_id\n text: This is a breaking change.\n level: 3\n") + require.Equal(t, "- id: change_id\n text: This is a breaking change.\n level: 3\n section: components\n", string(out)) } func TestYamlFormatter_RenderChecks(t *testing.T) { - formatter := formatters.YAMLFormatter{} - checks := formatters.Checks{ { Id: "change_id", @@ -52,31 +54,25 @@ func TestYamlFormatter_RenderChecks(t *testing.T) { }, } - out, err := formatter.RenderChecks(checks, formatters.RenderOpts{}) + out, err := yamlFormatter.RenderChecks(checks, formatters.NewRenderOpts()) require.NoError(t, err) - require.Equal(t, string(out), "- id: change_id\n level: info\n description: This is a breaking change.\n reuired: true\n") + require.Equal(t, "- id: change_id\n level: info\n description: This is a breaking change.\n reuired: true\n", string(out)) } func TestYamlFormatter_RenderDiff(t *testing.T) { - formatter := formatters.YAMLFormatter{} - - out, err := formatter.RenderDiff(nil, formatters.RenderOpts{}) + out, err := yamlFormatter.RenderDiff(nil, formatters.NewRenderOpts()) require.NoError(t, err) require.Empty(t, string(out)) } func TestYamlFormatter_RenderFlatten(t *testing.T) { - formatter := formatters.YAMLFormatter{} - - out, err := formatter.RenderFlatten(nil, formatters.RenderOpts{}) + out, err := yamlFormatter.RenderFlatten(nil, formatters.NewRenderOpts()) require.NoError(t, err) require.Empty(t, string(out)) } func TestYamlFormatter_RenderSummary(t *testing.T) { - formatter := formatters.YAMLFormatter{} - - out, err := formatter.RenderSummary(nil, formatters.RenderOpts{}) + out, err := yamlFormatter.RenderSummary(nil, formatters.NewRenderOpts()) require.NoError(t, err) require.Equal(t, string(out), "diff: false\n") } diff --git a/formatters/interface.go b/formatters/interface.go index b5ceaf11..2a0bbc0e 100644 --- a/formatters/interface.go +++ b/formatters/interface.go @@ -26,6 +26,7 @@ var formatters = map[Format]Formatter{ FormatYAML: YAMLFormatter{}, FormatJSON: JSONFormatter{}, FormatText: TEXTFormatter{}, + FormatSingleLine: SingleLineFormatter{}, FormatHTML: HTMLFormatter{}, FormatGithubActions: GitHubActionsFormatter{}, FormatJUnit: JUnitFormatter{}, @@ -34,22 +35,37 @@ var formatters = map[Format]Formatter{ // Lookup returns a formatter by its name func Lookup(format string, opts FormatterOpts) (Formatter, error) { f := Format(format) + l := checker.NewLocalizer(opts.Language) switch f { case FormatYAML: - return YAMLFormatter{}, nil + return YAMLFormatter{ + Localizer: l, + }, nil case FormatJSON: - return JSONFormatter{}, nil + return JSONFormatter{ + Localizer: l, + }, nil case FormatText: return TEXTFormatter{ - Localizer: checker.NewLocalizer(opts.Language), + Localizer: l, + }, nil + case FormatSingleLine: + return SingleLineFormatter{ + Localizer: l, }, nil case FormatHTML: - return HTMLFormatter{}, nil + return HTMLFormatter{ + Localizer: l, + }, nil case FormatGithubActions: - return GitHubActionsFormatter{}, nil + return GitHubActionsFormatter{ + Localizer: l, + }, nil case FormatJUnit: - return JUnitFormatter{}, nil + return JUnitFormatter{ + Localizer: l, + }, nil default: return nil, fmt.Errorf("unsupported format: %s", f) } diff --git a/formatters/interface_test.go b/formatters/interface_test.go index da5961ad..07a42fb4 100644 --- a/formatters/interface_test.go +++ b/formatters/interface_test.go @@ -1,42 +1,51 @@ -package formatters +package formatters_test import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tufin/oasdiff/formatters" ) +func TestUnsupportedLookup(t *testing.T) { + _, err := formatters.Lookup(string("invalid"), formatters.DefaultFormatterOpts()) + require.Error(t, err) +} + func TestDiffOutputFormats(t *testing.T) { - supportedFormats := SupportedFormatsByContentType(OutputDiff) + supportedFormats := formatters.SupportedFormatsByContentType(formatters.OutputDiff) assert.Len(t, supportedFormats, 4) - assert.Contains(t, supportedFormats, string(FormatYAML)) - assert.Contains(t, supportedFormats, string(FormatJSON)) - assert.Contains(t, supportedFormats, string(FormatText)) - assert.Contains(t, supportedFormats, string(FormatHTML)) + assert.Contains(t, supportedFormats, string(formatters.FormatYAML)) + assert.Contains(t, supportedFormats, string(formatters.FormatJSON)) + assert.Contains(t, supportedFormats, string(formatters.FormatText)) + assert.Contains(t, supportedFormats, string(formatters.FormatHTML)) } func TestSummaryOutputFormats(t *testing.T) { - supportedFormats := SupportedFormatsByContentType(OutputSummary) + supportedFormats := formatters.SupportedFormatsByContentType(formatters.OutputSummary) assert.Len(t, supportedFormats, 2) - assert.Contains(t, supportedFormats, string(FormatYAML)) - assert.Contains(t, supportedFormats, string(FormatJSON)) + assert.Contains(t, supportedFormats, string(formatters.FormatYAML)) + assert.Contains(t, supportedFormats, string(formatters.FormatJSON)) } func TestChangelogOutputFormats(t *testing.T) { - supportedFormats := SupportedFormatsByContentType(OutputChangelog) - assert.Len(t, supportedFormats, 4) - assert.Contains(t, supportedFormats, string(FormatYAML)) - assert.Contains(t, supportedFormats, string(FormatJSON)) - assert.Contains(t, supportedFormats, string(FormatText)) - assert.Contains(t, supportedFormats, string(FormatHTML)) + supportedFormats := formatters.SupportedFormatsByContentType(formatters.OutputChangelog) + assert.Len(t, supportedFormats, 5) + assert.Contains(t, supportedFormats, string(formatters.FormatYAML)) + assert.Contains(t, supportedFormats, string(formatters.FormatJSON)) + assert.Contains(t, supportedFormats, string(formatters.FormatText)) + assert.Contains(t, supportedFormats, string(formatters.FormatSingleLine)) + assert.Contains(t, supportedFormats, string(formatters.FormatHTML)) } func TestBreakingChangesOutputFormats(t *testing.T) { - supportedFormats := SupportedFormatsByContentType(OutputBreaking) - assert.Len(t, supportedFormats, 5) - assert.Contains(t, supportedFormats, string(FormatYAML)) - assert.Contains(t, supportedFormats, string(FormatJSON)) - assert.Contains(t, supportedFormats, string(FormatText)) - assert.Contains(t, supportedFormats, string(FormatGithubActions)) - assert.Contains(t, supportedFormats, string(FormatJUnit)) + supportedFormats := formatters.SupportedFormatsByContentType(formatters.OutputBreaking) + assert.Len(t, supportedFormats, 6) + assert.Contains(t, supportedFormats, string(formatters.FormatYAML)) + assert.Contains(t, supportedFormats, string(formatters.FormatJSON)) + assert.Contains(t, supportedFormats, string(formatters.FormatText)) + assert.Contains(t, supportedFormats, string(formatters.FormatSingleLine)) + assert.Contains(t, supportedFormats, string(formatters.FormatGithubActions)) + assert.Contains(t, supportedFormats, string(formatters.FormatJUnit)) } diff --git a/formatters/templates/changelog.html b/formatters/templates/changelog.html index 1d3354ca..83d30d80 100644 --- a/formatters/templates/changelog.html +++ b/formatters/templates/changelog.html @@ -118,7 +118,7 @@ {{ end }} - {{ .GetText }} + {{ .Text }} {{ end }} diff --git a/formatters/types.go b/formatters/types.go index 194d6d1f..ef5882ea 100644 --- a/formatters/types.go +++ b/formatters/types.go @@ -1,11 +1,14 @@ package formatters +import "github.com/tufin/oasdiff/checker" + type Format string const ( FormatYAML Format = "yaml" FormatJSON Format = "json" FormatText Format = "text" + FormatSingleLine Format = "singleline" FormatHTML Format = "html" FormatGithubActions Format = "githubactions" FormatJUnit Format = "junit" @@ -19,4 +22,11 @@ type FormatterOpts struct { // RenderOpts can be used to pass properties to the renderer method type RenderOpts struct { + ColorMode checker.ColorMode +} + +func NewRenderOpts() RenderOpts { + return RenderOpts{ + ColorMode: checker.ColorAuto, + } } diff --git a/formatters/util.go b/formatters/util.go deleted file mode 100644 index 090578ea..00000000 --- a/formatters/util.go +++ /dev/null @@ -1,19 +0,0 @@ -package formatters - -import ( - "regexp" -) - -var stripAnsiEscapesRegex = regexp.MustCompile(`\\u001b\[[0-9]*m|\\e\[[0-9]*m`) - -// StripANSIEscapeCodes removes ANSI escape codes -// TODO: remove this function once there is a better way to prevent ANSI escape codes in messages for json/yaml output -func StripANSIEscapeCodes(data []byte) []byte { - return stripAnsiEscapesRegex.ReplaceAll(data, nil) -} - -// StripANSIEscapeCodesStr removes ANSI escape codes -// TODO: remove this function once there is a better way to prevent ANSI escape codes in messages for json/yaml output -func StripANSIEscapeCodesStr(data string) string { - return stripAnsiEscapesRegex.ReplaceAllString(data, "") -} diff --git a/formatters/util_test.go b/formatters/util_test.go deleted file mode 100644 index 2d856da0..00000000 --- a/formatters/util_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package formatters - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStripANSIEscapeCodes(t *testing.T) { - input := "deleted the \\u001b[1m'header'\\u001b[0m request parameter \\u001b[1m'network-policies'\\u001b[0m" - output := StripANSIEscapeCodes([]byte(input)) - expectedOutput := "deleted the 'header' request parameter 'network-policies'" - assert.Equal(t, expectedOutput, string(output)) -} diff --git a/internal/breaking_changes.go b/internal/breaking_changes.go index 6d95d9ba..78134849 100644 --- a/internal/breaking_changes.go +++ b/internal/breaking_changes.go @@ -42,6 +42,7 @@ func getBreakingChangesCmd() *cobra.Command { cmd.PersistentFlags().VarP(newEnumSliceValue(checker.GetOptionalChecks(), nil, &flags.includeChecks), "include-checks", "i", "comma-separated list of optional checks (run 'oasdiff checks --required false' to see options)") cmd.PersistentFlags().IntVarP(&flags.deprecationDaysBeta, "deprecation-days-beta", "", checker.BetaDeprecationDays, "min days required between deprecating a beta resource and removing it") cmd.PersistentFlags().IntVarP(&flags.deprecationDaysStable, "deprecation-days-stable", "", checker.StableDeprecationDays, "min days required between deprecating a stable resource and removing it") + enumWithOptions(&cmd, newEnumValue([]string{"auto", "always", "never"}, "auto", &flags.color), "color", "", "when to output colored escape sequences") return &cmd } @@ -50,7 +51,7 @@ func runBreakingChanges(flags Flags, stdout io.Writer) (bool, *ReturnError) { return getChangelog(flags, stdout, checker.WARN) } -func outputBreakingChanges(format string, lang string, stdout io.Writer, errs checker.Changes) *ReturnError { +func outputBreakingChanges(format string, lang string, color string, stdout io.Writer, errs checker.Changes) *ReturnError { // formatter lookup formatter, err := formatters.Lookup(format, formatters.FormatterOpts{ Language: lang, @@ -60,7 +61,12 @@ func outputBreakingChanges(format string, lang string, stdout io.Writer, errs ch } // render - bytes, err := formatter.RenderBreakingChanges(errs, formatters.RenderOpts{}) + colorMode, err := checker.NewColorMode(color) + if err != nil { + return getErrInvalidColorMode(err) + } + + bytes, err := formatter.RenderBreakingChanges(errs, formatters.RenderOpts{ColorMode: colorMode}) if err != nil { return getErrFailedPrint("breaking "+format, err) } diff --git a/internal/changelog.go b/internal/changelog.go index 5133df47..c7443775 100644 --- a/internal/changelog.go +++ b/internal/changelog.go @@ -43,6 +43,7 @@ func getChangelogCmd() *cobra.Command { cmd.PersistentFlags().VarP(newEnumSliceValue(checker.GetOptionalChecks(), nil, &flags.includeChecks), "include-checks", "i", "comma-separated list of optional checks (run 'oasdiff checks --required false' to see options)") cmd.PersistentFlags().IntVarP(&flags.deprecationDaysBeta, "deprecation-days-beta", "", checker.BetaDeprecationDays, "min days required between deprecating a beta resource and removing it") cmd.PersistentFlags().IntVarP(&flags.deprecationDaysStable, "deprecation-days-stable", "", checker.StableDeprecationDays, "min days required between deprecating a stable resource and removing it") + enumWithOptions(&cmd, newEnumValue([]string{"auto", "always", "never"}, "auto", &flags.color), "color", "", "when to output colored escape sequences") return &cmd } @@ -65,11 +66,12 @@ func getChangelog(flags Flags, stdout io.Writer, level checker.Level) (bool, *Re } bcConfig := checker.GetAllChecks(flags.getIncludeChecks(), flags.getDeprecationDaysBeta(), flags.getDeprecationDaysStable()) - bcConfig.Localize = checker.NewLocalizer(flags.getLang()) errs, returnErr := filterIgnored( checker.CheckBackwardCompatibilityUntilLevel(bcConfig, diffResult.diffReport, diffResult.operationsSources, level), - flags.getWarnIgnoreFile(), flags.getErrIgnoreFile()) + flags.getWarnIgnoreFile(), + flags.getErrIgnoreFile(), + checker.NewLocalizer(flags.getLang())) if returnErr != nil { return false, returnErr @@ -77,12 +79,12 @@ func getChangelog(flags Flags, stdout io.Writer, level checker.Level) (bool, *Re if level == checker.WARN { // breaking changes - if returnErr := outputBreakingChanges(flags.getFormat(), flags.getLang(), stdout, errs); returnErr != nil { + if returnErr := outputBreakingChanges(flags.getFormat(), flags.getLang(), flags.getColor(), stdout, errs); returnErr != nil { return false, returnErr } } else { // changelog - if returnErr := outputChangelog(flags.getFormat(), flags.getLang(), stdout, errs, diffResult.specInfoPair); returnErr != nil { + if returnErr := outputChangelog(flags.getFormat(), flags.getLang(), flags.getColor(), stdout, errs, diffResult.specInfoPair); returnErr != nil { return false, returnErr } } @@ -98,11 +100,11 @@ func getChangelog(flags Flags, stdout io.Writer, level checker.Level) (bool, *Re return false, nil } -func filterIgnored(errs checker.Changes, warnIgnoreFile string, errIgnoreFile string) (checker.Changes, *ReturnError) { +func filterIgnored(errs checker.Changes, warnIgnoreFile string, errIgnoreFile string, l checker.Localizer) (checker.Changes, *ReturnError) { if warnIgnoreFile != "" { var err error - errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.WARN, errs, warnIgnoreFile) + errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.WARN, errs, warnIgnoreFile, l) if err != nil { return nil, getErrCantProcessIgnoreFile("warn", err) } @@ -110,7 +112,7 @@ func filterIgnored(errs checker.Changes, warnIgnoreFile string, errIgnoreFile st if errIgnoreFile != "" { var err error - errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, errIgnoreFile) + errs, err = checker.ProcessIgnoredBackwardCompatibilityErrors(checker.ERR, errs, errIgnoreFile, l) if err != nil { return nil, getErrCantProcessIgnoreFile("err", err) } @@ -119,7 +121,7 @@ func filterIgnored(errs checker.Changes, warnIgnoreFile string, errIgnoreFile st return errs, nil } -func outputChangelog(format string, lang string, stdout io.Writer, errs checker.Changes, specInfoPair *load.SpecInfoPair) *ReturnError { +func outputChangelog(format string, lang string, color string, stdout io.Writer, errs checker.Changes, specInfoPair *load.SpecInfoPair) *ReturnError { // formatter lookup formatter, err := formatters.Lookup(format, formatters.FormatterOpts{ Language: lang, @@ -129,7 +131,12 @@ func outputChangelog(format string, lang string, stdout io.Writer, errs checker. } // render - bytes, err := formatter.RenderChangelog(errs, formatters.RenderOpts{}, specInfoPair) + colorMode, err := checker.NewColorMode(color) + if err != nil { + return getErrInvalidColorMode(err) + } + + bytes, err := formatter.RenderChangelog(errs, formatters.RenderOpts{ColorMode: colorMode}, specInfoPair) if err != nil { return getErrFailedPrint("changelog "+format, err) } diff --git a/internal/changelog_flags.go b/internal/changelog_flags.go index f6a08135..efb27e47 100644 --- a/internal/changelog_flags.go +++ b/internal/changelog_flags.go @@ -27,6 +27,7 @@ type ChangelogFlags struct { warnIgnoreFile string deprecationDaysBeta int deprecationDaysStable int + color string } func (flags *ChangelogFlags) toConfig() *diff.Config { @@ -78,6 +79,10 @@ func (flags *ChangelogFlags) getLang() string { return flags.lang } +func (flags *ChangelogFlags) getColor() string { + return flags.color +} + func (flags *ChangelogFlags) getWarnIgnoreFile() string { return flags.warnIgnoreFile } diff --git a/internal/checks.go b/internal/checks.go index 4857d108..30ea078d 100644 --- a/internal/checks.go +++ b/internal/checks.go @@ -53,17 +53,17 @@ func getChecksCmd() *cobra.Command { } func runChecks(stdout io.Writer, flags ChecksFlags) *ReturnError { - return outputChecks(stdout, flags, getRules(flags.required, checker.NewLocalizer(flags.lang))) + return outputChecks(stdout, flags, getRules(flags.required)) } -func getRules(required string, l checker.Localizer) []checker.BackwardCompatibilityRule { +func getRules(required string) []checker.BackwardCompatibilityRule { switch required { case "all": - return checker.GetAllRules(l) + return checker.GetAllRules() case "false": - return checker.GetOptionalRules(l) + return checker.GetOptionalRules() case "true": - return checker.GetRequiredRules(l) + return checker.GetRequiredRules() } return nil @@ -118,7 +118,7 @@ func outputChecks(stdout io.Writer, flags ChecksFlags, rules []checker.BackwardC // render sort.Sort(checks) - bytes, err := formatter.RenderChecks(checks, formatters.RenderOpts{}) + bytes, err := formatter.RenderChecks(checks, formatters.NewRenderOpts()) if err != nil { return getErrFailedPrint("checks "+flags.format, err) } diff --git a/internal/diff.go b/internal/diff.go index 5b859030..618fcf28 100644 --- a/internal/diff.go +++ b/internal/diff.go @@ -69,7 +69,7 @@ func outputDiff(stdout io.Writer, diffReport *diff.Diff, format string) *ReturnE } // render - bytes, err := formatter.RenderDiff(diffReport, formatters.RenderOpts{}) + bytes, err := formatter.RenderDiff(diffReport, formatters.NewRenderOpts()) if err != nil { return getErrFailedPrint("diff "+format, err) } diff --git a/internal/diff_flags.go b/internal/diff_flags.go index e65a2712..1a06bce9 100644 --- a/internal/diff_flags.go +++ b/internal/diff_flags.go @@ -72,6 +72,10 @@ func (flags *DiffFlags) getLang() string { return "" } +func (flags *DiffFlags) getColor() string { + return "" +} + func (flags *DiffFlags) getWarnIgnoreFile() string { return "" } diff --git a/internal/errors.go b/internal/errors.go index e39f2caf..204e2a3a 100644 --- a/internal/errors.go +++ b/internal/errors.go @@ -25,6 +25,13 @@ func getErrFailedToLoadSpec(what string, source load.Source, err error) *ReturnE } } +func getErrFailedToFlattenSpec(what string, source load.Source, err error) *ReturnError { + return &ReturnError{ + error: fmt.Errorf("failed to flatten %s spec from %s with %v", what, source.Out(), err), + Code: 102, + } +} + func getErrFailedToLoadSpecs(what string, path string, err error) *ReturnError { return &ReturnError{ error: fmt.Errorf("failed to load %s specs from glob %q with %v", what, path, err), @@ -81,16 +88,16 @@ func getErrUnsupportedChecksFormat(format string) *ReturnError { } } -func getErrCantProcessIgnoreFile(what string, err error) *ReturnError { +func getErrInvalidColorMode(err error) *ReturnError { return &ReturnError{ - error: fmt.Errorf("can't process %s ignore file %v", what, err), - Code: 121, + error: err, + Code: 114, } } -func getErrFailedToFlattenSpec(what string, source load.Source, err error) *ReturnError { +func getErrCantProcessIgnoreFile(what string, err error) *ReturnError { return &ReturnError{ - error: fmt.Errorf("failed to flatten %s spec from %s with %v", what, source.Out(), err), - Code: 102, + error: fmt.Errorf("can't process %s ignore file %v", what, err), + Code: 121, } } diff --git a/internal/flags.go b/internal/flags.go index f45da8b8..d26e4b64 100644 --- a/internal/flags.go +++ b/internal/flags.go @@ -17,6 +17,7 @@ type Flags interface { getDeprecationDaysBeta() int getDeprecationDaysStable() int getLang() string + getColor() string getWarnIgnoreFile() string getErrIgnoreFile() string getFormat() string diff --git a/internal/flatten.go b/internal/flatten.go index 1a33dced..e3297dbd 100644 --- a/internal/flatten.go +++ b/internal/flatten.go @@ -79,7 +79,7 @@ func outputFlattenedSpec(stdout io.Writer, spec *openapi3.T, format string) *Ret } // render - bytes, err := formatter.RenderFlatten(spec, formatters.RenderOpts{}) + bytes, err := formatter.RenderFlatten(spec, formatters.NewRenderOpts()) if err != nil { return getErrFailedPrint("flatten "+format, err) } diff --git a/internal/summary.go b/internal/summary.go index 2de835cc..cdeb3589 100644 --- a/internal/summary.go +++ b/internal/summary.go @@ -61,7 +61,7 @@ func outputSummary(stdout io.Writer, diffReport *diff.Diff, format string) *Retu } // render - bytes, err := formatter.RenderSummary(diffReport, formatters.RenderOpts{}) + bytes, err := formatter.RenderSummary(diffReport, formatters.NewRenderOpts()) if err != nil { return getErrFailedPrint("summary "+format, err) } diff --git a/lint/checker.go b/lint/checker.go index 247b6838..83221f35 100644 --- a/lint/checker.go +++ b/lint/checker.go @@ -48,7 +48,7 @@ func (e Errors) Swap(i, j int) { e[i], e[j] = e[j], e[i] } -func Run(config Config, source string, spec *load.SpecInfo) Errors { +func Run(config *Config, source string, spec *load.SpecInfo) Errors { result := make(Errors, 0) if spec == nil { diff --git a/lint/checker_test.go b/lint/checker_test.go index 95de2e35..0ad7d896 100644 --- a/lint/checker_test.go +++ b/lint/checker_test.go @@ -21,5 +21,5 @@ func loadFrom(t *testing.T, path string) *load.SpecInfo { func TestRun(t *testing.T) { const source = "../data/lint/openapi.yaml" - require.Empty(t, lint.Run(*lint.DefaultConfig(), source, loadFrom(t, source))) + require.Empty(t, lint.Run(lint.DefaultConfig(), source, loadFrom(t, source))) } diff --git a/lint/info_test.go b/lint/info_test.go index 9976987d..48ba7240 100644 --- a/lint/info_test.go +++ b/lint/info_test.go @@ -10,7 +10,7 @@ import ( func TestInfo_NoInfo(t *testing.T) { const source = "../data/lint/info/no-info.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.InfoCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.InfoCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "info-missing", errs[0].Id) require.Equal(t, lint.LEVEL_ERROR, errs[0].Level) @@ -20,7 +20,7 @@ func TestInfo_NoInfo(t *testing.T) { func TestInfo_TitleMissing(t *testing.T) { const source = "../data/lint/info/title-missing.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.InfoCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.InfoCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "info-title-missing", errs[0].Id) require.Equal(t, lint.LEVEL_ERROR, errs[0].Level) @@ -30,7 +30,7 @@ func TestInfo_TitleMissing(t *testing.T) { func TestInfo_VersionMissing(t *testing.T) { const source = "../data/lint/info/version-missing.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.InfoCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.InfoCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "info-version-missing", errs[0].Id) require.Equal(t, lint.LEVEL_ERROR, errs[0].Level) @@ -40,7 +40,7 @@ func TestInfo_VersionMissing(t *testing.T) { func TestInfo_InvalidTOS(t *testing.T) { const source = "../data/lint/info/invalid-terms-of-service.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.InfoCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.InfoCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "info-invalid-terms-of-service", errs[0].Id) require.Equal(t, lint.LEVEL_ERROR, errs[0].Level) diff --git a/lint/path_params_test.go b/lint/path_params_test.go index 78c5250f..3e69e79f 100644 --- a/lint/path_params_test.go +++ b/lint/path_params_test.go @@ -9,19 +9,19 @@ import ( func TestPathParam_PathOK(t *testing.T) { const source = "../data/lint/path-params/path.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) require.Empty(t, errs) } func TestPathParam_MethodOK(t *testing.T) { const source = "../data/lint/path-params/method.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) require.Empty(t, errs) } func TestPathParam_MethodExtra(t *testing.T) { const source = "../data/lint/path-params/method-extra.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "path-param-extra", errs[0].Id) require.Equal(t, "path parameter \"bookId\" appears in the parameters section of the operation but is missing in the URL: GET /books", errs[0].Text) @@ -31,7 +31,7 @@ func TestPathParam_MethodExtra(t *testing.T) { func TestPathParam_PathExtra(t *testing.T) { const source = "../data/lint/path-params/path-extra.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "path-param-extra", errs[0].Id) require.Equal(t, "path parameter \"bookId\" appears in the parameters section of the path but is missing in the URL: GET /books", errs[0].Text) @@ -41,7 +41,7 @@ func TestPathParam_PathExtra(t *testing.T) { func TestPathParam_PathMissing(t *testing.T) { const source = "../data/lint/path-params/path-missing.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "path-param-missing", errs[0].Id) require.Equal(t, "path parameter \"bookId\" appears in the URL path but is missing from the parameters section of the path and operation: GET /books/{bookId}", errs[0].Text) @@ -51,7 +51,7 @@ func TestPathParam_PathMissing(t *testing.T) { func TestPathParam_Duplicate(t *testing.T) { const source = "../data/lint/path-params/duplicate.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "path-param-duplicate", errs[0].Id) require.Equal(t, "path parameter \"bookId\" is defined both in path and in operation: GET /books/{bookId}", errs[0].Text) @@ -61,7 +61,7 @@ func TestPathParam_Duplicate(t *testing.T) { func TestPathParam_NotRequired(t *testing.T) { const source = "../data/lint/path-params/not-required.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.PathParamsCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "path-param-not-required", errs[0].Id) require.Equal(t, "path parameter \"bookId\" should have required=true: GET /books/{bookId}", errs[0].Text) diff --git a/lint/regexp_test.go b/lint/regexp_test.go index ff738ea6..a6420ef7 100644 --- a/lint/regexp_test.go +++ b/lint/regexp_test.go @@ -10,7 +10,7 @@ import ( func TestRegexCheck(t *testing.T) { const source = "../data/lint/regex/openapi-invalid-regex.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "invalid-regex-pattern", errs[0].Id) require.Equal(t, lint.LEVEL_ERROR, errs[0].Level) @@ -20,7 +20,7 @@ func TestRegexCheck(t *testing.T) { func TestRegexCheck_Embedded(t *testing.T) { const source = "../data/lint/regex/openapi-invalid-regex-embedded.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) require.Len(t, errs, 7) for i := range errs { require.Equal(t, "invalid-regex-pattern", errs[i].Id) @@ -32,6 +32,6 @@ func TestRegexCheck_Embedded(t *testing.T) { func TestRegexCheck_Circular(t *testing.T) { const source = "../data/circular2.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) require.Empty(t, errs) } diff --git a/lint/required_params_test.go b/lint/required_params_test.go index bb5827ce..4e738c0e 100644 --- a/lint/required_params_test.go +++ b/lint/required_params_test.go @@ -9,13 +9,13 @@ import ( func TestRequiredParam_PathOK(t *testing.T) { const source = "../data/lint/required-params/path.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.RequiredParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.RequiredParamsCheck}), source, loadFrom(t, source)) require.Empty(t, errs) } func TestRequiredParam_PathWithDefault(t *testing.T) { const source = "../data/lint/required-params/path_with_default.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.RequiredParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.RequiredParamsCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "required-param-with-default", errs[0].Id) require.Equal(t, "required path parameter \"bookId\" shouldn't have a default value: /books/{bookId}", errs[0].Text) @@ -25,7 +25,7 @@ func TestRequiredParam_PathWithDefault(t *testing.T) { func TestRequiredParam_MethodWithDefault(t *testing.T) { const source = "../data/lint/required-params/method_with_default.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.RequiredParamsCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.RequiredParamsCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "required-param-with-default", errs[0].Id) require.Equal(t, "required path parameter \"bookId\" shouldn't have a default value: GET /books/{bookId}", errs[0].Text) diff --git a/lint/required_properties_test.go b/lint/required_properties_test.go index 0c3df809..ffc7ede7 100644 --- a/lint/required_properties_test.go +++ b/lint/required_properties_test.go @@ -10,14 +10,14 @@ import ( func TestRequirePropertiesCheck_OK(t *testing.T) { const source = "../data/lint/required-properties/ok.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) require.Empty(t, errs) } func TestRequirePropertiesCheck_Extra(t *testing.T) { const source = "../data/lint/required-properties/extra.yaml" - errs := lint.Run(*lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) + errs := lint.Run(lint.NewConfig([]lint.Check{lint.SchemaCheck}), source, loadFrom(t, source)) require.Len(t, errs, 1) require.Equal(t, "extra_required_props", errs[0].Id) require.Equal(t, lint.LEVEL_ERROR, errs[0].Level)