From 54dd969db368a8cd1f38f6c9fdc48bbb975ba4d2 Mon Sep 17 00:00:00 2001 From: HossamSaberr Date: Sun, 8 Mar 2026 07:56:18 +0200 Subject: [PATCH 1/3] Implement growable stack and max-depth tracking (#8) --- .../CTGrowableStackTest.class.st | 46 +++++++++++ .../CTTrackedGrowableStackTest.class.st | 82 +++++++++++++++++++ src/Containers-Stack/CTGrowableStack.class.st | 43 ++++++++++ .../CTTrackedGrowableStack.class.st | 27 ++++++ 4 files changed, 198 insertions(+) create mode 100644 src/Containers-Stack-Tests/CTGrowableStackTest.class.st create mode 100644 src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st create mode 100644 src/Containers-Stack/CTGrowableStack.class.st create mode 100644 src/Containers-Stack/CTTrackedGrowableStack.class.st diff --git a/src/Containers-Stack-Tests/CTGrowableStackTest.class.st b/src/Containers-Stack-Tests/CTGrowableStackTest.class.st new file mode 100644 index 0000000..0ec5176 --- /dev/null +++ b/src/Containers-Stack-Tests/CTGrowableStackTest.class.st @@ -0,0 +1,46 @@ +Class { + #name : 'CTGrowableStackTest', + #superclass : 'TestCase', + #instVars : [ + 'stack' + ], + #category : 'Containers-Stack-Tests', + #package : 'Containers-Stack-Tests' +} + +{ #category : 'running' } +CTGrowableStackTest >> setUp [ + super setUp. + stack := CTGrowableStack new +] + +{ #category : 'tests' } +CTGrowableStackTest >> testIsEmpty [ + self assert: stack isEmpty. + + stack push: 'x'. + self deny: stack isEmpty. + + stack pop. + self assert: stack isEmpty. +] + +{ #category : 'tests' } +CTGrowableStackTest >> testPop [ + stack push: 'first'. + stack push: 'second'. + + self assert: stack pop equals: 'second'. + self assert: stack size equals: 1. + self assert: stack pop equals: 'first'. + self assert: stack isEmpty. +] + +{ #category : 'tests' } +CTGrowableStackTest >> testPush [ + stack push: 'a'. + + self assert: stack size equals: 1. + self deny: stack isEmpty. + self assert: stack top equals: 'a'. +] diff --git a/src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st b/src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st new file mode 100644 index 0000000..424f48c --- /dev/null +++ b/src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st @@ -0,0 +1,82 @@ +Class { + #name : 'CTTrackedGrowableStackTest', + #superclass : 'TestCase', + #instVars : [ + 'stack' + ], + #category : 'Containers-Stack-Tests', + #package : 'Containers-Stack-Tests' +} + +{ #category : 'running' } +CTTrackedGrowableStackTest >> setUp [ + super setUp. + stack := CTTrackedGrowableStack new +] + +{ #category : 'tests' } +CTTrackedGrowableStackTest >> testErrorHandlingDoesNotAffectMaxDepth [ + self should: [ stack pop ] raise: Error. + self assert: stack maxDepth equals: 0. + + stack push: 'temp'. + stack pop. + + self should: [ stack pop ] raise: Error. + self assert: stack maxDepth equals: 1. +] + +{ #category : 'tests' } +CTTrackedGrowableStackTest >> testInitialMaxDepth [ + self assert: stack maxDepth equals: 0. + self assert: stack isEmpty. +] + +{ #category : 'tests' } +CTTrackedGrowableStackTest >> testMaxDepthAfterPop [ + stack push: 'apple'. + stack push: 'banana'. + self assert: stack maxDepth equals: 2. + + stack pop. + + self assert: stack size equals: 1. + self assert: stack maxDepth equals: 2. +] + +{ #category : 'tests' } +CTTrackedGrowableStackTest >> testMaxDepthWithFluctuations [ + stack push: 1. + stack push: 2. + stack pop. + stack pop. + + stack push: 3. + stack push: 4. + stack push: 5. + + self assert: stack maxDepth equals: 3. +] + +{ #category : 'tests' } +CTTrackedGrowableStackTest >> testMaxDepthWithLargeDataset [ + 1 to: 100 do: [ :i | stack push: i ]. + + self assert: stack maxDepth equals: 100. + self assert: stack size equals: 100. + + 1 to: 50 do: [ :i | stack pop ]. + + self assert: stack maxDepth equals: 100. + self assert: stack size equals: 50. +] + +{ #category : 'tests' } +CTTrackedGrowableStackTest >> testTopDoesNotAffectMaxDepth [ + stack push: 'hello'. + self assert: stack maxDepth equals: 1. + + self assert: stack top equals: 'hello'. + self assert: stack maxDepth equals: 1. + self assert: stack size equals: 1. +] diff --git a/src/Containers-Stack/CTGrowableStack.class.st b/src/Containers-Stack/CTGrowableStack.class.st new file mode 100644 index 0000000..9a0c04c --- /dev/null +++ b/src/Containers-Stack/CTGrowableStack.class.st @@ -0,0 +1,43 @@ +Class { + #name : 'CTGrowableStack', + #superclass : 'Object', + #instVars : [ + 'elements' + ], + #category : 'Containers-Stack', + #package : 'Containers-Stack' +} + +{ #category : 'initialization' } +CTGrowableStack >> initialize [ + super initialize. + elements := OrderedCollection new +] + +{ #category : 'testing' } +CTGrowableStack >> isEmpty [ + ^ elements isEmpty +] + +{ #category : 'removing' } +CTGrowableStack >> pop [ + self isEmpty ifTrue: [ self error: 'Stack is empty' ]. + ^ elements removeLast +] + +{ #category : 'adding' } +CTGrowableStack >> push: anObject [ + elements addLast: anObject. + ^ self +] + +{ #category : 'accessing' } +CTGrowableStack >> size [ + ^ elements size +] + +{ #category : 'accessing' } +CTGrowableStack >> top [ + self isEmpty ifTrue: [ self error: 'Stack is empty' ]. + ^ elements last +] diff --git a/src/Containers-Stack/CTTrackedGrowableStack.class.st b/src/Containers-Stack/CTTrackedGrowableStack.class.st new file mode 100644 index 0000000..3e0ce1f --- /dev/null +++ b/src/Containers-Stack/CTTrackedGrowableStack.class.st @@ -0,0 +1,27 @@ +Class { + #name : 'CTTrackedGrowableStack', + #superclass : 'CTGrowableStack', + #instVars : [ + 'maxDepth' + ], + #category : 'Containers-Stack', + #package : 'Containers-Stack' +} + +{ #category : 'initialization' } +CTTrackedGrowableStack >> initialize [ + super initialize. + maxDepth := 0 +] + +{ #category : 'accessing' } +CTTrackedGrowableStack >> maxDepth [ + ^ maxDepth +] + +{ #category : 'adding' } +CTTrackedGrowableStack >> push: anObject [ + super push: anObject. + maxDepth := maxDepth max: self size. + ^ self +] From 21a1b3b647e6ef0e4e5325e22479f6aa1d80102e Mon Sep 17 00:00:00 2001 From: HossamSaberr Date: Tue, 24 Mar 2026 18:26:05 +0200 Subject: [PATCH 2/3] Add internal capacity tests and max-depth tracking --- .../CTGrowableStackTest.class.st | 44 +++++++++++++++++++ .../CTTrackedGrowableStackTest.class.st | 30 +++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/Containers-Stack-Tests/CTGrowableStackTest.class.st b/src/Containers-Stack-Tests/CTGrowableStackTest.class.st index 0ec5176..e112c02 100644 --- a/src/Containers-Stack-Tests/CTGrowableStackTest.class.st +++ b/src/Containers-Stack-Tests/CTGrowableStackTest.class.st @@ -14,6 +14,50 @@ CTGrowableStackTest >> setUp [ stack := CTGrowableStack new ] +{ #category : 'tests' } +CTGrowableStackTest >> testExplicitCapacityDoubling [ + + | internalCollection | + + stack := CTGrowableStack new. + internalCollection := OrderedCollection new: 4. + stack instVarNamed: 'elements' put: internalCollection. + + 1 to: 4 do: [ :i | stack push: i ]. + self assert: internalCollection capacity equals: 4. + + stack push: 5. + + self assert: (stack instVarNamed: 'elements') capacity equals: 8. + self assert: stack size equals: 5. +] + +{ #category : 'tests' } +CTGrowableStackTest >> testInternalCapacityDoubling [ + + | internalCollection | + + internalCollection := stack instVarNamed: 'elements'. + + 1 to: 100 do: [ :i | stack push: i ]. + + self assert: stack size equals: 100. + self assert: internalCollection capacity >= 100. +] + +{ #category : 'tests' } +CTGrowableStackTest >> testInternalGrowth [ + + | initialCapacity | + + initialCapacity := stack size. + + 1 to: 20 do: [ :i | stack push: i ]. + + self assert: stack size equals: 20. + self assert: stack top equals: 20. +] + { #category : 'tests' } CTGrowableStackTest >> testIsEmpty [ self assert: stack isEmpty. diff --git a/src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st b/src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st index 424f48c..05c5374 100644 --- a/src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st +++ b/src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st @@ -44,6 +44,36 @@ CTTrackedGrowableStackTest >> testMaxDepthAfterPop [ self assert: stack maxDepth equals: 2. ] +{ #category : 'tests' } +CTTrackedGrowableStackTest >> testMaxDepthDuringInternalGrowth [ + + 1 to: 50 do: [ :i | stack push: i ]. + self assert: stack maxDepth equals: 50. + self assert: stack size equals: 50. + + 1 to: 25 do: [ :i | stack pop ]. + self assert: stack maxDepth equals: 50. + self assert: stack size equals: 25. +] + +{ #category : 'tests' } +CTTrackedGrowableStackTest >> testMaxDepthWithExplicitInternalGrowth [ + + | internalCollection | + stack := CTTrackedGrowableStack new. + internalCollection := OrderedCollection new: 4. + stack instVarNamed: 'elements' put: internalCollection. + + 1 to: 4 do: [ :i | stack push: i ]. + self assert: stack maxDepth equals: 4. + self assert: internalCollection capacity equals: 4. + + stack push: 5. + + self assert: stack maxDepth equals: 5. + self assert: (stack instVarNamed: 'elements') capacity equals: 8. +] + { #category : 'tests' } CTTrackedGrowableStackTest >> testMaxDepthWithFluctuations [ stack push: 1. From 472aa645c1e0417e955e5ae3437f4058060d38b7 Mon Sep 17 00:00:00 2001 From: HossamSaberr Date: Thu, 26 Mar 2026 09:35:29 +0200 Subject: [PATCH 3/3] Remove unused variable --- src/Containers-Stack-Tests/CTGrowableStackTest.class.st | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Containers-Stack-Tests/CTGrowableStackTest.class.st b/src/Containers-Stack-Tests/CTGrowableStackTest.class.st index e112c02..529bdf5 100644 --- a/src/Containers-Stack-Tests/CTGrowableStackTest.class.st +++ b/src/Containers-Stack-Tests/CTGrowableStackTest.class.st @@ -48,10 +48,6 @@ CTGrowableStackTest >> testInternalCapacityDoubling [ { #category : 'tests' } CTGrowableStackTest >> testInternalGrowth [ - | initialCapacity | - - initialCapacity := stack size. - 1 to: 20 do: [ :i | stack push: i ]. self assert: stack size equals: 20.