├── .circleci └── config.yml ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ ├── feature_request.yaml │ └── question.yaml ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── dep_build_v2.yml │ ├── dep_build_v3.yml │ └── main.yml ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .travis.yml ├── LICENSE ├── README.md ├── SECURITY.md ├── docs ├── javadoc │ ├── 2.10 │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com │ │ │ └── fasterxml │ │ │ │ └── jackson │ │ │ │ └── module │ │ │ │ └── kotlin │ │ │ │ ├── PackageVersion.html │ │ │ │ ├── class-use │ │ │ │ └── PackageVersion.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── script.js │ │ └── stylesheet.css │ ├── 2.11 │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com │ │ │ └── fasterxml │ │ │ │ └── jackson │ │ │ │ └── module │ │ │ │ └── kotlin │ │ │ │ ├── PackageVersion.html │ │ │ │ ├── class-use │ │ │ │ └── PackageVersion.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── script.js │ │ └── stylesheet.css │ ├── 2.12 │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com │ │ │ └── fasterxml │ │ │ │ └── jackson │ │ │ │ └── module │ │ │ │ └── kotlin │ │ │ │ ├── PackageVersion.html │ │ │ │ ├── class-use │ │ │ │ └── PackageVersion.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── script.js │ │ └── stylesheet.css │ ├── 2.13 │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com │ │ │ └── fasterxml │ │ │ │ └── jackson │ │ │ │ └── module │ │ │ │ └── kotlin │ │ │ │ ├── PackageVersion.html │ │ │ │ ├── class-use │ │ │ │ └── PackageVersion.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── script.js │ │ └── stylesheet.css │ ├── 2.14 │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com │ │ │ └── fasterxml │ │ │ │ └── jackson │ │ │ │ └── module │ │ │ │ └── kotlin │ │ │ │ ├── PackageVersion.html │ │ │ │ ├── class-use │ │ │ │ └── PackageVersion.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── script.js │ │ └── stylesheet.css │ ├── 2.6 │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com │ │ │ └── fasterxml │ │ │ │ └── jackson │ │ │ │ └── module │ │ │ │ └── kotlin │ │ │ │ ├── PackageVersion.html │ │ │ │ ├── class-use │ │ │ │ └── PackageVersion.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── resources │ │ │ ├── background.gif │ │ │ ├── tab.gif │ │ │ ├── titlebar.gif │ │ │ └── titlebar_end.gif │ │ └── stylesheet.css │ ├── 2.8 │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com │ │ │ └── fasterxml │ │ │ │ └── jackson │ │ │ │ └── module │ │ │ │ └── kotlin │ │ │ │ ├── PackageVersion.html │ │ │ │ ├── class-use │ │ │ │ └── PackageVersion.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── resources │ │ │ ├── background.gif │ │ │ ├── tab.gif │ │ │ ├── titlebar.gif │ │ │ └── titlebar_end.gif │ │ └── stylesheet.css │ └── 2.9 │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com │ │ └── fasterxml │ │ │ └── jackson │ │ │ └── module │ │ │ └── kotlin │ │ │ ├── PackageVersion.html │ │ │ ├── class-use │ │ │ └── PackageVersion.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── script.js │ │ └── stylesheet.css ├── value-class-handling.md └── value-class-support.md ├── mvnw ├── mvnw.cmd ├── pom.xml ├── release-notes ├── CREDITS-2.x └── VERSION-2.x └── src ├── main ├── java │ └── com │ │ └── fasterxml │ │ └── jackson │ │ └── module │ │ └── kotlin │ │ ├── PackageVersion.java.in │ │ └── WrapsNullableValueClassDeserializer.java ├── kotlin │ └── com │ │ └── fasterxml │ │ └── jackson │ │ └── module │ │ └── kotlin │ │ ├── ArgumentBucket.kt │ │ ├── ConstructorValueCreator.kt │ │ ├── Converters.kt │ │ ├── Exceptions.kt │ │ ├── Extensions.kt │ │ ├── InternalCommons.kt │ │ ├── KotlinAnnotationIntrospector.kt │ │ ├── KotlinBeanDeserializerModifier.kt │ │ ├── KotlinDeserializers.kt │ │ ├── KotlinFeature.kt │ │ ├── KotlinKeyDeserializers.kt │ │ ├── KotlinKeySerializers.kt │ │ ├── KotlinMixins.kt │ │ ├── KotlinModule.kt │ │ ├── KotlinNamesAnnotationIntrospector.kt │ │ ├── KotlinObjectSingletonDeserializer.kt │ │ ├── KotlinSerializers.kt │ │ ├── KotlinValueInstantiator.kt │ │ ├── MethodValueCreator.kt │ │ ├── ReflectionCache.kt │ │ ├── UnsignedNumbers.kt │ │ └── ValueCreator.kt └── resources │ └── META-INF │ ├── LICENSE │ ├── NOTICE │ └── services │ └── com.fasterxml.jackson.databind.Module ├── moditect └── module-info.java └── test └── kotlin └── com └── fasterxml └── jackson └── module └── kotlin ├── ArgumentBucketTest.kt ├── DslTest.kt ├── JDKSerializabilityTestHelper.kt ├── KotlinInstantiatorsTest.kt ├── KotlinModuleTest.kt ├── MissingKotlinParameterExceptionTest.kt ├── README.md ├── ReadValueTest.kt ├── ReadValuesTest.kt ├── ReflectionCacheTest.kt ├── TestCommons.kt ├── kogeraIntegration ├── README.md ├── deser │ ├── StrictNullChecksTest.kt │ └── valueClass │ │ ├── JacksonInjectTest.kt │ │ ├── NullableObjectEdgeCases.kt │ │ ├── ValueClasses.kt │ │ ├── WithoutCustomDeserializeMethodTest.kt │ │ ├── defaultArgument │ │ ├── NonNullObjectTest.kt │ │ ├── NullableObjectTest.kt │ │ ├── NullablePrimitiveTest.kt │ │ ├── PrimitiveTest.kt │ │ └── TwoUnitPrimitiveTest.kt │ │ ├── deserializer │ │ ├── SpecifiedForObjectMapperTest.kt │ │ └── byAnnotation │ │ │ ├── SpecifiedForClassTest.kt │ │ │ └── specifiedForProperty │ │ │ ├── NonNullObjectTest.kt │ │ │ ├── NullableObjectTest.kt │ │ │ ├── NullablePrimitiveTest.kt │ │ │ ├── PrimitiveTest.kt │ │ │ └── TwoUnitPrimitiveTest.kt │ │ ├── jsonCreator │ │ ├── HandledByJacksonTest.kt │ │ ├── HandledByKogeraTest.kt │ │ └── InCreatorArgumentTest.kt │ │ ├── mapKey │ │ ├── WithoutCustomDeserializeMethodTest.kt │ │ └── keyDeserializer │ │ │ ├── SpecifiedForObjectMapperTest.kt │ │ │ └── byAnnotation │ │ │ ├── SpecifiedForClassTest.kt │ │ │ └── SpecifiedForPropertyTest.kt │ │ └── parameterSize │ │ ├── nonNullObject │ │ ├── DeserializeByConstructorWithDefaultArgumentsTest.kt │ │ ├── DeserializeByConstructorWithoutDefaultArgumentsTest.kt │ │ ├── DeserializeByFactoryWithDefaultArgumentsTest.kt │ │ └── DeserializeByFactoryWithoutDefaultArgumentsTest.kt │ │ ├── nullableObject │ │ ├── DeserializeByConstructorWithDefaultArgumentsTest.kt │ │ ├── DeserializeByConstructorWithoutDefaultArgumentsTest.kt │ │ ├── DeserializeByFactoryWithDefaultArgumentsTest.kt │ │ └── DeserializeByFactoryWithoutDefaultArgumentsTest.kt │ │ ├── nullablePrimitive │ │ ├── DeserializeByConstructorWithDefaultArgumentsTest.kt │ │ ├── DeserializeByConstructorWithoutDefaultArgumentsTest.kt │ │ ├── DeserializeByFactoryWithDefaultArgumentsTest.kt │ │ └── DeserializeByFactoryWithoutDefaultArgumentsTest.kt │ │ ├── primitive │ │ ├── DeserializeByConstructorWithDefaultArgumentsTest.kt │ │ ├── DeserializeByConstructorWithoutDefaultArgumentsTest.kt │ │ ├── DeserializeByFactoryWithDefaultArgumentsTest.kt │ │ └── DeserializeByFactoryWithoutDefaultArgumentsTest.kt │ │ └── twoUnitPrimitive │ │ ├── DeserializeByConstructorWithDefaultArgumentsTest.kt │ │ ├── DeserializeByConstructorWithoutDefaultArgumentsTest.kt │ │ ├── DeserializeByFactoryWithDefaultArgumentsTest.kt │ │ └── DeserializeByFactoryWithoutDefaultArgumentsTest.kt └── ser │ └── valueClass │ ├── JsonKeyTest.kt │ ├── WithoutCustomSerializeMethodTest.kt │ ├── jsonInclude │ ├── JsonIncludeCustomTest.kt │ ├── JsonIncludeNonNullTest.kt │ └── ValueClasses.kt │ └── serializer │ ├── SpecifiedForObjectMapperTest.kt │ ├── ValueClasses.kt │ └── byAnnotation │ ├── nonNullObject │ └── ByAnnotationTest.kt │ ├── nullableObject │ ├── NonNullValueTest.kt │ └── NullValueTest.kt │ ├── nullablePrimitive │ ├── NonNullValueTest.kt │ └── NullValueTest.kt │ ├── primitive │ └── ByAnnotationTest.kt │ └── twoUnitPrimitive │ └── ByAnnotationTest.kt └── test ├── DurationTests.kt ├── ExtensionMethodsTests.kt ├── FailNullForPrimitiveTest.kt ├── IteratorTests.kt ├── KClassSerializerDeserializerTest.kt ├── KotlinBuiltinsTest.kt ├── KotlinFeatures.kt ├── NullToDefaultTests.kt ├── NullToEmptyCollectionTest.kt ├── NullToEmptyMapTest.kt ├── ObjectSingletonTest.kt ├── ParameterNameTests.kt ├── PropertyRequirednessTests.kt ├── SealedClassTest.kt ├── SequenceSerdesTests.kt ├── StrictNullChecksTest.kt ├── StrictNullChecksTestOld.kt ├── TestHelpers.kt ├── TestHelpersTest.kt ├── UnsignedNumbersOnKeyTest.kt ├── UnsignedNumbersTests.kt ├── VarargDeserTest.kt ├── github ├── CloneableJavaObj.java ├── GitHub281.kt ├── GitHub314.kt ├── GitHub338.kt ├── GitHub524.kt ├── GitHub530.kt ├── GitHub618.kt ├── GitHub625.kt ├── GitHub757.kt ├── GitHub800.kt ├── GitHub832.kt ├── GitHub841.kt ├── GitHub844.kt ├── GitHub873.kt ├── GitHub876.kt ├── GitHub917.kt ├── GitHub922.kt ├── GitHub922RequiredCollectionsDtoJava.java ├── GitHub976.kt ├── Github101.kt ├── Github104.kt ├── Github114.kt ├── Github120.kt ├── Github124.kt ├── Github131.kt ├── Github145.kt ├── Github148.kt ├── Github149.kt ├── Github15.kt ├── Github153.kt ├── Github155.kt ├── Github158.kt ├── Github161.kt ├── Github165.kt ├── Github165JavaTest.java ├── Github167.kt ├── Github168.kt ├── Github179.kt ├── Github180.kt ├── Github181.kt ├── Github194.kt ├── Github196.kt ├── Github207.kt ├── Github210.kt ├── Github22.kt ├── Github239.kt ├── Github25.kt ├── Github26.kt ├── Github269.kt ├── Github27.kt ├── Github270.kt ├── Github29.kt ├── Github308.kt ├── Github32.kt ├── Github335.kt ├── Github340.kt ├── Github356.kt ├── Github396.kt ├── Github42.kt ├── Github46.kt ├── Github464.kt ├── Github47.kt ├── Github490.kt ├── Github50.kt ├── Github52.kt ├── Github526.kt ├── Github536.kt ├── Github56.kt ├── Github57.kt ├── Github62.kt ├── Github630.kt ├── Github710.kt ├── Github722.kt ├── Github738.kt ├── Github80.kt ├── Github88.kt ├── Github91.kt ├── GithubDatabind1005Test.kt ├── GithubDatabind1328.kt ├── TestCasesFromSlack.kt └── failing │ ├── GitHub337.kt │ ├── GitHub451.kt │ ├── GitHub478.kt │ ├── Github138.kt │ ├── Github160DisableAnnotations.kt │ ├── Github242.kt │ ├── Github271AlphaSortProperties.kt │ ├── Github474.kt │ ├── Github518.kt │ ├── Github54.kt │ ├── Github611.kt │ ├── Github71.kt │ └── GithubDatabind1329.kt └── parameterSize ├── DeserializeByConstructorWithDefaultArgumentsTest.kt ├── DeserializeByConstructorWithoutDefaultArgumentsTest.kt ├── DeserializeByFactoryWithDefaultArgumentsTest.kt └── DeserializeByFactoryWithoutDefaultArgumentsTest.kt /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | orbs: 3 | maven: circleci/maven@1.0.2 4 | workflows: 5 | maven_test: 6 | when: false 7 | jobs: 8 | - maven/test 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Do not merge `pom.xml` from older version, as it will typically conflict 2 | 3 | pom.xml merge=ours 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [k163377, cowtowncoder] 4 | tidelift: maven/com.fasterxml.jackson.module:jackson-module-kotlin 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yaml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project 3 | labels: [ "enhancement" ] 4 | assignees: [ ] 5 | 6 | body: 7 | - type: textarea 8 | id: use-case 9 | attributes: 10 | label: Use case 11 | description: "A clear and concise description of what the use-case is. This will better help us understand the context in which you're looking for a new feature." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: desired-solution 16 | attributes: 17 | label: Describe the solution you'd like 18 | description: "A clear and concise description of what you want to happen." 19 | validations: 20 | required: true 21 | - type: textarea 22 | id: alternatives 23 | attributes: 24 | label: Describe alternatives you've considered 25 | description: "A clear and concise description of any alternative solutions or features you've considered." 26 | validations: 27 | required: false 28 | - type: textarea 29 | id: additional-context 30 | attributes: 31 | label: Additional context 32 | description: "Add any other context or screenshots about the feature request here." 33 | - type: markdown 34 | attributes: 35 | value: "Thanks for suggesting a feature! We appreciate your feedback and will consider it for future enhancements." 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.yaml: -------------------------------------------------------------------------------- 1 | name: Question 2 | description: Anything you're not sure about? Just ask us 3 | labels: [ "question" ] 4 | assignees: [ ] 5 | 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: "Before asking your question, please check out the docs." 10 | - type: textarea 11 | id: user-question 12 | attributes: 13 | label: Your question 14 | placeholder: "What would you like to know?" 15 | validations: 16 | required: true 17 | - type: markdown 18 | attributes: 19 | value: "Thanks for reaching out! We'll do our best to help." 20 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | groups: 8 | github-actions: 9 | patterns: 10 | - "*" 11 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Thanks for submitting a pull request! Please ensure that you have based your code on [the correct branch](https://github.com/FasterXML/jackson-module-kotlin/#branches): 2 | 3 | - The current stable release branch for bugfixes of limited scope 4 | - The upcoming [minor](https://semver.org) release branch for backwards compatible changes to existing functionality or addition of new functionality 5 | - `master` for significant changes to existing behavior 6 | 7 | If you're unsure which branch to use, open an [issue](https://github.com/FasterXML/jackson-module-kotlin/issues) and ask, we're happy to talk over proposed changes. 8 | 9 | Finally, to have your code merged you will have to fill out the [Contributor License Agreement](https://github.com/FasterXML/jackson/blob/master/contributor-agreement.pdf) and email a scan/photo of the result to info at fasterxml dot com. 10 | -------------------------------------------------------------------------------- /.github/workflows/dep_build_v2.yml: -------------------------------------------------------------------------------- 1 | name: Re-build on jackson-databind v2 push 2 | on: 3 | repository_dispatch: 4 | types: [jackson-databind-pushed] 5 | # just for testing 6 | workflow_dispatch: 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | java_version: ['8', '17', '21', '24'] 18 | # Versions need to align with ones in 'main.yml' workflow 19 | kotlin_version: ['2.0.21', '2.1.20', '2.2.0-RC'] 20 | env: 21 | JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1" 22 | steps: 23 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 24 | with: 25 | ref: 2.x 26 | - name: Set up JDK 27 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 28 | with: 29 | distribution: 'temurin' 30 | java-version: ${{ matrix.java_version }} 31 | cache: 'maven' 32 | - name: Build and test 33 | run: ./mvnw -B -ff -ntp -Dversion.kotlin=${{ matrix.kotlin_version }} clean verify 34 | 35 | # No recursive rebuild (yet?) 36 | -------------------------------------------------------------------------------- /.github/workflows/dep_build_v3.yml: -------------------------------------------------------------------------------- 1 | name: Re-build on jackson-databind v3 push 2 | on: 3 | repository_dispatch: 4 | types: [jackson-databind-pushed-v3] 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | java_version: ['17', '21', '24'] 16 | # Versions need to align with ones in 'main.yml' workflow 17 | kotlin_version: ['2.0.21', '2.1.20', '2.2.0-RC'] 18 | env: 19 | JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1" 20 | steps: 21 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 22 | with: 23 | ref: 3.x 24 | - name: Set up JDK 25 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 26 | with: 27 | distribution: 'temurin' 28 | java-version: ${{ matrix.java_version }} 29 | cache: 'maven' 30 | - name: Build and test 31 | run: ./mvnw -B -ff -ntp -Dversion.kotlin=${{ matrix.kotlin_version }} clean verify 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # use glob syntax. 2 | syntax: glob 3 | *.class 4 | *~ 5 | *.bak 6 | *.off 7 | *.old 8 | .DS_Store 9 | 10 | # building 11 | target 12 | 13 | # Eclipse 14 | .classpath 15 | .project 16 | .settings 17 | 18 | # IDEA 19 | .idea 20 | *.iml 21 | *.ipr 22 | *.iws 23 | /target 24 | /.gradle/ 25 | /gradle/ 26 | /out/ 27 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - openjdk8 5 | - openjdk11 6 | 7 | # whitelist 8 | branches: 9 | only: 10 | - master 11 | - "2.13" 12 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Last Updated: 2022-09-20 4 | 5 | ## Supported Versions 6 | 7 | Current status of open branches, with new releases, can be found from [Jackson Releases](https://github.com/FasterXML/jackson/wiki/Jackson-Releases) 8 | wiki page 9 | 10 | ## Reporting a Vulnerability 11 | 12 | The recommended mechanism for reporting possible security vulnerabilities follows 13 | so-called "Coordinated Disclosure Plan" (see [definition of DCP](https://vuls.cert.org/confluence/display/Wiki/Coordinated+Vulnerability+Disclosure+Guidance) 14 | for general idea). The first step is to file a [Tidelift security contact](https://tidelift.com/security): 15 | Tidelift will route all reports via their system to maintainers of relevant package(s), and start the 16 | process that will evaluate concern and issue possible fixes, send update notices and so on. 17 | Note that you do not need to be a Tidelift subscriber to file a security contact. 18 | 19 | Alternatively you may also report possible vulnerabilities to `info` at fasterxml dot com 20 | mailing address. Note that filing an issue to go with report is fine, but if you do that please 21 | DO NOT include details of security problem in the issue but only in email contact. 22 | This is important to give us time to provide a patch, if necessary, for the problem. 23 | 24 | ## Verifying Artifact signatures 25 | 26 | (for more in-depth explanation, see [Apache Release Signing](https://infra.apache.org/release-signing#keys-policy) document) 27 | 28 | To verify that any given Jackson artifact has been signed with a valid key, have a look at `KEYS` file of the main Jackson repo: 29 | 30 | https://github.com/FasterXML/jackson/blob/master/KEYS 31 | 32 | which lists all known valid keys in use. 33 | -------------------------------------------------------------------------------- /docs/javadoc/2.10/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.10.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.10/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.10.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.10/com/fasterxml/jackson/module/kotlin/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.fasterxml.jackson.module.kotlin (jackson-module-kotlin 2.10.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

com.fasterxml.jackson.module.kotlin

14 |
15 |

