diff --git a/src/Containers-Stack-Tests/CTGrowableStackTest.class.st b/src/Containers-Stack-Tests/CTGrowableStackTest.class.st new file mode 100644 index 0000000..529bdf5 --- /dev/null +++ b/src/Containers-Stack-Tests/CTGrowableStackTest.class.st @@ -0,0 +1,86 @@ +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 >> 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 [ + + 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. + + 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..05c5374 --- /dev/null +++ b/src/Containers-Stack-Tests/CTTrackedGrowableStackTest.class.st @@ -0,0 +1,112 @@ +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 >> 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. + 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 +]