SlideShare a Scribd company logo
Noury	Bouraqadi	&	Dave	Mason	
http://pharojs.org	
Tutorial

Pharo-Based TDD 

for Javascript Apps
Run	on		Javascript	
+	
Develop	in	Pharo		
=
Tools	
+	
Framework	
=	
MIT	
License
Why	
•  Develop	in	Smalltalk	all	the	time	J	
•  Portability	
•  Front-end/standalone	
•  Reuse	existing	JS	libraries	
•  Run-time	Speed	
?
Javascript	0%		 100%	
Development	 Production	
100%	 Pharo	 0%	
Develop	in	Pharo,	Run	on		Javascript
Javascript	0%		 100%	
Smalltalk	classes	
100%	 Pharo	 0%	
Develop	in	Pharo,	Run	on		Javascript		
Set	of	classes	+	
entry	point	class
Javascript	0%		 100%	
Convert	Smalltalk	to	JS	
100%	 Pharo	 0%	
Develop	in	Pharo,	Run	on		Javascript		
Only	classes	reachable	
from	the		
entry	point	class
1.	Write	Tests	
3.	Export	to	JS	
2.	Pass	the	tests	
Lifecycle	with	
Javascript	0%		 100%	
100%	 Pharo	 0%
Case	Study:	TDD	of	a	Physics	Simulation	
•  Reuse	an	existing	JS	Library	
•  Testing	hybrid	app	=	Pharo	+	Javascript	
•  Link	Pharo	code	to	JS	objects	including	DOM	
•  Pushing	to	production
Backlog	
•  At	start	up	3	bodies	
è 1	floor	
è 2	falling	rectangles	
•  "Add	xxx"	buttons			
è	Adds	a	body	
•  "Reset"	button		
è	Removes	all	bodies
Write	Tests	100%	Pharo	&	0%	JS		
PjWebAppTestCase	subclass:	#PhysicsSimTest	
	instanceVariableNames:	''	
	classVariableNames:	''	
	package:	'ESUG2018'
Write	Tests	100%	Pharo	&	0%	JS		
PjWebAppTestCase	subclass:	#PhysicsSimTest	
	instanceVariableNames:	''	
	classVariableNames:	''	
	package:	'ESUG2018'	
App	should	
run	on	a	web	
browser
Running	the	Tests	~50%	Pharo	&	~50%	JS	
app	
Controller	
engine
Running	the	Tests	~50%	Pharo	&	~50%	JS	
PhysicsSimTest>>testAppInitialSetup	
	self	assert:	app	bodies	size	equals:	3.	
Body	1	
JS	Object	
Body	2	
JS	Object	
Body	3	
JS	Object
Running	the	Tests	~50%	Pharo	&	~50%	JS	
PhysicsSimTest>>testAppInitialSetup	
	self	assert:	app	bodies	size	equals:	3.	
Instance	of	the	
entry	point	class	
Pharo	Object
Running	the	Tests	~50%	Pharo	&	~50%	JS	
Missing	
entry	point	class	
appClass	subclassResponsibility
Defining	the	Entry	Point	Class	
	
PjFileBasedWebApp	subclass:	#PhysicsSim	
	instanceVariableNames:	'engine'	
	classVariableNames:	''	
	package:	'ESUG2018'	
We	rely	on	an	
external	HTML	file
Test	References	Entry	Point	Class	
PhysicsSimTest	class>>appClass	
	^	PhysicsSim	
Entry	point	class
Test	Requests	App	Folder
Test	Requests	App	Folder	
Folder	where	
HTML	+	other	files	
are	located
HTML	File	=	App's	View	
...	
<button	id="resetButton"	class="green">Reset</button>	
<div	id="simulationView"></div>	
...	
<script	src="js/matter.js"></script>	
<script	src="index.js"></script>	
...	
Third-party	
JS	Library
HTML	File	=	App's	View	
...	
<button	id="resetButton"	class="green">Reset</button>	
<div	id="simulationView"></div>	
...	
<script	src="js/matter.js"></script>	
<script	src="js/index.js"></script>	
...	
Link	to	JS	Code	
Generated	by	
PharoJS
HTML	File	=	App's	View	
...	
<button	id="resetButton"	class="green">Reset</button>	
<div	id="simulationView"></div>	
...	
<script	src="js/matter.js"></script>	
<script	src="js/index.js"></script>	
...	
No	Behavior!
HTML	File	=	App's	View	
...	
<button	id="resetButton"	class="green">Reset</button>	
<div	id="simulationView"></div>	
...	
<script	src="js/matter.js"></script>	
<script	src="js/index.js"></script>	
...	
No	Behavior!	
ID	=	to	attach	
Pharo	code
Rerun	Tests	
PharoJS	Opens	
HTML	file	in	a	
web	browser
Rerun	Tests	
PharoJS	Opens	
HTML	file	in	a	
web	browser	
No	
Simulation!
Rerun	Tests
Fixing	the	App	
PhysicsSim>>initialize	
	super	initialize.	
	self	createAndStartEngine.	
	self	setupAndStartRendering.	
	
