Create contact book model
This commit is contained in:
54
src/ContactBook/Contact.class.st
Normal file
54
src/ContactBook/Contact.class.st
Normal file
@@ -0,0 +1,54 @@
|
||||
"
|
||||
I represent a person with a name and an email address. I'm usually
|
||||
part of a contact book.
|
||||
"
|
||||
Class {
|
||||
#name : #Contact,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'fullname',
|
||||
'email'
|
||||
],
|
||||
#category : #ContactBook
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
Contact class >> newNamed: aNameString email: anEmailString [
|
||||
^ self new
|
||||
fullname: aNameString;
|
||||
email: anEmailString;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Contact >> email [
|
||||
|
||||
^ email
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Contact >> email: anObject [
|
||||
|
||||
email := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Contact >> fullname [
|
||||
|
||||
^ fullname
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Contact >> fullname: aString [
|
||||
|
||||
fullname := aString
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Contact >> printOn: aStream [
|
||||
aStream
|
||||
nextPutAll: self fullname;
|
||||
nextPutAll: ' <';
|
||||
nextPutAll: self email;
|
||||
nextPutAll: '>'
|
||||
]
|
||||
44
src/ContactBook/ContactBook.class.st
Normal file
44
src/ContactBook/ContactBook.class.st
Normal file
@@ -0,0 +1,44 @@
|
||||
Class {
|
||||
#name : #ContactBook,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'contacts'
|
||||
],
|
||||
#category : #ContactBook
|
||||
}
|
||||
|
||||
{ #category : #demos }
|
||||
ContactBook class >> createDefault [
|
||||
^ self new
|
||||
addContact: (Contact newNamed: 'Damien Cassou' email: 'damien@cassou.me');
|
||||
addContact: (Contact newNamed: 'Marcus Denker' email: 'marcus.denker@inria.fr');
|
||||
addContact: (Contact newNamed: 'Tudor Girba' email: 'tudor@tudorgirba.com');
|
||||
addContact: (Contact newNamed: 'Clara Allende' email: 'clari.allende@gmail.com');
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #writing }
|
||||
ContactBook >> addContact: aContact [
|
||||
self contacts add: aContact
|
||||
]
|
||||
|
||||
{ #category : #reading }
|
||||
ContactBook >> contacts [
|
||||
^ contacts
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
ContactBook >> initialize [
|
||||
super initialize.
|
||||
contacts := OrderedCollection new
|
||||
]
|
||||
|
||||
{ #category : #deleting }
|
||||
ContactBook >> removeContact: aContact [
|
||||
self contacts remove: aContact
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
ContactBook >> size [
|
||||
^ contacts size
|
||||
]
|
||||
40
src/ContactBook/ContactBookTest.class.st
Normal file
40
src/ContactBook/ContactBookTest.class.st
Normal file
@@ -0,0 +1,40 @@
|
||||
Class {
|
||||
#name : #ContactBookTest,
|
||||
#superclass : #TestCase,
|
||||
#instVars : [
|
||||
'blog',
|
||||
'post'
|
||||
],
|
||||
#category : #ContactBook
|
||||
}
|
||||
|
||||
{ #category : #running }
|
||||
ContactBookTest >> setUp [
|
||||
blog := ContactBook new.
|
||||
blog addContact: (Contact newNamed: 'Tudor Girba' email: 'tudor@tudorgirba.com').
|
||||
|
||||
post := Contact newNamed: 'Clara Allende' email: 'clari.allende@gmail.com'
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
ContactBookTest >> testAddContact [
|
||||
blog addContact: post.
|
||||
self assert: blog size equals: 2
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
ContactBookTest >> testContacts [
|
||||
blog addContact: post.
|
||||
self assert: blog contacts size equals: 2
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
ContactBookTest >> testRemoveContact [
|
||||
blog removeContact: blog contacts first.
|
||||
self assert: blog size equals: 0
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
ContactBookTest >> testSize [
|
||||
self assert: blog size equals: 1
|
||||
]
|
||||
26
src/ContactBook/ContactTest.class.st
Normal file
26
src/ContactBook/ContactTest.class.st
Normal file
@@ -0,0 +1,26 @@
|
||||
Class {
|
||||
#name : #ContactTest,
|
||||
#superclass : #TestCase,
|
||||
#category : #ContactBook
|
||||
}
|
||||
|
||||
{ #category : #tests }
|
||||
ContactTest >> testCreation [
|
||||
|
||||
| contact |
|
||||
contact := Contact
|
||||
newNamed: 'Marcus Denker'
|
||||
email: 'marcus.denker@inria.fr'.
|
||||
self assert: contact fullname equals: 'Marcus Denker'.
|
||||
self assert: contact email equals: 'marcus.denker@inria.fr'
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
ContactTest >> testPrinting [
|
||||
|
||||
| contact |
|
||||
contact := Contact
|
||||
newNamed: 'Marcus Denker'
|
||||
email: 'marcus.denker@inria.fr'.
|
||||
self assert: contact asString equals: 'Marcus Denker <marcus.denker@inria.fr>'
|
||||
]
|
||||
@@ -1,7 +1,7 @@
|
||||
Class {
|
||||
#name : #TBHeaderComponent,
|
||||
#superclass : #WAComponent,
|
||||
#category : #'TinyBlog-Components'
|
||||
#category : #ContactBook
|
||||
}
|
||||
|
||||
{ #category : #rendering }
|
||||
@@ -4,14 +4,14 @@ Class {
|
||||
#instVars : [
|
||||
'header'
|
||||
],
|
||||
#category : #'TinyBlog-Components'
|
||||
#category : #ContactBook
|
||||
}
|
||||
|
||||
{ #category : #acccessing }
|
||||
TBScreenComponent >> blog [
|
||||
"Return the current blog. In the future we will ask the
|
||||
session to return the blog of the currently logged in user."
|
||||
^ TBBlog current
|
||||
^ ContactBook current
|
||||
]
|
||||
|
||||
{ #category : #acccessing }
|
||||
62
src/ContactBook/WAContactBook.class.st
Normal file
62
src/ContactBook/WAContactBook.class.st
Normal file
@@ -0,0 +1,62 @@
|
||||
Class {
|
||||
#name : #WAContactBook,
|
||||
#superclass : #WAComponent,
|
||||
#instVars : [
|
||||
'contactBook'
|
||||
],
|
||||
#category : #ContactBook
|
||||
}
|
||||
|
||||
{ #category : #initialization }
|
||||
WAContactBook class >> initialize [
|
||||
WAAdmin register: self asApplicationAt: 'contacts'.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
WAContactBook >> contactBook [
|
||||
^ contactBook ifNil: [ contactBook := ContactBook createDefault ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
WAContactBook >> contacts [
|
||||
^ self contactBook contacts
|
||||
]
|
||||
|
||||
{ #category : #iterating }
|
||||
WAContactBook >> contactsDo: aBlock [
|
||||
self contacts do: aBlock
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
WAContactBook >> renderContact: aContact on: html [
|
||||
html tableRow: [
|
||||
html
|
||||
tableData: aContact fullname;
|
||||
tableData: aContact email ]
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
WAContactBook >> renderContactsOn: html [
|
||||
html table: [
|
||||
html tableHead: [
|
||||
html
|
||||
tableHeading: 'Name';
|
||||
tableHeading: 'Email' ].
|
||||
self contactsDo: [ :contact | self renderContact: contact on: html ] ]
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
WAContactBook >> renderContentOn: html [
|
||||
"Main entry point of the view. Render both a title and the list of contacts."
|
||||
|
||||
html heading
|
||||
level: 1;
|
||||
with: 'My Contact Book'.
|
||||
self renderContactsOn: html
|
||||
]
|
||||
|
||||
{ #category : #updating }
|
||||
WAContactBook >> updateRoot: anHtmlRoot [
|
||||
super updateRoot: anHtmlRoot.
|
||||
anHtmlRoot title: 'Contact Book'
|
||||
]
|
||||
1
src/ContactBook/package.st
Normal file
1
src/ContactBook/package.st
Normal file
@@ -0,0 +1 @@
|
||||
Package { #name : #ContactBook }
|
||||
@@ -1,47 +0,0 @@
|
||||
Class {
|
||||
#name : #TBApplicationRootComponent,
|
||||
#superclass : #WAComponent,
|
||||
#instVars : [
|
||||
'main'
|
||||
],
|
||||
#category : #'TinyBlog-Components'
|
||||
}
|
||||
|
||||
{ #category : #testing }
|
||||
TBApplicationRootComponent class >> canBeRoot [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
TBApplicationRootComponent class >> initialize [
|
||||
"self initialize"
|
||||
| app |
|
||||
app := WAAdmin register: self asApplicationAt: 'TinyBlog'.
|
||||
app
|
||||
addLibrary: JQDeploymentLibrary;
|
||||
addLibrary: JQUiDeploymentLibrary;
|
||||
addLibrary: SBSDeploymentLibrary
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
TBApplicationRootComponent >> children [
|
||||
^ { main }
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
TBApplicationRootComponent >> initialize [
|
||||
super initialize.
|
||||
main := TBScreenComponent new
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
TBApplicationRootComponent >> renderContentOn: html [
|
||||
html render: main
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
TBApplicationRootComponent >> updateRoot: anHtmlRoot [
|
||||
super updateRoot: anHtmlRoot.
|
||||
anHtmlRoot beHtml5.
|
||||
anHtmlRoot title: 'TinyBlog'
|
||||
]
|
||||
@@ -1,108 +0,0 @@
|
||||
Class {
|
||||
#name : #TBBlog,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'posts'
|
||||
],
|
||||
#category : #TinyBlog
|
||||
}
|
||||
|
||||
{ #category : #demos }
|
||||
TBBlog class >> createDemoPosts [
|
||||
"TBBlog createDemoPosts"
|
||||
self current
|
||||
writeBlogPost: ((TBPost title: 'Welcome in TinyBlog' text: 'TinyBlog is a small blog engine made with Pharo.' category: 'TinyBlog') visible: true);
|
||||
writeBlogPost: ((TBPost
|
||||
title: 'Report Pharo Sprint'
|
||||
text: 'Friday, June 12 there was a Pharo sprint / Moose dojo. It was a nice event with more than 15 motivated sprinters. With the help of candies, cakes and chocolate, huge work has been done'
|
||||
category: 'Pharo') visible: true);
|
||||
writeBlogPost: ((TBPost
|
||||
title: 'Brick on top of Bloc - Preview'
|
||||
text: 'We are happy to announce the first preview version of Brick, a new widget set created from scratch on top of Bloc. Brick is being developed primarily by Alex Syrel (together with Alain Plantec, Andrei Chis and myself), and the work is sponsored by ESUG. Brick is part of the Glamorous Toolkit effort and will provide the basis for the new versions of the development tools.'
|
||||
category: 'Pharo') visible: true);
|
||||
writeBlogPost: ((TBPost
|
||||
title: 'The sad story of unclassified blog posts'
|
||||
text: 'So sad that I can read this.') visible: true);
|
||||
writeBlogPost: ((TBPost
|
||||
title: 'Working with Pharo on the Raspberry Pi'
|
||||
text: 'Hardware is getting cheaper and many new small devices like the famous Raspberry Pi provide new computation power that was one once only available on regular desktop computers.'
|
||||
category: 'Pharo') visible: true)
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
TBBlog class >> current [
|
||||
"answer the instance of the TBRepository"
|
||||
^ self selectAll
|
||||
ifNotEmpty: [ :x | x anyOne ]
|
||||
ifEmpty: [ self new save ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
TBBlog class >> initialize [
|
||||
self reset
|
||||
]
|
||||
|
||||
{ #category : #reading }
|
||||
TBBlog class >> initializeVoyageOnMemoryDB [
|
||||
VOMemoryRepository new enableSingleton
|
||||
]
|
||||
|
||||
{ #category : #reading }
|
||||
TBBlog class >> isVoyageRoot [
|
||||
"Indicates that instances of this class are top level documents in noSQL databases"
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
TBBlog class >> reset [
|
||||
self initializeVoyageOnMemoryDB.
|
||||
]
|
||||
|
||||
{ #category : #reading }
|
||||
TBBlog >> allBlogPosts [
|
||||
^ posts
|
||||
]
|
||||
|
||||
{ #category : #reading }
|
||||
TBBlog >> allBlogPostsFromCategory: aCategory [
|
||||
^ posts select: [ :p | p category = aCategory ]
|
||||
]
|
||||
|
||||
{ #category : #reading }
|
||||
TBBlog >> allCategories [
|
||||
^ (self allBlogPosts collect: [ :p | p category ]) asSet
|
||||
]
|
||||
|
||||
{ #category : #reading }
|
||||
TBBlog >> allVisibleBlogPosts [
|
||||
^ posts select: [ :p | p isVisible ]
|
||||
]
|
||||
|
||||
{ #category : #reading }
|
||||
TBBlog >> allVisibleBlogPostsFromCategory: aCategory [
|
||||
^ posts select: [ :p | p category = aCategory and: [ p isVisible ] ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
TBBlog >> initialize [
|
||||
super initialize.
|
||||
posts := OrderedCollection new
|
||||
]
|
||||
|
||||
{ #category : #deleting }
|
||||
TBBlog >> removeAllPosts [
|
||||
posts := OrderedCollection new.
|
||||
self save
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
TBBlog >> size [
|
||||
^ posts size
|
||||
]
|
||||
|
||||
{ #category : #writing }
|
||||
TBBlog >> writeBlogPost: aPost [
|
||||
"Add the blog post in database."
|
||||
self allBlogPosts add: aPost.
|
||||
self save
|
||||
]
|
||||
@@ -1,80 +0,0 @@
|
||||
Class {
|
||||
#name : #TBBlogTest,
|
||||
#superclass : #TestCase,
|
||||
#instVars : [
|
||||
'blog',
|
||||
'post',
|
||||
'first',
|
||||
'previousRepository'
|
||||
],
|
||||
#category : #'TinyBlog-Tests'
|
||||
}
|
||||
|
||||
{ #category : #running }
|
||||
TBBlogTest >> setUp [
|
||||
previousRepository := VORepository current.
|
||||
VORepository setRepository: VOMemoryRepository new.
|
||||
blog := TBBlog current.
|
||||
first := TBPost title: 'A title' text: 'A text' category: 'First Category'.
|
||||
blog writeBlogPost: first.
|
||||
|
||||
post := (TBPost title: 'Another title' text: 'Another text' category: 'Second Category') beVisible
|
||||
]
|
||||
|
||||
{ #category : #running }
|
||||
TBBlogTest >> tearDown [
|
||||
VORepository setRepository: previousRepository
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testAddBlogPost [
|
||||
blog writeBlogPost: post.
|
||||
self assert: blog size equals: 2
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testAllBlogPosts [
|
||||
blog writeBlogPost: post.
|
||||
self assert: blog allBlogPosts size equals: 2
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testAllBlogPostsFromCategory [
|
||||
self assert: (blog allBlogPostsFromCategory: 'First Category')
|
||||
size equals: 1
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testAllCategories [
|
||||
blog writeBlogPost: post.
|
||||
self assert: blog allCategories size equals: 2
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testAllVisibleBlogPosts [
|
||||
blog writeBlogPost: post.
|
||||
self assert: blog allVisibleBlogPosts size equals: 1
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testAllVisibleBlogPostsFromCategory [
|
||||
blog writeBlogPost: post.
|
||||
self assert: (blog allVisibleBlogPostsFromCategory: 'First Category') size equals: 0.
|
||||
self assert: (blog allVisibleBlogPostsFromCategory: 'Second Category') size equals: 1.
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testRemoveAllBlogPosts [
|
||||
blog removeAllPosts.
|
||||
self assert: blog size equals: 0
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testSize [
|
||||
self assert: blog size equals: 1
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBBlogTest >> testUnclassifiedBlogPosts [
|
||||
self assert: (blog allBlogPosts select: [ :p | p isUnclassified ]) size equals: 0
|
||||
]
|
||||
@@ -1,120 +0,0 @@
|
||||
Class {
|
||||
#name : #TBPost,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'title',
|
||||
'text',
|
||||
'date',
|
||||
'category',
|
||||
'visible'
|
||||
],
|
||||
#category : #TinyBlog
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
TBPost class >> title: aTitle text: aText [
|
||||
^ self new
|
||||
title: aTitle;
|
||||
text: aText;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
TBPost class >> title: aTitle text: aText category: aCategory [
|
||||
^ (self title: aTitle text: aText)
|
||||
category: aCategory;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
TBPost class >> unclassifiedTag [
|
||||
^ 'Unclassified'
|
||||
]
|
||||
|
||||
{ #category : #action }
|
||||
TBPost >> beVisible [
|
||||
self visible: true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> category [
|
||||
|
||||
^ category
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> category: anObject [
|
||||
|
||||
category := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> date [
|
||||
|
||||
^ date
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> date: anObject [
|
||||
|
||||
date := anObject
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
TBPost >> initialize [
|
||||
super initialize.
|
||||
self category: self class unclassifiedTag.
|
||||
self date: Date today.
|
||||
self notVisible.
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
TBPost >> isUnclassified [
|
||||
^ self category = self class unclassifiedTag
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
TBPost >> isVisible [
|
||||
^ self visible
|
||||
]
|
||||
|
||||
{ #category : #action }
|
||||
TBPost >> notVisible [
|
||||
self visible: false
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> text [
|
||||
|
||||
^ text
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> text: anObject [
|
||||
|
||||
text := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> title [
|
||||
|
||||
^ title
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> title: anObject [
|
||||
|
||||
title := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> visible [
|
||||
|
||||
^ visible
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
TBPost >> visible: anObject [
|
||||
|
||||
visible := anObject
|
||||
]
|
||||
@@ -1,29 +0,0 @@
|
||||
Class {
|
||||
#name : #TBPostTest,
|
||||
#superclass : #TestCase,
|
||||
#category : #'TinyBlog-Tests'
|
||||
}
|
||||
|
||||
{ #category : #tests }
|
||||
TBPostTest >> testPostIsCreatedCorrectly [
|
||||
|
||||
| post |
|
||||
post := TBPost
|
||||
title: 'Welcome to TinyBlog'
|
||||
text: 'TinyBlog is a small blog engine made with Pharo.'
|
||||
category: 'TinyBlog'.
|
||||
self assert: post title equals: 'Welcome to TinyBlog'.
|
||||
self assert: post text equals: 'TinyBlog is a small blog engine made with Pharo.'.
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
TBPostTest >> testWithoutCategoryIsUnclassified [
|
||||
|
||||
| post |
|
||||
post := TBPost
|
||||
title: 'Welcome to TinyBlog'
|
||||
text: 'TinyBlog is a small blog engine made with Pharo.'.
|
||||
self assert: post title equals: 'Welcome to TinyBlog'.
|
||||
self assert: post isUnclassified.
|
||||
self deny: post isVisible
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
Package { #name : #TinyBlog }
|
||||
Reference in New Issue
Block a user