Skip to content

Test added for "withAll" #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
74 changes: 39 additions & 35 deletions src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,48 @@
I am an implementation of an ordered set. Compared to other sets I am very efficient for small sizes, speed- and space-wise. I also mantain the order in which elements are added when iterating.
"
Class {
#name : #CTSmallOrderedSet,
#superclass : #Object,
#name : 'CTSmallOrderedSet',
#superclass : 'Object',
#instVars : [
'size',
'table'
],
#category : #'Containers-SmallOrderedSet'
#category : 'Containers-SmallOrderedSet',
#package : 'Containers-SmallOrderedSet'
}

{ #category : #'instance creation' }
{ #category : 'instance creation' }
CTSmallOrderedSet class >> new [
^ self new: 3
]

{ #category : #'instance creation' }
{ #category : 'instance creation' }
CTSmallOrderedSet class >> new: anInteger [
^ self basicNew initialize: anInteger; yourself
]

{ #category : #'instance creation' }
{ #category : 'instance creation' }
CTSmallOrderedSet class >> withAll: aDictionary [
^ (self new: aDictionary size)
addAll: aDictionary;
yourself
]

{ #category : #adding }
{ #category : 'adding' }
CTSmallOrderedSet >> add: newObject [
(self findIndexFor: newObject) = 0
ifTrue: [ self privateAdd: newObject ].
^ newObject
]

{ #category : #adding }
{ #category : 'adding' }
CTSmallOrderedSet >> addAll: aCollection [
aCollection do: [ :each |
self add: each ].
^ aCollection
]

{ #category : #converting }
{ #category : 'converting' }
CTSmallOrderedSet >> asArray [
| array index |
array := Array new: self size.
Expand All @@ -54,82 +55,82 @@ CTSmallOrderedSet >> asArray [
^ array
]

{ #category : #enumerating }
{ #category : 'enumerating' }
CTSmallOrderedSet >> do: aOneArgumentBlock [
1 to: size do: [ :i |
aOneArgumentBlock value: (table at: i) ]
]

{ #category : #enumerating }
{ #category : 'enumerating' }
CTSmallOrderedSet >> do: aOneArgumentBlock separatedBy: aNiladicBlock [
1 to: size do: [ :i |
i > 1 ifTrue: [ aNiladicBlock value ].
aOneArgumentBlock value: (table at: i) ]
]

{ #category : #'private ' }
{ #category : 'private ' }
CTSmallOrderedSet >> errorNotFound [
self error: 'Not found'
]

{ #category : #'private ' }
{ #category : 'private ' }
CTSmallOrderedSet >> findIndexFor: aKey [
1 to: size do: [ :index |
(table at: index) = aKey
ifTrue: [ ^ index ] ].
^ 0
]

{ #category : #'private ' }
{ #category : 'private' }
CTSmallOrderedSet >> grow [
| newTable |
"#replaceFrom:to:with:startingAt: would be better but not portable"
newTable := Array new: 2 * size.
1 to: size do: [ :index |
newTable at: index put: (table at: index) ].
table := newTable
| newTable newSize |
newSize := (table isEmpty) ifTrue: [1] ifFalse: [2 * table size]. "Ensure it grows from 0"
newTable := Array new: newSize.
1 to: size do: [ :index |
newTable at: index put: (table at: index) ].
table := newTable
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSet >> includes: anObject [
^ (self findIndexFor: anObject) ~= 0
]

{ #category : #initialization }
{ #category : 'initialization' }
CTSmallOrderedSet >> initialize: anInteger [
self initialize.
size := 0.
table := Array new: anInteger
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSet >> isCollection [
^ true
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSet >> isEmpty [
^ size = 0
]

{ #category : #copying }
{ #category : 'copying' }
CTSmallOrderedSet >> postCopy [
super postCopy.
table := table copy
]

{ #category : #'private ' }
{ #category : 'private ' }
CTSmallOrderedSet >> privateAdd: newObject [
size = table size ifTrue: [ self grow ].
table at: (size := size + 1) put: newObject.
]

{ #category : #removing }
{ #category : 'removing' }
CTSmallOrderedSet >> remove: anObject [
^ self remove: anObject ifAbsent: [ self errorNotFound ]
]

{ #category : #removing }
{ #category : 'removing' }
CTSmallOrderedSet >> remove: anObject ifAbsent: aNiladicBlock [
| index |
index := self findIndexFor: anObject.
Expand All @@ -139,15 +140,18 @@ CTSmallOrderedSet >> remove: anObject ifAbsent: aNiladicBlock [
^ anObject
]

{ #category : #'private ' }
CTSmallOrderedSet >> removeIndex: index [
table at: index put: nil.
index to: size - 1 do: [ :i |
table at: i put: (table at: i + 1) ].
size := size - 1
{ #category : 'private' }
CTSmallOrderedSet >> removeIndex: index [
(index < 1 or: [ index > size ])
ifTrue: [ self error: 'Index out of bounds' ].
table at: index put: nil.
index to: size - 1 do: [ :i |
table at: i put: (table at: i + 1) ].
table at: size put: nil.
size := size - 1.
]

{ #category : #accessing }
{ #category : 'accessing' }
CTSmallOrderedSet >> size [
^ size
]
82 changes: 65 additions & 17 deletions src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
Class {
#name : #CTSmallOrderedSetTest,
#superclass : #TestCase,
#name : 'CTSmallOrderedSetTest',
#superclass : 'TestCase',
#instVars : [
'collection'
],
#category : #'Containers-SmallOrderedSet'
#category : 'Containers-SmallOrderedSet',
#package : 'Containers-SmallOrderedSet'
}

{ #category : #configuration }
{ #category : 'configuration' }
CTSmallOrderedSetTest >> collectionClass [
^ CTSmallOrderedSet
]

{ #category : #running }
{ #category : 'running' }
CTSmallOrderedSetTest >> setUp [
super setUp.
collection := CTSmallOrderedSet new
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testAdd [
| object |
object := Object new.
Expand All @@ -28,34 +29,34 @@ CTSmallOrderedSetTest >> testAdd [
self assert: (collection add: object) equals: object
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testAddAll [
collection addAll: #(2 1 1).
self assert: collection size equals: 2.
self assert: (collection includes: 1).
self assert: (collection includes: 2)
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testAddAllKeepsOrder [
collection addAll: #(2 1 1 3 4 5 5 5 6).
self assert: collection size equals: 6.
self assert: collection asArray equals: #(2 1 3 4 5 6).
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testAsArray [
collection addAll: #(2 1 1).
self assert: collection asArray equals: #(2 1).
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testAsArrayWithStrangeOrder [
collection addAll: #(2 1 3 2 1).
self assert: collection asArray equals: #(2 1 3).
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testCopy [
| copy |
collection add: 1.
Expand All @@ -69,7 +70,7 @@ CTSmallOrderedSetTest >> testCopy [
self deny: (copy includes: 2).
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testDo [
| seen |
collection addAll: #(2 1 1).
Expand All @@ -81,14 +82,14 @@ CTSmallOrderedSetTest >> testDo [
self assert: (seen at: 2) equals: 1
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testIncludes [
self deny: (collection includes: 0).
collection add: 0.
self assert: (collection includes: 0)
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testIsEmpty [
self assert: collection isEmpty.
collection add: 1.
Expand All @@ -97,14 +98,14 @@ CTSmallOrderedSetTest >> testIsEmpty [
self assert: collection isEmpty
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testRemove [
collection add: 1.
self assert: (collection remove: 1) equals: 1.
self should: [ collection remove: 1 ] raise: Error
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testRemoveIfAbsent [
| absent |
collection add: 1.
Expand All @@ -117,9 +118,56 @@ CTSmallOrderedSetTest >> testRemoveIfAbsent [
self assert: absent.
]

{ #category : #testing }
{ #category : 'testing' }
CTSmallOrderedSetTest >> testSize [
self assert: collection size equals: 0.
collection addAll: #(2 1 1).
self assert: collection size equals: 2.
]

{ #category : 'testing' }
CTSmallOrderedSetTest >> testWithAll [
| emptySet singleSet duplicateSet orderedSet mixedSet largeSet unorderedSet specialCharSet expected |

"Empty Collection Input"
emptySet := CTSmallOrderedSet withAll: #().
self assert: emptySet isEmpty.

"Single Element Collection"
singleSet := CTSmallOrderedSet withAll: #(42).
self assert: singleSet size equals: 1.
self assert: (singleSet includes: 42).

"Collection With Only Duplicates"
duplicateSet := CTSmallOrderedSet withAll: #(7 7 7 7 7).
self assert: duplicateSet size equals: 1.
self assert: (duplicateSet includes: 7).

"Already Ordered Input"
orderedSet := CTSmallOrderedSet withAll: #(10 20 30).
expected := #(10 20 30).
self assert: orderedSet asArray equals: expected.

"Mixed Data Types"
mixedSet := CTSmallOrderedSet withAll: #(1 'a' 2 'b' 1 'a').
self assert: mixedSet size equals: 4.
self assert: (mixedSet includes: 1).
self assert: (mixedSet includes: 'a').
self assert: (mixedSet includes: 2).
self assert: (mixedSet includes: 'b').

"Large Input Collection"
largeSet := CTSmallOrderedSet withAll: (1 to: 10000).
self assert: largeSet size equals: 10000.

"Unordered Input"
unorderedSet := CTSmallOrderedSet withAll: #(5 2 8 1 3).
self assert: unorderedSet asArray equals: #(5 2 8 1 3).

"Collection With Special Characters"
specialCharSet := CTSmallOrderedSet withAll: #('hello' 'world' 'hello!' 'world#').
self assert: specialCharSet size equals: 4.
self assert: (specialCharSet includes: 'hello!').
self assert: (specialCharSet includes: 'world#').

]
2 changes: 1 addition & 1 deletion src/Containers-SmallOrderedSet/package.st
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Package { #name : #'Containers-SmallOrderedSet' }
Package { #name : 'Containers-SmallOrderedSet' }