PhysicsSim>>bodies	
	^	engine	world	bodies	
	
	
JS	Doc/Examples	 Pharo	Code
Fixing	the	App	
PhysicsSim>>matterJsRoot	
	^	window	Matter	
	
PhysicsSim>>createAndStartEngine	
	|	runner	|	
	engine	:=	self	matterJsRoot	Engine	create.	
	runner	:=	self	matterJsRoot	Runner	create.	
	self	matterJsRoot	Runner	run:	runner	with:	engine	
Proxy	to	
Javascript	global
Fixing	the	App	
PhysicsSim>>matterJsRoot	
	^	window	Matter	
	
PhysicsSim>>createAndStartEngine	
	|	runner	|	
	engine	:=	self	matterJsRoot	Engine	create.	
	runner	:=	self	matterJsRoot	Runner	create.	
	self	matterJsRoot	Runner	run:	runner	with:	engine	
PharoJS	generated	
accessor	to	JS	
object	property
Fixing	the	App	
PhysicsSim>>matterJsRoot	
	^	window	Matter	
	
PhysicsSim>>createAndStartEngine	
	|	runner	|	
	engine	:=	self	matterJsRoot	Engine	create.	
	runner	:=	self	matterJsRoot	Runner	create.	
	self	matterJsRoot	Runner	run:	runner	with:	engine	
Calling	JS	method	
create()
Fixing	the	App	
PhysicsSim>>matterJsRoot	
	^	window	Matter	
	
PhysicsSim>>createAndStartEngine	
	|	runner	|	
	engine	:=	self	matterJsRoot	Engine	create.	
	runner	:=	self	matterJsRoot	Runner	create.	
	self	matterJsRoot	Runner	run:	runner	with:	engine	
