Skip to content

Commit

Permalink
[Bug]: Description Generation - Don't Write Null Accessors (#359)
Browse files Browse the repository at this point in the history
* [Bug]: Description Generation - Don't Write Null Accessors

* [Test]: Change Write Test - Don't Write Default
  • Loading branch information
seandenigris authored Jun 19, 2024
1 parent fcf8fdd commit 6d5f022
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 30 deletions.
20 changes: 20 additions & 0 deletions source/Magritte-Developer/MADeveloperTests.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Class {
#name : #MADeveloperTests,
#superclass : #TestCase,
#category : #'Magritte-Developer-Tests'
}

{ #category : #accessing }
MADeveloperTests >> testGenerateDescriptionSource [

| desc |
desc := MANumberDescription new
default: 5;
yourself.

self
assert: desc storeString
equals: 'MANumberDescription new
default: 5;
yourself'
]
3 changes: 2 additions & 1 deletion source/Magritte-Developer/MASelectorAccessor.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ MASelectorAccessor >> maCompile: templateString asAccessor: aSymbol forinstVarNa

{ #category : #'*Magritte-Developer-private' }
MASelectorAccessor >> maSetUp: aClass for: anMAElementDescription [
"Ensure inst var, setter and getter exist"

| variableName needsInstVar defaultArgumentType setterArgumentName |
variableName := self readSelector.
needsInstVar := (aClass hasInstVarNamed: variableName) not.
Expand All @@ -31,7 +33,6 @@ MASelectorAccessor >> maSetUp: aClass for: anMAElementDescription [
{ #category : #'*Magritte-Developer-private' }
MASelectorAccessor >> store: anObject inDescriptionOn: aStream [
anObject storeVia: self inDescriptionOn: aStream.

]

{ #category : #'*Magritte-Developer-private' }
Expand Down
1 change: 1 addition & 0 deletions source/Magritte-Developer/Object.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Object class >> maAddField: aSymbol with: customizationBlock [

{ #category : #'*Magritte-Developer' }
Object >> storeVia: anAccessor inDescriptionOn: aStream [

aStream
nextPutAll: anAccessor writeSelector , ' (';
store: self;
Expand Down
53 changes: 33 additions & 20 deletions source/Magritte-Model/MAElementDescription.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,21 @@ MAElementDescription >> initialAnswer: aValuable [
self propertyAt: #initialAnswer put: aValuable
]

{ #category : #utility }
MAElementDescription >> isIgnorableValue: anObject [

| ignorableValues isIgnorableDefault |

ignorableValues := OrderedCollection
with: nil
with: self undefinedValue.

isIgnorableDefault := self shouldCacheDefault not and: [ anObject = self default ].
isIgnorableDefault ifTrue: [ ignorableValues add: self default ].

^ ignorableValues includes: anObject
]

{ #category : #'lazy initialization' }
MAElementDescription >> lazilyInitializeFrom: currentValue for: anObject [
"- The default value is cached if the description's #shouldCacheDefault property is true. An example when caching is necessary is for to-many relations because the user may modify the collection, which will then be thrown away if not cached
Expand Down Expand Up @@ -124,21 +139,12 @@ MAElementDescription >> printFor: anObject on: aWriteStream [
{ #category : #utility }
MAElementDescription >> shouldWrite: anObject over: anotherObject [

| defaultValues areBothDefaultValues isIgnorableDefault |

self isVisible ifFalse: [ ^ false ].
self isReadOnly ifTrue: [ ^ false ].

defaultValues := OrderedCollection
with: nil
with: self undefinedValue.

isIgnorableDefault := self shouldCacheDefault not and: [ anObject = self default ].
isIgnorableDefault ifTrue: [ defaultValues add: self default ].

areBothDefaultValues := { anObject. anotherObject } allSatisfy: [ :obj | defaultValues includes: obj ].
((self isIgnorableValue: anObject) and: [ self isIgnorableValue: anotherObject ])
ifTrue: [ ^ false ].

areBothDefaultValues ifTrue: [ ^ false ].
(anObject == anotherObject or: [ anObject = anotherObject ])
ifTrue: [ ^ false ].

Expand All @@ -151,13 +157,20 @@ MAElementDescription >> shouldWrite: anObject over: anotherObject [

{ #category : #printing }
MAElementDescription >> storeOn: aStream [
aStream
nextPutAll: self className;
nextPutAll: ' new'; cr.
(self magritteDescription reject: #isReadOnly) do: [ :desc |
| value |
value := desc read: self.
(value ~= desc default and: [ value isNotNil ]) ifTrue: [
desc accessor store: value inDescriptionOn: aStream ] ].
aStream nextPutAll: 'yourself'

| source formattedSource |
source := String streamContents: [ :str |
str
nextPutAll: self className;
nextPutAll: ' new'; cr.
(self magritteDescription reject: #isReadOnly) do: [ :desc |
| value |
value := desc read: self.
(desc isIgnorableValue: value) ifFalse: [
desc accessor store: value inDescriptionOn: str ] ].
str nextPutAll: 'yourself' ].

formattedSource := (RBParser parseExpression: source) formattedCode.

aStream << formattedSource
]
11 changes: 10 additions & 1 deletion source/Magritte-Model/MANullAccessor.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Class {
#instVars : [
'uuid'
],
#category : 'Magritte-Model-Accessor'
#category : #'Magritte-Model-Accessor'
}

{ #category : #testing }
Expand Down Expand Up @@ -42,6 +42,11 @@ MANullAccessor >> hash [
^ super hash bitXor: self uuid hash
]

{ #category : #accessing }
MANullAccessor >> maSetUp: aClass for: anMAElementDescription [
"do nothing"
]

{ #category : #model }
MANullAccessor >> read: aModel [
MAReadError signal: 'This message is not appropriate for this object'
Expand All @@ -57,6 +62,10 @@ MANullAccessor >> storeOn: aStream [
nextPut: $)
]

{ #category : #accessing }
MANullAccessor >> storeVia: anAccessor inDescriptionOn: aStream [
]

{ #category : #accessing }
MANullAccessor >> uuid [
^ uuid
Expand Down
4 changes: 2 additions & 2 deletions source/Magritte-Model/Object.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ Object >> isSameAs: rhs [
]

{ #category : #'*Magritte-Model' }
Object >> isSameAs: rhs using: valuableDescription [
Object >> isSameAs: rhs using: descriptionValuable [
"Use #isSameAs: unless you need to cache the description for efficiency.
CAUTION: this may not work if the description depends on the instance e.g. uses `self` in a block
(See comment below for more details)"
^ valuableDescription value allSatisfy: [ :desc |
^ descriptionValuable value allSatisfy: [ :desc |
| myVal rhsVal |
(desc accessor canRead: rhs)
ifFalse: [ false ]
Expand Down
14 changes: 8 additions & 6 deletions source/Magritte-Tests-Model/MAStraightMementoTest.class.st
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Class {
#name : #MAStraightMementoTest,
#superclass : #MAMementoTest,
#category : 'Magritte-Tests-Model-Memento'
#category : #'Magritte-Tests-Model-Memento'
}

{ #category : #testing }
Expand Down Expand Up @@ -49,12 +49,14 @@ MAStraightMementoTest >> testValidateRequired [

{ #category : #'tests-basic' }
MAStraightMementoTest >> testWrite [
self write: self includedInstance.
self assert: self value = self includedInstance.

"No need to save the default value"
self write: self defaultInstance.
self assert: self value = self defaultInstance.

self assert: self value equals: self nullInstance.
self write: self nullInstance.
self assert: self value = self nullInstance
self assert: self value equals: self nullInstance.

self write: self includedInstance.
self assert: self value equals: self includedInstance.
]

0 comments on commit 6d5f022

Please sign in to comment.