Skip to content
Merged
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
36 changes: 35 additions & 1 deletion src/Molecule-Tests/MolComponentImplTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ MolComponentImplTest >> testForEventsRemoveProducer [

| component |
component := MolCompleteComponentImpl start: #myComponentA.
"initial state"
self assert: (component eventsSubscribers at: MolUsedEvents) equals: MolUtils defaultComponentName.

component forEvents: MolUsedEvents useAllProducers: #(#producerA #producerB #producerC).

Expand All @@ -247,7 +249,8 @@ MolComponentImplTest >> testForEventsRemoveProducer [

component forEvents: MolUsedEvents removeProducer: #producerC.
self assert: component eventsSubscribers size equals: 1.
self assert: (component eventsSubscribers at: MolUsedEvents) equals: nil.
"back to initial state"
self assert: (component eventsSubscribers at: MolUsedEvents) equals: MolUtils defaultComponentName.
]

{ #category : #'tests - connecting - events producers' }
Expand Down Expand Up @@ -673,6 +676,37 @@ MolComponentImplTest >> testStart2 [
self assert: component componentName equals: #compA.
]

{ #category : #'tests - connecting - events producers' }
MolComponentImplTest >> testStartAndStopComponentWithRemoveProducerSeveralTimes [
"This test reproduce issue #246: Exception after several starts and stops of same component"

| compA compB |
"start first implemention of a component contract"
compA := MolCompleteComponentImpl start: #compA.
compB := MolCompleteComponentImpl start: #compB.

"link compB to compA"
compB forServices: MolUsedServices useProvider: #compA.
compB forEvents: MolUsedEvents useProducer: #compA.
compB getMolUsedEventsSubscriber subscribe: compB.

"call the service of the first component, it answer #service"
self assert: compB getMolUsedServicesProvider service equals: #service.

"stop and start component several times"
1 to: 10 do:[ :i |
compB forEvents: MolUsedEvents removeProducer: #compA.
compB class stop: #compB.
compB := MolCompleteComponentImpl start: #compB.
compB forServices: MolUsedServices useProvider: #compA.
compB forEvents: MolUsedEvents useProducer: #compA.
compB getMolUsedEventsSubscriber subscribe: compB.
self assert: compB getMolUsedServicesProvider service equals: #service.
].


]

{ #category : #'tests - component creation' }
MolComponentImplTest >> testStartWithGeneratedName [

Expand Down
5 changes: 4 additions & 1 deletion src/Molecule/MolComponentImpl.trait.st
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,10 @@ MolComponentImpl >> forEvents: anEventsTrait removeProducer: aComponentName [

producers := self eventsSubscribers at: anEventsTrait.
producers ifNil:[ ^self ].
producers = aComponentName ifTrue:[ self eventsSubscribers at: anEventsTrait put: nil. ^ self ].
producers = aComponentName ifTrue:[
"Molecule issue #242: store the default component name when a producer is removed to going back to the initial state"
self eventsSubscribers at: anEventsTrait put: MolUtils defaultComponentName. ^ self
].
(producers isArray and:[producers includes: aComponentName]) ifTrue: [ | newProducers |
newProducers := producers asOrderedCollection copy.
newProducers remove: aComponentName.
Expand Down
23 changes: 14 additions & 9 deletions src/Molecule/MolEventSubscriber.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,20 @@ MolEventSubscriber >> connectOriginator: componentName to: aComponent [
"Connect a component to event pipeline"

| key connect |
key := aComponent eventsSubscribers at: self events ifAbsent: [ nil ].
connect := key isSymbol ifTrue:[ componentName = key ] ifFalse:[ key includes: componentName ].

connect ifTrue: [
self events allSelectors do: [ :event |
| originator |
originator := self originatorsLinks at: componentName.
originator ifNil: [ ^ self error: 'Component originator is nil' ].
originator when: event send: event to: aComponent ] ]
key := aComponent eventsSubscribers at: self events ifAbsent: [ MolUtils defaultComponentName ].

connect := key isSymbol
ifTrue:[ componentName = key ]
ifFalse:[ key includes: componentName ].

"Cannot connect, stop here"
connect ifFalse:[ ^ self ].

self events allSelectors do: [ :event |
| originator |
originator := self originatorsLinks at: componentName.
originator ifNil: [ ^ self error: 'Component originator is nil' ].
originator when: event send: event to: aComponent ]
]

{ #category : #private }
Expand Down
Loading