Calling	JS	method	
run(runner,	engine)
Fixing	the	App	
PhysicsSim>>setupAndStartRendering	
|	render	simulationView	|	
simulationView	:=	self	elementAt:	#simulationView.	
render	:=	self	matterJsRoot	Render	create:		
	 	{#element	->	simulationView.	
	 	#engine	->	engine.	
	 	#options	->	{#width	->	800.	
	 	 	 	 	#height	->	600.	
	 	 	 	 	#wireframes	->	false.	
	 	 	 	 	#background	->	'transparent'}}	asJsObject.	
self	matterJsRoot	Render	run:	render
Fixing	the	App	
PhysicsSim>>setupAndStartRendering	
|	render	simulationView	|	
simulationView	:=	self	elementAt:	#simulationView.	
render	:=	self	matterJsRoot	Render	create:		
	 	{#element	->	simulationView.	
	 	#engine	->	engine.	
	 	#options	->	{#width	->	800.	
	 	 	 	 	#height	->	600.	
	 	 	 	 	#wireframes	->	false.	
	 	 	 	 	#background	->	'transparent'}}	asJsObject.	
self	matterJsRoot	Render	run:	render	
Finds	the	DOM	element	
with	ID	"SimulationView"	
HTML	
...	
<div	id="simulationView"></div>	
...
Fixing	the	App	
PhysicsSim>>setupAndStartRendering	
|	render	simulationView	|	
simulationView	:=	self	elementAt:	#simulationView.	
render	:=	self	matterJsRoot	Render	create:		
	 	{#element	->	simulationView.	
	 	#engine	->	engine.	
	 	#options	->	{#width	->	800.	
	 	 	 	 	#height	->	600.	
	 	 	 	 	#wireframes	->	false.	
	 	 	 	 	#background	->	'transparent'}}	asJsObject.	
self	matterJsRoot	Render	run:	render	
Create	a	JS	Object	
from	a	Pharo	
Dictionary
Defining	Literal	JS	Objects	in	Pharo	
{#element	->	simulationView.	
#engine	->	engine.	
#options	->	{	
	#width	->	800.	
	#height	->	600.	
	#wireframes	->	false.	
	#background	->	'transparent'}	
}	asJsObject.	
JS	Doc/Examples	 Pharo	Code	
{element	:	simulationView.	
engine	:engine.	
options	:	{	
	width	:	800.	
	height	:	600.	
	wireframes	:	false.	
	background	:	'transparent'}	
}	
Javascript	code		 Pharo	equivalent
Rerun	Tests
Fixing	the	App	
PhysicsSim>>initialize	
	super	initialize.	
	self	createAndStartEngine.	
	self	setupAndStartRendering.	
	self	addInitialBodies
Bodies.rectangle(	
	400,		
	610,		
	810,		
	60,		
	{	isStatic:	true	});	
Creating	MatterJS	Bodies	
	
	
self	matterJsRoot	Bodies		
	rectangle:	400	
	y:	610		
	width:	810	
	height:	60		
	options:	{	
	 	#isStatic	->	true}	asJsObject.	
JS	Doc/Examples	 Pharo	Code	
Javascript	code		 Pharo	equivalent
1st	Test	Passes!
More	features	=	Button	Handling
Reset	=	Delete	Mobile	Bodies
HTML	ID	for	Linking	with	Pharo	
HTML	
...	
<button	id="resetButton">Reset</button>	
...
Write	Tests	for	Reset	Button	
PhysicsSimTest>>testResetDeleteMobileBodiesOnly	
	self	clickElementById:	#resetButton.	
	self	assert:	app	bodies	size	equals:	1.	
HTML	
...	
<button	id="resetButton">Reset</button>	
...
Write	Tests	for	Reset	Button	
PhysicsSimTest>>testResetDeleteMobileBodiesOnly	
	self	clickElementById:	#resetButton.	
	self	assert:	app	bodies	size	equals:	1.	
HTML	
...	
<button	id="resetButton">Reset</button>	
...	
Pharo	triggers	event	
on	DOM	object!
Test	Fails
Add	Behavior	to	HTML	Button	
PhysicsSim>>initialize	
	...	
	self	onClick:	#resetButton		
	 	do:	[	self	matterJsRoot	World		
	 	 	 	clear:	engine	world		
	 	 	 	keepStatic:	true]
Add	Behavior	to	HTML	Button	
PhysicsSim>>initialize	
	...	
	self	onClick:	#resetButton		
	 	do:	[	self	matterJsRoot	World		
	 	 	 	clear:	engine	world		
	 	 	 	keepStatic:	true]	
HTML	ID
Add	Behavior	to	HTML	Button	
PhysicsSim>>initialize	
	...	
	self	onClick:	#resetButton	
	 	do:	[	self	matterJsRoot	World		
	 	 	 	clear:	engine	world		
	 	 	 	keepStatic:	true]	
Pharo	Block	
Calling		
MatterJS	Library
Add	Behavior	to	HTML	Button	
Value		
Pharo	Block	
Click	on		
HTML	Button
Lifecycle	with	
Javascript	0%		 100%	
100%	 Pharo	 0%	
3.	Export	to	JS	
1.	Write	Tests	
2.	Pass	the	tests
Export	App	for	Production	
100%	Javascript
Export	App	for	Production	
100%	Javascript
Export	App	for	Production	
100%	Javascript
Exported	JS	file
Exported	JS	file	
...	
<script	src="js/matter.js"></script>	
<script	src="js/index.js"></script>	
...
http://pharojs.org/Demo/MatterJsDemo/index.html
Beyond	Research!
Open	Source	for	the	Real	World	
Pharo	Tradition!
nootrix.com	
Farmers Market
nootrix.com	
GPS	
Navigation	
Zoomable	
Map	
Update	
Markers
What	Next?	
•  Better	support	for	mobile	apps	
	
•  Migrate	to	Pharo	7	
•  Improve	Code	Extraction	
•  Middleware	for	hybrid	apps	
This	
afternoon!
Learn	more	about	PharoJS	
•  Web:	http://pharojs.org	
– FAQ	+	...	
– Thanks	ESUG	for	the	support	
•  Slack:	https://pharojs.slack.com/	
– Discussions	
•  Twitter:	https://twitter.com/pharojs	
– News	
– Subscription	to	PharoJS	Slack
Noury	Bouraqadi	&	Dave	Mason	
Develop	in	Pharo	
Run	on		Javascript	
http://pharojs.org

More Related Content

PDF
Bloc for Pharo: Current State and Future Perspective
PDF
Pharo Virtual Machine: News from the Front
PDF
Pharo 10 and beyond
PDF
Application Development with Pharo
PDF
Design Principles for a High-Performance Smalltalk
PDF
How Fast is AI in Pharo? Benchmarking Linear Regression
PPTX
Jakarta EE Test Strategies (2022)
PDF
Code Refactoring
Bloc for Pharo: Current State and Future Perspective
Pharo Virtual Machine: News from the Front
Pharo 10 and beyond
Application Development with Pharo
Design Principles for a High-Performance Smalltalk
How Fast is AI in Pharo? Benchmarking Linear Regression
Jakarta EE Test Strategies (2022)
Code Refactoring

What's hot (20)

PDF
Build and release iOS apps using Fastlane tools
PDF
Solid Principles & Design patterns with PHP examples
PDF
Applications in Pharo
ODP
Spring cloud for microservices architecture
PPTX
Testing Principles
PDF
Training Webinar: Fitting OutSystems applications into Enterprise Architecture
PDF
Python testing using mock and pytest
PPTX
Python Programming Draft PPT.pptx
PDF
Client Side Monitoring With Prometheus
PPT
24 lecture origin_of_species
PPTX
Postman Collection Format v2.0 (pre-draft)
PDF
Training Webinar: Top front-end techniques for OutSystems
PPTX
Kivy report
PDF
API for Beginners
PDF
apidays Paris 2022 - Generating APIs from business models, Frederic Fontanet,...
PPTX
Using AWS Well Architectured Framework for Software Architecture Evaluations ...
PDF
PharoJS: Hijack the JavaScript Ecosystem
PPTX
"Introduction to JMeter" @ CPTM 3rd Session
PDF
Designing Mobile Experiences
PDF
Postman: An Introduction for Testers
Build and release iOS apps using Fastlane tools
Solid Principles & Design patterns with PHP examples
Applications in Pharo
Spring cloud for microservices architecture
Testing Principles
Training Webinar: Fitting OutSystems applications into Enterprise Architecture
Python testing using mock and pytest
Python Programming Draft PPT.pptx
Client Side Monitoring With Prometheus
24 lecture origin_of_species
Postman Collection Format v2.0 (pre-draft)
Training Webinar: Top front-end techniques for OutSystems
Kivy report
API for Beginners
apidays Paris 2022 - Generating APIs from business models, Frederic Fontanet,...
Using AWS Well Architectured Framework for Software Architecture Evaluations ...
PharoJS: Hijack the JavaScript Ecosystem
"Introduction to JMeter" @ CPTM 3rd Session
Designing Mobile Experiences
Postman: An Introduction for Testers
Ad

Similar to PharoJS: Pharo-Based TDD for Javascript Applications (20)

PDF
Pharo JS
PDF
PharoJS
PDF
PharoJS - Zürich Smalltalk Group Meetup November 2023
PDF
Pharo
PDF
Getting Started with Selenium
PPTX
00 JavaScript Part 1 Course - Introduction
PPTX
Le Tour de xUnit
PDF
New types of tests for Java projects
PPTX
Xray for Jira - How to automate your QA process
PDF
New types of tests for Java projects
PDF
Behat bdd training (php) course slides pdf
PPTX
Bccon use notes objects in memory and other useful
PDF
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
PDF
How To Use Selenium Successfully (Java Edition)
PDF
Foundation selenium java
PDF
First-class undefined classes for Pharo
PDF
First-Class Undefined Classes for Pharo, From Alternative Designs to a Unifie...
PPTX
How to crack java script certification
PDF
ITFT - Java Coding
PDF
Leveling Up With Unit Testing - LonghornPHP 2022
Pharo JS
PharoJS
PharoJS - Zürich Smalltalk Group Meetup November 2023
Pharo
Getting Started with Selenium
00 JavaScript Part 1 Course - Introduction
Le Tour de xUnit
New types of tests for Java projects
Xray for Jira - How to automate your QA process
New types of tests for Java projects
Behat bdd training (php) course slides pdf
Bccon use notes objects in memory and other useful
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
How To Use Selenium Successfully (Java Edition)
Foundation selenium java
First-class undefined classes for Pharo
First-Class Undefined Classes for Pharo, From Alternative Designs to a Unifie...
How to crack java script certification
ITFT - Java Coding
Leveling Up With Unit Testing - LonghornPHP 2022
Ad

More from ESUG (20)

PDF
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
PDF
Micromaid: A simple Mermaid-like chart generator for Pharo
PDF
Directing Generative AI for Pharo Documentation
PDF
Even Lighter Than Lightweiht: Augmenting Type Inference with Primitive Heuris...
PDF
Composing and Performing Electronic Music on-the-Fly with Pharo and Coypu
PDF
Gamifying Agent-Based Models in Cormas: Towards the Playable Architecture for...
PDF
Analysing Python Machine Learning Notebooks with Moose
PDF
FASTTypeScript metamodel generation using FAST traits and TreeSitter project
PDF
Migrating Katalon Studio Tests to Playwright with Model Driven Engineering
PDF
Package-Aware Approach for Repository-Level Code Completion in Pharo
PDF
Evaluating Benchmark Quality: a Mutation-Testing- Based Methodology
PDF
An Analysis of Inline Method Refactoring
PDF
Identification of unnecessary object allocations using static escape analysis
PDF
Control flow-sensitive optimizations In the Druid Meta-Compiler
PDF
Clean Blocks (IWST 2025, Gdansk, Poland)
PDF
Encoding for Objects Matters (IWST 2025)
PDF
Challenges of Transpiling Smalltalk to JavaScript
PDF
Immersive experiences: what Pharo users do!
PDF
ChatPharo: an Open Architecture for Understanding How to Talk Live to LLMs
PDF
Cavrois - an Organic Window Management (ESUG 2025)
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
Micromaid: A simple Mermaid-like chart generator for Pharo
Directing Generative AI for Pharo Documentation
Even Lighter Than Lightweiht: Augmenting Type Inference with Primitive Heuris...
Composing and Performing Electronic Music on-the-Fly with Pharo and Coypu
Gamifying Agent-Based Models in Cormas: Towards the Playable Architecture for...
Analysing Python Machine Learning Notebooks with Moose
FASTTypeScript metamodel generation using FAST traits and TreeSitter project
Migrating Katalon Studio Tests to Playwright with Model Driven Engineering
Package-Aware Approach for Repository-Level Code Completion in Pharo
Evaluating Benchmark Quality: a Mutation-Testing- Based Methodology
An Analysis of Inline Method Refactoring
Identification of unnecessary object allocations using static escape analysis
Control flow-sensitive optimizations In the Druid Meta-Compiler
Clean Blocks (IWST 2025, Gdansk, Poland)
Encoding for Objects Matters (IWST 2025)
Challenges of Transpiling Smalltalk to JavaScript
Immersive experiences: what Pharo users do!
ChatPharo: an Open Architecture for Understanding How to Talk Live to LLMs
Cavrois - an Organic Window Management (ESUG 2025)

Recently uploaded (20)

PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Unlocking AI with Model Context Protocol (MCP)
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Electronic commerce courselecture one. Pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PPTX
Big Data Technologies - Introduction.pptx
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Machine learning based COVID-19 study performance prediction
PDF
cuic standard and advanced reporting.pdf
PDF
Empathic Computing: Creating Shared Understanding
Spectral efficient network and resource selection model in 5G networks
Unlocking AI with Model Context Protocol (MCP)
The AUB Centre for AI in Media Proposal.docx
Per capita expenditure prediction using model stacking based on satellite ima...
Review of recent advances in non-invasive hemoglobin estimation
Dropbox Q2 2025 Financial Results & Investor Presentation
Electronic commerce courselecture one. Pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
NewMind AI Weekly Chronicles - August'25-Week II
Big Data Technologies - Introduction.pptx
MIND Revenue Release Quarter 2 2025 Press Release
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Machine learning based COVID-19 study performance prediction
cuic standard and advanced reporting.pdf
Empathic Computing: Creating Shared Understanding

PharoJS: Pharo-Based TDD for Javascript Applications