From a48d9bcd81857b90a311e447756013f171c6079a Mon Sep 17 00:00:00 2001 From: Norbert Hartl Date: Thu, 17 Sep 2026 23:12:01 +0200 Subject: [PATCH] Give HOP-Extra a test package The adaptor had no test at all, and there was nowhere to put one: HOP-Core-Tests requires HOP-Core, so a test for an Extra class does not belong there. Both directions of the handler are covered now - a prepared object answers as it is, a named class still gives a fresh handler per request. Co-Authored-By: Claude Opus 5 (1M context) --- source/BaselineOfHOP/BaselineOfHOP.class.st | 2 ++ .../HOPTestZincHandler.class.st | 26 +++++++++++++++++ .../HOPZincHandlerAdaptorTest.class.st | 29 +++++++++++++++++++ source/HOP-Extra-Tests/package.st | 1 + 4 files changed, 58 insertions(+) create mode 100644 source/HOP-Extra-Tests/HOPTestZincHandler.class.st create mode 100644 source/HOP-Extra-Tests/HOPZincHandlerAdaptorTest.class.st create mode 100644 source/HOP-Extra-Tests/package.st diff --git a/source/BaselineOfHOP/BaselineOfHOP.class.st b/source/BaselineOfHOP/BaselineOfHOP.class.st index 66f9977..868cbae 100644 --- a/source/BaselineOfHOP/BaselineOfHOP.class.st +++ b/source/BaselineOfHOP/BaselineOfHOP.class.st @@ -20,6 +20,8 @@ BaselineOfHOP >> baseline: spec [ spec requires: #('HOP-Core') ]; package: 'HOP-Extra' with: [ spec requires: #('HOP-Core') ]; + package: 'HOP-Extra-Tests' with: [ + spec requires: #('HOP-Extra') ]; package: 'HOP-Roassal' with: [ spec requires: #('HOP-Core') ] ] ] diff --git a/source/HOP-Extra-Tests/HOPTestZincHandler.class.st b/source/HOP-Extra-Tests/HOPTestZincHandler.class.st new file mode 100644 index 0000000..c76707a --- /dev/null +++ b/source/HOP-Extra-Tests/HOPTestZincHandler.class.st @@ -0,0 +1,26 @@ +Class { + #name : 'HOPTestZincHandler', + #superclass : 'Object', + #instVars : [ + 'answer', + 'seenRequest' + ], + #category : 'HOP-Extra-Tests', + #package : 'HOP-Extra-Tests' +} + +{ #category : 'accessing' } +HOPTestZincHandler >> answer: aString [ + answer := aString +] + +{ #category : 'public' } +HOPTestZincHandler >> handleRequest: aRequest [ + seenRequest := aRequest. + ^ ZnResponse ok: (ZnEntity text: answer) +] + +{ #category : 'accessing' } +HOPTestZincHandler >> seenRequest [ + ^ seenRequest +] diff --git a/source/HOP-Extra-Tests/HOPZincHandlerAdaptorTest.class.st b/source/HOP-Extra-Tests/HOPZincHandlerAdaptorTest.class.st new file mode 100644 index 0000000..40e0e33 --- /dev/null +++ b/source/HOP-Extra-Tests/HOPZincHandlerAdaptorTest.class.st @@ -0,0 +1,29 @@ +Class { + #name : 'HOPZincHandlerAdaptorTest', + #superclass : 'TestCase', + #category : 'HOP-Extra-Tests', + #package : 'HOP-Extra-Tests' +} + +{ #category : 'tests' } +HOPZincHandlerAdaptorTest >> testAHandlerClassStillGivesAFreshOnePerRequest [ + "Unchanged for every route that names a class, which is all of them today: each request gets + its own handler and nothing is carried between them." + | adaptor | + adaptor := HOPZincHandlerAdaptor new handlerClass: HOPTestZincHandler; yourself. + self deny: adaptor handler identicalTo: adaptor handler +] + +{ #category : 'tests' } +HOPZincHandlerAdaptorTest >> testAPreparedHandlerIsTheOneThatAnswers [ + "The point of taking an object rather than a class: whoever builds the route can prepare the + handler, and that same prepared object answers the request." + | handler adaptor request | + handler := HOPTestZincHandler new answer: 'prepared'; yourself. + adaptor := HOPZincHandlerAdaptor new handler: handler; yourself. + request := ZnRequest get: '/anything'. + self + assert: (adaptor handleRoute: (HOPRouteMatch new request: request; yourself)) entity contents + equals: 'prepared'. + self assert: handler seenRequest identicalTo: request +] diff --git a/source/HOP-Extra-Tests/package.st b/source/HOP-Extra-Tests/package.st new file mode 100644 index 0000000..43fff7a --- /dev/null +++ b/source/HOP-Extra-Tests/package.st @@ -0,0 +1 @@ +Package { #name : 'HOP-Extra-Tests' }