Classes

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/javadoc/2.10/package-list: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin 2 | -------------------------------------------------------------------------------- /docs/javadoc/2.10/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/javadoc/2.11/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.11.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.11/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.11.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.11/com/fasterxml/jackson/module/kotlin/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.fasterxml.jackson.module.kotlin (jackson-module-kotlin 2.11.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

com.fasterxml.jackson.module.kotlin

14 |
15 |

Classes

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/javadoc/2.11/package-list: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin 2 | -------------------------------------------------------------------------------- /docs/javadoc/2.11/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/javadoc/2.12/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.12.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.12/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.12.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.12/com/fasterxml/jackson/module/kotlin/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.fasterxml.jackson.module.kotlin (jackson-module-kotlin 2.12.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

com.fasterxml.jackson.module.kotlin

14 |
15 |

Classes

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/javadoc/2.12/package-list: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin 2 | -------------------------------------------------------------------------------- /docs/javadoc/2.12/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/javadoc/2.13/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.13.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.13/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.13.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.13/com/fasterxml/jackson/module/kotlin/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.fasterxml.jackson.module.kotlin (jackson-module-kotlin 2.13.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

com.fasterxml.jackson.module.kotlin

14 |
15 |

Classes

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/javadoc/2.13/package-list: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin 2 | -------------------------------------------------------------------------------- /docs/javadoc/2.13/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/javadoc/2.14/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.14.0 API) 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/javadoc/2.14/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.14.0 API) 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/javadoc/2.14/com/fasterxml/jackson/module/kotlin/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.fasterxml.jackson.module.kotlin (jackson-module-kotlin 2.14.0 API) 8 | 9 | 10 | 11 | 12 |

com.fasterxml.jackson.module.kotlin

13 |
14 |

Classes

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.14/package-list: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin 2 | -------------------------------------------------------------------------------- /docs/javadoc/2.14/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/javadoc/2.6/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.6.0 API) 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/javadoc/2.6/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.6.0 API) 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/javadoc/2.6/com/fasterxml/jackson/module/kotlin/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.fasterxml.jackson.module.kotlin (jackson-module-kotlin 2.6.0 API) 8 | 9 | 10 | 11 | 12 |

com.fasterxml.jackson.module.kotlin

13 |
14 |

Classes

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.6/package-list: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin 2 | -------------------------------------------------------------------------------- /docs/javadoc/2.6/resources/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/docs/javadoc/2.6/resources/background.gif -------------------------------------------------------------------------------- /docs/javadoc/2.6/resources/tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/docs/javadoc/2.6/resources/tab.gif -------------------------------------------------------------------------------- /docs/javadoc/2.6/resources/titlebar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/docs/javadoc/2.6/resources/titlebar.gif -------------------------------------------------------------------------------- /docs/javadoc/2.6/resources/titlebar_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/docs/javadoc/2.6/resources/titlebar_end.gif -------------------------------------------------------------------------------- /docs/javadoc/2.8/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.8.0 API) 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/javadoc/2.8/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.8.0 API) 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/javadoc/2.8/com/fasterxml/jackson/module/kotlin/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.fasterxml.jackson.module.kotlin (jackson-module-kotlin 2.8.0 API) 8 | 9 | 10 | 11 | 12 |

com.fasterxml.jackson.module.kotlin

13 |
14 |

Classes

