diff --git a/src/Containers-Queue-Tests/CTQueueTest.class.st b/src/Containers-Queue-Tests/CTQueueTest.class.st index 6d1149e..aa8a6bd 100644 --- a/src/Containers-Queue-Tests/CTQueueTest.class.st +++ b/src/Containers-Queue-Tests/CTQueueTest.class.st @@ -3,17 +3,18 @@ I'm a simple queue i.e., first in first out structure. I support basic collection protocol and in addition enqueue and dequeue as in Scala. " Class { - #name : #CTQueueTest, - #superclass : #TestCase, - #category : #'Containers-Queue-Tests' + #name : 'CTQueueTest', + #superclass : 'TestCase', + #category : 'Containers-Queue-Tests', + #package : 'Containers-Queue-Tests' } -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> queueClass [ ^ CTQueue ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testAdd [ | queue | queue := self queueClass new. @@ -23,7 +24,7 @@ CTQueueTest >> testAdd [ self assert: (queue includes: 2) ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testAddAll [ "Ensure queueAll adds multiple elements at once." | queue | @@ -35,7 +36,7 @@ CTQueueTest >> testAddAll [ self assert: queue remove equals: 40. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testAddAllLargeCollection [ "Test adding a large collection via addAll." | queue collection size | @@ -48,7 +49,7 @@ CTQueueTest >> testAddAllLargeCollection [ self assert: queue isEmpty. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testAddGarantyFIFOOrder [ "Ensure elements are dequeued in FIFO order." | queue | @@ -62,7 +63,7 @@ CTQueueTest >> testAddGarantyFIFOOrder [ self assert: queue isEmpty. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testAddNilElement [ "Test adding a nil element to the queue." | queue | @@ -74,7 +75,28 @@ CTQueueTest >> testAddNilElement [ self assert: queue isEmpty. ] -{ #category : #tests } +{ #category : 'tests' } +CTQueueTest >> testAddUnless [ + | queue | + queue := self queueClass new. + queue add: 1 unless: [ :v | (v rem: 2) = 0]. + self assert: (queue includes: 1). + self assert: queue size equals: 1 . + queue add: 2 unless: [ :v | (v rem: 2) = 0]. + self assert: (queue includes: 1). + self assert: (queue includes: 2) . + self assert: queue size equals: 2 . + queue add: 4 unless: [ :v | (v rem: 2) = 0]. + self assert: (queue includes: 1). + self assert: (queue includes: 2) . + self assert: queue size equals: 2 . + queue add: 3 unless: [ :v | (v rem: 2) = 0]. + self assert: (queue includes: 1). + self assert: (queue includes: 2) . + self assert: queue size equals: 2 +] + +{ #category : 'tests' } CTQueueTest >> testDoIteration [ "Test iterating over the queue with do: in FIFO order." | queue collected | @@ -86,19 +108,19 @@ CTQueueTest >> testDoIteration [ self assert: queue size equals: 4. "Iteration should not modify the queue" ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testEmptyQueue [ self assert: self queueClass new isEmpty ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testEmptyQueueRemove [ | queue | queue := self queueClass new. self assert: queue remove isNil. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testIncludes [ "Test the includes: method for existing and non-existing elements." | queue | @@ -109,7 +131,7 @@ CTQueueTest >> testIncludes [ self assert: queue size equals: 3. "includes: should not modify the queue" ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testInterleavedAddRemove [ "Test interleaved add and remove operations to ensure FIFO order and correctness." | queue | @@ -125,7 +147,7 @@ CTQueueTest >> testInterleavedAddRemove [ self assert: queue isEmpty. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testIsEmpty [ "Ensure isEmpty works correctly." | queue | @@ -137,7 +159,7 @@ CTQueueTest >> testIsEmpty [ self assert: queue isEmpty. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testLargeQueuePerformance [ "Verify FIFO behavior and performance with a large queue." | queue size startTime endTime duration maxDuration | @@ -162,7 +184,7 @@ CTQueueTest >> testLargeQueuePerformance [ self assert: queue isEmpty. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testPeek [ "Ensure peek returns the first element without removing it." | queue | @@ -173,7 +195,7 @@ CTQueueTest >> testPeek [ self assert: queue size equals: 2. "Peek should not remove elements" ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testPoll [ "Ensure poll behaves correctly, returning nil when empty." | queue | @@ -185,17 +207,17 @@ CTQueueTest >> testPoll [ self assert: queue poll isNil. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testQueue [ self assert: self queueClass new isEmpty ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testQueueGarantyFIFOOrder [ self assert: self queueClass new isEmpty ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testRemove [ "Ensure remove behaves correctly, returning nil when empty." | queue | @@ -207,7 +229,7 @@ CTQueueTest >> testRemove [ self assert: queue remove equals: 2 ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testRemoveIfNone [ "Ensure removeIfNone works correctly." | queue result | @@ -216,7 +238,7 @@ CTQueueTest >> testRemoveIfNone [ self assert: result equals: 'fallback'. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testSizeAccuracy [ "Test that the size method accurately reflects the number of elements." | queue | @@ -232,7 +254,7 @@ CTQueueTest >> testSizeAccuracy [ self assert: queue size equals: 2. ] -{ #category : #tests } +{ #category : 'tests' } CTQueueTest >> testStressAddRemove [ "Stress test with many add and remove operations." | queue iterations | @@ -248,4 +270,4 @@ CTQueueTest >> testStressAddRemove [ queue addAll: (1 to: 1000). 1 to: 1000 do: [ :i | self assert: queue remove equals: i ]. self assert: queue isEmpty. -] \ No newline at end of file +] diff --git a/src/Containers-Queue-Tests/package.st b/src/Containers-Queue-Tests/package.st index ccf49f0..c9e25b5 100644 --- a/src/Containers-Queue-Tests/package.st +++ b/src/Containers-Queue-Tests/package.st @@ -1 +1 @@ -Package { #name : #'Containers-Queue-Tests' } +Package { #name : 'Containers-Queue-Tests' } diff --git a/src/Containers-Queue/CTQueue.class.st b/src/Containers-Queue/CTQueue.class.st index 2baf9bb..7f213fa 100644 --- a/src/Containers-Queue/CTQueue.class.st +++ b/src/Containers-Queue/CTQueue.class.st @@ -2,17 +2,18 @@ I'm a simple FIFO queue i.e., first in first out structure. I support basic collection protocol with efficient O(1) add and remove operations using a singly linked list. " Class { - #name : #CTQueue, - #superclass : #Object, + #name : 'CTQueue', + #superclass : 'Object', #instVars : [ 'head', 'tail', 'size' ], - #category : #'Containers-Queue' + #category : 'Containers-Queue', + #package : 'Containers-Queue' } -{ #category : #adding } +{ #category : 'adding' } CTQueue >> add: anElement [ "Add an element to the end of the queue (FIFO order)." | newNode | @@ -28,14 +29,39 @@ CTQueue >> add: anElement [ ^ anElement ] -{ #category : #adding } +{ #category : 'adding' } +CTQueue >> add: anElement unless: aTestIsTrue [ + "Add an element to the end of the queue (FIFO order)." + | newNode | + + head ifNil: [ + newNode := CTQueueNode new value: anElement. + head := newNode. + tail := newNode. + ] ifNotNil: [ + |current| + current := head . + [ current = tail ] whileFalse: [ + (aTestIsTrue value: current value) ifTrue: [ ^ current value ] . + current := current next + ] . + (aTestIsTrue value: tail value) ifTrue: [ ^ tail value ] . + newNode := CTQueueNode new value: anElement. + tail next: newNode. + tail := newNode. + ]. + size := size + 1. + ^ anElement +] + +{ #category : 'adding' } CTQueue >> addAll: aCollection [ "Add all elements from aCollection to the end of the queue." aCollection do: [ :each | self add: each ]. ^ aCollection ] -{ #category : #iterating } +{ #category : 'iterating' } CTQueue >> do: aBlock [ "Iterate over elements in FIFO order." | current | @@ -46,7 +72,7 @@ CTQueue >> do: aBlock [ ] ] -{ #category : #testing } +{ #category : 'testing' } CTQueue >> includes: anElement [ "Check if anElement exists in the queue." | current | @@ -58,7 +84,7 @@ CTQueue >> includes: anElement [ ^ false ] -{ #category : #initialization } +{ #category : 'initialization' } CTQueue >> initialize [ "Initialize an empty queue." super initialize. @@ -67,25 +93,25 @@ CTQueue >> initialize [ size := 0. ] -{ #category : #testing } +{ #category : 'testing' } CTQueue >> isEmpty [ "Return true if the queue is empty." ^ head isNil ] -{ #category : #accessing } +{ #category : 'accessing' } CTQueue >> peek [ "Return the front element without removing it, or nil if empty." ^ head ifNil: [ nil ] ifNotNil: [ head value ] ] -{ #category : #removing } +{ #category : 'removing' } CTQueue >> poll [ "Return and remove the front element, or nil if empty." ^ self remove ] -{ #category : #removing } +{ #category : 'removing' } CTQueue >> remove [ "Return and remove the oldest element, or nil if empty." | value | @@ -97,15 +123,15 @@ CTQueue >> remove [ ^ value ] -{ #category : #removing } +{ #category : 'removing' } CTQueue >> removeIfNone: aBlock [ "Return and remove the oldest element, or evaluate aBlock if empty." head ifNil: [ ^ aBlock value ]. ^ self remove ] -{ #category : #accessing } +{ #category : 'accessing' } CTQueue >> size [ "Return the number of elements in the queue." ^ size -] \ No newline at end of file +] diff --git a/src/Containers-Queue/CTQueueNode.class.st b/src/Containers-Queue/CTQueueNode.class.st index 430c3b2..f72eaeb 100644 --- a/src/Containers-Queue/CTQueueNode.class.st +++ b/src/Containers-Queue/CTQueueNode.class.st @@ -1,29 +1,30 @@ Class { - #name : #CTQueueNode, - #superclass : #Object, + #name : 'CTQueueNode', + #superclass : 'Object', #instVars : [ 'value', 'next' ], - #category : #'Containers-Queue' + #category : 'Containers-Queue', + #package : 'Containers-Queue' } -{ #category : #accessing } +{ #category : 'accessing' } CTQueueNode >> next [ ^ next ] -{ #category : #accessing } +{ #category : 'accessing' } CTQueueNode >> next: aNode [ next := aNode ] -{ #category : #accessing } +{ #category : 'accessing' } CTQueueNode >> value [ ^ value ] -{ #category : #accessing } +{ #category : 'accessing' } CTQueueNode >> value: anObject [ value := anObject -] \ No newline at end of file +] diff --git a/src/Containers-Queue/package.st b/src/Containers-Queue/package.st index 500d4dd..bee4046 100644 --- a/src/Containers-Queue/package.st +++ b/src/Containers-Queue/package.st @@ -1 +1 @@ -Package { #name : #'Containers-Queue' } +Package { #name : 'Containers-Queue' }