Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PharoJS: Pharo-Based TDD for Javascript Applications

503 views

Published on

Title: PharoJS: Pharo-Based TDD for Javascript Applications


First Name: Noury , Dave
Last Name: Bouraqadi , Mason
Email: noury.bouraqadi@imt-lille-douai.fr , dmason@ryerson.ca
Title: PharoJS: Pharo-Based TDD for Javascript Applications

Abstract:
This talk is an update on PharoJS (http://pharojs.org). It covers the current status of the PharoJS development process, as well as its tools.
Through an example, we will describe how to use PharoJS, and how it supports TDD, starting with a Pharo code, and ultimately compiling it to Javascript that runs on a JS interpreter (Web browser, NodeJS...).
The talk will also give a glimpse of some recent applications developed using PharoJS, and draw a roadmap for the future of PharoJS.

Bio:
Noury Bouraqadi is a full professor in Software Engineering and Robotics at IMT Lille Douai (France).
His research aims at easing development of complex software using dynamic languages, in the context of distributed systems.
He specifically focuses on mobile autonomous robots and multi-robot systems.
More at: *http://car.imt-lille-douai.fr/noury*

Dave Mason is a full professor at Ryerson University (Canada).
His is interested in:
- "Programming for the rest of us" - a programming language/environment to make programming - particularly of dynamic or large datasets - accessible to the non-programmers of the world.
- up-front optimizing Java compiler called OptiJava
- issues relating to software reliability engineering, particularly Probabilistic Program Execution using Smalltalk,
- programming languages, particularly pure object-oriented languages like Smalltalk, Self and Ruby and mostly-functional languages like Scheme and Clojure,
More at: *http://sarg.ryerson.ca/dmason/*

Published in: Technology
  • Be the first to comment

PharoJS: Pharo-Based TDD for Javascript Applications

  1. 1. Noury Bouraqadi & Dave Mason http://pharojs.org Tutorial
 Pharo-Based TDD 
 for Javascript Apps
  2. 2. Run on Javascript + Develop in Pharo =
  3. 3. Tools + Framework = MIT License
  4. 4. Why •  Develop in Smalltalk all the time J •  Portability •  Front-end/standalone •  Reuse existing JS libraries •  Run-time Speed ?
  5. 5. Javascript 0% 100% Development Production 100% Pharo 0% Develop in Pharo, Run on Javascript
  6. 6. Javascript 0% 100% Smalltalk classes 100% Pharo 0% Develop in Pharo, Run on Javascript Set of classes + entry point class
  7. 7. Javascript 0% 100% Convert Smalltalk to JS 100% Pharo 0% Develop in Pharo, Run on Javascript Only classes reachable from the entry point class
  8. 8. 1. Write Tests 3. Export to JS 2. Pass the tests Lifecycle with Javascript 0% 100% 100% Pharo 0%
  9. 9. 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
  10. 10. Backlog •  At start up 3 bodies è 1 floor è 2 falling rectangles •  "Add xxx" buttons è Adds a body •  "Reset" button è Removes all bodies
  11. 11. Write Tests 100% Pharo & 0% JS PjWebAppTestCase subclass: #PhysicsSimTest instanceVariableNames: '' classVariableNames: '' package: 'ESUG2018'
  12. 12. Write Tests 100% Pharo & 0% JS PjWebAppTestCase subclass: #PhysicsSimTest instanceVariableNames: '' classVariableNames: '' package: 'ESUG2018' App should run on a web browser
  13. 13. Running the Tests ~50% Pharo & ~50% JS app Controller engine
  14. 14. 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
  15. 15. Running the Tests ~50% Pharo & ~50% JS PhysicsSimTest>>testAppInitialSetup self assert: app bodies size equals: 3. Instance of the entry point class Pharo Object
  16. 16. Running the Tests ~50% Pharo & ~50% JS Missing entry point class appClass subclassResponsibility
  17. 17. Defining the Entry Point Class PjFileBasedWebApp subclass: #PhysicsSim instanceVariableNames: 'engine' classVariableNames: '' package: 'ESUG2018' We rely on an external HTML file
  18. 18. Test References Entry Point Class PhysicsSimTest class>>appClass ^ PhysicsSim Entry point class
  19. 19. Test Requests App Folder
  20. 20. Test Requests App Folder Folder where HTML + other files are located
  21. 21. 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
  22. 22. 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
  23. 23. 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!
  24. 24. 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
  25. 25. Rerun Tests PharoJS Opens HTML file in a web browser
  26. 26. Rerun Tests PharoJS Opens HTML file in a web browser No Simulation!
  27. 27. Rerun Tests
  28. 28. Fixing the App PhysicsSim>>initialize super initialize. self createAndStartEngine. self setupAndStartRendering. PhysicsSim>>bodies ^ engine world bodies JS Doc/Examples Pharo Code
  29. 29. 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
  30. 30. 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
  31. 31. 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()
  32. 32. 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)
  33. 33. 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
  34. 34. 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> ...
  35. 35. 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
  36. 36. 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
  37. 37. Rerun Tests
  38. 38. Fixing the App PhysicsSim>>initialize super initialize. self createAndStartEngine. self setupAndStartRendering. self addInitialBodies
  39. 39. 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
  40. 40. 1st Test Passes!
  41. 41. More features = Button Handling
  42. 42. Reset = Delete Mobile Bodies
  43. 43. HTML ID for Linking with Pharo HTML ... <button id="resetButton">Reset</button> ...
  44. 44. Write Tests for Reset Button PhysicsSimTest>>testResetDeleteMobileBodiesOnly self clickElementById: #resetButton. self assert: app bodies size equals: 1. HTML ... <button id="resetButton">Reset</button> ...
  45. 45. 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!
  46. 46. Test Fails
  47. 47. Add Behavior to HTML Button PhysicsSim>>initialize ... self onClick: #resetButton do: [ self matterJsRoot World clear: engine world keepStatic: true]
  48. 48. Add Behavior to HTML Button PhysicsSim>>initialize ... self onClick: #resetButton do: [ self matterJsRoot World clear: engine world keepStatic: true] HTML ID
  49. 49. Add Behavior to HTML Button PhysicsSim>>initialize ... self onClick: #resetButton do: [ self matterJsRoot World clear: engine world keepStatic: true] Pharo Block Calling MatterJS Library
  50. 50. Add Behavior to HTML Button Value Pharo Block Click on HTML Button
  51. 51. Lifecycle with Javascript 0% 100% 100% Pharo 0% 3. Export to JS 1. Write Tests 2. Pass the tests
  52. 52. Export App for Production 100% Javascript
  53. 53. Export App for Production 100% Javascript
  54. 54. Export App for Production 100% Javascript
  55. 55. Exported JS file
  56. 56. Exported JS file ... <script src="js/matter.js"></script> <script src="js/index.js"></script> ...
  57. 57. http://pharojs.org/Demo/MatterJsDemo/index.html
  58. 58. Beyond Research!
  59. 59. Open Source for the Real World Pharo Tradition!
  60. 60. nootrix.com Farmers Market
  61. 61. nootrix.com GPS Navigation Zoomable Map Update Markers
  62. 62. What Next? •  Better support for mobile apps •  Migrate to Pharo 7 •  Improve Code Extraction •  Middleware for hybrid apps This afternoon!
  63. 63. 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
  64. 64. Noury Bouraqadi & Dave Mason Develop in Pharo Run on Javascript http://pharojs.org

×