15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.8/package-list: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin 2 | -------------------------------------------------------------------------------- /docs/javadoc/2.8/resources/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/docs/javadoc/2.8/resources/background.gif -------------------------------------------------------------------------------- /docs/javadoc/2.8/resources/tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/docs/javadoc/2.8/resources/tab.gif -------------------------------------------------------------------------------- /docs/javadoc/2.8/resources/titlebar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/docs/javadoc/2.8/resources/titlebar.gif -------------------------------------------------------------------------------- /docs/javadoc/2.8/resources/titlebar_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FasterXML/jackson-module-kotlin/a41d7479fbfae2f581bf83bef872e4cf7e54e365/docs/javadoc/2.8/resources/titlebar_end.gif -------------------------------------------------------------------------------- /docs/javadoc/2.9/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.9.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.9/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Classes (jackson-module-kotlin 2.9.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

All Classes

14 |
15 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/javadoc/2.9/com/fasterxml/jackson/module/kotlin/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.fasterxml.jackson.module.kotlin (jackson-module-kotlin 2.9.0 API) 8 | 9 | 10 | 11 | 12 | 13 |

com.fasterxml.jackson.module.kotlin

14 |
15 |

Classes

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/javadoc/2.9/package-list: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin 2 | -------------------------------------------------------------------------------- /docs/javadoc/2.9/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/fasterxml/jackson/module/kotlin/PackageVersion.java.in: -------------------------------------------------------------------------------- 1 | package @package@; 2 | 3 | import com.fasterxml.jackson.core.Version; 4 | import com.fasterxml.jackson.core.Versioned; 5 | import com.fasterxml.jackson.core.util.VersionUtil; 6 | 7 | /** 8 | * Automatically generated from PackageVersion.java.in during 9 | * packageVersion-generate execution of maven-replacer-plugin in 10 | * pom.xml. 11 | */ 12 | public final class PackageVersion implements Versioned { 13 | public final static Version VERSION = VersionUtil.parseVersion( 14 | "@projectversion@", "@projectgroupid@", "@projectartifactid@"); 15 | 16 | @Override 17 | public Version version() { 18 | return VERSION; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/com/fasterxml/jackson/module/kotlin/WrapsNullableValueClassDeserializer.java: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin; 2 | 3 | import com.fasterxml.jackson.core.JacksonException; 4 | import com.fasterxml.jackson.core.JsonParser; 5 | import com.fasterxml.jackson.databind.DeserializationContext; 6 | import com.fasterxml.jackson.databind.JavaType; 7 | import com.fasterxml.jackson.databind.deser.std.StdDeserializer; 8 | import kotlin.jvm.JvmClassMappingKt; 9 | import kotlin.reflect.KClass; 10 | import org.jetbrains.annotations.NotNull; 11 | import org.jetbrains.annotations.Nullable; 12 | 13 | import java.io.IOException; 14 | 15 | /** 16 | * An interface to be inherited by JsonDeserializer that handles value classes that may wrap nullable. 17 | */ 18 | // To ensure maximum compatibility with StdDeserializer, this class is written in Java. 19 | public abstract class WrapsNullableValueClassDeserializer extends StdDeserializer { 20 | protected WrapsNullableValueClassDeserializer(@NotNull KClass vc) { 21 | super(JvmClassMappingKt.getJavaClass(vc)); 22 | } 23 | 24 | protected WrapsNullableValueClassDeserializer(@NotNull Class vc) { 25 | super(vc); 26 | } 27 | 28 | protected WrapsNullableValueClassDeserializer(@NotNull JavaType valueType) { 29 | super(valueType); 30 | } 31 | 32 | protected WrapsNullableValueClassDeserializer(@NotNull StdDeserializer src) { 33 | super(src); 34 | } 35 | 36 | @Override 37 | @NotNull 38 | public final Class handledType() { 39 | //noinspection unchecked 40 | return (Class) super.handledType(); 41 | } 42 | 43 | /** 44 | * If the parameter definition is a value class that wraps a nullable and is non-null, 45 | * and the input to JSON is explicitly null, this value is used. 46 | * Note that this will only be called from the KotlinValueInstantiator, 47 | * so it will not work for top-level deserialization of value classes. 48 | */ 49 | // It is defined so that null can also be returned so that Nulls.SKIP can be applied. 50 | @Nullable 51 | public abstract D getBoxedNullValue(); 52 | 53 | @Override 54 | public abstract D deserialize(@NotNull JsonParser p, @NotNull DeserializationContext ctxt) 55 | throws IOException, JacksonException; 56 | } 57 | -------------------------------------------------------------------------------- /src/main/kotlin/com/fasterxml/jackson/module/kotlin/ConstructorValueCreator.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import kotlin.reflect.KFunction 4 | import kotlin.reflect.jvm.isAccessible 5 | 6 | internal class ConstructorValueCreator(override val callable: KFunction) : ValueCreator() { 7 | override val accessible: Boolean = callable.isAccessible 8 | override val bucketGenerator: BucketGenerator = BucketGenerator.forConstructor(callable.parameters.size) 9 | 10 | init { 11 | // To prevent the call from failing, save the initial value and then rewrite the flag. 12 | if (!accessible) callable.isAccessible = true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/fasterxml/jackson/module/kotlin/Exceptions.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.core.JsonParser 4 | import com.fasterxml.jackson.databind.JsonMappingException 5 | import com.fasterxml.jackson.databind.exc.InvalidNullException 6 | import kotlin.reflect.KParameter 7 | 8 | /** 9 | * Specialized [JsonMappingException] sub-class used to indicate that a mandatory Kotlin constructor 10 | * parameter was missing or null. 11 | */ 12 | @Deprecated( 13 | "It is recommended that MismatchedInputException be referenced when possible," + 14 | " as the change is discussed for 2.17 and later." + 15 | " See #617 for details.", 16 | ReplaceWith( 17 | "MismatchedInputException", 18 | "com.fasterxml.jackson.databind.exc.MismatchedInputException" 19 | ), 20 | DeprecationLevel.WARNING 21 | ) 22 | // When deserialized by the JDK, the parameter property will be null, ignoring nullability. 23 | // This is a temporary workaround for #572 and we will eventually remove this class. 24 | class MissingKotlinParameterException( 25 | @property:Deprecated( 26 | "KParameter is not serializable and will be removed in 2.17 or later. See #572 for details.", 27 | level = DeprecationLevel.WARNING 28 | ) 29 | @Transient 30 | val parameter: KParameter, 31 | processor: JsonParser? = null, 32 | msg: String 33 | ) : InvalidNullException(processor, msg, null) 34 | -------------------------------------------------------------------------------- /src/main/kotlin/com/fasterxml/jackson/module/kotlin/InternalCommons.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.databind.JsonMappingException 5 | import java.lang.reflect.AnnotatedElement 6 | import java.util.* 7 | import kotlin.reflect.KClass 8 | import kotlin.reflect.KType 9 | import kotlin.reflect.full.memberProperties 10 | import kotlin.reflect.jvm.javaField 11 | import kotlin.reflect.jvm.jvmErasure 12 | 13 | internal val defaultConstructorMarker: Class<*> by lazy { 14 | Class.forName("kotlin.jvm.internal.DefaultConstructorMarker") 15 | } 16 | 17 | internal fun JsonMappingException.wrapWithPath(refFrom: Any?, refFieldName: String) = JsonMappingException.wrapWithPath(this, refFrom, refFieldName) 18 | internal fun JsonMappingException.wrapWithPath(refFrom: Any?, index: Int) = JsonMappingException.wrapWithPath(this, refFrom, index) 19 | 20 | internal fun Int.toBitSet(): BitSet { 21 | var i = this 22 | var index = 0 23 | val bits = BitSet(32) 24 | while (i != 0) { 25 | if (i % 2 != 0) { 26 | bits.set(index) 27 | } 28 | ++index 29 | i = i shr 1 30 | } 31 | return bits 32 | } 33 | 34 | // In the future, value classes without @JvmInline will be available, and unboxing may not be able to handle it. 35 | // https://github.com/FasterXML/jackson-module-kotlin/issues/464 36 | // The JvmInline annotation can be added to Java classes, 37 | // so the isKotlinClass decision is necessary (the order is preferable in terms of possible frequency). 38 | internal fun Class<*>.isUnboxableValueClass() = annotations.any { it is JvmInline } && this.isKotlinClass() 39 | 40 | internal fun KType.erasedType(): Class = this.jvmErasure.java 41 | 42 | internal fun AnnotatedElement.hasCreatorAnnotation(): Boolean = getAnnotation(JsonCreator::class.java) 43 | ?.let { it.mode != JsonCreator.Mode.DISABLED } 44 | ?: false 45 | 46 | // Determine if the unbox result of value class is nullable 47 | internal fun KClass<*>.wrapsNullable(): Boolean = 48 | this.memberProperties.first { it.javaField != null }.returnType.isMarkedNullable 49 | -------------------------------------------------------------------------------- /src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinBeanDeserializerModifier.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.databind.BeanDescription 4 | import com.fasterxml.jackson.databind.DeserializationConfig 5 | import com.fasterxml.jackson.databind.JsonDeserializer 6 | import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier 7 | 8 | // [module-kotlin#225]: keep Kotlin singletons as singletons 9 | object KotlinBeanDeserializerModifier : BeanDeserializerModifier() { 10 | private fun readResolve(): Any = KotlinBeanDeserializerModifier 11 | 12 | override fun modifyDeserializer( 13 | config: DeserializationConfig, 14 | beanDesc: BeanDescription, 15 | deserializer: JsonDeserializer<*> 16 | ): JsonDeserializer { 17 | val modifiedFromParent = super.modifyDeserializer(config, beanDesc, deserializer) 18 | 19 | val objectSingletonInstance = objectSingletonInstance(beanDesc.beanClass) 20 | return if (objectSingletonInstance != null) { 21 | KotlinObjectSingletonDeserializer(objectSingletonInstance, modifiedFromParent) 22 | } else { 23 | modifiedFromParent 24 | } 25 | } 26 | } 27 | 28 | private fun objectSingletonInstance(beanClass: Class<*>): Any? = if (!beanClass.isKotlinClass()) { 29 | null 30 | } else { 31 | beanClass.kotlin.objectInstance 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinMixins.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonIgnore 5 | import com.fasterxml.jackson.annotation.JsonProperty 6 | 7 | internal abstract class ClosedRangeMixin @JsonCreator constructor(public val start: T, @get:JsonProperty("end") public val endInclusive: T) { 8 | @JsonIgnore abstract public fun getEnd(): T 9 | @JsonIgnore abstract public fun getFirst(): T 10 | @JsonIgnore abstract public fun getLast(): T 11 | @JsonIgnore abstract public fun getIncrement(): T 12 | @JsonIgnore abstract public fun isEmpty(): Boolean 13 | @JsonIgnore abstract public fun getStep(): T 14 | @JsonIgnore abstract public fun getEndExclusive(): T 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinObjectSingletonDeserializer.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.core.JsonParser 4 | import com.fasterxml.jackson.databind.BeanProperty 5 | import com.fasterxml.jackson.databind.DeserializationContext 6 | import com.fasterxml.jackson.databind.JsonDeserializer 7 | import com.fasterxml.jackson.databind.deser.ContextualDeserializer 8 | import com.fasterxml.jackson.databind.deser.ResolvableDeserializer 9 | 10 | internal fun JsonDeserializer<*>.asSingletonDeserializer(singleton: Any) = 11 | KotlinObjectSingletonDeserializer(singleton, this) 12 | 13 | /** deserialize as normal, but return the canonical singleton instance. */ 14 | internal class KotlinObjectSingletonDeserializer( 15 | private val singletonInstance: Any, 16 | private val defaultDeserializer: JsonDeserializer<*> 17 | ) : JsonDeserializer(), 18 | // Additional interfaces of a specific 'JsonDeserializer' must be supported 19 | // Kotlin objectInstances are currently handled by a BeanSerializer which 20 | // implements 'ContextualDeserializer' and 'ResolvableDeserializer'. 21 | ContextualDeserializer, 22 | ResolvableDeserializer { 23 | 24 | override fun resolve(ctxt: DeserializationContext?) { 25 | if (defaultDeserializer is ResolvableDeserializer) { 26 | defaultDeserializer.resolve(ctxt) 27 | } 28 | } 29 | 30 | override fun createContextual(ctxt: DeserializationContext?, property: BeanProperty?): JsonDeserializer<*> = 31 | if (defaultDeserializer is ContextualDeserializer) { 32 | defaultDeserializer.createContextual(ctxt, property) 33 | .asSingletonDeserializer(singletonInstance) 34 | } else { 35 | this 36 | } 37 | 38 | override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Any { 39 | defaultDeserializer.deserialize(p, ctxt) 40 | return singletonInstance 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/fasterxml/jackson/module/kotlin/UnsignedNumbers.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import java.math.BigInteger 4 | 5 | fun Short.asUByte() = when { 6 | this >= 0 && this <= UByte.MAX_VALUE.toShort() -> this.toUByte() 7 | else -> null 8 | } 9 | 10 | fun Int.asUShort() = when { 11 | this >= 0 && this <= UShort.MAX_VALUE.toInt() -> this.toUShort() 12 | else -> null 13 | } 14 | 15 | fun Long.asUInt() = when { 16 | this >= 0 && this <= UInt.MAX_VALUE.toLong() -> this.toUInt() 17 | else -> null 18 | } 19 | 20 | private val uLongMaxValue = BigInteger(ULong.MAX_VALUE.toString()) 21 | fun BigInteger.asULong() = when { 22 | this >= BigInteger.ZERO && this <= uLongMaxValue -> this.toLong().toULong() 23 | else -> null 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/fasterxml/jackson/module/kotlin/ValueCreator.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.databind.DeserializationContext 4 | import com.fasterxml.jackson.databind.MapperFeature 5 | import kotlin.reflect.KFunction 6 | import kotlin.reflect.KParameter 7 | import kotlin.reflect.full.valueParameters 8 | 9 | /** 10 | * A class that abstracts the creation of instances by calling KFunction. 11 | * @see KotlinValueInstantiator 12 | */ 13 | internal sealed class ValueCreator { 14 | /** 15 | * Function to be call. 16 | */ 17 | protected abstract val callable: KFunction 18 | 19 | /** 20 | * Initial value for accessibility by reflection. 21 | */ 22 | protected abstract val accessible: Boolean 23 | 24 | protected abstract val bucketGenerator: BucketGenerator 25 | 26 | fun generateBucket(): ArgumentBucket = bucketGenerator.generate() 27 | 28 | /** 29 | * ValueParameters of the KFunction to be called. 30 | */ 31 | // If this result is cached, it will coexist with the SoftReference managed value in kotlin-reflect, 32 | // and there is a risk of doubling the memory consumption, so it should not be cached. 33 | // @see #584 34 | val valueParameters: List get() = callable.valueParameters 35 | 36 | /** 37 | * Checking process to see if access from context is possible. 38 | * @throws IllegalAccessException 39 | */ 40 | fun checkAccessibility(ctxt: DeserializationContext) { 41 | if ((!accessible && ctxt.config.isEnabled(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)) || 42 | (accessible && ctxt.config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS))) { 43 | return 44 | } 45 | 46 | throw IllegalAccessException("Cannot access to function or companion object instance, target: $callable") 47 | } 48 | 49 | /** 50 | * Function call with default values enabled. 51 | */ 52 | fun callBy(args: ArgumentBucket): T = if (args.isFullInitialized) { 53 | callable.call(*args.arguments) 54 | } else { 55 | callable.callBy(args) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/LICENSE: -------------------------------------------------------------------------------- 1 | This copy of Jackson JSON processor databind module is licensed under the 2 | Apache (Software) License, version 2.0 ("the License"). 3 | See the License for details about distribution rights, and the 4 | specific rights regarding derivative works. 5 | 6 | You may obtain a copy of the License at: 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/NOTICE: -------------------------------------------------------------------------------- 1 | # Jackson JSON processor 2 | 3 | Jackson is a high-performance, Free/Open Source JSON processing library. 4 | It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has 5 | been in development since 2007. 6 | It is currently developed by a community of developers, as well as supported 7 | commercially by FasterXML.com. 8 | 9 | ## Copyright 10 | 11 | Copyright 2007-, Tatu Saloranta (tatu.saloranta@iki.fi) 12 | 13 | ## Licensing 14 | 15 | Jackson core and extension components may be licensed under different licenses. 16 | To find the details that apply to this artifact see the accompanying LICENSE file. 17 | For more information, including possible other licensing options, contact 18 | FasterXML.com (http://fasterxml.com). 19 | 20 | ## Credits 21 | 22 | A list of contributors may be found from CREDITS file, which is included 23 | in some artifacts (usually source distributions); but is always available 24 | from the source code management (SCM) system project uses. 25 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module: -------------------------------------------------------------------------------- 1 | com.fasterxml.jackson.module.kotlin.KotlinModule 2 | -------------------------------------------------------------------------------- /src/moditect/module-info.java: -------------------------------------------------------------------------------- 1 | // Manually created 02-Nov-2020 for 2 | // https://github.com/FasterXML/jackson-module-kotlin/issues/385 3 | module com.fasterxml.jackson.kotlin { 4 | requires java.desktop; 5 | 6 | requires kotlin.reflect; 7 | requires kotlin.stdlib; 8 | 9 | requires com.fasterxml.jackson.annotation; 10 | requires com.fasterxml.jackson.databind; 11 | 12 | exports com.fasterxml.jackson.module.kotlin; 13 | 14 | provides com.fasterxml.jackson.databind.Module with 15 | com.fasterxml.jackson.module.kotlin.KotlinModule; 16 | } 17 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/JDKSerializabilityTestHelper.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import org.junit.jupiter.api.Assertions.fail 4 | import java.io.ByteArrayInputStream 5 | import java.io.ByteArrayOutputStream 6 | import java.io.ObjectInputStream 7 | import java.io.ObjectOutputStream 8 | 9 | fun jdkSerialize(o: Any): ByteArray { 10 | val bytes = ByteArrayOutputStream(1000) 11 | val obOut = ObjectOutputStream(bytes) 12 | obOut.writeObject(o) 13 | obOut.close() 14 | return bytes.toByteArray() 15 | } 16 | 17 | fun jdkDeserialize(raw: ByteArray): T { 18 | val objIn = ObjectInputStream(ByteArrayInputStream(raw)) 19 | return try { 20 | @Suppress("UNCHECKED_CAST") 21 | objIn.readObject() as T 22 | } catch (e: ClassNotFoundException) { 23 | fail("Missing class: " + e.message) 24 | } finally { 25 | objIn.close() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinInstantiatorsTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator 4 | import org.junit.jupiter.api.Assertions.* 5 | import org.junit.jupiter.api.Test 6 | 7 | class KotlinInstantiatorsTest { 8 | private val deserConfig = defaultMapper.deserializationConfig 9 | 10 | private val kotlinInstantiators = KotlinInstantiators( 11 | ReflectionCache(10), 12 | nullToEmptyCollection = false, 13 | nullToEmptyMap = false, 14 | nullIsSameAsDefault = false, 15 | strictNullChecks = false 16 | ) 17 | 18 | @Test 19 | fun `Provides default instantiator for Java class`() { 20 | val javaType = defaultMapper.constructType(String::class.java) 21 | val defaultInstantiator = StdValueInstantiator(deserConfig, javaType) 22 | val instantiator = kotlinInstantiators.findValueInstantiator( 23 | deserConfig, 24 | deserConfig.introspect(javaType), 25 | defaultInstantiator 26 | ) 27 | 28 | assertEquals(defaultInstantiator, instantiator) 29 | } 30 | 31 | @Test 32 | fun `Provides KotlinValueInstantiator for Kotlin class`() { 33 | class TestClass 34 | 35 | val javaType = defaultMapper.constructType(TestClass::class.java) 36 | val instantiator = kotlinInstantiators.findValueInstantiator( 37 | deserConfig, 38 | deserConfig.introspect(javaType), 39 | StdValueInstantiator(deserConfig, javaType) 40 | ) 41 | 42 | assertTrue(instantiator is StdValueInstantiator) 43 | assertTrue(instantiator::class == KotlinValueInstantiator::class) 44 | } 45 | 46 | @Test 47 | fun `Throws for Kotlin class when default instantiator isn't StdValueInstantiator`() { 48 | class TestClass 49 | class DefaultClass 50 | 51 | val subClassInstantiator = object : StdValueInstantiator( 52 | deserConfig, 53 | defaultMapper.constructType(DefaultClass::class.java) 54 | ) {} 55 | 56 | assertThrows(IllegalStateException::class.java) { 57 | kotlinInstantiators.findValueInstantiator( 58 | deserConfig, 59 | deserConfig.introspect(defaultMapper.constructType(TestClass::class.java)), 60 | subClassInstantiator 61 | ) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/MissingKotlinParameterExceptionTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import org.junit.jupiter.api.Test 4 | import kotlin.test.assertNotNull 5 | import kotlin.test.assertNull 6 | 7 | class MissingKotlinParameterExceptionTest { 8 | @Test 9 | fun jdkSerializabilityTest() { 10 | val param = ::MissingKotlinParameterException.parameters.first() 11 | val ex = MissingKotlinParameterException(param, null, "test") 12 | 13 | val serialized = jdkSerialize(ex) 14 | val deserialized = jdkDeserialize(serialized) 15 | 16 | assertNotNull(deserialized) 17 | // see comment at MissingKotlinParameterException 18 | assertNull(deserialized.parameter) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/README.md: -------------------------------------------------------------------------------- 1 | # Failing tests 2 | 3 | These are tests for filed issues on GitHub that have not been fixed. Failing tests are good to 4 | have because they can both concisely document known issues with the library but also serve as 5 | notification for when that functionality has been fixed. 6 | 7 | The tests pass because either the failing assertions have their `AssertionError` or the Jackson call 8 | that throws has its exception caught. 9 | 10 | ## Writing a failing test 11 | 12 | Create a failing test by writing it as you would any other test, making any calls or assertions 13 | necessary to demonstrate the failing behavior. Then, surround the failing call with the 14 | `expectFailure()` function, passing the expected exception and a message that will be printed 15 | if the failure does _not_ occur, which implies that the functionality has been fixed. 16 | 17 | See the below examples: 18 | 19 | ```kotlin 20 | @Test 21 | fun failingTest() { 22 | expectFailure("The call that fails with MismatchedInputException has been fixed!") { 23 | mapper.callThatFailsWithMismatchedInputException() 24 | } 25 | } 26 | ``` 27 | 28 | ```kotlin 29 | @Test 30 | fun serializeAndDeserializeTypeable() { 31 | val oldEntity = MyEntity(null, null) 32 | val json = mapper.writeValueAsString(oldEntity) 33 | val newEntity = mapper.readValue(json) 34 | 35 | expectFailure("GitHub #335 has been fixed!") { 36 | // newEntity.type is the string "null" instead of the null value 37 | assertNull(newEntity.type) 38 | } 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReadValuesTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.core.JsonParser 4 | import com.fasterxml.jackson.databind.DeserializationContext 5 | import com.fasterxml.jackson.databind.RuntimeJsonMappingException 6 | import com.fasterxml.jackson.databind.deser.std.StdDeserializer 7 | import com.fasterxml.jackson.databind.module.SimpleModule 8 | import org.junit.jupiter.api.Nested 9 | import org.junit.jupiter.api.Test 10 | import org.junit.jupiter.api.assertThrows 11 | import kotlin.test.assertEquals 12 | 13 | class ReadValuesTest { 14 | class MyStrDeser : StdDeserializer(String::class.java) { 15 | override fun deserialize( 16 | p: JsonParser, 17 | ctxt: DeserializationContext 18 | ): String? = p.valueAsString.takeIf { it != "bar" } 19 | } 20 | 21 | @Nested 22 | inner class CheckTypeMismatchTest { 23 | val mapper = jacksonObjectMapper().registerModule( 24 | object : SimpleModule() { 25 | init { 26 | addDeserializer(String::class.java, MyStrDeser()) 27 | } 28 | } 29 | )!! 30 | 31 | @Test 32 | fun readValuesJsonParserNext() { 33 | val src = mapper.createParser(""""foo"${"\n"}"bar"""") 34 | val itr = mapper.readValues(src) 35 | 36 | assertEquals("foo", itr.next()) 37 | assertThrows { 38 | itr.next() 39 | } 40 | } 41 | 42 | @Test 43 | fun readValuesJsonParserNextValue() { 44 | val src = mapper.createParser(""""foo"${"\n"}"bar"""") 45 | val itr = mapper.readValues(src) 46 | 47 | assertEquals("foo", itr.nextValue()) 48 | assertThrows { 49 | itr.nextValue() 50 | } 51 | } 52 | 53 | @Test 54 | fun readValuesTypedJsonParser() { 55 | val reader = mapper.reader() 56 | val src = reader.createParser(""""foo"${"\n"}"bar"""") 57 | val itr = reader.readValuesTyped(src) 58 | 59 | assertEquals("foo", itr.next()) 60 | assertThrows { 61 | itr.next() 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCacheTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import org.junit.jupiter.api.Test 4 | import kotlin.test.assertNotNull 5 | 6 | class ReflectionCacheTest { 7 | @Test 8 | fun serializeEmptyCache() { 9 | val cache = ReflectionCache(100) 10 | val serialized = jdkSerialize(cache) 11 | val deserialized = jdkDeserialize(serialized) 12 | 13 | assertNotNull(deserialized) 14 | // Deserialized instance also do not raise exceptions 15 | deserialized.kotlinFromJava(ReflectionCacheTest::class.java.getDeclaredMethod("serializeEmptyCache")) 16 | } 17 | 18 | @Test 19 | fun serializeNotEmptyCache() { 20 | val method = ReflectionCacheTest::class.java.getDeclaredMethod("serializeNotEmptyCache") 21 | 22 | val cache = ReflectionCache(100).apply { kotlinFromJava(method) } 23 | val serialized = jdkSerialize(cache) 24 | val deserialized = jdkDeserialize(serialized) 25 | 26 | assertNotNull(deserialized) 27 | // Deserialized instance also do not raise exceptions 28 | deserialized.kotlinFromJava(method) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/TestCommons.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin 2 | 3 | import com.fasterxml.jackson.core.PrettyPrinter 4 | import com.fasterxml.jackson.core.util.DefaultIndenter 5 | import com.fasterxml.jackson.core.util.DefaultPrettyPrinter 6 | import com.fasterxml.jackson.databind.ObjectMapper 7 | import com.fasterxml.jackson.databind.ObjectWriter 8 | import java.io.File 9 | import java.io.FileOutputStream 10 | import java.io.OutputStreamWriter 11 | import java.nio.charset.StandardCharsets 12 | import kotlin.reflect.KParameter 13 | import kotlin.reflect.full.memberProperties 14 | import kotlin.reflect.full.primaryConstructor 15 | import kotlin.test.assertEquals 16 | 17 | // This `printer` is used to match the output from Jackson to the newline char of the source code. 18 | // If this is removed, comparisons will fail in a Windows-like platform. 19 | val LF_PRINTER: PrettyPrinter = 20 | DefaultPrettyPrinter().withObjectIndenter(DefaultIndenter().withLinefeed("\n")) 21 | 22 | fun ObjectMapper.testPrettyWriter(): ObjectWriter = this.writer().with(LF_PRINTER) 23 | internal val defaultMapper = jacksonObjectMapper() 24 | 25 | internal inline fun callPrimaryConstructor(mapper: (KParameter) -> Any? = { it.name }): T = 26 | T::class.primaryConstructor!!.run { 27 | val args = parameters.associateWith { mapper(it) } 28 | callBy(args) 29 | } 30 | 31 | // Function for comparing non-data classes. 32 | internal inline fun assertReflectEquals(expected: T, actual: T) { 33 | T::class.memberProperties.forEach { 34 | assertEquals(it.get(expected), it.get(actual)) 35 | } 36 | } 37 | 38 | internal fun createTempJson(json: String): File { 39 | val file = File.createTempFile("temp", ".json") 40 | file.deleteOnExit() 41 | OutputStreamWriter( 42 | FileOutputStream(file), 43 | StandardCharsets.UTF_8 44 | ).use { writer -> 45 | writer.write(json) 46 | writer.flush() 47 | } 48 | return file 49 | } 50 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/README.md: -------------------------------------------------------------------------------- 1 | This package contains some portions from `zIntegration` of the `jackson-module-kogera` project. 2 | https://github.com/ProjectMapK/jackson-module-kogera/tree/develop/src/test/kotlin/io/github/projectmapk/jackson/module/kogera/zIntegration 3 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NonNullObjectTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.defaultArgument 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NonNullObject 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Test 9 | 10 | class NonNullObjectTest { 11 | data class ByConstructor( 12 | val nn: NonNullObject = NonNullObject("foo"), 13 | val nNn: NonNullObject? = NonNullObject("bar"), 14 | val nN: NonNullObject? = null 15 | ) 16 | 17 | @Test 18 | fun byConstructorTest() { 19 | assertEquals(ByConstructor(), defaultMapper.readValue("{}")) 20 | } 21 | 22 | data class ByFactory(val nn: NonNullObject, val nNn: NonNullObject?, val nN: NonNullObject?) { 23 | companion object { 24 | @JvmStatic 25 | @JsonCreator 26 | fun creator( 27 | nn: NonNullObject = NonNullObject("foo"), 28 | nNn: NonNullObject? = NonNullObject("bar"), 29 | nN: NonNullObject? = null 30 | ) = ByFactory(nn, nNn, nN) 31 | } 32 | } 33 | 34 | @Test 35 | fun byFactoryTest() { 36 | assertEquals(ByFactory.creator(), defaultMapper.readValue("{}")) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NullableObjectTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.defaultArgument 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullableObject 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Assertions.assertThrows 9 | import org.junit.jupiter.api.Test 10 | 11 | class NullableObjectTest { 12 | data class ByConstructor( 13 | val nnNn: NullableObject = NullableObject("foo"), 14 | val nnN: NullableObject = NullableObject(null), 15 | val nNn: NullableObject? = NullableObject("bar"), 16 | val nN: NullableObject? = null 17 | ) 18 | 19 | @Test 20 | fun byConstructorTestFailing() { 21 | // #761(KT-57357) fixed 22 | assertThrows(Error::class.java) { 23 | assertEquals(ByConstructor(), defaultMapper.readValue("{}")) 24 | } 25 | } 26 | 27 | data class ByFactory( 28 | val nnNn: NullableObject = NullableObject("foo"), 29 | val nnN: NullableObject = NullableObject(null), 30 | val nNn: NullableObject? = NullableObject("bar"), 31 | val nN: NullableObject? = null 32 | ) { 33 | companion object { 34 | @JvmStatic 35 | @JsonCreator 36 | fun creator( 37 | nn: NullableObject = NullableObject("foo"), 38 | nnN: NullableObject = NullableObject(null), 39 | nNn: NullableObject? = NullableObject("bar"), 40 | nN: NullableObject? = null 41 | ) = ByFactory(nn, nnN, nNn, nN) 42 | } 43 | } 44 | 45 | @Test 46 | fun byFactoryTest() { 47 | // #761(KT-57357) fixed 48 | assertThrows(Error::class.java) { 49 | assertEquals(ByFactory.creator(), defaultMapper.readValue("{}")) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NullablePrimitiveTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.defaultArgument 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullablePrimitive 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions 8 | import org.junit.jupiter.api.Assertions.assertEquals 9 | import org.junit.jupiter.api.Test 10 | 11 | class NullablePrimitiveTest { 12 | data class ByConstructor( 13 | val nnNn: NullablePrimitive = NullablePrimitive(1), 14 | val nnN: NullablePrimitive = NullablePrimitive(null), 15 | val nNn: NullablePrimitive? = NullablePrimitive(2), 16 | val nN: NullablePrimitive? = null 17 | ) 18 | 19 | @Test 20 | fun byConstructorTestFailing() { 21 | // #761(KT-57357) fixed 22 | Assertions.assertThrows(Error::class.java) { 23 | assertEquals(ByConstructor(), defaultMapper.readValue("{}")) 24 | } 25 | } 26 | 27 | data class ByFactory( 28 | val nnNn: NullablePrimitive = NullablePrimitive(1), 29 | val nnN: NullablePrimitive = NullablePrimitive(null), 30 | val nNn: NullablePrimitive? = NullablePrimitive(2), 31 | val nN: NullablePrimitive? = null 32 | ) { 33 | companion object { 34 | @JvmStatic 35 | @JsonCreator 36 | fun creator( 37 | nnNn: NullablePrimitive = NullablePrimitive(1), 38 | nnN: NullablePrimitive = NullablePrimitive(null), 39 | nNn: NullablePrimitive? = NullablePrimitive(2), 40 | nN: NullablePrimitive? = null 41 | ) = ByFactory(nnNn, nnN, nNn, nN) 42 | } 43 | } 44 | 45 | @Test 46 | fun byFactoryTest() { 47 | // #761(KT-57357) fixed 48 | Assertions.assertThrows(Error::class.java) { 49 | assertEquals(ByFactory.creator(), defaultMapper.readValue("{}")) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/PrimitiveTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.defaultArgument 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Test 9 | 10 | class PrimitiveTest { 11 | data class ByConstructor( 12 | val nn: Primitive = Primitive(1), 13 | val nNn: Primitive? = Primitive(2), 14 | val nN: Primitive? = null 15 | ) 16 | 17 | @Test 18 | fun byConstructorTest() { 19 | assertEquals(ByConstructor(), defaultMapper.readValue("{}")) 20 | } 21 | 22 | data class ByFactory(val nn: Primitive, val nNn: Primitive?, val nN: Primitive?) { 23 | companion object { 24 | @JvmStatic 25 | @JsonCreator 26 | fun creator( 27 | nn: Primitive = Primitive(1), 28 | nNn: Primitive? = Primitive(2), 29 | nN: Primitive? = null 30 | ) = ByFactory(nn, nNn, nN) 31 | } 32 | } 33 | 34 | @Test 35 | fun byFactoryTest() { 36 | assertEquals(ByFactory.creator(), defaultMapper.readValue("{}")) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/TwoUnitPrimitiveTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.defaultArgument 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.TwoUnitPrimitive 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Test 9 | 10 | class TwoUnitPrimitiveTest { 11 | data class ByConstructor( 12 | val nn: TwoUnitPrimitive = TwoUnitPrimitive(1), 13 | val nNn: TwoUnitPrimitive? = TwoUnitPrimitive(2), 14 | val nN: TwoUnitPrimitive? = null 15 | ) 16 | 17 | @Test 18 | fun byConstructorTest() { 19 | assertEquals(ByConstructor(), defaultMapper.readValue("{}")) 20 | } 21 | 22 | data class ByFactory(val nn: TwoUnitPrimitive, val nNn: TwoUnitPrimitive?, val nN: TwoUnitPrimitive?) { 23 | companion object { 24 | @JvmStatic 25 | @JsonCreator 26 | fun creator( 27 | nn: TwoUnitPrimitive = TwoUnitPrimitive(1), 28 | nNn: TwoUnitPrimitive? = TwoUnitPrimitive(2), 29 | nN: TwoUnitPrimitive? = null 30 | ) = ByFactory(nn, nNn, nN) 31 | } 32 | } 33 | 34 | @Test 35 | fun byFactoryTest() { 36 | assertEquals(ByFactory.creator(), defaultMapper.readValue("{}")) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/SpecifiedForClassTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.deserializer.byAnnotation 2 | 3 | import com.fasterxml.jackson.core.JsonParser 4 | import com.fasterxml.jackson.databind.DeserializationContext 5 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize 6 | import com.fasterxml.jackson.databind.deser.std.StdDeserializer 7 | import com.fasterxml.jackson.module.kotlin.defaultMapper 8 | import com.fasterxml.jackson.module.kotlin.readValue 9 | import org.junit.jupiter.api.Assertions.assertEquals 10 | import org.junit.jupiter.api.Test 11 | 12 | class SpecifiedForClassTest { 13 | @JsonDeserialize(using = Value.Deserializer::class) 14 | @JvmInline 15 | value class Value(val v: Int) { 16 | class Deserializer : StdDeserializer(Value::class.java) { 17 | override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Value = Value(p.intValue + 100) 18 | } 19 | } 20 | 21 | @Test 22 | fun directDeserTest() { 23 | val result = defaultMapper.readValue("1") 24 | 25 | assertEquals(Value(101), result) 26 | } 27 | 28 | data class Wrapper(val v: Value) 29 | 30 | @Test 31 | fun paramDeserTest() { 32 | val result = defaultMapper.readValue("""{"v":1}""") 33 | 34 | assertEquals(Wrapper(Value(101)), result) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/PrimitiveTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.deserializer.byAnnotation.specifiedForProperty 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Nested 9 | import org.junit.jupiter.api.Test 10 | 11 | class PrimitiveTest { 12 | data class NonNull( 13 | @get:JsonDeserialize(using = Primitive.Deserializer::class) 14 | val getterAnn: Primitive, 15 | @field:JsonDeserialize(using = Primitive.Deserializer::class) 16 | val fieldAnn: Primitive 17 | ) 18 | 19 | @Test 20 | fun nonNull() { 21 | val result = defaultMapper.readValue( 22 | """ 23 | { 24 | "getterAnn" : 1, 25 | "fieldAnn" : 2 26 | } 27 | """.trimIndent() 28 | ) 29 | assertEquals(NonNull(Primitive(101), Primitive(102)), result) 30 | } 31 | 32 | data class Nullable( 33 | @get:JsonDeserialize(using = Primitive.Deserializer::class) 34 | val getterAnn: Primitive?, 35 | @field:JsonDeserialize(using = Primitive.Deserializer::class) 36 | val fieldAnn: Primitive? 37 | ) 38 | 39 | @Nested 40 | inner class NullableTest { 41 | @Test 42 | fun nonNullInput() { 43 | val result = defaultMapper.readValue( 44 | """ 45 | { 46 | "getterAnn" : 1, 47 | "fieldAnn" : 2 48 | } 49 | """.trimIndent() 50 | ) 51 | assertEquals(Nullable(Primitive(101), Primitive(102)), result) 52 | } 53 | 54 | @Test 55 | fun nullInput() { 56 | val result = defaultMapper.readValue( 57 | """ 58 | { 59 | "getterAnn" : null, 60 | "fieldAnn" : null 61 | } 62 | """.trimIndent() 63 | ) 64 | assertEquals(Nullable(null, null), result) 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByJacksonTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.jsonCreator 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Assertions.assertEquals 7 | import org.junit.jupiter.api.Test 8 | 9 | // Test for Creator that can be handled by the Jackson mechanism. 10 | class HandledByJacksonTest { 11 | @JvmInline 12 | value class PrimitiveMultiParamCreator(val value: Int) { 13 | companion object { 14 | // Avoiding unboxing by making the return value of Creator nullable 15 | @JvmStatic 16 | @JsonCreator 17 | fun creator(first: Int, second: Int): PrimitiveMultiParamCreator? = 18 | PrimitiveMultiParamCreator(first + second) 19 | } 20 | } 21 | 22 | @Test 23 | fun primitiveNullableCreatorTest() { 24 | val r: PrimitiveMultiParamCreator = defaultMapper.readValue("""{"first":1,"second":2}""") 25 | assertEquals(PrimitiveMultiParamCreator(3), r) 26 | } 27 | 28 | @JvmInline 29 | value class NullableObjectMultiParamCreator(val value: Int?) { 30 | companion object { 31 | // Avoiding unboxing by making the return value of Creator nullable 32 | @JvmStatic 33 | @JsonCreator 34 | fun creator(first: Int, second: Int): NullableObjectMultiParamCreator? = 35 | NullableObjectMultiParamCreator(first + second) 36 | } 37 | } 38 | 39 | @Test 40 | fun nullableObjectNullableCreatorTest() { 41 | val r: NullableObjectMultiParamCreator = defaultMapper.readValue("""{"first":1,"second":2}""") 42 | assertEquals(NullableObjectMultiParamCreator(3), r) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/mapKey/keyDeserializer/byAnnotation/SpecifiedForClassTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.mapKey.keyDeserializer.byAnnotation 2 | 3 | import com.fasterxml.jackson.databind.DeserializationContext 4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Test 9 | import com.fasterxml.jackson.databind.KeyDeserializer as JacksonKeyDeserializer 10 | 11 | class SpecifiedForClassTest { 12 | @JsonDeserialize(keyUsing = Value.KeyDeserializer::class) 13 | @JvmInline 14 | value class Value(val v: Int) { 15 | class KeyDeserializer : JacksonKeyDeserializer() { 16 | override fun deserializeKey(key: String, ctxt: DeserializationContext) = Value(key.toInt() + 100) 17 | } 18 | } 19 | 20 | @Test 21 | fun directDeserTest() { 22 | val result = defaultMapper.readValue>("""{"1":null}""") 23 | 24 | assertEquals(mapOf(Value(101) to null), result) 25 | } 26 | 27 | data class Wrapper(val v: Map) 28 | 29 | @Test 30 | fun paramDeserTest() { 31 | val result = defaultMapper.readValue("""{"v":{"1":null}}""") 32 | 33 | assertEquals(Wrapper(mapOf(Value(101) to null)), result) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/mapKey/keyDeserializer/byAnnotation/SpecifiedForPropertyTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.mapKey.keyDeserializer.byAnnotation 2 | 3 | import com.fasterxml.jackson.databind.DeserializationContext 4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Test 9 | import com.fasterxml.jackson.databind.KeyDeserializer as JacksonKeyDeserializer 10 | 11 | class SpecifiedForPropertyTest { 12 | @JvmInline 13 | value class Value(val v: Int) { 14 | class KeyDeserializer : JacksonKeyDeserializer() { 15 | override fun deserializeKey(key: String, ctxt: DeserializationContext) = Value(key.toInt() + 100) 16 | } 17 | } 18 | 19 | data class Wrapper(@JsonDeserialize(keyUsing = Value.KeyDeserializer::class) val v: Map) 20 | 21 | @Test 22 | fun paramDeserTest() { 23 | val result = defaultMapper.readValue("""{"v":{"1":null}}""") 24 | 25 | assertEquals(Wrapper(mapOf(Value(101) to null)), result) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/ser/valueClass/JsonKeyTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.ser.valueClass 2 | 3 | import com.fasterxml.jackson.annotation.JsonKey 4 | import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder 5 | import com.fasterxml.jackson.module.kotlin.testPrettyWriter 6 | import kotlin.test.Test 7 | import kotlin.test.assertEquals 8 | 9 | class JsonKeyTest { 10 | @JvmInline 11 | value class JsonKeyGetter(val value: Int) { 12 | @get:JsonKey 13 | val jsonKey: String 14 | get() = this.toString() 15 | } 16 | 17 | interface IJsonKeyGetter { 18 | @get:JsonKey 19 | val jsonKey: String 20 | get() = this.toString() 21 | } 22 | 23 | @JvmInline 24 | value class JsonKeyGetterImplementation(val value: Int) : IJsonKeyGetter 25 | 26 | @JvmInline 27 | value class JsonKeyGetterImplementationDisabled(val value: Int) : IJsonKeyGetter { 28 | @get:JsonKey(false) 29 | override val jsonKey: String 30 | get() = super.jsonKey 31 | } 32 | 33 | private val writer = jacksonMapperBuilder().build().testPrettyWriter() 34 | 35 | @Test 36 | fun test() { 37 | val src = mapOf( 38 | JsonKeyGetter(0) to 0, 39 | JsonKeyGetterImplementation(1) to 1, 40 | JsonKeyGetterImplementationDisabled(2) to 2 41 | ) 42 | 43 | assertEquals( 44 | """ 45 | { 46 | "JsonKeyGetter(value=0)" : 0, 47 | "JsonKeyGetterImplementation(value=1)" : 1, 48 | "2" : 2 49 | } 50 | """.trimIndent(), 51 | writer.writeValueAsString(src) 52 | ) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/ser/valueClass/jsonInclude/JsonIncludeCustomTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.ser.valueClass.jsonInclude 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import kotlin.test.Test 6 | import kotlin.test.assertEquals 7 | 8 | class JsonIncludeCustomTest { 9 | class NullFilter { 10 | override fun equals(other: Any?) = other == null 11 | } 12 | 13 | @JsonInclude( 14 | value = JsonInclude.Include.CUSTOM, 15 | valueFilter = NullFilter::class 16 | ) 17 | data class NullFilterDto( 18 | val pN: Primitive? = null, 19 | val nnoN: NonNullObject? = null, 20 | val noN1: NullableObject? = null, 21 | val npN: NullablePrimitive? = null, 22 | val tupN: TwoUnitPrimitive? = null 23 | ) 24 | 25 | @Test 26 | fun nullFilterTest() { 27 | val dto = NullFilterDto() 28 | assertEquals("{}", defaultMapper.writeValueAsString(dto)) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/ser/valueClass/jsonInclude/JsonIncludeNonNullTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.ser.valueClass.jsonInclude 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import kotlin.test.Test 6 | import kotlin.test.assertEquals 7 | import kotlin.test.assertNotEquals 8 | 9 | class JsonIncludeNonNullTest { 10 | @JsonInclude(value = JsonInclude.Include.NON_NULL) 11 | data class Dto( 12 | val pN: Primitive? = null, 13 | val nnoN: NonNullObject? = null, 14 | val noN1: NullableObject? = null, 15 | val npN: NullablePrimitive? = null, 16 | val tupN: TwoUnitPrimitive? = null 17 | ) 18 | 19 | @Test 20 | fun success() { 21 | val dto = Dto() 22 | assertEquals("{}", defaultMapper.writeValueAsString(dto)) 23 | } 24 | 25 | // It is under consideration whether it should be serialized because it is non-null in Kotlin, 26 | // but it is tentatively regarded as a failure. 27 | @JsonInclude(value = JsonInclude.Include.NON_NULL, content = JsonInclude.Include.NON_NULL) 28 | data class DtoFails( 29 | val noNn: NullableObject = NullableObject(null), 30 | val noN2: NullableObject? = NullableObject(null), 31 | val npNn: NullablePrimitive = NullablePrimitive(null), 32 | val npN2: NullablePrimitive? = NullablePrimitive(null), 33 | val map: Map = mapOf( 34 | "noNn" to NullableObject(null), 35 | "npNn" to NullablePrimitive(null) 36 | ) 37 | ) 38 | 39 | @Test 40 | fun fails() { 41 | val dto = DtoFails() 42 | val result = defaultMapper.writeValueAsString(dto) 43 | assertNotEquals("""{"map":{}}""", result) 44 | assertEquals("""{"noNn":null,"noN2":null,"npNn":null,"npN2":null,"map":{"noNn":null,"npNn":null}}""", result) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/ser/valueClass/jsonInclude/ValueClasses.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.ser.valueClass.jsonInclude 2 | 3 | @JvmInline 4 | value class Primitive(val v: Int) 5 | 6 | @JvmInline 7 | value class NonNullObject(val v: String) 8 | 9 | @JvmInline 10 | value class NullableObject(val v: String?) 11 | 12 | @JvmInline 13 | value class NullablePrimitive(val v: Int?) 14 | 15 | @JvmInline 16 | value class TwoUnitPrimitive(val v: Long) 17 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/ser/valueClass/serializer/ValueClasses.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.ser.valueClass.serializer 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator 4 | import com.fasterxml.jackson.databind.SerializerProvider 5 | import com.fasterxml.jackson.databind.ser.std.StdSerializer 6 | 7 | @JvmInline 8 | value class Primitive(val v: Int) { 9 | class Serializer : StdSerializer(Primitive::class.java) { 10 | override fun serialize(value: Primitive, gen: JsonGenerator, provider: SerializerProvider) { 11 | gen.writeNumber(value.v + 100) 12 | } 13 | } 14 | } 15 | 16 | @JvmInline 17 | value class NonNullObject(val v: String) { 18 | class Serializer : StdSerializer(NonNullObject::class.java) { 19 | override fun serialize(value: NonNullObject, gen: JsonGenerator, provider: SerializerProvider) { 20 | gen.writeString("${value.v}-ser") 21 | } 22 | } 23 | } 24 | 25 | @JvmInline 26 | value class NullableObject(val v: String?) { 27 | class Serializer : StdSerializer(NullableObject::class.java) { 28 | override fun serialize(value: NullableObject, gen: JsonGenerator, provider: SerializerProvider) { 29 | gen.writeString(value.v?.let { "$it-ser" } ?: "NULL") 30 | } 31 | } 32 | } 33 | 34 | @JvmInline 35 | value class NullablePrimitive(val v: Int?) { 36 | class Serializer : StdSerializer(NullablePrimitive::class.java) { 37 | override fun serialize(value: NullablePrimitive, gen: JsonGenerator, provider: SerializerProvider) { 38 | value.v?.let { gen.writeNumber(it + 100) } ?: gen.writeString("NULL") 39 | } 40 | } 41 | } 42 | 43 | @JvmInline 44 | value class TwoUnitPrimitive(val v: Long) { 45 | class Serializer : StdSerializer(TwoUnitPrimitive::class.java) { 46 | override fun serialize(value: TwoUnitPrimitive, gen: JsonGenerator, provider: SerializerProvider) { 47 | gen.writeNumber(value.v + 100) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/ser/valueClass/serializer/byAnnotation/nonNullObject/ByAnnotationTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.kogeraIntegration.ser.valueClass.serializer.byAnnotation.nonNullObject 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize 4 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.kogeraIntegration.ser.valueClass.serializer.NonNullObject 6 | import com.fasterxml.jackson.module.kotlin.testPrettyWriter 7 | import kotlin.test.Test 8 | import kotlin.test.assertEquals 9 | 10 | class ByAnnotationTest { 11 | companion object { 12 | val writer = jacksonObjectMapper().testPrettyWriter() 13 | } 14 | 15 | data class NonNullSrc( 16 | @get:JsonSerialize(using = NonNullObject.Serializer::class) 17 | val getterAnn: NonNullObject, 18 | @field:JsonSerialize(using = NonNullObject.Serializer::class) 19 | val fieldAnn: NonNullObject 20 | ) 21 | 22 | @Test 23 | fun nonNull() { 24 | val src = NonNullSrc(NonNullObject("foo"), NonNullObject("bar")) 25 | 26 | assertEquals( 27 | """ 28 | { 29 | "getterAnn" : "foo-ser", 30 | "fieldAnn" : "bar-ser" 31 | } 32 | """.trimIndent(), 33 | writer.writeValueAsString(src) 34 | ) 35 | } 36 | 37 | data class NullableSrc( 38 | @get:JsonSerialize(using = NonNullObject.Serializer::class) 39 | val getterAnn: NonNullObject?, 40 | @field:JsonSerialize(using = NonNullObject.Serializer::class) 41 | val fieldAnn: NonNullObject? 42 | ) 43 | 44 | @Test 45 | fun nullableWithoutNull() { 46 | val src = NullableSrc(NonNullObject("foo"), NonNullObject("bar")) 47 | 48 | assertEquals( 49 | """ 50 | { 51 | "getterAnn" : "foo-ser", 52 | "fieldAnn" : "bar-ser" 53 | } 54 | """.trimIndent(), 55 | writer.writeValueAsString(src) 56 | ) 57 | } 58 | 59 | @Test 60 | fun nullableWithNull() { 61 | val src = NullableSrc(null, null) 62 | 63 | assertEquals( 64 | """ 65 | { 66 | "getterAnn" : null, 67 | "fieldAnn" : null 68 | } 69 | """.trimIndent(), 70 | writer.writeValueAsString(src) 71 | ) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/FailNullForPrimitiveTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test 2 | 3 | import com.fasterxml.jackson.databind.DeserializationFeature 4 | import com.fasterxml.jackson.databind.exc.MismatchedInputException 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Assertions.assertThrows 9 | import org.junit.jupiter.api.Test 10 | 11 | class FailNullForPrimitiveTest { 12 | val mapper = jacksonObjectMapper() 13 | .enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) 14 | 15 | data class NoDefaultValue( 16 | val foo: Int, 17 | val bar: Int? 18 | ) 19 | 20 | @Test 21 | fun noDefaultValueTest() { 22 | // If no default value is set, it will fail if undefined or null is entered 23 | assertThrows(MismatchedInputException::class.java) { 24 | mapper.readValue("{}") 25 | } 26 | 27 | assertThrows(MismatchedInputException::class.java) { 28 | mapper.readValue("""{"foo":null}""") 29 | } 30 | 31 | assertEquals(NoDefaultValue(0, null), mapper.readValue("""{"foo":0}""")) 32 | } 33 | 34 | data class HasDefaultValue( 35 | val foo: Int = -1, 36 | val bar: Int? = -1 37 | ) 38 | 39 | @Test 40 | fun hasDefaultValueTest() { 41 | // If a default value is set, an input of undefined will succeed, but null will fail 42 | assertEquals(HasDefaultValue(-1, -1), mapper.readValue("{}")) 43 | 44 | assertThrows(MismatchedInputException::class.java) { 45 | mapper.readValue("""{"foo":null}""") 46 | } 47 | 48 | assertEquals(HasDefaultValue(0, null), mapper.readValue("""{"foo":0, "bar":null}""")) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/IteratorTests.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.databind.SerializationFeature 6 | import com.fasterxml.jackson.databind.annotation.JsonSerialize 7 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 8 | import org.junit.jupiter.api.Test 9 | import kotlin.test.assertEquals 10 | 11 | class TestIteratorSubclass { 12 | class TinyPerson(val name: String, val age: Int) 13 | class KotlinPersonIterator(private val personList: List) : Iterator by personList.iterator() 14 | 15 | val mapper: ObjectMapper = jacksonObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, false) 16 | 17 | @Test 18 | fun testKotlinIteratorWithTypeRef() { 19 | val expectedJson = """[{"name":"Fred","age":10},{"name":"Max","age":11}]""" 20 | val people = KotlinPersonIterator(listOf(TinyPerson("Fred", 10), TinyPerson("Max", 11))) 21 | val typeRef = object : TypeReference>() {} 22 | val kotlinJson = mapper.writerFor(typeRef).writeValueAsString(people) 23 | assertEquals(expectedJson, kotlinJson) 24 | } 25 | 26 | @Test 27 | fun testKotlinIterator() { 28 | val expectedJson = """[{"name":"Fred","age":10},{"name":"Max","age":11}]""" 29 | val people = KotlinPersonIterator(listOf(TinyPerson("Fred", 10), TinyPerson("Max", 11))) 30 | val kotlinJson = mapper.writeValueAsString(people) 31 | assertEquals(expectedJson, kotlinJson) 32 | } 33 | 34 | class Company( 35 | val name: String, 36 | @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") @JsonSerialize(`as` = java.util.Iterator::class) val people: KotlinPersonIterator 37 | ) 38 | 39 | @Test 40 | fun testKotlinIteratorAsField() { 41 | val expectedJson = """{"name":"KidVille","people":[{"name":"Fred","age":10},{"name":"Max","age":11}]}""" 42 | val people = KotlinPersonIterator(listOf(TinyPerson("Fred", 10), TinyPerson("Max", 11))) 43 | val company = Company("KidVille", people) 44 | val kotlinJson = mapper.writeValueAsString(company) 45 | assertEquals(expectedJson, kotlinJson) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/NullToEmptyCollectionTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.KotlinFeature.NullToEmptyCollection 5 | import com.fasterxml.jackson.module.kotlin.kotlinModule 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestNullToEmptyCollection { 10 | 11 | private data class TestClass(val foo: List) 12 | 13 | @Test 14 | fun nonNullCaseStillWorks() { 15 | val mapper = createMapper() 16 | assertEquals(listOf(1, 2), mapper.readValue("""{"foo": [1,2]}""", TestClass::class.java).foo) 17 | } 18 | 19 | @Test 20 | fun shouldMapNullValuesToEmpty() { 21 | val mapper = createMapper() 22 | assertEquals(emptyList(), mapper.readValue("{}", TestClass::class.java).foo) 23 | assertEquals(emptyList(), mapper.readValue("""{"foo": null}""", TestClass::class.java).foo) 24 | 25 | } 26 | 27 | private fun createMapper(): ObjectMapper { 28 | return ObjectMapper().registerModule(kotlinModule { enable(NullToEmptyCollection) }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/NullToEmptyMapTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.KotlinFeature.NullToEmptyMap 5 | import com.fasterxml.jackson.module.kotlin.kotlinModule 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestNullToEmptyMap { 10 | 11 | private data class TestClass(val foo: Map) 12 | 13 | @Test 14 | fun nonNullCaseStillWorks() { 15 | val mapper = createMapper() 16 | assertEquals(mapOf("bar" to 1), mapper.readValue("""{"foo": {"bar": 1}}""", TestClass::class.java).foo) 17 | } 18 | 19 | @Test 20 | fun shouldMapNullValuesToEmpty() { 21 | val mapper = createMapper() 22 | assertEquals(emptyMap(), mapper.readValue("{}", TestClass::class.java).foo) 23 | assertEquals(emptyMap(), mapper.readValue("""{"foo": null}""", TestClass::class.java).foo) 24 | 25 | } 26 | 27 | private fun createMapper(): ObjectMapper { 28 | return ObjectMapper().registerModule(kotlinModule { enable(NullToEmptyMap) }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/ObjectSingletonTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.KotlinFeature.SingletonSupport 5 | import com.fasterxml.jackson.module.kotlin.kotlinModule 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Test 9 | 10 | // [module-kotlin#225]: keep Kotlin singletons as singletons 11 | class TestObjectSingleton { 12 | val mapper: ObjectMapper = ObjectMapper() 13 | .registerModule(kotlinModule { enable(SingletonSupport) }) 14 | 15 | object Singleton { 16 | var content = 1 // mutable state 17 | } 18 | 19 | @Test 20 | fun deserializationPreservesSingletonProperty() { 21 | val js = mapper.writeValueAsString(Singleton) 22 | val newSingleton = mapper.readValue(js) 23 | 24 | assertEquals(Singleton, newSingleton) 25 | } 26 | 27 | @Test 28 | fun deserializationResetsSingletonObjectState() { 29 | // persist current singleton state 30 | val js = mapper.writeValueAsString(Singleton) 31 | val initial = Singleton.content 32 | 33 | // mutate the in-memory singleton state 34 | val after = initial + 1 35 | Singleton.content = after 36 | assertEquals(Singleton.content, after) 37 | 38 | // read back persisted state resets singleton state 39 | val newSingleton = mapper.readValue(js) 40 | assertEquals(initial, Singleton.content) 41 | assertEquals(initial, newSingleton.content) 42 | } 43 | 44 | @Test 45 | fun deserializedObjectsBehaveLikeSingletons() { 46 | val js = mapper.writeValueAsString(Singleton) 47 | val newSingleton = mapper.readValue(js) 48 | assertEquals(Singleton.content, newSingleton.content) 49 | 50 | newSingleton.content += 1 51 | 52 | assertEquals(Singleton.content, newSingleton.content) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/TestHelpers.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test 2 | 3 | import kotlin.test.fail 4 | 5 | /** 6 | * Expect a block to throw an exception. If a different type of exception is thrown or no 7 | * exception is produced by the block, fail the test. In the latter case, no exception being 8 | * thrown, fixMessage is printed. 9 | * 10 | * This function is intended to allow failing tests to be written and run as part of the build 11 | * without causing it to fail, except if the failure is fixed, in which case the fixMessage 12 | * should make it clear what has happened (i.e. that some previously broken functionality 13 | * has been fixed). 14 | * 15 | * @param T The expected throwable 16 | * @param fixMessage The message to print when the block succeeds 17 | * @param block The block to execute 18 | */ 19 | inline fun expectFailure( 20 | fixMessage: String, 21 | block: () -> Unit 22 | ) { 23 | try { 24 | block() 25 | } catch (e: Throwable) { 26 | val throwableType = T::class 27 | if (throwableType.isInstance(e)) { 28 | // Expected exception, do nothing 29 | } else { 30 | fail("Expected $throwableType but got $e") 31 | } 32 | 33 | return 34 | } 35 | 36 | fail(fixMessage) 37 | } 38 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/TestHelpersTest.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test 2 | 3 | import org.junit.jupiter.api.Assertions.assertThrows 4 | import org.junit.jupiter.api.Test 5 | import kotlin.test.assertEquals 6 | 7 | class TestHelpersTest { 8 | @Test 9 | fun expectFailure_ExpectedExceptionThrown() { 10 | expectFailure("This will not be printed") { 11 | throw AssertionError("This is expected") 12 | } 13 | } 14 | 15 | @Test 16 | fun expectFailure_AnotherExceptionThrown() { 17 | val throwable = assertThrows(AssertionError::class.java) { 18 | expectFailure("This will not be printed") { 19 | throw Exception("This is not expected") 20 | } 21 | } 22 | 23 | assertEquals("Expected class java.lang.AssertionError but got java.lang.Exception: This is not expected", throwable.message) 24 | } 25 | 26 | @Test 27 | fun expectFailure_NoExceptionThrown() { 28 | val fixMessage = "Test will fail with this message" 29 | val throwable = assertThrows(AssertionError::class.java) { 30 | expectFailure(fixMessage) { 31 | // Do nothing 32 | } 33 | } 34 | 35 | assertEquals(fixMessage, throwable.message) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/CloneableJavaObj.java: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | 5 | public class CloneableJavaObj implements Cloneable { 6 | public final String id; 7 | 8 | @JsonCreator 9 | public CloneableJavaObj(String id) { 10 | this.id = id; 11 | } 12 | 13 | public String getId() { 14 | return id; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub281.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonIdentityInfo 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo 5 | import com.fasterxml.jackson.annotation.ObjectIdGenerators 6 | import com.fasterxml.jackson.module.kotlin.defaultMapper 7 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 8 | import com.fasterxml.jackson.module.kotlin.readValue 9 | import com.fasterxml.jackson.module.kotlin.testPrettyWriter 10 | import kotlin.test.Test 11 | import kotlin.test.assertEquals 12 | import kotlin.test.assertSame 13 | 14 | class GitHub281 { 15 | @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@type") 16 | @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator::class, property = "@id") 17 | interface Entity 18 | 19 | object NumberEntity : Entity 20 | 21 | data class NumberValue(val value: Int) { 22 | val entity = NumberEntity 23 | } 24 | 25 | private val json = """ 26 | [ { 27 | "value" : 10, 28 | "entity" : { 29 | "@type" : ".GitHub281${'$'}NumberEntity", 30 | "@id" : 1 31 | } 32 | }, { 33 | "value" : 11, 34 | "entity" : 1 35 | } ] 36 | """.trimIndent() 37 | 38 | @Test 39 | fun `test writing involving type, id and object`() { 40 | val input = listOf(NumberValue(10), NumberValue(11)) 41 | 42 | val output = jacksonObjectMapper() 43 | .testPrettyWriter() 44 | .writeValueAsString(input) 45 | 46 | assertEquals(json, output) 47 | } 48 | 49 | @Test 50 | fun `test reading involving type, id and object`() { 51 | val output = defaultMapper.readValue>(json) 52 | 53 | assertEquals(2, output.size) 54 | val (a, b) = output 55 | assertSame(NumberEntity::class.java, a.entity.javaClass) 56 | assertSame(NumberEntity::class.java, b.entity.javaClass) 57 | assertEquals(10, a.value) 58 | assertEquals(11, b.value) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub314.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.MapperFeature 4 | import com.fasterxml.jackson.module.kotlin.jsonMapper 5 | import com.fasterxml.jackson.module.kotlin.kotlinModule 6 | import kotlin.test.Test 7 | import kotlin.test.assertEquals 8 | 9 | class GitHub314 { 10 | // Since Nothing? is compiled as a Void, it can be serialized by specifying ALLOW_VOID_VALUED_PROPERTIES 11 | data object NothingData { 12 | val data: Nothing? = null 13 | } 14 | 15 | @Test 16 | fun test() { 17 | val expected = """{"data":null}""" 18 | 19 | val withoutKotlinModule = jsonMapper { enable(MapperFeature.ALLOW_VOID_VALUED_PROPERTIES) } 20 | assertEquals(expected, withoutKotlinModule.writeValueAsString(NothingData)) 21 | 22 | val withKotlinModule = jsonMapper { 23 | enable(MapperFeature.ALLOW_VOID_VALUED_PROPERTIES) 24 | addModule(kotlinModule()) 25 | } 26 | 27 | assertEquals(expected, withKotlinModule.writeValueAsString(NothingData)) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub618.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator 4 | import com.fasterxml.jackson.databind.SerializerProvider 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize 6 | import com.fasterxml.jackson.databind.ser.std.StdSerializer 7 | import com.fasterxml.jackson.module.kotlin.defaultMapper 8 | import org.junit.jupiter.api.Test 9 | import kotlin.test.assertEquals 10 | 11 | class GitHub618 { 12 | @JsonSerialize(using = V.Serializer::class) 13 | @JvmInline 14 | value class V(val value: String) { 15 | class Serializer : StdSerializer(V::class.java) { 16 | override fun serialize(p0: V, p1: JsonGenerator, p2: SerializerProvider) { 17 | p1.writeString(p0.toString()) 18 | } 19 | } 20 | } 21 | 22 | data class D(val v: V?) 23 | 24 | @Test 25 | fun test() { 26 | // expected: {"v":null}, but NullPointerException thrown 27 | assertEquals("""{"v":null}""", defaultMapper.writeValueAsString(D(null))) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub625.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertEquals 7 | import kotlin.test.assertNotEquals 8 | 9 | class GitHub625 { 10 | @JvmInline 11 | value class Primitive(val v: Int) 12 | 13 | @JvmInline 14 | value class NonNullObject(val v: String) 15 | 16 | @JvmInline 17 | value class NullableObject(val v: String?) 18 | 19 | @JsonInclude(value = JsonInclude.Include.NON_NULL, content = JsonInclude.Include.NON_NULL) 20 | data class Dto( 21 | val primitive: Primitive? = null, 22 | val nonNullObject: NonNullObject? = null, 23 | val nullableObject: NullableObject? = null 24 | ) { 25 | fun getPrimitiveGetter(): Primitive? = null 26 | fun getNonNullObjectGetter(): NonNullObject? = null 27 | fun getNullableObjectGetter(): NullableObject? = null 28 | } 29 | 30 | @Test 31 | fun test() { 32 | val dto = Dto() 33 | assertEquals("{}", defaultMapper.writeValueAsString(dto)) 34 | } 35 | 36 | @JsonInclude(value = JsonInclude.Include.NON_EMPTY, content = JsonInclude.Include.NON_NULL) 37 | data class FailingDto( 38 | val nullableObject1: NullableObject = NullableObject(null), 39 | val nullableObject2: NullableObject? = NullableObject(null), 40 | val map: Map = mapOf("nullableObject" to NullableObject(null),) 41 | ) { 42 | fun getNullableObjectGetter1(): NullableObject = NullableObject(null) 43 | fun getNullableObjectGetter2(): NullableObject? = NullableObject(null) 44 | fun getMapGetter(): Map = mapOf("nullableObject" to NullableObject(null)) 45 | } 46 | 47 | @Test 48 | fun failing() { 49 | val json = defaultMapper.writeValueAsString(FailingDto()) 50 | 51 | assertNotEquals("{}", json) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub757.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.json.JsonMapper 4 | import com.fasterxml.jackson.module.kotlin.KotlinFeature 5 | import com.fasterxml.jackson.module.kotlin.KotlinModule 6 | import com.fasterxml.jackson.module.kotlin.convertValue 7 | import org.junit.jupiter.api.Test 8 | import kotlin.test.assertNull 9 | 10 | class GitHub757 { 11 | @Test 12 | fun test() { 13 | val kotlinModule = KotlinModule.Builder() 14 | .enable(KotlinFeature.NewStrictNullChecks) 15 | .build() 16 | val mapper = JsonMapper.builder() 17 | .addModule(kotlinModule) 18 | .build() 19 | val convertValue = mapper.convertValue(null) 20 | assertNull(convertValue) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub832.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonAnyGetter 4 | import com.fasterxml.jackson.annotation.JsonAnySetter 5 | import com.fasterxml.jackson.databind.ObjectMapper 6 | import com.fasterxml.jackson.module.kotlin.KotlinModule 7 | import com.fasterxml.jackson.module.kotlin.readValue 8 | import org.junit.jupiter.api.Test 9 | import kotlin.test.assertEquals 10 | 11 | class GitHub832 { 12 | data class AnySetter @JvmOverloads constructor( 13 | val test: String? = null, 14 | @JsonAnySetter 15 | @get:JsonAnyGetter 16 | val anything: Map = mutableMapOf(), 17 | ) 18 | 19 | @Test 20 | fun testDeserialization() { 21 | val json = """ 22 | { 23 | "widget": { 24 | "debug": "on" 25 | } 26 | } """.trimMargin() 27 | val jacksonMapper = ObjectMapper() 28 | jacksonMapper.registerModules(KotlinModule.Builder().build()) 29 | val anySetter = jacksonMapper.readValue(json) 30 | assertEquals("widget", anySetter.anything.entries.first().key) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub841.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonInclude 5 | import com.fasterxml.jackson.databind.ObjectMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import com.fasterxml.jackson.module.kotlin.registerKotlinModule 8 | import org.junit.jupiter.api.Test 9 | import kotlin.test.assertEquals 10 | 11 | class GitHub841 { 12 | object Foo { 13 | override fun toString(): String = "Foo()" 14 | 15 | @JvmStatic 16 | @JsonCreator 17 | fun deserialize(): Foo { 18 | return Foo 19 | } 20 | } 21 | 22 | private val mapper = ObjectMapper() 23 | .setSerializationInclusion(JsonInclude.Include.NON_ABSENT) 24 | .registerKotlinModule() 25 | 26 | @Test 27 | fun shouldDeserializeSimpleObject() { 28 | val value = Foo 29 | val serialized = mapper.writeValueAsString(value) 30 | val deserialized = mapper.readValue(serialized) 31 | 32 | assertEquals(value, deserialized) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub844.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeInfo 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "_type") 10 | private sealed class BaseClass 11 | 12 | private data class ChildClass(val text: String) : BaseClass() 13 | 14 | class GitHub844 { 15 | @Test 16 | fun test() { 17 | val json = """ 18 | { 19 | "_type": "ChildClass", 20 | "text": "Test" 21 | } 22 | """ 23 | 24 | val message = defaultMapper.readValue(json) 25 | 26 | assertEquals(ChildClass("Test"), message) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub873.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonValue 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import kotlin.test.Test 7 | 8 | class GitHub873 { 9 | @JvmInline 10 | value class Person( 11 | val properties: Map, 12 | ) 13 | 14 | data class TimestampedPerson( 15 | val timestamp: Long, 16 | val person: Person, 17 | ) 18 | 19 | @Test 20 | fun `should serialize value class`() { 21 | 22 | val person = Person( 23 | mapOf( 24 | "id" to "123", 25 | "updated" to "2023-11-22 12:11:23", 26 | "login" to "2024-01-15", 27 | ), 28 | ) 29 | 30 | val serialized = defaultMapper.writeValueAsString( 31 | TimestampedPerson( 32 | 123L, 33 | Person(person.properties), 34 | ) 35 | ) 36 | 37 | val deserialized = defaultMapper.readValue(serialized) 38 | 39 | assert( 40 | deserialized == TimestampedPerson( 41 | 123L, 42 | Person(person.properties), 43 | ) 44 | ) 45 | } 46 | 47 | @JvmInline 48 | value class MapAsJsonValue(val value: String) { 49 | @get:JsonValue 50 | val jsonValue get() = mapOf("key" to value) 51 | } 52 | 53 | data class JsonValueWrapper(val value: MapAsJsonValue) 54 | 55 | @Test 56 | fun `JsonValue is serialized in the same way`() { 57 | val data = JsonValueWrapper(MapAsJsonValue("value")) 58 | val json = defaultMapper.writeValueAsString(data) 59 | 60 | assert("""{"value":{"key":"value"}}""" == json) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub917.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | import com.fasterxml.jackson.annotation.OptBoolean 6 | import com.fasterxml.jackson.databind.exc.InvalidNullException 7 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 8 | import com.fasterxml.jackson.module.kotlin.readValue 9 | import org.junit.jupiter.api.Test 10 | import org.junit.jupiter.api.assertThrows 11 | import kotlin.test.assertEquals 12 | 13 | class GitHub917 { 14 | data class Failing(val data: T) 15 | 16 | val mapper = jacksonObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL) 17 | 18 | @Test 19 | fun failing() { 20 | val value = Failing(null) 21 | val json = mapper.writeValueAsString(value) 22 | 23 | assertThrows { 24 | val deserializedValue = mapper.readValue>(json) 25 | assertEquals(value ,deserializedValue) 26 | } 27 | } 28 | 29 | data class WorkAround(@JsonProperty(isRequired = OptBoolean.FALSE) val data: T) 30 | 31 | @Test 32 | fun workAround() { 33 | val value = WorkAround(null) 34 | val json = mapper.writeValueAsString(value) 35 | 36 | val deserializedValue = mapper.readValue>(json) 37 | assertEquals(value ,deserializedValue) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub922RequiredCollectionsDtoJava.java: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class GitHub922RequiredCollectionsDtoJava { 10 | private final List list; 11 | private final Map map; 12 | 13 | @JsonCreator 14 | public GitHub922RequiredCollectionsDtoJava( 15 | @JsonProperty(value = "list", required = true) List list, 16 | @JsonProperty(value = "map", required = true) Map map 17 | ) { 18 | this.list = list; 19 | this.map = map; 20 | } 21 | 22 | public List getList() { 23 | return list; 24 | } 25 | 26 | public Map getMap() { 27 | return map; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub976.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.exc.InvalidNullException 4 | import com.fasterxml.jackson.module.kotlin.KotlinFeature 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | import org.junit.jupiter.api.assertThrows 7 | import kotlin.test.Test 8 | 9 | class GitHub976 { 10 | data class PrimitiveList(val list: List) 11 | 12 | @Test 13 | fun strictNullChecks() { 14 | val om = jacksonObjectMapper { 15 | enable(KotlinFeature.StrictNullChecks) 16 | } 17 | assertThrows { 18 | om.readValue("""{"list": [""] }""".toByteArray(), PrimitiveList::class.java) 19 | } 20 | } 21 | 22 | @Test 23 | fun newStrictNullChecksRegression() { 24 | val om = jacksonObjectMapper { 25 | enable(KotlinFeature.NewStrictNullChecks) 26 | } 27 | assertThrows { 28 | om.readValue("""{"list": [""] }""".toByteArray(), PrimitiveList::class.java) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github101.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JacksonInject 4 | import com.fasterxml.jackson.databind.InjectableValues 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | import org.junit.jupiter.api.Test 7 | import java.util.UUID 8 | import kotlin.test.assertEquals 9 | 10 | class TestGithub101_JacksonInjectTest { 11 | @Test 12 | fun `JacksonInject-annotated parameters are populated when constructing Kotlin data classes`() { 13 | val contextualValue = UUID.randomUUID() 14 | val reader = jacksonObjectMapper() 15 | .readerFor(SomeDatum::class.java) 16 | .with(InjectableValues.Std(mapOf("context" to contextualValue))) 17 | assertEquals( 18 | SomeDatum("test", contextualValue), 19 | reader.readValue("""{ "value": "test" }""") 20 | ) 21 | } 22 | 23 | data class SomeDatum(val value: String, @JacksonInject("context") val contextualValue: UUID) 24 | } 25 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github104.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.junit.jupiter.api.Test 6 | 7 | class TestGithub104 { 8 | abstract class SuperClass(val name: String) 9 | 10 | class SubClass(name: String) : SuperClass(name) 11 | // note this would fail if the constructor parameter is not named the same as the property 12 | 13 | 14 | @Test 15 | fun testIt() { 16 | val jsonValue = """{"name":"TestName"}""" 17 | 18 | defaultMapper.readValue(jsonValue) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github120.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonValue 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub120 { 10 | data class Foo @JsonCreator(mode = JsonCreator.Mode.DELEGATING) constructor ( 11 | @JsonValue 12 | val value: Long 13 | ) 14 | 15 | data class Bar( 16 | val foo: Foo 17 | ) 18 | 19 | @Test 20 | fun testNestedJsonValue() { 21 | val foo = Foo(4711L) 22 | val bar = Bar(foo) 23 | val asString = defaultMapper.writeValueAsString(bar) 24 | assertEquals("{\"foo\":4711}", asString) 25 | 26 | val fromString = defaultMapper.readValue(asString, Bar::class.java) 27 | assertEquals(bar, fromString) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github124.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonIgnore 5 | import com.fasterxml.jackson.annotation.JsonProperty 6 | import com.fasterxml.jackson.module.kotlin.defaultMapper 7 | import com.fasterxml.jackson.module.kotlin.readValue 8 | import org.junit.jupiter.api.Test 9 | 10 | class TestGithub124 { 11 | // test for [module-kotlin#124]: broken in 2.9.3, fixed in 2.9.6 12 | @Test 13 | fun test() { 14 | // with 2.9.3 prints 15 | // Foo(name=foo, query=NonSerializable, rawQuery=bar) 16 | // but with 2.9.4 throws: 17 | // com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class DeserializationTest$Foo] value failed for JSON property query due to missing (therefore NULL) value for creator parameter rawQuery which is a non-nullable type 18 | // at [Source: (String)"{"name": "foo", "query": "bar"}"; line: 1, column: 31] (through reference chain: DeserializationTest$Foo["query"]) 19 | val deserialized: Foo = defaultMapper.readValue("{\"name\": \"foo\", \"query\": \"bar\"}") 20 | println(deserialized) 21 | 22 | val serialized = defaultMapper.writeValueAsString(deserialized) 23 | 24 | // with 2.9.3 prints 25 | // {"name":"foo","query":"bar"} 26 | println(serialized) 27 | } 28 | 29 | class NonSerializable(private val field: Any?) { 30 | override fun toString() = "NonSerializable" 31 | } 32 | 33 | data class Foo(@JsonProperty("name") val name: String, 34 | @JsonIgnore val query: NonSerializable, 35 | @JsonProperty("query") val rawQuery: String) { 36 | @JsonCreator 37 | constructor(@JsonProperty("name") name: String, 38 | @JsonProperty("query") rawQuery: String): this(name, NonSerializable(rawQuery), rawQuery) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github131.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertEquals 7 | 8 | class TestGithub131 { 9 | open class BaseClass(val name: String) 10 | 11 | class DerivedClass(name: String) : BaseClass(name) 12 | 13 | @Test 14 | fun testFailureCase() { 15 | val x = defaultMapper.readValue("""{"name":"abc"}""") 16 | assertEquals(DerivedClass("abc").name, x.name) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github148.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import org.junit.jupiter.api.Nested 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertEquals 7 | 8 | class TestGithub148 { 9 | enum class CorrectType { 10 | TYPEA, 11 | TYPEB, 12 | } 13 | 14 | enum class IncorrectType { 15 | TYPEA { 16 | override fun desc() = "type a" 17 | }, 18 | 19 | TYPEB { 20 | override fun desc() = "type b" 21 | }; 22 | 23 | abstract fun desc(): String 24 | } 25 | 26 | data class CorrentBean( 27 | val name: String, 28 | val type: CorrectType 29 | ) 30 | 31 | data class IncorrentBean( 32 | val name: String, 33 | val type: IncorrectType 34 | ) 35 | 36 | @Nested 37 | inner class DemoApplicationTests { 38 | @Test 39 | fun correntBean() { 40 | assertEquals("{\"name\":\"corrent\",\"type\":\"TYPEA\"}", defaultMapper.writeValueAsString(CorrentBean("corrent", CorrectType.TYPEA))) 41 | } 42 | 43 | @Test 44 | fun incorrentBean() { 45 | assertEquals("{\"name\":\"incorrent\",\"type\":\"TYPEA\"}", defaultMapper.writeValueAsString(IncorrentBean("incorrent", IncorrectType.TYPEA))) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github15.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.* 4 | import org.junit.jupiter.api.Test 5 | import kotlin.test.assertEquals 6 | 7 | class TestGithub15 { 8 | @Test fun testEnumConstructorWithParm() { 9 | val one = defaultMapper.readValue("\"ONE\"", TestEnum::class.java) 10 | assertEquals(TestEnum.ONE, one) 11 | val two = defaultMapper.readValue("\"TWO\"", TestEnum::class.java) 12 | assertEquals(TestEnum.TWO, two) 13 | } 14 | 15 | @Test fun testNormEnumWithoutParam() { 16 | val one = defaultMapper.readValue("\"ONE\"", TestOther::class.java) 17 | assertEquals(TestOther.ONE, one) 18 | val two = defaultMapper.readValue("\"TWO\"", TestOther::class.java) 19 | assertEquals(TestOther.TWO, two) 20 | } 21 | 22 | @Test fun testClassWithEnumsNeedingConstruction() { 23 | val obj: UsingEnum = defaultMapper.readValue("""{"x":"ONE","y":"TWO"}""") 24 | assertEquals(TestEnum.ONE, obj.x) 25 | assertEquals(TestOther.TWO, obj.y) 26 | } 27 | } 28 | 29 | private class UsingEnum(val x: TestEnum, val y: TestOther) 30 | 31 | private enum class TestEnum(val i: Int) { 32 | ONE(1), 33 | TWO(2) 34 | } 35 | 36 | private enum class TestOther { 37 | ONE, TWO 38 | } 39 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github155.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | 8 | class TestGithub155 { 9 | data class Foo @JvmOverloads constructor( 10 | @JsonProperty("name") val name: String, 11 | @JsonProperty("age") val age: Int = 0, 12 | @JsonProperty("country") val country: String = "whatever", 13 | @JsonProperty("city") val city: String = "nada") 14 | 15 | @Test 16 | fun testGithub155() { 17 | defaultMapper.readValue(""" 18 | {"name":"fred","age":12,"country":"Libertad","city":"Northville"} 19 | """.trimIndent()) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github158.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub158 { 10 | enum class SampleImpl constructor(override val value: String): Sample { 11 | One("oney"), 12 | Two("twoey") 13 | } 14 | 15 | interface Sample { 16 | val value: String 17 | } 18 | 19 | data class SampleContainer(@JsonDeserialize(`as` = SampleImpl::class) val sample: Sample) 20 | 21 | @Test 22 | fun testEnumSerDeser() { 23 | val original = SampleContainer(SampleImpl.One) 24 | 25 | val json = defaultMapper.writeValueAsString(original) 26 | // println(json) 27 | val obj = defaultMapper.readValue(json) 28 | assertEquals(original, obj) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github161.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.DeserializationFeature 4 | import com.fasterxml.jackson.databind.exc.MismatchedInputException 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.fail 8 | 9 | class TestGithub161 { 10 | data class Foo( 11 | val foo: Int, 12 | val bar: Int 13 | ) 14 | 15 | @Test 16 | fun testPrimitiveBeingZeroed() { 17 | val json = """{"foo":17}""" 18 | val objectMapper = jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true) 19 | try { 20 | objectMapper.readValue(json, Foo::class.java) 21 | fail("Expected an error on the missing primitive value") 22 | } catch (_: MismatchedInputException) { 23 | // success 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github165.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | import com.fasterxml.jackson.annotation.JsonSetter 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Test 8 | import kotlin.test.assertEquals 9 | import kotlin.test.assertFalse 10 | import kotlin.test.assertTrue 11 | 12 | class TestGithub165 { 13 | class Github165KotlinTest(@JsonProperty("name") var showName: String) 14 | { 15 | var yearSetterCalled: Boolean = false; 16 | var nameSetterCalled: Boolean = false; 17 | 18 | @JsonProperty("year") lateinit var showYear: String 19 | 20 | @JsonSetter("year") 21 | fun setYear(value: String) 22 | { 23 | yearSetterCalled = true 24 | this.showYear = value 25 | } 26 | 27 | @JsonSetter("name") 28 | fun setName(value: String) 29 | { 30 | nameSetterCalled = true 31 | this.showName = value 32 | } 33 | } 34 | 35 | @Test 36 | fun testJsonSetterCalledKotlin() { 37 | val obj = defaultMapper.readValue("""{"name":"Fred","year":"1942"}""") 38 | assertEquals("1942", obj.showYear) 39 | assertEquals("Fred", obj.showName) 40 | assertTrue(obj.yearSetterCalled) 41 | assertFalse(obj.nameSetterCalled) 42 | } 43 | 44 | @Test 45 | fun testJsonSetterCalledJava() { 46 | val obj = defaultMapper.readValue("""{"name":"Fred","year":"1942"}""") 47 | assertEquals("1942", obj.showYear) 48 | assertEquals("Fred", obj.showName) 49 | assertTrue(obj.yearSetterCalled) 50 | assertFalse(obj.nameSetterCalled) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github165JavaTest.java: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonSetter; 5 | 6 | public class Github165JavaTest 7 | { 8 | @JsonProperty("name") 9 | public String showName; 10 | 11 | @JsonProperty("year") 12 | public String showYear; 13 | 14 | public boolean nameSetterCalled = false; 15 | public boolean yearSetterCalled = false; 16 | 17 | public Github165JavaTest(@JsonProperty("name") String name) { 18 | this.showName = name; 19 | } 20 | 21 | @JsonSetter("name") 22 | public void setName(String value) { 23 | nameSetterCalled = true; 24 | this.showName = value; 25 | } 26 | 27 | @JsonSetter("year") 28 | public void setYear(String value) { 29 | yearSetterCalled = true; 30 | this.showYear = value; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github167.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import org.junit.jupiter.api.Test 6 | import java.util.function.IntSupplier 7 | 8 | class TestGithub167 { 9 | val samObject = IntSupplier { 42 } 10 | 11 | val answer = 42 12 | val samObjectSynthetic = IntSupplier { answer } 13 | 14 | @Test 15 | fun withKotlinExtension() { 16 | defaultMapper.writeValueAsString(samObject) 17 | } 18 | 19 | @Test 20 | fun withKotlinExtension_Synthetic() { 21 | defaultMapper.writeValueAsString(samObjectSynthetic) 22 | } 23 | 24 | 25 | @Test 26 | fun withoutKotlinExtension() { 27 | ObjectMapper().writeValueAsString(samObject) 28 | } 29 | 30 | @Test 31 | fun withoutKotlinExtension_Synthetic() { 32 | ObjectMapper().writeValueAsString(samObjectSynthetic) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github168.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Test 8 | import org.junit.jupiter.api.assertThrows 9 | import kotlin.test.assertEquals 10 | 11 | class TestGithub168 { 12 | @Suppress("UNUSED_PARAMETER") 13 | class TestClass(@JsonProperty(value = "foo", required = true) foo: String?, val baz: String) 14 | 15 | @Test 16 | fun testIfRequiredIsReallyRequiredWhenNullUsed() { 17 | val obj = defaultMapper.readValue("""{"foo":null,"baz":"whatever"}""") 18 | assertEquals("whatever", obj.baz) 19 | } 20 | 21 | @Test 22 | fun testIfRequiredIsReallyRequiredWhenAbsent() { 23 | assertThrows { 24 | val obj = defaultMapper.readValue("""{"baz":"whatever"}""") 25 | assertEquals("whatever", obj.baz) 26 | } 27 | } 28 | 29 | @Test 30 | fun testIfRequiredIsReallyRequiredWhenValuePresent() { 31 | val obj = defaultMapper.readValue("""{"foo":"yay!","baz":"whatever"}""") 32 | assertEquals("whatever", obj.baz) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github179.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Test 8 | import kotlin.test.assertEquals 9 | 10 | // verifying work around for this issue, no bug present 11 | 12 | class TestGithub179 { 13 | @Test 14 | fun listOfStrings() { 15 | val strings = defaultMapper.readValue("""[ "first", "second" ]""") 16 | assertEquals(strings.values, listOf("first", "second")) 17 | } 18 | 19 | @Test 20 | fun embeddedListOfStrings() { 21 | val stringsContainer = defaultMapper.readValue( 22 | """{ "strings" : [ "first", "second" ] }""") 23 | assertEquals(stringsContainer.strings.values, listOf("first", "second")) 24 | } 25 | 26 | @Test 27 | fun embeddedListOfEnums() { 28 | val myEnumsContainer = defaultMapper.readValue( 29 | """{ "myEnums" : [ "first", "second" ] }""") 30 | assertEquals(myEnumsContainer.myEnums.values, listOf(MyEnum.FIRST, MyEnum.SECOND)) 31 | } 32 | 33 | private class StringsContainer(@JsonProperty("strings") val strings: Strings) 34 | 35 | private class MyEnumsContainer(@JsonProperty("myEnums") val myEnums: MyEnums) 36 | 37 | private class Strings @JsonCreator(mode = JsonCreator.Mode.DELEGATING) constructor(val values : List) 38 | 39 | private class MyEnums @JsonCreator(mode = JsonCreator.Mode.DELEGATING) constructor(val values : List) 40 | 41 | private enum class MyEnum { 42 | @JsonProperty("first") FIRST, 43 | @JsonProperty("second") SECOND 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github180.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Test 8 | import kotlin.test.assertNull 9 | 10 | class TestGithub180 { 11 | class TestClass(val instantName: String? = null, val someInt: Int? = null) { 12 | companion object { 13 | @JvmStatic 14 | @JsonCreator 15 | fun create( 16 | @JsonProperty("instantName") instantName: String?, 17 | @JsonProperty("someInt") someInt: Int? 18 | ): TestClass { 19 | return TestClass(instantName, someInt) 20 | } 21 | } 22 | 23 | } 24 | 25 | @Test 26 | fun testMissingProperty() { 27 | val obj = defaultMapper.readValue("""{}""") 28 | assertNull(obj.instantName) 29 | assertNull(obj.someInt) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github181.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub181 { 10 | enum class HealthStatus { 11 | FAILED, 12 | OK 13 | } 14 | 15 | data class HealthStatusMap @JsonCreator(mode = JsonCreator.Mode.DELEGATING) constructor (val statuses: Map) 16 | : Map by statuses { 17 | 18 | fun isPassing() = statuses.all { (_, v) -> v == HealthStatus.OK } 19 | } 20 | 21 | @Test 22 | fun testReflectionExceptionOnDelegatedMap() { 23 | val testInstance = HealthStatusMap(mapOf("failed" to HealthStatus.FAILED, "okey dokey" to HealthStatus.OK)) 24 | val json = defaultMapper.writeValueAsString(testInstance) 25 | assertEquals("{\"failed\":\"FAILED\",\"okey dokey\":\"OK\"}", json) 26 | val newInstance = defaultMapper.readValue(json) 27 | assertEquals(testInstance, newInstance) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github194.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonIdentityInfo 4 | import com.fasterxml.jackson.annotation.ObjectIdGenerators 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import org.junit.jupiter.api.Test 7 | import java.util.UUID 8 | import kotlin.test.assertEquals 9 | 10 | class TestGithub194 { 11 | val id: UUID = UUID.fromString("149800a6-7855-4e09-9185-02e442da8013") 12 | val json = """{"id": "$id", "name": "Foo"}""" 13 | 14 | @Test 15 | fun testIdentityInfo() { 16 | val value = defaultMapper.readValue(json, WithIdentity::class.java) 17 | assertEquals(id, value.id) 18 | assertEquals(id.toString(), value.idString) 19 | assertEquals("Foo", value.name) 20 | } 21 | 22 | @JsonIdentityInfo( 23 | property = "id", 24 | scope = WithIdentity::class, 25 | generator = ObjectIdGenerators.PropertyGenerator::class 26 | ) 27 | class WithIdentity(val id: UUID, 28 | val idString: String = id.toString(), 29 | val name: String) 30 | 31 | @Test 32 | fun testIdentityInfo_WithDefaultId() { 33 | val value = defaultMapper.readValue(json, WithIdentityAndDefaultId::class.java) 34 | assertEquals(id, value.id) 35 | assertEquals(id.toString(), value.idString) 36 | assertEquals("Foo", value.name) 37 | } 38 | 39 | @JsonIdentityInfo( 40 | property = "id", 41 | scope = WithIdentityAndDefaultId::class, 42 | generator = ObjectIdGenerators.PropertyGenerator::class 43 | ) 44 | class WithIdentityAndDefaultId(val id: UUID, 45 | val idString: String = id.toString(), 46 | val name: String) 47 | } 48 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github196.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertSame 7 | 8 | /** 9 | * An empty object should be deserialized as *the* Unit instance 10 | */ 11 | class TestGithub196 { 12 | @Test 13 | fun testUnitSingletonDeserialization() { 14 | assertSame(defaultMapper.readValue("{}"), Unit) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github207.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonValue 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Assertions.* 7 | import org.junit.jupiter.api.Test 8 | 9 | class TestGithub207 { 10 | open class Wrapper(@JsonValue val value: String) { 11 | 12 | override fun equals(other: Any?): Boolean { 13 | if (this === other) return true 14 | if (javaClass != other?.javaClass) return false 15 | 16 | other as Wrapper 17 | 18 | if (value != other.value) return false 19 | 20 | return true 21 | } 22 | 23 | override fun hashCode(): Int = 24 | value.hashCode() 25 | 26 | override fun toString(): String = 27 | value 28 | 29 | } 30 | 31 | class ExtendedWrapper(value: String) : Wrapper(value) 32 | 33 | private val objectMapper = ObjectMapper() 34 | 35 | @Test 36 | fun shouldDeserializeJsonString() { 37 | // given 38 | val json = "\"foo\"" 39 | 40 | // when 41 | val deserialized = objectMapper.readValue(json) 42 | 43 | // then 44 | assertEquals(Wrapper("foo"), deserialized) 45 | } 46 | 47 | @Test 48 | fun shouldSerializeJsonString() { 49 | // given 50 | val wrapperObject = Wrapper("foo") 51 | 52 | // when 53 | val serialized = objectMapper.writeValueAsString(wrapperObject) 54 | 55 | // then 56 | assertEquals("\"foo\"", serialized) 57 | } 58 | 59 | @Test 60 | fun shouldDeserializeJsonString_Extended() { 61 | // given 62 | val json = "\"foo\"" 63 | 64 | // when 65 | val deserialized = objectMapper.readValue(json) 66 | 67 | // then 68 | assertEquals(ExtendedWrapper("foo"), deserialized) 69 | } 70 | 71 | @Test 72 | fun shouldSerializeJsonString_Extended() { 73 | // given 74 | val wrapperObject = ExtendedWrapper("foo") 75 | 76 | // when 77 | val serialized = objectMapper.writeValueAsString(wrapperObject) 78 | 79 | // then 80 | assertEquals("\"foo\"", serialized) 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github210.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.junit.jupiter.api.Test 6 | 7 | 8 | class TestGithub210 { 9 | class ExampleFail1(val stringItem: String, val regexItem: Regex) 10 | class ExampleFail2(val regexItem: Regex, val stringItem: String) 11 | 12 | class ExampleNoFail(val regexItem: RegexLike, val stringItem: String) 13 | class RegexLike(val pattern: String, val options: List) 14 | 15 | @Test 16 | fun testSerDesOfRegex() { 17 | val happyJson = """{"stringItem":"hello","regexItem":{"options":[],"pattern":"test"}}""" 18 | val troubleJson = """{"regexItem":{"options":[],"pattern":"test"},"stringItem":"hello"}""" 19 | 20 | defaultMapper.readValue(happyJson) 21 | defaultMapper.readValue(troubleJson) 22 | 23 | defaultMapper.readValue(happyJson) 24 | defaultMapper.readValue(happyJson) 25 | 26 | // the following used to fail on stringItem being missing, the KotlinValueInstantiator is confused 27 | defaultMapper.readValue(troubleJson) // fail {"regexItem":{"pattern":"test","options":[]},"stringItem":"hello"} 28 | defaultMapper.readValue(troubleJson) // fail {"regexItem":{"pattern":"test","options":[]},"stringItem":"hello"} 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github22.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore 4 | import com.fasterxml.jackson.annotation.JsonValue 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Test 8 | import kotlin.test.assertEquals 9 | 10 | class TestGithub22 { 11 | class StringValue constructor(s: String) { 12 | val other: String = s 13 | 14 | @JsonValue override fun toString() = other 15 | } 16 | 17 | data class StringValue2(@get:JsonIgnore val s: String) { 18 | @JsonValue override fun toString() = s 19 | } 20 | 21 | @Test fun testJsonValueNoMatchingMemberWithConstructor() { 22 | val expectedJson = "\"test\"" 23 | val expectedObj = StringValue("test") 24 | 25 | val actualJson = defaultMapper.writeValueAsString(expectedObj) 26 | assertEquals(expectedJson, actualJson) 27 | 28 | val actualObj = defaultMapper.readValue("\"test\"") 29 | assertEquals(expectedObj.other, actualObj.other) 30 | 31 | } 32 | 33 | @Test fun testJsonValue2DataClassIgnoredMemberInConstructor() { 34 | val expectedJson = "\"test\"" 35 | val expectedObj = StringValue2("test") 36 | 37 | val actualJson = defaultMapper.writeValueAsString(expectedObj) 38 | assertEquals(expectedJson, actualJson) 39 | 40 | val actualObj = defaultMapper.readValue("\"test\"") 41 | assertEquals(expectedObj, actualObj) 42 | 43 | } 44 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github239.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonSubTypes 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo 5 | import com.fasterxml.jackson.annotation.JsonTypeName 6 | import com.fasterxml.jackson.databind.ObjectMapper 7 | import com.fasterxml.jackson.module.kotlin.kotlinModule 8 | import com.fasterxml.jackson.module.kotlin.readValue 9 | import org.junit.jupiter.api.Test 10 | import kotlin.test.assertEquals 11 | 12 | 13 | class TestGithub239 { 14 | 15 | @JsonTypeInfo(use = JsonTypeInfo.Id.NAME) 16 | sealed class Github239Either { 17 | 18 | @JsonTypeName("a") 19 | data class A(var field: String = "") : Github239Either() 20 | 21 | @JsonTypeName("b") 22 | data class B(var otherField: String = "") : Github239Either() 23 | 24 | } 25 | 26 | @JsonTypeInfo(use = JsonTypeInfo.Id.NAME) 27 | @JsonSubTypes( 28 | JsonSubTypes.Type(Github239EitherCustomized.A::class, name = "a"), 29 | JsonSubTypes.Type(Github239EitherCustomized.B::class, name = "b") 30 | ) 31 | sealed class Github239EitherCustomized { 32 | 33 | data class A(var field: String = "") : Github239EitherCustomized() 34 | 35 | data class B(var otherField: String = "") : Github239EitherCustomized() 36 | 37 | } 38 | 39 | val json = """[ 40 | { 41 | "@type": "a", 42 | "field": "value" 43 | }, 44 | { 45 | "@type": "b", 46 | "otherField": "1234" 47 | } 48 | ]""" 49 | 50 | val mapper = ObjectMapper() 51 | .registerModule(kotlinModule()) 52 | 53 | @Test 54 | fun test_implicit_subclasses() { 55 | 56 | val array = mapper.readValue>(json) 57 | 58 | assertEquals(2, array.size) 59 | assertEquals(Github239Either.A("value"), array[0]) 60 | assertEquals(Github239Either.B("1234"), array[1]) 61 | 62 | } 63 | 64 | @Test 65 | fun test_explicit_subclasses() { 66 | 67 | val array = mapper.readValue>(json) 68 | 69 | assertEquals(2, array.size) 70 | assertEquals(Github239EitherCustomized.A("value"), array[0]) 71 | assertEquals(Github239EitherCustomized.B("1234"), array[1]) 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github25.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder 5 | import com.fasterxml.jackson.module.kotlin.* 6 | import org.junit.jupiter.api.Test 7 | import kotlin.properties.Delegates 8 | import kotlin.test.assertEquals 9 | 10 | class TestGithub25 { 11 | @JsonPropertyOrder(alphabetic = true) 12 | class SomethingWithDelegates(val data: MutableMap = hashMapOf()) { 13 | val name: String by lazy { "fred" } 14 | @get:JsonIgnore val ignoreMe: String by lazy { "ignored" } 15 | var changeable: String = "starting value" 16 | @get:JsonIgnore var otherData1: String by data 17 | @get:JsonIgnore var otherData2: String by data 18 | @get:JsonIgnore val otherData3: String by data 19 | var somethingNotNull: String by Delegates.notNull() 20 | 21 | fun withOtherData(value: String): SomethingWithDelegates { 22 | somethingNotNull = value 23 | return this 24 | } 25 | } 26 | 27 | @Test fun testSerWithDelegates() { 28 | val json = defaultMapper.writeValueAsString(SomethingWithDelegates(linkedMapOf("otherData1" to "1", "otherData2" to "2", "otherData3" to "3")) 29 | .withOtherData("exists")) 30 | assertEquals("""{"data":{"otherData1":"1","otherData2":"2","otherData3":"3"},"changeable":"starting value","name":"fred","somethingNotNull":"exists"}""", json) 31 | } 32 | 33 | @Test fun testDeserWithDelegates() { 34 | val json = """{"changeable":"new value","data":{"otherData1":"1","otherData2":"2","otherData3":"3"},"somethingNotNull":"exists"}""" 35 | val obj: SomethingWithDelegates = defaultMapper.readValue(json) 36 | assertEquals("fred", obj.name) // not set by the Json, isn't in the constructor and is read only delegate 37 | assertEquals("ignored", obj.ignoreMe) 38 | assertEquals("new value", obj.changeable) 39 | assertEquals("1", obj.otherData1) 40 | assertEquals("2", obj.otherData2) 41 | assertEquals("3", obj.otherData3) 42 | assertEquals("exists", obj.somethingNotNull) 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github26.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertEquals 7 | 8 | data class ClassWithPrimitivesWithDefaults(val i: Int = 5, val x: Int) 9 | 10 | class TestGithub26 { 11 | @Test fun testConstructorWithPrimitiveTypesDefaultedExplicitlyAndImplicitly() { 12 | val check1: ClassWithPrimitivesWithDefaults = defaultMapper.readValue("""{"i":3,"x":2}""") 13 | assertEquals(3, check1.i) 14 | assertEquals(2, check1.x) 15 | 16 | val check2: ClassWithPrimitivesWithDefaults = defaultMapper.readValue("""{}""") 17 | assertEquals(5, check2.i) 18 | assertEquals(0, check2.x) 19 | 20 | val check3: ClassWithPrimitivesWithDefaults = defaultMapper.readValue("""{"i": 2}""") 21 | assertEquals(2, check3.i) 22 | assertEquals(0, check3.x) 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github270.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import org.junit.jupiter.api.Test 5 | import kotlin.test.assertEquals 6 | 7 | class TestGithub270 { 8 | data class Wrapper(private val field: String) { 9 | val upper = field.uppercase() 10 | fun field() = field 11 | fun stillAField() = field 12 | } 13 | 14 | @Test 15 | fun testPublicFieldOverlappingFunction() { 16 | val json = defaultMapper.writeValueAsString(Wrapper("Hello")) 17 | assertEquals("""{"upper":"HELLO"}""", json) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github29.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertEquals 7 | 8 | class TestGithub29 { 9 | data class Github29TestObj(val name: String, val other: String = "test") 10 | 11 | @Test fun testDefaultValuesInDeser() { 12 | val check1: Github29TestObj = defaultMapper.readValue("""{"name": "bla"}""") 13 | assertEquals("bla", check1.name) 14 | assertEquals("test", check1.other) 15 | 16 | val check2: Github29TestObj = defaultMapper.readValue("""{"name": "bla", "other": "fish"}""") 17 | assertEquals("bla", check2.name) 18 | assertEquals("fish", check2.other) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github308.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore 4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 5 | import com.fasterxml.jackson.annotation.JsonProperty 6 | import com.fasterxml.jackson.module.kotlin.defaultMapper 7 | import com.fasterxml.jackson.module.kotlin.readValue 8 | import org.junit.jupiter.api.Test 9 | import kotlin.test.assertEquals 10 | import kotlin.test.assertNotNull 11 | import kotlin.test.assertNull 12 | 13 | class TestGithub308 { 14 | @JsonIgnoreProperties(ignoreUnknown = true) 15 | data class TestDto( 16 | @JsonIgnore 17 | var id: Long? = null, 18 | var cityId: Int? = null 19 | ) { 20 | @JsonProperty("id") 21 | private fun unpackId(idObj: Int?) { 22 | cityId = idObj 23 | } 24 | } 25 | 26 | @Test 27 | fun createTestDto() { 28 | val dto: TestDto = defaultMapper.readValue("""{"id":12345}""") 29 | 30 | assertNotNull(dto) 31 | assertNull(dto.id) 32 | assertEquals(dto.cityId, 12345) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github335.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonSubTypes 4 | import com.fasterxml.jackson.annotation.JsonSubTypes.Type 5 | import com.fasterxml.jackson.annotation.JsonTypeInfo 6 | import com.fasterxml.jackson.annotation.JsonTypeInfo.As 7 | import com.fasterxml.jackson.annotation.JsonTypeInfo.Id 8 | import com.fasterxml.jackson.module.kotlin.defaultMapper 9 | import com.fasterxml.jackson.module.kotlin.readValue 10 | import org.junit.jupiter.api.Test 11 | import kotlin.test.assertEquals 12 | 13 | class Github335Test { 14 | interface Payload 15 | data class UniquePayload(val data: String) : Payload 16 | 17 | data class MyEntity( 18 | val type: String?, 19 | @JsonTypeInfo(use = Id.NAME, include = As.EXTERNAL_PROPERTY, property = "type") 20 | @JsonSubTypes(Type(value = UniquePayload::class, name = "UniquePayload")) 21 | val payload: Payload? 22 | ) 23 | 24 | @Test 25 | fun serializeAndDeserializeTypeable() { 26 | val oldEntity = MyEntity(null, null) 27 | val json = defaultMapper.writeValueAsString(oldEntity) 28 | val newEntity = defaultMapper.readValue(json) 29 | 30 | assertEquals(oldEntity, newEntity) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github340.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.kotlinModule 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class OwnerRequestTest { 10 | private val jackson = ObjectMapper().registerModule(kotlinModule()) 11 | 12 | val json = """{"foo": "Got a foo"}""" 13 | 14 | class NoIsField(val foo: String? = null) 15 | 16 | class IsField(val foo: String? = null) { 17 | val isFoo = foo != null 18 | } 19 | 20 | @Test 21 | fun testDeserHit340() { 22 | val value: IsField = jackson.readValue(json) 23 | // Fixed 24 | assertEquals("Got a foo", value.foo) 25 | } 26 | 27 | @Test 28 | fun testDeserWithoutIssue() { 29 | val value: NoIsField = jackson.readValue(json) 30 | assertEquals("Got a foo", value.foo) 31 | } 32 | 33 | // A test case for isSetter to work, added with the fix for this issue. 34 | class IsSetter { 35 | lateinit var isFoo: String 36 | } 37 | 38 | @Test 39 | fun isSetterTest() { 40 | val json = """{"isFoo":"bar"}""" 41 | val isSetter: IsSetter = jackson.readValue(json) 42 | 43 | assertEquals("bar", isSetter.isFoo) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github356.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub356 { 10 | @Test 11 | fun deserializeInlineClass() { 12 | assertEquals( 13 | ClassWithInlineMember(InlineClass("bar")), 14 | defaultMapper.readValue("""{"inlineClassProperty":"bar"}""") 15 | ) 16 | } 17 | 18 | @Test 19 | fun serializeInlineClass() { 20 | assertEquals( 21 | """{"inlineClassProperty":"bar"}""", 22 | defaultMapper.writeValueAsString(ClassWithInlineMember(InlineClass("bar"))) 23 | ) 24 | } 25 | 26 | @Test 27 | fun deserializeValueClass() { 28 | assertEquals( 29 | ClassWithValueMember(ValueClass("bar")), 30 | defaultMapper.readValue("""{"valueClassProperty":"bar"}""") 31 | ) 32 | } 33 | 34 | @Test 35 | fun serializeValueClass() { 36 | assertEquals( 37 | """{"valueClassProperty":"bar"}""", 38 | defaultMapper.writeValueAsString(ClassWithValueMember(ValueClass("bar"))) 39 | ) 40 | } 41 | } 42 | 43 | @JvmInline 44 | value class InlineClass(val value: String) 45 | 46 | @JsonDeserialize(builder = ClassWithInlineMember.JacksonBuilder::class) 47 | data class ClassWithInlineMember(val inlineClassProperty: InlineClass) { 48 | data class JacksonBuilder constructor(val inlineClassProperty: String) { 49 | fun build() = ClassWithInlineMember(InlineClass(inlineClassProperty)) 50 | } 51 | } 52 | 53 | @JvmInline 54 | value class ValueClass(val value: String) 55 | 56 | @JsonDeserialize(builder = ClassWithValueMember.JacksonBuilder::class) 57 | data class ClassWithValueMember(val valueClassProperty: ValueClass) { 58 | data class JacksonBuilder constructor(val valueClassProperty: String) { 59 | fun build() = ClassWithValueMember(ValueClass(valueClassProperty)) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github396.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.dataformat.xml.XmlMapper 4 | import com.fasterxml.jackson.module.kotlin.registerKotlinModule 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertEquals 7 | 8 | class Github396 { 9 | /** 10 | * Succeeds in Jackson 2.11.x, but fails in Jackson 2.12.0. 11 | * But succeeds again in 2.15.0. 12 | * 13 | * See https://github.com/FasterXML/jackson-module-kotlin/issues/396 14 | */ 15 | @Test 16 | fun testMissingConstructor() { 17 | val mapper = XmlMapper().registerKotlinModule() 18 | 19 | val xml = "" 20 | val product: Product = mapper.readValue(xml, Product::class.java) 21 | 22 | assertEquals(Product(Stuff(null)), product) 23 | } 24 | 25 | private data class Stuff(val str: String?) 26 | private data class Product(val stuff: Stuff?) 27 | } 28 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github42.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.DeserializationFeature 4 | import com.fasterxml.jackson.databind.JsonMappingException 5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Test 9 | import org.junit.jupiter.api.assertThrows 10 | 11 | class TestGithub42_FailOnNullForPrimitives { 12 | 13 | data class OptionalIntRequiredBoolean(val optInt: Int = -1, val reqBool: Boolean) 14 | 15 | val mapper = jacksonObjectMapper().enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) 16 | 17 | @Test fun `optional primitive parameter defaulted if not in json when FAIL_ON_NULL_FOR_PRIMITIVES is true`() { 18 | val actualObj: OptionalIntRequiredBoolean = mapper.readValue(""" 19 | { 20 | "reqBool": false 21 | } 22 | """) 23 | 24 | assertEquals(OptionalIntRequiredBoolean(reqBool = false), actualObj) 25 | } 26 | 27 | @Test fun `Exception thrown if required primitive parameter not in json when FAIL_ON_NULL_FOR_PRIMITIVES is true`() { 28 | assertThrows { 29 | mapper.readValue("""{"optInt": 2}""") 30 | } 31 | } 32 | 33 | @Test fun `optional parameter has json value if provided when FAIL_ON_NULL_FOR_PRIMITIVES is true`() { 34 | val actualObj: OptionalIntRequiredBoolean = mapper.readValue(""" 35 | { 36 | "optInt": 3, 37 | "reqBool": true 38 | } 39 | """) 40 | 41 | assertEquals(OptionalIntRequiredBoolean(3, true), actualObj) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github47.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.MapperFeature 4 | import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub47 { 10 | 11 | class ConfigItem(val configItemId: String) 12 | 13 | @Test 14 | fun testCaseInsensitivePropertyNames() { 15 | val mapper = jacksonMapperBuilder() 16 | .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) 17 | .build() 18 | 19 | val jsonWithMismtachedPropertyName = """ 20 | { 21 | "configItemID": "test" 22 | } 23 | """ 24 | 25 | val item: ConfigItem = mapper.readValue(jsonWithMismtachedPropertyName) 26 | assertEquals("test", item.configItemId) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github50.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github; 2 | 3 | import com.fasterxml.jackson.annotation.JsonUnwrapped 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub50 { 10 | data class Name(val firstName: String, val lastName: String) 11 | 12 | data class Employee( 13 | @get:JsonUnwrapped val name: Name, 14 | val position: String 15 | ) 16 | 17 | @Test 18 | fun testGithub50UnwrappedError() { 19 | val json = """{"firstName":"John","lastName":"Smith","position":"Manager"}""" 20 | val obj: Employee = defaultMapper.readValue(json) 21 | assertEquals(Name("John", "Smith"), obj.name) 22 | assertEquals("Manager", obj.position) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github52.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub52 { 10 | @Test 11 | fun testBooleanPropertyInConstructor() { 12 | data class BooleanPropertyInConstructor( 13 | @JsonProperty("is_bar") 14 | val bar: Boolean = true 15 | ) 16 | 17 | assertEquals("""{"is_bar":true}""", defaultMapper.writeValueAsString(BooleanPropertyInConstructor())) 18 | } 19 | 20 | @Test 21 | fun testIsPrefixedBooleanPropertyInConstructor() { 22 | data class IsPrefixedBooleanPropertyInConstructor( 23 | @JsonProperty("is_bar2") 24 | val isBar2: Boolean = true 25 | ) 26 | 27 | assertEquals("""{"is_bar2":true}""", defaultMapper.writeValueAsString(IsPrefixedBooleanPropertyInConstructor())) 28 | } 29 | 30 | @Test 31 | fun testIsPrefixedStringPropertyInConstructor() { 32 | data class IsPrefixedStringPropertyInConstructor( 33 | @JsonProperty("is_lol") 34 | val lol: String = "sdf" 35 | ) 36 | 37 | assertEquals("""{"is_lol":"sdf"}""", defaultMapper.writeValueAsString(IsPrefixedStringPropertyInConstructor())) 38 | } 39 | 40 | @Test 41 | fun testBooleanPropertyInBody() { 42 | data class BooleanPropertyInBody( 43 | @JsonIgnore val placeholder: String = "placeholder" 44 | ) { 45 | @JsonProperty("is_foo") 46 | val foo: Boolean = true 47 | } 48 | 49 | assertEquals("""{"is_foo":true}""", defaultMapper.writeValueAsString(BooleanPropertyInBody())) 50 | } 51 | 52 | @Test 53 | fun testIsPrefixedBooleanPropertyInBody() { 54 | data class IsPrefixedBooleanPropertyInBody( 55 | @JsonIgnore val placeholder: String = "placeholder" 56 | ) { 57 | @JsonProperty("is_foo2") 58 | val isFoo2: Boolean = true 59 | } 60 | 61 | assertEquals("""{"is_foo2":true}""", defaultMapper.writeValueAsString(IsPrefixedBooleanPropertyInBody())) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github526.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonSetter 4 | import com.fasterxml.jackson.annotation.Nulls 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Test 8 | import kotlin.test.assertEquals 9 | 10 | class Github526 { 11 | data class D(@JsonSetter(nulls = Nulls.SKIP) val v: Int = -1) 12 | 13 | @Test 14 | fun test() { 15 | val d = defaultMapper.readValue("""{"v":null}""") 16 | 17 | assertEquals(-1, d.v) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github536.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonKey 4 | import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder 5 | import com.fasterxml.jackson.module.kotlin.testPrettyWriter 6 | import org.junit.jupiter.api.Assertions.assertEquals 7 | import org.junit.jupiter.api.Test 8 | 9 | class Github536 { 10 | @JvmInline 11 | value class JsonKeyGetter(val value: Int) { 12 | @get:JsonKey 13 | val jsonKey: String 14 | get() = this.toString() 15 | } 16 | 17 | interface IJsonKeyGetter { 18 | @get:JsonKey 19 | val jsonKey: String 20 | get() = this.toString() 21 | } 22 | 23 | @JvmInline 24 | value class JsonKeyGetterImplementation(val value: Int) : IJsonKeyGetter 25 | 26 | @JvmInline 27 | value class JsonKeyGetterImplementationDisabled(val value: Int) : IJsonKeyGetter { 28 | @get:JsonKey(false) 29 | override val jsonKey: String 30 | get() = super.jsonKey 31 | } 32 | 33 | private val writer = jacksonMapperBuilder().build().testPrettyWriter() 34 | 35 | @Test 36 | fun test() { 37 | val src = mapOf( 38 | JsonKeyGetter(0) to 0, 39 | JsonKeyGetterImplementation(1) to 1, 40 | JsonKeyGetterImplementationDisabled(2) to 2 41 | ) 42 | 43 | assertEquals( 44 | """ 45 | { 46 | "JsonKeyGetter(value=0)" : 0, 47 | "JsonKeyGetterImplementation(value=1)" : 1, 48 | "2" : 2 49 | } 50 | """.trimIndent(), 51 | writer.writeValueAsString(src) 52 | ) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github57.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.DeserializationContext 4 | import com.fasterxml.jackson.databind.KeyDeserializer 5 | import com.fasterxml.jackson.databind.module.SimpleModule 6 | import com.fasterxml.jackson.module.kotlin.* 7 | import org.junit.jupiter.api.Test 8 | 9 | class TestGithub57 { 10 | data class Github57Data(val map: Map, String>) 11 | 12 | @Test 13 | fun testProblemsWithMaps() { 14 | val mapper = jacksonObjectMapper().registerModule(KotlinPairKeySerializerModule()) 15 | val test = Github57Data(mapOf(Pair("p1", "p2") to "value1")) 16 | val jsonString = mapper.writeValueAsString(test) //works: {"map":{"(string1, string2)":"string3"}} 17 | mapper.readValue(jsonString) 18 | } 19 | 20 | class KotlinPairKeyDeserializer: KeyDeserializer() { 21 | override fun deserializeKey(key: String, context: DeserializationContext): Any { 22 | return if (key.startsWith('(') && key.endsWith(')')) { 23 | val parts = key.substring(1, key.length-2).split(',') 24 | if (parts.size != 2) { 25 | throw IllegalStateException("Pair() expects a serialized format of '(first,second)', cannot understand '$key'") 26 | } 27 | Pair(parts[0], parts[1]) 28 | } else { 29 | throw IllegalStateException("Pair() expects a serialized format of '(first,second)', cannot understand '$key'") 30 | } 31 | } 32 | } 33 | 34 | class KotlinPairKeySerializerModule : SimpleModule() { 35 | init { 36 | addKeyDeserializer(Pair::class.java, KotlinPairKeyDeserializer()) 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github62.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import org.junit.jupiter.api.Test 5 | import kotlin.test.assertEquals 6 | 7 | class TestGithub62 { 8 | @Test 9 | fun testAnonymousClassSerialization() { 10 | val externalValue = "ggg" 11 | 12 | val result = defaultMapper.writeValueAsString(object { 13 | val value = externalValue 14 | }) 15 | 16 | assertEquals("""{"value":"ggg"}""", result) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github630.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.KotlinFeature 6 | import com.fasterxml.jackson.module.kotlin.KotlinModule 7 | import org.junit.jupiter.api.Test 8 | import kotlin.test.assertEquals 9 | 10 | class Github630 { 11 | private val mapper = ObjectMapper() 12 | .registerModule(KotlinModule.Builder().enable(KotlinFeature.KotlinPropertyNameAsImplicitName).build())!! 13 | 14 | data class Dto( 15 | // from #570, #603 16 | val FOO: Int = 0, 17 | val bAr: Int = 0, 18 | @JsonProperty("b") 19 | val BAZ: Int = 0, 20 | @JsonProperty("q") 21 | val qUx: Int = 0, 22 | // from #71 23 | internal val quux: Int = 0, 24 | // from #434 25 | val `corge-corge`: Int = 0, 26 | // additional 27 | @get:JvmName("aaa") 28 | val grault: Int = 0 29 | ) 30 | 31 | @Test 32 | fun test() { 33 | val dto = Dto() 34 | 35 | assertEquals( 36 | """{"FOO":0,"bAr":0,"b":0,"q":0,"quux":0,"corge-corge":0,"grault":0}""", 37 | mapper.writeValueAsString(dto) 38 | ) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github710.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.KotlinFeature 5 | import com.fasterxml.jackson.module.kotlin.KotlinModule 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class Github710 { 10 | interface I { 11 | val foo: T 12 | val bAr: T get() = foo 13 | } 14 | 15 | class C(override val foo: Int) : I 16 | 17 | @Test 18 | fun test() { 19 | val mapper = KotlinModule.Builder().enable(KotlinFeature.KotlinPropertyNameAsImplicitName) 20 | .let { ObjectMapper().registerModule(it.build()) } 21 | val result = mapper.writeValueAsString(C(1)) 22 | 23 | assertEquals("""{"foo":1,"bAr":1}""", result) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github722.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JacksonInject 4 | import com.fasterxml.jackson.annotation.JsonCreator 5 | import com.fasterxml.jackson.annotation.JsonProperty 6 | import com.fasterxml.jackson.databind.InjectableValues 7 | import com.fasterxml.jackson.databind.ObjectMapper 8 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 9 | import org.junit.jupiter.api.Test 10 | import kotlin.test.assertEquals 11 | 12 | class Github722 { 13 | data class FailingDto @JsonCreator constructor( 14 | @JacksonInject("foo") 15 | @JsonProperty("foo") 16 | val foo: Int = 100, 17 | @JacksonInject("bar") 18 | @JsonProperty("bar") 19 | val bar: Int? = 200 20 | ) 21 | 22 | val injectValues = mapOf("foo" to 1, "bar" to 2) 23 | val expected = FailingDto(1, 2) 24 | 25 | @Test 26 | fun onPlainMapper() { 27 | // Succeeds in plain mapper 28 | val plainMapper = ObjectMapper() 29 | assertEquals( 30 | expected, 31 | plainMapper.readerFor(FailingDto::class.java) 32 | .with(InjectableValues.Std(injectValues)) 33 | .readValue("{}") 34 | ) 35 | } 36 | 37 | @Test 38 | fun failing() { 39 | // The kotlin mapper uses the Kotlin default value instead of the Inject value. 40 | val reader = jacksonObjectMapper() 41 | .readerFor(FailingDto::class.java) 42 | .with(InjectableValues.Std(injectValues)) 43 | val result = reader.readValue("{}") 44 | 45 | // fixed 46 | // assertNotEquals(result, expected, "GitHubXXX fixed.") 47 | assertEquals(expected, result) 48 | } 49 | 50 | data class WithoutDefaultValue( 51 | @JacksonInject("foo") 52 | val foo: Int, 53 | @JacksonInject("bar") 54 | val bar: Int? 55 | ) 56 | 57 | @Test 58 | fun withoutDefaultValue() { 59 | val reader = jacksonObjectMapper() 60 | .readerFor(WithoutDefaultValue::class.java) 61 | .with(InjectableValues.Std(injectValues)) 62 | val result = reader.readValue("{}") 63 | 64 | // If there is no default value, the problem does not occur. 65 | assertEquals(WithoutDefaultValue(1, 2), result) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github738.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonSetter 4 | import com.fasterxml.jackson.annotation.Nulls 5 | import com.fasterxml.jackson.databind.exc.MismatchedInputException 6 | import com.fasterxml.jackson.module.kotlin.defaultMapper 7 | import com.fasterxml.jackson.module.kotlin.readValue 8 | import org.junit.jupiter.api.Assertions.assertThrows 9 | import org.junit.jupiter.api.Test 10 | 11 | class Github738 { 12 | data class D(@JsonSetter(nulls = Nulls.FAIL) val v: Int) 13 | 14 | @Test 15 | fun test() { 16 | // nulls = FAIL is reflected if it is primitive and missing 17 | assertThrows(MismatchedInputException::class.java) { defaultMapper.readValue("{}") } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github80.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertEquals 7 | 8 | class TestGithub80 { 9 | @Test 10 | fun testIsBool() { 11 | val example = IsBoolExample(true) 12 | val json = defaultMapper.writeValueAsString(example) 13 | assertEquals("{\"isTrueOrFalse\":true}", json) 14 | 15 | val deserialized = defaultMapper.readValue(json, IsBoolExample::class.java) 16 | assertEquals(example.isTrueOrFalse, deserialized.isTrueOrFalse) 17 | } 18 | 19 | @Test 20 | fun testAnnotatedIsBool() { 21 | val example = IsBoolAnnotatedExample(true) 22 | val json = defaultMapper.writeValueAsString(example) 23 | assertEquals("{\"isTrueOrFalse\":true}", json) 24 | 25 | val deserialized = defaultMapper.readValue(json, IsBoolAnnotatedExample::class.java) 26 | assertEquals(example.isTrue, deserialized.isTrue) 27 | } 28 | 29 | class IsBoolExample(val isTrueOrFalse: Boolean) 30 | 31 | class IsBoolAnnotatedExample(@JsonProperty("isTrueOrFalse") val isTrue: Boolean) 32 | } 33 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github88.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import org.junit.jupiter.api.Test 5 | import kotlin.test.assertEquals 6 | 7 | class TestGithub88 { 8 | class CloneableKotlinObj(val id: String) : Cloneable 9 | 10 | @Test 11 | fun shouldDeserializeSuccessfullyKotlinCloneableObject() { 12 | val result = defaultMapper.writeValueAsString(CloneableKotlinObj("123")) 13 | 14 | assertEquals("{\"id\":\"123\"}", result) 15 | } 16 | 17 | @Test 18 | fun shouldDeserializeSuccessfullyJavaCloneableObject() { 19 | val result = defaultMapper.writeValueAsString(CloneableJavaObj("123")) 20 | 21 | assertEquals("{\"id\":\"123\"}", result) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/Github91.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonValue 5 | import com.fasterxml.jackson.module.kotlin.defaultMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Assertions.assertEquals 8 | import org.junit.jupiter.api.Test 9 | 10 | class TestGithub91 { 11 | data class DataClass1(val name: String, val content: DataClass2) 12 | 13 | data class DataClass2 @JsonCreator(mode = JsonCreator.Mode.DELEGATING) constructor(@JsonValue val content: String) 14 | 15 | private val jsonData = """ 16 | { 17 | "name": "my name", 18 | "content": "some value" 19 | } 20 | """ 21 | 22 | @Test 23 | fun testJsonParsing() { 24 | val dataClass1 = defaultMapper.readValue(jsonData) 25 | assertEquals(DataClass1("my name", DataClass2("some value")), dataClass1) 26 | assertEquals("{\"name\":\"my name\",\"content\":\"some value\"}", defaultMapper.writeValueAsString(dataClass1)) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GithubDatabind1005Test.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | import com.fasterxml.jackson.databind.ObjectMapper 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import org.junit.jupiter.api.Test 8 | 9 | class TestGithubDatabind1005 { 10 | 11 | // make a class seem kinda like a Java class, but with a second generated constructor 12 | // this is Ugly Kotlin but is making it easier for Java people to see and debug. 13 | class Something @JsonCreator constructor(@JsonProperty("name") name: String, 14 | @JsonProperty("age") age: Int = 0) { // default value causes synthetic constructor to be generated 15 | val name: String = name 16 | val age: Int = age 17 | } 18 | 19 | @Test fun testSyntheticGeneratedConstructorIsIgnored() { 20 | ObjectMapper().readValue("""{"name":"fred","age":99}""") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GithubDatabind1328.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github 2 | 3 | import com.fasterxml.jackson.annotation.JsonSubTypes 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo 5 | import com.fasterxml.jackson.annotation.JsonTypeName 6 | import com.fasterxml.jackson.module.kotlin.defaultMapper 7 | import com.fasterxml.jackson.module.kotlin.readValue 8 | import org.junit.jupiter.api.Test 9 | import kotlin.test.assertEquals 10 | 11 | class TestGithubDatabind1328 { 12 | @Test 13 | fun testPolymorphicWithEnum() { 14 | val invite = defaultMapper.readValue( 15 | """|{ 16 | | "kind": "CONTACT", 17 | | "to": { 18 | | "name": "Foo" 19 | | } 20 | |}""".trimMargin() 21 | ) 22 | 23 | assertEquals(InviteKind.CONTACT, invite.kind) 24 | assertEquals("Foo", (invite.to as InviteToContact).name) 25 | } 26 | 27 | 28 | data class Invite( 29 | val kind: InviteKind, 30 | @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "kind", visible = true) 31 | @JsonSubTypes( 32 | JsonSubTypes.Type(InviteToContact::class), 33 | JsonSubTypes.Type(InviteToUser::class) 34 | ) 35 | val to: InviteTo 36 | ) 37 | 38 | interface InviteTo 39 | 40 | @JsonTypeName("CONTACT") 41 | data class InviteToContact( 42 | val name: String? = null 43 | ): InviteTo 44 | 45 | @JsonTypeName("USER") 46 | data class InviteToUser( 47 | val user: String 48 | ): InviteTo 49 | 50 | enum class InviteKind { 51 | CONTACT, 52 | USER 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/GitHub337.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | import com.fasterxml.jackson.databind.MapperFeature.SORT_PROPERTIES_ALPHABETICALLY 6 | import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder 7 | import com.fasterxml.jackson.module.kotlin.testPrettyWriter 8 | import org.junit.jupiter.api.Test 9 | import kotlin.test.assertEquals 10 | 11 | /** 12 | * Fields named "is…" are only serialized if they are Boolean 13 | */ 14 | class TestGitHub337 { 15 | private val mapper = jacksonMapperBuilder() 16 | .configure(SORT_PROPERTIES_ALPHABETICALLY, true) 17 | .build() 18 | .setSerializationInclusion(JsonInclude.Include.ALWAYS) 19 | private val writer = mapper.testPrettyWriter() 20 | 21 | @Test 22 | fun test_ClassWithIsFields() { 23 | data class ClassWithIsFields( 24 | val isBooleanField: Boolean, 25 | val isIntField: Int 26 | ) 27 | 28 | val problematic = ClassWithIsFields(true, 9) 29 | val expected = """ 30 | { 31 | "isBooleanField" : true, 32 | "isIntField" : 9 33 | }""".trimIndent() 34 | assertEquals(expected, writer.writeValueAsString(problematic)) 35 | } 36 | 37 | @Test 38 | fun test_AnnotatedClassWithIsFields() { 39 | data class ClassWithIsFields( 40 | @JsonProperty("isBooleanField") val isBooleanField: Boolean, 41 | @JsonProperty("isIntField") val isIntField: Int 42 | ) 43 | 44 | val problematic = ClassWithIsFields(true, 9) 45 | val expected = """ 46 | { 47 | "isBooleanField" : true, 48 | "isIntField" : 9 49 | }""".trimIndent() 50 | assertEquals(expected, writer.writeValueAsString(problematic)) 51 | } 52 | 53 | @Test 54 | fun test_AnnotatedGetClassWithIsFields() { 55 | data class ClassWithIsFields( 56 | @JsonProperty("isBooleanField") val isBooleanField: Boolean, 57 | @get:JsonProperty("isIntField") val isIntField: Int 58 | ) 59 | 60 | val problematic = ClassWithIsFields(true, 9) 61 | val expected = """ 62 | { 63 | "isBooleanField" : true, 64 | "isIntField" : 9 65 | }""".trimIndent() 66 | assertEquals(expected, writer.writeValueAsString(problematic)) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/GitHub451.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import org.junit.jupiter.api.Test 5 | import org.junit.jupiter.api.assertThrows 6 | import org.opentest4j.AssertionFailedError 7 | import kotlin.test.assertEquals 8 | 9 | class GitHub451 { 10 | data class Target( 11 | val `foo-bar`: String, 12 | @get:JvmName("getBaz-qux") 13 | val bazQux: String 14 | ) { 15 | fun `getQuux-corge`(): String = `foo-bar` 16 | @JvmName("getGrault-graply") 17 | fun getGraultGraply(): String = bazQux 18 | } 19 | 20 | @Test 21 | fun serializeTest() { 22 | val expected = """{"foo-bar":"a","baz-qux":"b","quux-corge":"a","grault-graply":"b"}""" 23 | 24 | val src = Target("a", "b") 25 | val json = defaultMapper.writeValueAsString(src) 26 | assertThrows("GitHub #451 has been fixed!") { 27 | assertEquals(expected, json) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/GitHub478.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude.Include.NON_DEFAULT 4 | import com.fasterxml.jackson.module.kotlin.jsonMapper 5 | import com.fasterxml.jackson.module.kotlin.kotlinModule 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 8 | import org.junit.jupiter.api.Test 9 | import kotlin.test.assertEquals 10 | 11 | class GitHub478Test { 12 | val mapper = jsonMapper { 13 | addModule(kotlinModule()) 14 | serializationInclusion(NON_DEFAULT) 15 | } 16 | 17 | data class Data(val flag: Boolean = true) 18 | 19 | @Test 20 | fun omitsDefaultValueWhenSerializing() { 21 | expectFailure("GitHub478 has been fixed!") { 22 | assertEquals("""{}""", mapper.writeValueAsString(Data())) 23 | } 24 | } 25 | 26 | @Test 27 | fun serializesNonDefaultValue() { 28 | expectFailure("GitHub478 has been fixed!") { 29 | assertEquals("""{"flag": false}""", mapper.writeValueAsString(Data(flag = false))) 30 | } 31 | } 32 | 33 | @Test 34 | fun usesDefaultWhenDeserializing() { 35 | assertEquals(Data(), mapper.readValue("{}")) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github138.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | import com.fasterxml.jackson.databind.exc.InvalidDefinitionException 5 | import com.fasterxml.jackson.dataformat.xml.XmlMapper 6 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty 7 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement 8 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText 9 | import com.fasterxml.jackson.module.kotlin.readValue 10 | import com.fasterxml.jackson.module.kotlin.registerKotlinModule 11 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 12 | import org.junit.jupiter.api.Test 13 | 14 | class TestGithub138 { 15 | @JacksonXmlRootElement(localName = "sms") 16 | @JsonIgnoreProperties(ignoreUnknown = true) 17 | data class Sms( 18 | @JacksonXmlProperty(localName = "Phone", isAttribute = true) 19 | val phone: String?, 20 | 21 | @JacksonXmlText 22 | val text: String? = "" 23 | ) 24 | 25 | @Test 26 | fun testDeserProblem() { 27 | val xml = """Lorem ipsum""" 28 | val xmlMapper = XmlMapper().registerKotlinModule() 29 | expectFailure("GitHub #138 has been fixed!") { 30 | xmlMapper.readValue(xml) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github160DisableAnnotations.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.databind.MapperFeature 4 | import com.fasterxml.jackson.databind.exc.MismatchedInputException 5 | import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder 6 | import com.fasterxml.jackson.module.kotlin.readValue 7 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 8 | import org.junit.jupiter.api.Test 9 | 10 | class TestGithub160 { 11 | data class DataClass(val blah: String) 12 | 13 | @Test 14 | fun dataClass() { 15 | val mapper = jacksonMapperBuilder() 16 | .configure(MapperFeature.USE_ANNOTATIONS, false) 17 | .build() 18 | expectFailure("GitHub #160 has been fixed!") { 19 | mapper.readValue("""{"blah":"blah"}""") 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github242.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import org.junit.jupiter.api.Test 6 | import kotlin.test.assertEquals 7 | 8 | // Also see https://github.com/FasterXML/jackson-databind/issues/3392 9 | class Github242 { 10 | data class IntValue(val value: Int) 11 | 12 | // Since `nullish` is entered for a `non-null` value, deserialization is expected to fail, 13 | // but at the moment the process continues with the default value set on the `databind`. 14 | @Test 15 | fun `test value throws - Int`(){ 16 | val v0 = defaultMapper.readValue("{}") 17 | val v1 = defaultMapper.readValue("{\"value\":null}") 18 | 19 | assertEquals(0, v0.value) 20 | assertEquals(v0, v1) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github271AlphaSortProperties.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.annotation.JsonPropertyOrder 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub271 { 10 | @JsonPropertyOrder(alphabetic=true) 11 | data class Foo(val a: String, val c: String) { 12 | val b = "b" 13 | } 14 | 15 | @Test 16 | fun testAlphabeticFields() { 17 | val json = defaultMapper.writeValueAsString(Foo("a", "c")) 18 | expectFailure("GitHub #271 has been fixed!") { 19 | assertEquals("""{"a":"a","b":"b","c":"c"}""", json) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github474.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub474 { 10 | @Test 11 | fun jsonPropertyAnnotationRespectedOnParentClass() { 12 | open class Parent(@JsonProperty("parent-prop") val parent: String) 13 | class Child(@JsonProperty("child-prop") val child: String) : Parent(child) 14 | 15 | expectFailure("GitHub #474 has been fixed!") { 16 | assertEquals( 17 | """{"child-prop":"foo","parent-prop":"foo"}""", 18 | defaultMapper.writeValueAsString(Child("foo")) 19 | ) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github518.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.module.kotlin.KotlinFeature.SingletonSupport 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.jsonMapper 6 | import com.fasterxml.jackson.module.kotlin.kotlinModule 7 | import com.fasterxml.jackson.module.kotlin.readValue 8 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 9 | import org.junit.jupiter.api.Test 10 | import kotlin.test.assertSame 11 | 12 | /** 13 | * An empty object should be deserialized as *the* Unit instance for a nullable Unit reference Type. 14 | */ 15 | class TestGithub518 { 16 | 17 | /** 18 | * Empty object did not serialize to the singleton Unit before 2.13 as described in 19 | * https://github.com/FasterXML/jackson-module-kotlin/issues/196. 20 | */ 21 | @Test 22 | fun deserializeEmptyObjectToSingletonUnit() { 23 | assertSame(defaultMapper.readValue("{}"), Unit) 24 | } 25 | 26 | /** 27 | * Empty object does not serialize to the singleton Unit for a nullable reference Type as described in 28 | * https://github.com/FasterXML/jackson-module-kotlin/issues/518. 29 | */ 30 | @Test 31 | fun deserializeEmptyObjectToSingletonUnitFails() { 32 | expectFailure("GitHub #518 has been fixed!") { 33 | assertSame(defaultMapper.readValue("{}"), Unit) 34 | } 35 | } 36 | 37 | /** 38 | * Empty object serializes to the singleton Unit for a nullable reference if singleton support is enabled. Is this 39 | * setting really required to deserialize Unit correctly or should it also work correctly without singleton support 40 | * enabled? 41 | */ 42 | @Test 43 | fun deserializeEmptyObjectToSingletonUnitWithSingletonSupport() { 44 | val objectMapper = jsonMapper { addModule(kotlinModule { configure(SingletonSupport, true) }) } 45 | assertSame(objectMapper.readValue("{}"), Unit) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github54.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.annotation.JsonIdentityInfo 4 | import com.fasterxml.jackson.annotation.ObjectIdGenerators 5 | import com.fasterxml.jackson.databind.deser.UnresolvedForwardReference 6 | import com.fasterxml.jackson.module.kotlin.defaultMapper 7 | import com.fasterxml.jackson.module.kotlin.readValue 8 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 9 | import org.junit.jupiter.api.Test 10 | 11 | class TestGithub54 { 12 | @Test 13 | fun testDeserWithIdentityInfo() { 14 | val entity1 = Entity1("test_entity1") 15 | val entity2 = Entity2("test_entity2", entity1 = entity1) 16 | val rootEntity1 = Entity1("root_entity1", entity2 = entity2) 17 | 18 | entity1.parent = rootEntity1 19 | entity1.entity2 = entity2 20 | 21 | val json = defaultMapper.writeValueAsString(entity1) 22 | expectFailure("GitHub #54 has been fixed!") { 23 | defaultMapper.readValue(json) 24 | } 25 | 26 | } 27 | } 28 | 29 | @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator::class) 30 | data class Entity1(val name: String, var entity2: Entity2? = null, var parent: Entity1? = null) 31 | 32 | @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator::class) 33 | class Entity2(val name: String, var entity1: Entity1? = null) 34 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github611.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | import com.fasterxml.jackson.module.kotlin.defaultMapper 5 | import com.fasterxml.jackson.module.kotlin.readValue 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub611 { 10 | 11 | class TestClass(@JsonProperty("id") var id: UShort) { 12 | // Empty constructor 13 | constructor() : this(1u) 14 | } 15 | 16 | // Value fits into UShort, but not (Java) Short 17 | private val jsonData = """ 18 | { 19 | "id": 50000 20 | } 21 | """ 22 | 23 | @Test 24 | fun testJsonParsing() { 25 | val dataClassInstance = defaultMapper.readValue(jsonData) 26 | assertEquals(50000.toUShort(), dataClassInstance.id) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/Github71.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.module.kotlin.defaultMapper 4 | import com.fasterxml.jackson.module.kotlin.readValue 5 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 6 | import org.junit.jupiter.api.Test 7 | import kotlin.test.assertEquals 8 | 9 | class TestGithub71 { 10 | open class Identifiable { 11 | internal var identity: Long? = null 12 | } 13 | 14 | @Test 15 | fun testInternalPropertySerliazation() { 16 | val json = defaultMapper.writeValueAsString(Identifiable()) 17 | 18 | expectFailure("GitHub #71 has been fixed!") { 19 | assertEquals("{\"identity\":null}", json) // fails: {"identity$jackson_module_kotlin":null} 20 | val newInstance = defaultMapper.readValue(json) 21 | assertEquals(Identifiable(), newInstance) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/failing/GithubDatabind1329.kt: -------------------------------------------------------------------------------- 1 | package com.fasterxml.jackson.module.kotlin.test.github.failing 2 | 3 | import com.fasterxml.jackson.annotation.JsonSubTypes 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo 5 | import com.fasterxml.jackson.annotation.JsonTypeName 6 | import com.fasterxml.jackson.module.kotlin.defaultMapper 7 | import com.fasterxml.jackson.module.kotlin.readValue 8 | import com.fasterxml.jackson.module.kotlin.test.expectFailure 9 | import org.junit.jupiter.api.Test 10 | import kotlin.test.assertEquals 11 | import kotlin.test.assertNull 12 | 13 | /** 14 | * Broken in databind 2.8.0+ (not 2.8.0.rc2 which works) and not a problem with the Kotlin module 15 | */ 16 | class GithubDatabind1329 { 17 | @Test 18 | fun testPolymorphicWithEnum() { 19 | val invite = defaultMapper.readValue( 20 | """|{ 21 | | "kind": "CONTACT", 22 | | "kindForMapper": "CONTACT", 23 | | "to": { 24 | | "name": "Foo" 25 | | } 26 | |}""".trimMargin() 27 | ) 28 | 29 | assertEquals(InviteKind.CONTACT, invite.kind) 30 | expectFailure("GitHub Databind issue #1329 has been fixed!") { 31 | assertNull(invite.kindForMapper) 32 | } 33 | 34 | assertEquals("Foo", (invite.to as InviteToContact).name) 35 | } 36 | 37 | data class Invite( 38 | val kind: InviteKind, 39 | // workaround for https://github.com/FasterXML/jackson-databind/issues/999 (should be fixed in 2.8.x) 40 | val kindForMapper: String? = null, 41 | @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "kindForMapper", visible = false) 42 | @JsonSubTypes( 43 | JsonSubTypes.Type(InviteToContact::class), 44 | JsonSubTypes.Type(InviteToUser::class) 45 | ) 46 | val to: InviteTo 47 | ) 48 | 49 | interface InviteTo 50 | 51 | @JsonTypeName("CONTACT") 52 | data class InviteToContact( 53 | val name: String? = null 54 | ) : InviteTo 55 | 56 | @JsonTypeName("USER") 57 | data class InviteToUser( 58 | val user: String 59 | ) : InviteTo 60 | 61 | enum class InviteKind { 62 | CONTACT, 63 | USER 64 | } 65 | } 66 | --------------------------------------------------------------------------------