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
62 changes: 62 additions & 0 deletions src/Molecule-Tests/MolCompleteComponentForkedImpl.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"
This component send an event in a forked thread
"
Class {
#name : #MolCompleteComponentForkedImpl,
#superclass : #MolCompleteComponentImpl,
#instVars : [
'service'
],
#category : #'Molecule-Tests-Resources - Components'
}

{ #category : #'life cycle' }
MolCompleteComponentForkedImpl >> componentActivate [

super componentActivate.

self startEventSending
]

{ #category : #'life cycle' }
MolCompleteComponentForkedImpl >> componentPassivate [

self stopEventSending.

super componentPassivate
]

{ #category : #private }
MolCompleteComponentForkedImpl >> doEventSending [

| notifier |
notifier := self getMolUsedEventsNotifier.

"simulate a processing time here"
100 milliSecond wait.

notifier event
]

{ #category : #private }
MolCompleteComponentForkedImpl >> startEventSending [

service := TKTParameterizableService new
step: [ self doEventSending ];
name: 'Molecule Test - sending event';
stepDelay: 50 milliSecond.

service start
]

{ #category : #private }
MolCompleteComponentForkedImpl >> stopEventSending [

service stop
]

{ #category : #accessing }
MolCompleteComponentForkedImpl >> thread [

^ service
]
15 changes: 15 additions & 0 deletions src/Molecule-Tests/MolComponentImplTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,21 @@ MolComponentImplTest >> testParametersProviders [
self assert: component parametersProviders isEmpty.
]

{ #category : #'tests - connecting - events producers' }
MolComponentImplTest >> testSendEventInAForkDuringCleanUp [

| component |
component := MolCompleteComponentForkedImpl start.
self assert: component thread isRunning.

10 milliSecond wait.
MolComponentManager cleanUp.

"waiting for thread loop"
5 second wait. "here no error"
self deny: component thread isRunning
]

{ #category : #tests }
MolComponentImplTest >> testServicesDoIfNone [

Expand Down
64 changes: 41 additions & 23 deletions src/Molecule-Tests/MolEventNotifierTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,31 @@ Class {
#category : #'Molecule-Tests-Cases'
}

{ #category : #test }
MolEventNotifierTest >> setUp [

MolComponentManager cleanUp.
{ #category : #running }
MolEventNotifierTest >> setUp [

super setUp.

MolComponentManager cleanUp
]

{ #category : #test }
MolEventNotifierTest >> tearDown [
{ #category : #running }
MolEventNotifierTest >> tearDown [

MolComponentManager cleanUp.

super tearDown
]

{ #category : #test }
{ #category : #tests }
MolEventNotifierTest >> testActivate [
| notifier |
notifier := MolEventNotifier new.
notifier activate.
self assert: notifier isActive.
]

{ #category : #test }
{ #category : #tests }
MolEventNotifierTest >> testDeactivate [
| notifier |
notifier := MolEventNotifier new.
Expand All @@ -36,7 +40,7 @@ MolEventNotifierTest >> testDeactivate [
self assert: notifier isActive not.
]

{ #category : #test }
{ #category : #tests }
MolEventNotifierTest >> testDoesNotUnderstand [
| originator notifier error |
originator := MolCompleteComponentImpl new.
Expand All @@ -50,7 +54,7 @@ MolEventNotifierTest >> testDoesNotUnderstand [
self assert: (error isKindOf: MessageNotUnderstood).
]

{ #category : #test }
{ #category : #tests }
MolEventNotifierTest >> testDoesNotUnderstandWithoutCorrectDefinition [
| notifier error |
notifier := MolEventNotifier new.
Expand All @@ -62,41 +66,55 @@ MolEventNotifierTest >> testDoesNotUnderstandWithoutCorrectDefinition [
notifier event. "Make a log but not raised an error"
]

{ #category : #test }
{ #category : #tests }
MolEventNotifierTest >> testInitialize [

| notifier |
notifier := MolEventNotifier new.
self assert: notifier interface isNil.
self assert: notifier originator isNil.
self assert: notifier isActive equals: false.
self deny: notifier isActive
]

{ #category : #test }
{ #category : #tests }
MolEventNotifierTest >> testInterfaceOriginator [

| notifier originator |
originator := MolCompleteComponentImpl new.
notifier := MolEventNotifier interface: MolUsedEvents originator: originator.
notifier := MolEventNotifier
interface: MolUsedEvents
originator: originator.
self assert: notifier interface identicalTo: MolUsedEvents.
self assert: notifier originator identicalTo: originator.
self assert: notifier isActive equals: false.
self deny: notifier isActive
]

{ #category : #test }
{ #category : #tests }
MolEventNotifierTest >> testIsNotFoundEventsNotifier [
| notifier |
notifier := MolEventNotifier new.
self assert: notifier isNotFoundEventsNotifier not.
]

{ #category : #test }
{ #category : #tests }
MolEventNotifierTest >> testRelease [
| notifier originator |

| notifier originator error |
originator := MolCompleteComponentImpl new.
notifier := MolEventNotifier interface: MolUsedEvents originator: originator.
notifier := MolEventNotifier
interface: MolUsedEvents
originator: originator.
notifier activate.

notifier release.
self assert: notifier interface isNil.
self assert: notifier originator isNil.
self assert: notifier isActive equals: false.
self deny: notifier isActive.

"try to send an event when release: do nothing"
notifier event.

"MolUsedEvent>>subEvent not exists: continue to raise not understood message to identify call problems"
error := nil.
[notifier subEvent] on: Error do:[ :e | error := e ].
self assert: (error isKindOf: MessageNotUnderstood).
]
2 changes: 1 addition & 1 deletion src/Molecule-Tests/MolUtilsTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ MolUtilsTest >> testActivateComponents [
{ #category : #tests }
MolUtilsTest >> testAllComponentImplementationClassesOfType [

self assert: (MolUtils allComponentImplementationClassesOfType: MolCompleteComponent) size equals: 6.
self assert: (MolUtils allComponentImplementationClassesOfType: MolCompleteComponent) size equals: 7.
]

{ #category : #tests }
Expand Down
82 changes: 52 additions & 30 deletions src/Molecule/MolEventNotifier.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -21,62 +21,59 @@ MolEventNotifier class >> interface: aMolUsedEvents originator: aComponent [

{ #category : #actions }
MolEventNotifier >> activate [

isActive := true
]

{ #category : #actions }
MolEventNotifier >> deactivate [

isActive := false
]

{ #category : #'reflective operations' }
MolEventNotifier >> doesNotUnderstand: aMessage [
"Event message is called by a Notifier, the message not exists in MolEventNotifier so the system called doesNotUnderstand: message. Check if the event message is known by the event interface and trigger the event."
| isEventExist |
interface ifNil:[ ^ super doesNotUnderstand: aMessage ].
originator ifNil:[
MolUtils log: 'Originator not defined for event: ' , aMessage selector.
^ self
].
isEventExist := interface includesSelector: aMessage selector.

isEventExist
ifTrue: [
isActive
ifTrue: [
MolUtils log: originator printString , ' send event: ' , aMessage selector.
originator triggerEvent: aMessage selector withArguments: aMessage arguments.
] ifFalse: [
MolUtils log: 'An inactive component: ', originator printString , ' send event: ' , aMessage selector. ].
^ self.
] ifFalse: [
MolUtils log: originator printString , ' send an undefined event: ' , aMessage selector.
].

^ super doesNotUnderstand: aMessage




self interface
ifNil: [ "cannot interpret the message, return not understand"
^ super doesNotUnderstand: aMessage ]
ifNotNil: [
| isEventExist |
isEventExist := self interface includesSelector: aMessage selector.
isEventExist
ifFalse: [
MolUtils log:
self originator printString , ' send an undefined event: '
, aMessage selector.
"the event not exists, stop production here and return not understand"
^ super doesNotUnderstand: aMessage ]
ifTrue: [ self produceEvent: aMessage ] ]
]

{ #category : #'initialize-release' }
{ #category : #initialization }
MolEventNotifier >> initialize [

super initialize.
self deactivate.

self deactivate
]

{ #category : #accessing }
MolEventNotifier >> interface [

^ interface
]

{ #category : #accessing }
MolEventNotifier >> interface: anInterface [

interface := anInterface
]

{ #category : #accessing }
MolEventNotifier >> isActive [

^ isActive
]

Expand All @@ -88,18 +85,43 @@ MolEventNotifier >> isFoundEventsNotifier [

{ #category : #accessing }
MolEventNotifier >> originator [

^ originator
]

{ #category : #accessing }
MolEventNotifier >> originator: aComponent [

originator := aComponent
]

{ #category : #'initialize-release' }
{ #category : #private }
MolEventNotifier >> produceEvent: aMessage [
"Produce an event to offered components"

"If the notifier is not active, stop production here"
self isActive ifFalse: [ ^ self ].

"If there is no originator, stop the production here"
self originator ifNil: [
MolUtils log:
'Originator not defined for event: ' , aMessage selector.
^ self ].

MolUtils log:
self originator printString , ' send event: ' , aMessage selector.

"produce the event using object trigger mecanism"
self originator
triggerEvent: aMessage selector
withArguments: aMessage arguments
]

{ #category : #dependencies }
MolEventNotifier >> release [

self deactivate.
interface := nil.
originator := nil.
super release.

super release
]