Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defaults for non-mandatory arguments in instance creation json mapping #198

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,30 @@ PetOrdersRESTfulControllerTest >> testOverlyComplexOrderCreation [
assert: order date equals: '2018-10-24T18:05:46.418Z'
]

{ #category : 'tests - orders' }
PetOrdersRESTfulControllerTest >> testOverlyComplexOrderCreationWithoutSpecifyingStatusUsesDefaultValue [

| response order |

response := resourceController
createOrderBasedOn: ( self requestToPOSTAsOverlyComplexOrder:
'{"date":"2018-10-24T18:05:46.418Z","pet":{"alternativeName":"Fido","itsType":"Dog"}}' )
within: self newHttpRequestContext.

self
assert: response isSuccess;
assert: response status equals: 201;
assertUrl: response location equals: 'https://petstore.example.com/orders/1';
assert: response hasEntity;
assert: orderRepository count equals: 1.
order := orderRepository findAll first.
self
assert: order pet name equals: 'Fido';
assert: order pet type equals: 'Dog';
assert: order pet status equals: 'UNKNOWN';
assert: order date equals: '2018-10-24T18:05:46.418Z'
]

{ #category : 'tests' }
PetOrdersRESTfulControllerTest >> testRoutes [

Expand Down
3 changes: 2 additions & 1 deletion source/Stargate-Examples/PetOrdersRESTfulController.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ PetOrdersRESTfulController >> configureOverlyComplexOrderDecodingOn: reader [
mapProperty: #theStatus as: #Status.
mapping
mapCreationSending: #named:ofType:withStatus:
withArguments: { #alternativeName. #itsType. #theStatus }
withArguments: { #alternativeName. #itsType. #theStatus };
argumentNamed: #theStatus defaultingTo: 'UNKNOWN'
].
reader for: PetOrder createInstanceUsing: [ :mapping |
mapping
Expand Down
53 changes: 36 additions & 17 deletions source/Stargate-NeoJSON-Extensions/InstanceCreationMapping.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,25 @@ Class {
#superclass : 'NeoJSONObjectMapping',
#instVars : [
'instanceCreationSelector',
'argumentNames'
'argumentNames',
'defaultsByArgumentName'
],
#category : 'Stargate-NeoJSON-Extensions',
#package : 'Stargate-NeoJSON-Extensions'
}

{ #category : 'mapping' }
InstanceCreationMapping >> argumentNamed: anArgumentName defaultingTo: aValue [

defaultsByArgumentName at: anArgumentName put: aValue
]

{ #category : 'private' }
InstanceCreationMapping >> defaultFor: argumentName ifAbsent: aBlock [

^ defaultsByArgumentName at: argumentName ifAbsent: aBlock
]

{ #category : 'private' }
InstanceCreationMapping >> errorDescriptionForMissing: propertyNames [

Expand All @@ -40,8 +53,9 @@ InstanceCreationMapping >> errorDescriptionForMissing: propertyNames [
{ #category : 'mapping' }
InstanceCreationMapping >> mapCreationSending: anInstanceCreationSelector withArguments: anArgumentCollection [

instanceCreationSelector := anInstanceCreationSelector.
argumentNames := anArgumentCollection
instanceCreationSelector := anInstanceCreationSelector.
argumentNames := anArgumentCollection.
defaultsByArgumentName := Dictionary new
]

{ #category : 'mapping' }
Expand All @@ -62,20 +76,25 @@ InstanceCreationMapping >> mapProperty: aKey as: aValueSchema [
{ #category : 'parsing' }
InstanceCreationMapping >> readFrom: jsonReader [

| argumentByName arguments missingArguments |

argumentByName := Dictionary new.
jsonReader parseMapKeysDo: [ :key |
( self propertyNamed: key ifAbsent: [ nil ] )
ifNil: [ "read, skip & ignore value" jsonReader next ]
ifNotNil: [ :mapping | mapping readObject: argumentByName from: jsonReader ]
].
| argumentByName arguments missingArguments |
argumentByName := Dictionary new.
jsonReader parseMapKeysDo: [ :key |
( self propertyNamed: key ifAbsent: [ nil ] )
ifNil: [ "read, skip & ignore value" jsonReader next ]
ifNotNil: [ :mapping | mapping readObject: argumentByName from: jsonReader ]
].

missingArguments := OrderedCollection new.
arguments := argumentNames collect: [ :argumentName |
argumentByName at: argumentName ifAbsent: [ missingArguments add: argumentName ] ].
missingArguments ifNotEmpty: [
jsonReader error: ( self errorDescriptionForMissing: missingArguments ) ].
missingArguments := OrderedCollection new.
arguments := argumentNames collect: [ :argumentName |
argumentByName
at: argumentName
ifAbsent: [
self
defaultFor: argumentName
ifAbsent: [ missingArguments add: argumentName ] ]
].
missingArguments ifNotEmpty: [
jsonReader error: ( self errorDescriptionForMissing: missingArguments ) ].

^ subjectClass perform: instanceCreationSelector withArguments: arguments
^ subjectClass perform: instanceCreationSelector withArguments: arguments
]