[{"data":1,"prerenderedAt":3263},["ShallowReactive",2],{"navigation":3,"\u002Fblog\u002F2015-03-01-unit-tests-with-intern":406,"\u002Fblog\u002F2015-03-01-unit-tests-with-intern-surround":3252},[4,8,39,52,264,310,319,380,397],{"title":5,"path":6,"stem":7},"Notes","\u002Fnotes","1.notes\u002Findex",{"title":9,"path":10,"stem":11,"children":12,"page":30},"Architecture","\u002Fnotes\u002Farchitecture","1.notes\u002Farchitecture",[13,17,31,35],{"title":14,"path":15,"stem":16},"API Management","\u002Fnotes\u002Farchitecture\u002Fapi-management","1.notes\u002Farchitecture\u002Fapi-management",{"title":18,"path":19,"stem":20,"children":21,"page":30},"Data","\u002Fnotes\u002Farchitecture\u002Fdata","1.notes\u002Farchitecture\u002Fdata",[22,26],{"title":23,"path":24,"stem":25},"ERD","\u002Fnotes\u002Farchitecture\u002Fdata\u002Ferd","1.notes\u002Farchitecture\u002Fdata\u002Ferd",{"title":27,"path":28,"stem":29},"SCWD","\u002Fnotes\u002Farchitecture\u002Fdata\u002Fscwd","1.notes\u002Farchitecture\u002Fdata\u002Fscwd",false,{"title":32,"path":33,"stem":34},"Microservices","\u002Fnotes\u002Farchitecture\u002Fmicroservices","1.notes\u002Farchitecture\u002Fmicroservices",{"title":36,"path":37,"stem":38},"OAuth","\u002Fnotes\u002Farchitecture\u002Foauth","1.notes\u002Farchitecture\u002Foauth",{"title":40,"path":41,"stem":42,"children":43,"page":30},"Archive","\u002Fnotes\u002Farchive","1.notes\u002Farchive",[44,48],{"title":45,"path":46,"stem":47},"Google Web Toolkit","\u002Fnotes\u002Farchive\u002Fgwt","1.notes\u002Farchive\u002Fgwt",{"title":49,"path":50,"stem":51},"Jekyll","\u002Fnotes\u002Farchive\u002Fjekyll","1.notes\u002Farchive\u002Fjekyll",{"title":53,"path":54,"stem":55,"children":56,"page":30},"Development","\u002Fnotes\u002Fdevelopment","1.notes\u002Fdevelopment",[57,74,112,149,226,239,260],{"title":58,"icon":30,"path":59,"stem":60,"children":61,"page":30},"IDE","\u002Fnotes\u002Fdevelopment\u002Fide","1.notes\u002Fdevelopment\u002FIDE",[62,66,70],{"title":63,"path":64,"stem":65},"Jetbrains IDE","\u002Fnotes\u002Fdevelopment\u002Fide\u002Fjetbrains","1.notes\u002Fdevelopment\u002FIDE\u002Fjetbrains",{"title":67,"path":68,"stem":69},"NVIM","\u002Fnotes\u002Fdevelopment\u002Fide\u002Fnvim","1.notes\u002Fdevelopment\u002FIDE\u002Fnvim",{"title":71,"path":72,"stem":73},"tmux","\u002Fnotes\u002Fdevelopment\u002Fide\u002Ftmux","1.notes\u002Fdevelopment\u002FIDE\u002Ftmux",{"title":75,"path":76,"stem":77,"children":78,"page":30},"Algo","\u002Fnotes\u002Fdevelopment\u002Falgo","1.notes\u002Fdevelopment\u002Falgo",[79,83,87,91,95],{"title":80,"path":81,"stem":82},"Algorithms","\u002Fnotes\u002Fdevelopment\u002Falgo\u002Falgorithms","1.notes\u002Fdevelopment\u002Falgo\u002Falgorithms",{"title":84,"path":85,"stem":86},"Data Structures","\u002Fnotes\u002Fdevelopment\u002Falgo\u002Fdata_structures","1.notes\u002Fdevelopment\u002Falgo\u002Fdata_structures",{"title":88,"path":89,"stem":90},"Kata","\u002Fnotes\u002Fdevelopment\u002Falgo\u002Fkata","1.notes\u002Fdevelopment\u002Falgo\u002Fkata",{"title":92,"path":93,"stem":94},"O-notation","\u002Fnotes\u002Fdevelopment\u002Falgo\u002Fo-notation","1.notes\u002Fdevelopment\u002Falgo\u002Fo-notation",{"title":96,"path":97,"stem":98,"children":99,"page":30},"Sorting","\u002Fnotes\u002Fdevelopment\u002Falgo\u002Fsorting","1.notes\u002Fdevelopment\u002Falgo\u002Fsorting",[100,104,108],{"title":101,"path":102,"stem":103},"Buble Sort","\u002Fnotes\u002Fdevelopment\u002Falgo\u002Fsorting\u002Fbublesort","1.notes\u002Fdevelopment\u002Falgo\u002Fsorting\u002Fbublesort",{"title":105,"path":106,"stem":107},"Merge Sort","\u002Fnotes\u002Fdevelopment\u002Falgo\u002Fsorting\u002Fmergesort","1.notes\u002Fdevelopment\u002Falgo\u002Fsorting\u002Fmergesort",{"title":109,"path":110,"stem":111},"Quicksort","\u002Fnotes\u002Fdevelopment\u002Falgo\u002Fsorting\u002Fquicksort","1.notes\u002Fdevelopment\u002Falgo\u002Fsorting\u002Fquicksort",{"title":113,"path":114,"stem":115,"children":116,"page":30},"DataStructures","\u002Fnotes\u002Fdevelopment\u002Fdata_structures","1.notes\u002Fdevelopment\u002Fdata_structures",[117,121,125,129,133,137,141,145],{"title":118,"path":119,"stem":120},"ArrayList","\u002Fnotes\u002Fdevelopment\u002Fdata_structures\u002Farray_list","1.notes\u002Fdevelopment\u002Fdata_structures\u002Farray_list",{"title":122,"path":123,"stem":124},"Arrays","\u002Fnotes\u002Fdevelopment\u002Fdata_structures\u002Farrays","1.notes\u002Fdevelopment\u002Fdata_structures\u002Farrays",{"title":126,"path":127,"stem":128},"HashSet","\u002Fnotes\u002Fdevelopment\u002Fdata_structures\u002Fhash_set","1.notes\u002Fdevelopment\u002Fdata_structures\u002Fhash_set",{"title":130,"path":131,"stem":132},"LinkedList","\u002Fnotes\u002Fdevelopment\u002Fdata_structures\u002Flinked_list","1.notes\u002Fdevelopment\u002Fdata_structures\u002Flinked_list",{"title":134,"path":135,"stem":136},"PriorityQueue","\u002Fnotes\u002Fdevelopment\u002Fdata_structures\u002Fpriority_queue","1.notes\u002Fdevelopment\u002Fdata_structures\u002Fpriority_queue",{"title":138,"path":139,"stem":140},"Stack","\u002Fnotes\u002Fdevelopment\u002Fdata_structures\u002Fstack","1.notes\u002Fdevelopment\u002Fdata_structures\u002Fstack",{"title":142,"path":143,"stem":144},"TreeSet","\u002Fnotes\u002Fdevelopment\u002Fdata_structures\u002Ftree_set","1.notes\u002Fdevelopment\u002Fdata_structures\u002Ftree_set",{"title":146,"path":147,"stem":148},"Vector","\u002Fnotes\u002Fdevelopment\u002Fdata_structures\u002Fvector","1.notes\u002Fdevelopment\u002Fdata_structures\u002Fvector",{"title":150,"path":151,"stem":152,"children":153,"page":30},"Java","\u002Fnotes\u002Fdevelopment\u002Fjava","1.notes\u002Fdevelopment\u002Fjava",[154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,214,218,222],{"title":155,"path":156,"stem":157},"Bit Operations","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fbit-operations","1.notes\u002Fdevelopment\u002Fjava\u002Fbit-operations",{"title":159,"path":160,"stem":161},"Cheatsheet","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fcheatsheet","1.notes\u002Fdevelopment\u002Fjava\u002Fcheatsheet",{"title":163,"path":164,"stem":165},"Clean Code","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fclean-code-presentation","1.notes\u002Fdevelopment\u002Fjava\u002Fclean-code-presentation",{"title":167,"path":168,"stem":169},"Java Datasource","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fdata-sources","1.notes\u002Fdevelopment\u002Fjava\u002Fdata-sources",{"title":171,"path":172,"stem":173},"Dependency Injection","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fdependency-injection-presentation","1.notes\u002Fdevelopment\u002Fjava\u002Fdependency-injection-presentation",{"title":175,"path":176,"stem":177},"Java SE","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fjava-standard-edition","1.notes\u002Fdevelopment\u002Fjava\u002Fjava-standard-edition",{"title":179,"path":180,"stem":181},"Java Memory Model","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fjmm","1.notes\u002Fdevelopment\u002Fjava\u002Fjmm",{"title":183,"path":184,"stem":185},"JPA","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fjpa","1.notes\u002Fdevelopment\u002Fjava\u002Fjpa",{"title":187,"path":188,"stem":189},"Keywords","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fkeywords","1.notes\u002Fdevelopment\u002Fjava\u002Fkeywords",{"title":191,"path":192,"stem":193},"Maven","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fmaven","1.notes\u002Fdevelopment\u002Fjava\u002Fmaven",{"title":195,"path":196,"stem":197},"Spring AOP","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fspring-aop-presentation","1.notes\u002Fdevelopment\u002Fjava\u002Fspring-aop-presentation",{"title":199,"path":200,"stem":201},"Spring Boot","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fspring-boot","1.notes\u002Fdevelopment\u002Fjava\u002Fspring-boot",{"title":203,"path":204,"stem":205},"Spring Core","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fspring-core-presentation","1.notes\u002Fdevelopment\u002Fjava\u002Fspring-core-presentation",{"title":207,"path":208,"stem":209},"Spring Data","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fspring-data","1.notes\u002Fdevelopment\u002Fjava\u002Fspring-data",{"title":211,"path":212,"stem":213},"Spring JDBC","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fspring-jdbc","1.notes\u002Fdevelopment\u002Fjava\u002Fspring-jdbc",{"title":215,"path":216,"stem":217},"Spring MVC","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fspring-mvc-presentation","1.notes\u002Fdevelopment\u002Fjava\u002Fspring-mvc-presentation",{"title":219,"path":220,"stem":221},"Spring Security","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Fspring-security","1.notes\u002Fdevelopment\u002Fjava\u002Fspring-security",{"title":223,"path":224,"stem":225},"Testing","\u002Fnotes\u002Fdevelopment\u002Fjava\u002Ftesting","1.notes\u002Fdevelopment\u002Fjava\u002Ftesting",{"title":227,"path":228,"stem":229,"children":230,"page":30},"Js","\u002Fnotes\u002Fdevelopment\u002Fjs","1.notes\u002Fdevelopment\u002Fjs",[231,235],{"title":232,"path":233,"stem":234},"JavaScript","\u002Fnotes\u002Fdevelopment\u002Fjs\u002Fjava-script","1.notes\u002Fdevelopment\u002Fjs\u002Fjava-script",{"title":236,"path":237,"stem":238},"NodeJS","\u002Fnotes\u002Fdevelopment\u002Fjs\u002Fnode-js","1.notes\u002Fdevelopment\u002Fjs\u002Fnode-js",{"title":240,"path":241,"stem":242,"children":243,"page":30},"PowerPlatform","\u002Fnotes\u002Fdevelopment\u002Fpower_platform","1.notes\u002Fdevelopment\u002Fpower_platform",[244,248,252,256],{"title":245,"path":246,"stem":247},"Power Apps","\u002Fnotes\u002Fdevelopment\u002Fpower_platform\u002Fpower-apps","1.notes\u002Fdevelopment\u002Fpower_platform\u002Fpower-apps",{"title":249,"path":250,"stem":251},"Power Automate","\u002Fnotes\u002Fdevelopment\u002Fpower_platform\u002Fpower-automate","1.notes\u002Fdevelopment\u002Fpower_platform\u002Fpower-automate",{"title":253,"path":254,"stem":255},"Power BI","\u002Fnotes\u002Fdevelopment\u002Fpower_platform\u002Fpower-bi","1.notes\u002Fdevelopment\u002Fpower_platform\u002Fpower-bi",{"title":257,"path":258,"stem":259},"Sharepoint","\u002Fnotes\u002Fdevelopment\u002Fpower_platform\u002Fsharepoint","1.notes\u002Fdevelopment\u002Fpower_platform\u002Fsharepoint",{"title":261,"path":262,"stem":263},"Python","\u002Fnotes\u002Fdevelopment\u002Fpython","1.notes\u002Fdevelopment\u002Fpython",{"title":265,"path":266,"stem":267,"children":268,"page":30},"Devops","\u002Fnotes\u002Fdevops","1.notes\u002Fdevops",[269,273,277,281,285,289,293,297,306],{"title":270,"path":271,"stem":272},"Containers","\u002Fnotes\u002Fdevops\u002Fcontainers","1.notes\u002Fdevops\u002Fcontainers",{"title":274,"path":275,"stem":276},"Curl","\u002Fnotes\u002Fdevops\u002Fcurl","1.notes\u002Fdevops\u002Fcurl",{"title":278,"path":279,"stem":280},"GCP","\u002Fnotes\u002Fdevops\u002Fgcp","1.notes\u002Fdevops\u002Fgcp",{"title":282,"path":283,"stem":284},"GIT","\u002Fnotes\u002Fdevops\u002Fgit","1.notes\u002Fdevops\u002Fgit",{"title":286,"path":287,"stem":288},"Jenkins","\u002Fnotes\u002Fdevops\u002Fjenkins","1.notes\u002Fdevops\u002Fjenkins",{"title":290,"path":291,"stem":292},"Kubernetes","\u002Fnotes\u002Fdevops\u002Fkubernetes","1.notes\u002Fdevops\u002Fkubernetes",{"title":294,"path":295,"stem":296},"Linux","\u002Fnotes\u002Fdevops\u002Flinux","1.notes\u002Fdevops\u002Flinux",{"title":298,"path":299,"stem":300,"children":301,"page":30},"Os","\u002Fnotes\u002Fdevops\u002Fos","1.notes\u002Fdevops\u002Fos",[302],{"title":303,"path":304,"stem":305},"MAC OS","\u002Fnotes\u002Fdevops\u002Fos\u002Fmacos","1.notes\u002Fdevops\u002Fos\u002Fmacos",{"title":307,"path":308,"stem":309},"WSL","\u002Fnotes\u002Fdevops\u002Fwsl","1.notes\u002Fdevops\u002Fwsl",{"title":311,"path":312,"stem":313,"children":314,"page":30},"Hardware","\u002Fnotes\u002Fhardware","1.notes\u002Fhardware",[315],{"title":316,"path":317,"stem":318},"Keyboard","\u002Fnotes\u002Fhardware\u002Fkeyboard","1.notes\u002Fhardware\u002Fkeyboard",{"title":320,"path":321,"stem":322,"children":323,"page":30},"Homelab","\u002Fnotes\u002Fhomelab","1.notes\u002Fhomelab",[324,328,337,350],{"title":325,"path":326,"stem":327},"Proxmox","\u002Fnotes\u002Fhomelab\u002F_-proxmox-1","1.notes\u002Fhomelab\u002F_ proxmox 1",{"title":329,"path":330,"stem":331,"children":332,"page":30},"Cloudflare","\u002Fnotes\u002Fhomelab\u002Fcloudflare","1.notes\u002Fhomelab\u002Fcloudflare",[333],{"title":334,"path":335,"stem":336},"Cloudflare Workers","\u002Fnotes\u002Fhomelab\u002Fcloudflare\u002Fworkers","1.notes\u002Fhomelab\u002Fcloudflare\u002Fworkers",{"title":338,"path":339,"stem":340,"children":341,"page":30},"HomeAssistant","\u002Fnotes\u002Fhomelab\u002Fhome_assistant","1.notes\u002Fhomelab\u002Fhome_assistant",[342,346],{"title":343,"path":344,"stem":345},"EspHome debugger","\u002Fnotes\u002Fhomelab\u002Fhome_assistant\u002Fesphome-debugger","1.notes\u002Fhomelab\u002Fhome_assistant\u002Fesphome-debugger",{"title":347,"path":348,"stem":349},"GIT integration","\u002Fnotes\u002Fhomelab\u002Fhome_assistant\u002Fgit-integration","1.notes\u002Fhomelab\u002Fhome_assistant\u002Fgit-integration",{"title":325,"path":351,"stem":352,"children":353},"\u002Fnotes\u002Fhomelab\u002Fproxmox","1.notes\u002Fhomelab\u002Fproxmox",[354,358,362,365,369,373,377],{"title":355,"path":356,"stem":357},"Issue: TASK ERROR: Device \u002Fdev\u002Fdri\u002Fcard1 does not exist","\u002Fnotes\u002Fhomelab\u002Fproxmox\u002Fissue_task_error_device_dev_dri_card1_does-not-exist","1.notes\u002Fhomelab\u002Fproxmox\u002FIssue_TASK_ERROR_device_dev_dri_card1_does not exist",{"title":359,"path":360,"stem":361},"Mount USB Drive To LXC Container","\u002Fnotes\u002Fhomelab\u002Fproxmox\u002Fmount-usb-drive-to-lxc-container","1.notes\u002Fhomelab\u002Fproxmox\u002FMount USB drive to LXC container",{"title":325,"path":363,"stem":364},"\u002Fnotes\u002Fhomelab\u002Fproxmox\u002F_-proxmox","1.notes\u002Fhomelab\u002Fproxmox\u002F_ proxmox",{"title":366,"path":367,"stem":368},"ARR","\u002Fnotes\u002Fhomelab\u002Fproxmox\u002Farr","1.notes\u002Fhomelab\u002Fproxmox\u002Farr",{"title":370,"path":371,"stem":372},"Auto login via SSH from Proxmox UI","\u002Fnotes\u002Fhomelab\u002Fproxmox\u002Fauto_login_via_ssh_from_proxmox_ui","1.notes\u002Fhomelab\u002Fproxmox\u002Fauto_login_via_ssh_from_proxmox_ui",{"title":374,"path":375,"stem":376},"Installation","\u002Fnotes\u002Fhomelab\u002Fproxmox\u002Fdokploy","1.notes\u002Fhomelab\u002Fproxmox\u002Fdokploy",{"title":290,"path":378,"stem":379},"\u002Fnotes\u002Fhomelab\u002Fproxmox\u002Fkubernetes","1.notes\u002Fhomelab\u002Fproxmox\u002Fkubernetes",{"title":381,"path":382,"stem":383,"children":384,"page":30},"Leadership","\u002Fnotes\u002Fleadership","1.notes\u002Fleadership",[385,389,393],{"title":386,"path":387,"stem":388},"Leader Toolbox","\u002Fnotes\u002Fleadership\u002Fleader-toolbox","1.notes\u002Fleadership\u002Fleader-toolbox",{"title":390,"path":391,"stem":392},"Enterprise Project Structure","\u002Fnotes\u002Fleadership\u002Fproject-doc-structure","1.notes\u002Fleadership\u002Fproject-doc-structure",{"title":394,"path":395,"stem":396},"Scrum template","\u002Fnotes\u002Fleadership\u002Fscrum-template","1.notes\u002Fleadership\u002Fscrum-template",{"title":398,"path":399,"stem":400,"children":401,"page":30},"Products","\u002Fnotes\u002Fproducts","1.notes\u002Fproducts",[402],{"title":403,"path":404,"stem":405},"BigQuery","\u002Fnotes\u002Fproducts\u002Fgcp-big-query","1.notes\u002Fproducts\u002Fgcp-big-query",{"id":407,"title":408,"authors":409,"badge":409,"body":410,"date":3243,"description":3244,"extension":3245,"image":409,"meta":3246,"navigation":637,"path":3248,"seo":3249,"stem":3250,"__hash__":3251},"posts\u002F2.blog\u002F2015-03-01-unit-tests-with-intern.md","Testing Node applications with Intern framework",null,{"type":411,"value":412,"toc":3215},"minimark",[413,418,422,425,428,433,436,447,454,539,543,548,554,558,565,571,577,787,797,801,804,809,877,880,886,889,895,902,932,936,939,943,946,952,955,961,965,971,1050,1056,1062,1066,1070,1073,1079,1083,1086,1092,1095,1101,1105,1111,1117,1287,1291,1294,1298,1303,1533,1546,1550,1553,1559,1562,1568,1572,1575,1597,1600,1603,1606,1609,1630,1633,1639,1789,1792,1798,1984,1990,2206,2209,2214,2217,2223,2229,2232,2238,2378,2381,2387,2390,2393,2396,2636,2639,2645,2648,2654,2800,2803,2809,2812,2815,2818,2821,2827,3182,3185,3196,3199,3202,3211],[414,415,417],"h1",{"id":416},"introduction","Introduction",[419,420,421],"p",{},"In JS world, regressions may appear at every change without any warning, so tests are equally important as production code. The same rule applies to every non static typed languages, but let's stay on JS.",[419,423,424],{},"Intern is a complete framework for testing JavaScript Web sites and applications. I will use it to demostrate how to test NodeJS applications using intern framework. First I configure testing infrastructure so we could start writing business logic and testing it.",[419,426,427],{},"#Set up infrastructure",[429,430,432],"h2",{"id":431},"create-node-project","Create Node project",[419,434,435],{},"Create NodeJS project:",[437,438,443],"pre",{"className":439,"code":441,"language":442},[440],"language-text","mkdir intern-unit-tests\ncd intern-unit-tests\n","text",[444,445,441],"code",{"__ignoreMap":446},"",[419,448,449,450,453],{},"Create init ",[444,451,452],{},"package.json",":",[437,455,459],{"className":456,"code":457,"language":458,"meta":446,"style":446},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"name\": \"intern-unit-tests\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\"\n}\n","js",[444,460,461,470,497,518,533],{"__ignoreMap":446},[462,463,466],"span",{"class":464,"line":465},"line",1,[462,467,469],{"class":468},"sMK4o","{\n",[462,471,473,476,480,483,487,489,492,494],{"class":464,"line":472},2,[462,474,475],{"class":468},"  \"",[462,477,479],{"class":478},"sfazB","name",[462,481,482],{"class":468},"\"",[462,484,486],{"class":485},"swJcz",": ",[462,488,482],{"class":468},[462,490,491],{"class":478},"intern-unit-tests",[462,493,482],{"class":468},[462,495,496],{"class":468},",\n",[462,498,500,502,505,507,509,511,514,516],{"class":464,"line":499},3,[462,501,475],{"class":468},[462,503,504],{"class":478},"version",[462,506,482],{"class":468},[462,508,486],{"class":485},[462,510,482],{"class":468},[462,512,513],{"class":478},"1.0.0",[462,515,482],{"class":468},[462,517,496],{"class":468},[462,519,521,523,526,528,530],{"class":464,"line":520},4,[462,522,475],{"class":468},[462,524,525],{"class":478},"description",[462,527,482],{"class":468},[462,529,486],{"class":485},[462,531,532],{"class":468},"\"\"\n",[462,534,536],{"class":464,"line":535},5,[462,537,538],{"class":468},"}\n",[429,540,542],{"id":541},"implementing-rest-endpoint-using-expressjs","Implementing REST endpoint using ExpressJS",[544,545,547],"h3",{"id":546},"install-expressjs","Install ExpressJS:",[437,549,552],{"className":550,"code":551,"language":442},[440],"npm install express --save-dev\n",[444,553,551],{"__ignoreMap":446},[544,555,557],{"id":556},"implement-application-endpoints","Implement application endpoints",[419,559,560,561,564],{},"We will create application code in ",[444,562,563],{},"src"," directory:",[437,566,569],{"className":567,"code":568,"language":442},[440],"mkdir src\n",[444,570,568],{"__ignoreMap":446},[419,572,573,574,453],{},"Create file: ",[444,575,576],{},"src\u002Fapp.js",[437,578,580],{"className":456,"code":579,"language":458,"meta":446,"style":446},"var express = require('express');\nvar app = express();\n\napp.get('\u002Ftest', function (req, res) {\n    console.log('hitting test');\n    res.json({status: 'ok'});\n});\nconsole.log('App is configured');\nmodule.exports = app;\n",[444,581,582,616,633,639,682,705,741,750,773],{"__ignoreMap":446},[462,583,584,588,592,595,599,602,605,608,610,613],{"class":464,"line":465},[462,585,587],{"class":586},"spNyl","var",[462,589,591],{"class":590},"sTEyZ"," express ",[462,593,594],{"class":468},"=",[462,596,598],{"class":597},"s2Zo4"," require",[462,600,601],{"class":590},"(",[462,603,604],{"class":468},"'",[462,606,607],{"class":478},"express",[462,609,604],{"class":468},[462,611,612],{"class":590},")",[462,614,615],{"class":468},";\n",[462,617,618,620,623,625,628,631],{"class":464,"line":472},[462,619,587],{"class":586},[462,621,622],{"class":590}," app ",[462,624,594],{"class":468},[462,626,627],{"class":597}," express",[462,629,630],{"class":590},"()",[462,632,615],{"class":468},[462,634,635],{"class":464,"line":499},[462,636,638],{"emptyLinePlaceholder":637},true,"\n",[462,640,641,644,647,650,652,654,657,659,662,665,668,672,674,677,679],{"class":464,"line":520},[462,642,643],{"class":590},"app",[462,645,646],{"class":468},".",[462,648,649],{"class":597},"get",[462,651,601],{"class":590},[462,653,604],{"class":468},[462,655,656],{"class":478},"\u002Ftest",[462,658,604],{"class":468},[462,660,661],{"class":468},",",[462,663,664],{"class":586}," function",[462,666,667],{"class":468}," (",[462,669,671],{"class":670},"sHdIc","req",[462,673,661],{"class":468},[462,675,676],{"class":670}," res",[462,678,612],{"class":468},[462,680,681],{"class":468}," {\n",[462,683,684,687,689,692,694,696,699,701,703],{"class":464,"line":535},[462,685,686],{"class":590},"    console",[462,688,646],{"class":468},[462,690,691],{"class":597},"log",[462,693,601],{"class":485},[462,695,604],{"class":468},[462,697,698],{"class":478},"hitting test",[462,700,604],{"class":468},[462,702,612],{"class":485},[462,704,615],{"class":468},[462,706,708,711,713,716,718,721,724,726,729,732,734,737,739],{"class":464,"line":707},6,[462,709,710],{"class":590},"    res",[462,712,646],{"class":468},[462,714,715],{"class":597},"json",[462,717,601],{"class":485},[462,719,720],{"class":468},"{",[462,722,723],{"class":485},"status",[462,725,453],{"class":468},[462,727,728],{"class":468}," '",[462,730,731],{"class":478},"ok",[462,733,604],{"class":468},[462,735,736],{"class":468},"}",[462,738,612],{"class":485},[462,740,615],{"class":468},[462,742,744,746,748],{"class":464,"line":743},7,[462,745,736],{"class":468},[462,747,612],{"class":590},[462,749,615],{"class":468},[462,751,753,756,758,760,762,764,767,769,771],{"class":464,"line":752},8,[462,754,755],{"class":590},"console",[462,757,646],{"class":468},[462,759,691],{"class":597},[462,761,601],{"class":590},[462,763,604],{"class":468},[462,765,766],{"class":478},"App is configured",[462,768,604],{"class":468},[462,770,612],{"class":590},[462,772,615],{"class":468},[462,774,776,779,782,785],{"class":464,"line":775},9,[462,777,778],{"class":468},"module.exports",[462,780,781],{"class":468}," =",[462,783,784],{"class":590}," app",[462,786,615],{"class":468},[419,788,789,790,792,793,796],{},"Above application hosts ",[444,791,656],{}," endpoint which returns JSON: ",[444,794,795],{},"{status: 'ok'}"," and logs activity each activity.",[429,798,800],{"id":799},"hosting-application-on-the-server","Hosting application on the server",[419,802,803],{},"To host that application we will need server.",[419,805,573,806,453],{},[444,807,808],{},"src\u002Fserver.js",[437,810,812],{"className":456,"code":811,"language":458,"meta":446,"style":446},"var app = require('.\u002Fapp');\napp.listen(8080);\nconsole.log('Application is running on port 8080');\n",[444,813,814,837,856],{"__ignoreMap":446},[462,815,816,818,820,822,824,826,828,831,833,835],{"class":464,"line":465},[462,817,587],{"class":586},[462,819,622],{"class":590},[462,821,594],{"class":468},[462,823,598],{"class":597},[462,825,601],{"class":590},[462,827,604],{"class":468},[462,829,830],{"class":478},".\u002Fapp",[462,832,604],{"class":468},[462,834,612],{"class":590},[462,836,615],{"class":468},[462,838,839,841,843,846,848,852,854],{"class":464,"line":472},[462,840,643],{"class":590},[462,842,646],{"class":468},[462,844,845],{"class":597},"listen",[462,847,601],{"class":590},[462,849,851],{"class":850},"sbssI","8080",[462,853,612],{"class":590},[462,855,615],{"class":468},[462,857,858,860,862,864,866,868,871,873,875],{"class":464,"line":499},[462,859,755],{"class":590},[462,861,646],{"class":468},[462,863,691],{"class":597},[462,865,601],{"class":590},[462,867,604],{"class":468},[462,869,870],{"class":478},"Application is running on port 8080",[462,872,604],{"class":468},[462,874,612],{"class":590},[462,876,615],{"class":468},[419,878,879],{},"Lets run server:",[437,881,884],{"className":882,"code":883,"language":442},[440],"node src\u002Fserver\n",[444,885,883],{"__ignoreMap":446},[419,887,888],{},"Console output should display:",[437,890,893],{"className":891,"code":892,"language":442},[440],"App is configured\nApplication is running on port 8080\nhitting test\n",[444,894,892],{"__ignoreMap":446},[419,896,897,898,901],{},"And when hitting: ",[444,899,900],{},"http:\u002F\u002Flocalhost:8080\u002Ftest"," in the browser you should get:",[437,903,905],{"className":456,"code":904,"language":458,"meta":446,"style":446},"{\n\"status\": \"ok\"\n}\n",[444,906,907,911,928],{"__ignoreMap":446},[462,908,909],{"class":464,"line":465},[462,910,469],{"class":468},[462,912,913,915,917,919,921,923,925],{"class":464,"line":472},[462,914,482],{"class":468},[462,916,723],{"class":478},[462,918,482],{"class":468},[462,920,486],{"class":485},[462,922,482],{"class":468},[462,924,731],{"class":478},[462,926,927],{"class":468},"\"\n",[462,929,930],{"class":464,"line":499},[462,931,538],{"class":468},[429,933,935],{"id":934},"install-and-initialize-grunt","Install and initialize Grunt",[419,937,938],{},"Before we start writing tests we need some test executor. For this purpose I use Grunt.",[544,940,942],{"id":941},"installing-grunt-dependencies","Installing Grunt dependencies",[419,944,945],{},"If you never used Grunt before you must first install it globally:",[437,947,950],{"className":948,"code":949,"language":442},[440],"npm install -g grunt\n",[444,951,949],{"__ignoreMap":446},[419,953,954],{},"Install Grunt locally:",[437,956,959],{"className":957,"code":958,"language":442},[440],"npm install grunt --save-dev\n",[444,960,958],{"__ignoreMap":446},[544,962,964],{"id":963},"grunt-configuration","Grunt configuration",[419,966,967,968,453],{},"Configure grunt, create ",[444,969,970],{},"Gruntfile.js",[437,972,974],{"className":456,"code":973,"language":458,"meta":446,"style":446},"module.exports = function (grunt) {\n    grunt.initConfig({\n    });\n\n    grunt.registerTask('default', []);\n};\n",[444,975,976,993,1007,1016,1020,1045],{"__ignoreMap":446},[462,977,978,980,982,984,986,989,991],{"class":464,"line":465},[462,979,778],{"class":468},[462,981,781],{"class":468},[462,983,664],{"class":586},[462,985,667],{"class":468},[462,987,988],{"class":670},"grunt",[462,990,612],{"class":468},[462,992,681],{"class":468},[462,994,995,998,1000,1003,1005],{"class":464,"line":472},[462,996,997],{"class":590},"    grunt",[462,999,646],{"class":468},[462,1001,1002],{"class":597},"initConfig",[462,1004,601],{"class":485},[462,1006,469],{"class":468},[462,1008,1009,1012,1014],{"class":464,"line":499},[462,1010,1011],{"class":468},"    }",[462,1013,612],{"class":485},[462,1015,615],{"class":468},[462,1017,1018],{"class":464,"line":520},[462,1019,638],{"emptyLinePlaceholder":637},[462,1021,1022,1024,1026,1029,1031,1033,1036,1038,1040,1043],{"class":464,"line":535},[462,1023,997],{"class":590},[462,1025,646],{"class":468},[462,1027,1028],{"class":597},"registerTask",[462,1030,601],{"class":485},[462,1032,604],{"class":468},[462,1034,1035],{"class":478},"default",[462,1037,604],{"class":468},[462,1039,661],{"class":468},[462,1041,1042],{"class":485}," [])",[462,1044,615],{"class":468},[462,1046,1047],{"class":464,"line":707},[462,1048,1049],{"class":468},"};\n",[419,1051,1052,1053,1055],{},"Now if you execute: ",[444,1054,988],{}," you should have such console output:",[437,1057,1060],{"className":1058,"code":1059,"language":442},[440],"Done, without errors.\n",[444,1061,1059],{"__ignoreMap":446},[429,1063,1065],{"id":1064},"install-and-configure-intern","Install and configure Intern",[544,1067,1069],{"id":1068},"installing-intern-dependencies","Installing Intern dependencies",[419,1071,1072],{},"Install Intern dependency:",[437,1074,1077],{"className":1075,"code":1076,"language":442},[440],"npm install intern --save-dev\n",[444,1078,1076],{"__ignoreMap":446},[544,1080,1082],{"id":1081},"intern-configuration","Intern configuration",[419,1084,1085],{},"Create tests directory:",[437,1087,1090],{"className":1088,"code":1089,"language":442},[440],"mkdir test\n",[444,1091,1089],{"__ignoreMap":446},[419,1093,1094],{},"Prepare intern configuration by copying example from intern directory:",[437,1096,1099],{"className":1097,"code":1098,"language":442},[440],"cp node_modules\u002Fintern\u002Ftests\u002Fexample.intern.js test\u002Fintern-config.js\n",[444,1100,1098],{"__ignoreMap":446},[429,1102,1104],{"id":1103},"create-first-unit-test","Create first unit test",[437,1106,1109],{"className":1107,"code":1108,"language":442},[440],"mkdir test\u002Funit\n",[444,1110,1108],{"__ignoreMap":446},[419,1112,1113,1114,453],{},"Create file, ",[444,1115,1116],{},"test\u002Funit\u002FappTest.js",[437,1118,1120],{"className":456,"code":1119,"language":458,"meta":446,"style":446},"define(function (require) {\n    var suite = require('intern!object');\n    var expect = require('intern\u002Fchai!expect');\n\n\n    suite({\n        ' strings': function () {\n            expect(\"Piotr\").to.equal('Piotr');\n        }\n    });\n});\n",[444,1121,1122,1141,1166,1190,1194,1198,1207,1226,1264,1269,1278],{"__ignoreMap":446},[462,1123,1124,1127,1129,1132,1134,1137,1139],{"class":464,"line":465},[462,1125,1126],{"class":597},"define",[462,1128,601],{"class":590},[462,1130,1131],{"class":586},"function",[462,1133,667],{"class":468},[462,1135,1136],{"class":670},"require",[462,1138,612],{"class":468},[462,1140,681],{"class":468},[462,1142,1143,1146,1149,1151,1153,1155,1157,1160,1162,1164],{"class":464,"line":472},[462,1144,1145],{"class":586},"    var",[462,1147,1148],{"class":590}," suite",[462,1150,781],{"class":468},[462,1152,598],{"class":597},[462,1154,601],{"class":485},[462,1156,604],{"class":468},[462,1158,1159],{"class":478},"intern!object",[462,1161,604],{"class":468},[462,1163,612],{"class":485},[462,1165,615],{"class":468},[462,1167,1168,1170,1173,1175,1177,1179,1181,1184,1186,1188],{"class":464,"line":499},[462,1169,1145],{"class":586},[462,1171,1172],{"class":590}," expect",[462,1174,781],{"class":468},[462,1176,598],{"class":597},[462,1178,601],{"class":485},[462,1180,604],{"class":468},[462,1182,1183],{"class":478},"intern\u002Fchai!expect",[462,1185,604],{"class":468},[462,1187,612],{"class":485},[462,1189,615],{"class":468},[462,1191,1192],{"class":464,"line":520},[462,1193,638],{"emptyLinePlaceholder":637},[462,1195,1196],{"class":464,"line":535},[462,1197,638],{"emptyLinePlaceholder":637},[462,1199,1200,1203,1205],{"class":464,"line":707},[462,1201,1202],{"class":597},"    suite",[462,1204,601],{"class":485},[462,1206,469],{"class":468},[462,1208,1209,1212,1215,1217,1219,1221,1224],{"class":464,"line":743},[462,1210,1211],{"class":468},"        '",[462,1213,1214],{"class":485}," strings",[462,1216,604],{"class":468},[462,1218,453],{"class":468},[462,1220,664],{"class":586},[462,1222,1223],{"class":468}," ()",[462,1225,681],{"class":468},[462,1227,1228,1231,1233,1235,1238,1240,1242,1244,1247,1249,1252,1254,1256,1258,1260,1262],{"class":464,"line":752},[462,1229,1230],{"class":597},"            expect",[462,1232,601],{"class":485},[462,1234,482],{"class":468},[462,1236,1237],{"class":478},"Piotr",[462,1239,482],{"class":468},[462,1241,612],{"class":485},[462,1243,646],{"class":468},[462,1245,1246],{"class":590},"to",[462,1248,646],{"class":468},[462,1250,1251],{"class":597},"equal",[462,1253,601],{"class":485},[462,1255,604],{"class":468},[462,1257,1237],{"class":478},[462,1259,604],{"class":468},[462,1261,612],{"class":485},[462,1263,615],{"class":468},[462,1265,1266],{"class":464,"line":775},[462,1267,1268],{"class":468},"        }\n",[462,1270,1272,1274,1276],{"class":464,"line":1271},10,[462,1273,1011],{"class":468},[462,1275,612],{"class":485},[462,1277,615],{"class":468},[462,1279,1281,1283,1285],{"class":464,"line":1280},11,[462,1282,736],{"class":468},[462,1284,612],{"class":590},[462,1286,615],{"class":468},[429,1288,1290],{"id":1289},"execute-intern-tests-with-grunt","Execute Intern tests with Grunt",[419,1292,1293],{},"Now we are ready to prepare test executor.",[544,1295,1297],{"id":1296},"configure-grunt","Configure Grunt",[419,1299,1300,1301,453],{},"Lets modify ",[444,1302,970],{},[437,1304,1306],{"className":456,"code":1305,"language":458,"meta":446,"style":446},"module.exports = function (grunt) {\n\n    grunt.initConfig({\n        intern: {\n            unit_testing: {\n                options: {\n                    config: 'test\u002Fintern-config',\n                    suites: ['test\u002Funit\u002FappTest']\n                }\n            }\n        }\n    });\n\n    grunt.loadNpmTasks('intern');\n\n    grunt.registerTask('default', ['test']);\n    grunt.registerTask('test', ['intern']);\n\n};\n\n",[444,1307,1308,1324,1328,1340,1349,1358,1367,1383,1403,1408,1413,1417,1426,1431,1454,1459,1492,1523,1528],{"__ignoreMap":446},[462,1309,1310,1312,1314,1316,1318,1320,1322],{"class":464,"line":465},[462,1311,778],{"class":468},[462,1313,781],{"class":468},[462,1315,664],{"class":586},[462,1317,667],{"class":468},[462,1319,988],{"class":670},[462,1321,612],{"class":468},[462,1323,681],{"class":468},[462,1325,1326],{"class":464,"line":472},[462,1327,638],{"emptyLinePlaceholder":637},[462,1329,1330,1332,1334,1336,1338],{"class":464,"line":499},[462,1331,997],{"class":590},[462,1333,646],{"class":468},[462,1335,1002],{"class":597},[462,1337,601],{"class":485},[462,1339,469],{"class":468},[462,1341,1342,1345,1347],{"class":464,"line":520},[462,1343,1344],{"class":485},"        intern",[462,1346,453],{"class":468},[462,1348,681],{"class":468},[462,1350,1351,1354,1356],{"class":464,"line":535},[462,1352,1353],{"class":485},"            unit_testing",[462,1355,453],{"class":468},[462,1357,681],{"class":468},[462,1359,1360,1363,1365],{"class":464,"line":707},[462,1361,1362],{"class":485},"                options",[462,1364,453],{"class":468},[462,1366,681],{"class":468},[462,1368,1369,1372,1374,1376,1379,1381],{"class":464,"line":743},[462,1370,1371],{"class":485},"                    config",[462,1373,453],{"class":468},[462,1375,728],{"class":468},[462,1377,1378],{"class":478},"test\u002Fintern-config",[462,1380,604],{"class":468},[462,1382,496],{"class":468},[462,1384,1385,1388,1390,1393,1395,1398,1400],{"class":464,"line":752},[462,1386,1387],{"class":485},"                    suites",[462,1389,453],{"class":468},[462,1391,1392],{"class":485}," [",[462,1394,604],{"class":468},[462,1396,1397],{"class":478},"test\u002Funit\u002FappTest",[462,1399,604],{"class":468},[462,1401,1402],{"class":485},"]\n",[462,1404,1405],{"class":464,"line":775},[462,1406,1407],{"class":468},"                }\n",[462,1409,1410],{"class":464,"line":1271},[462,1411,1412],{"class":468},"            }\n",[462,1414,1415],{"class":464,"line":1280},[462,1416,1268],{"class":468},[462,1418,1420,1422,1424],{"class":464,"line":1419},12,[462,1421,1011],{"class":468},[462,1423,612],{"class":485},[462,1425,615],{"class":468},[462,1427,1429],{"class":464,"line":1428},13,[462,1430,638],{"emptyLinePlaceholder":637},[462,1432,1434,1436,1438,1441,1443,1445,1448,1450,1452],{"class":464,"line":1433},14,[462,1435,997],{"class":590},[462,1437,646],{"class":468},[462,1439,1440],{"class":597},"loadNpmTasks",[462,1442,601],{"class":485},[462,1444,604],{"class":468},[462,1446,1447],{"class":478},"intern",[462,1449,604],{"class":468},[462,1451,612],{"class":485},[462,1453,615],{"class":468},[462,1455,1457],{"class":464,"line":1456},15,[462,1458,638],{"emptyLinePlaceholder":637},[462,1460,1462,1464,1466,1468,1470,1472,1474,1476,1478,1480,1482,1485,1487,1490],{"class":464,"line":1461},16,[462,1463,997],{"class":590},[462,1465,646],{"class":468},[462,1467,1028],{"class":597},[462,1469,601],{"class":485},[462,1471,604],{"class":468},[462,1473,1035],{"class":478},[462,1475,604],{"class":468},[462,1477,661],{"class":468},[462,1479,1392],{"class":485},[462,1481,604],{"class":468},[462,1483,1484],{"class":478},"test",[462,1486,604],{"class":468},[462,1488,1489],{"class":485},"])",[462,1491,615],{"class":468},[462,1493,1495,1497,1499,1501,1503,1505,1507,1509,1511,1513,1515,1517,1519,1521],{"class":464,"line":1494},17,[462,1496,997],{"class":590},[462,1498,646],{"class":468},[462,1500,1028],{"class":597},[462,1502,601],{"class":485},[462,1504,604],{"class":468},[462,1506,1484],{"class":478},[462,1508,604],{"class":468},[462,1510,661],{"class":468},[462,1512,1392],{"class":485},[462,1514,604],{"class":468},[462,1516,1447],{"class":478},[462,1518,604],{"class":468},[462,1520,1489],{"class":485},[462,1522,615],{"class":468},[462,1524,1526],{"class":464,"line":1525},18,[462,1527,638],{"emptyLinePlaceholder":637},[462,1529,1531],{"class":464,"line":1530},19,[462,1532,1049],{"class":468},[419,1534,1535,1536,1538,1539,1542,1543,1545],{},"This configuration loads ",[444,1537,1447],{}," task, configures ",[444,1540,1541],{},"intern:unit_testing"," task and assignes it to ",[444,1544,1484],{}," alias task.",[544,1547,1549],{"id":1548},"executing-intern-tests","Executing Intern tests",[419,1551,1552],{},"Lets execute first unit task:",[437,1554,1557],{"className":1555,"code":1556,"language":442},[440],"grunt test\n",[444,1558,1556],{"__ignoreMap":446},[419,1560,1561],{},"With output:",[437,1563,1566],{"className":1564,"code":1565,"language":442},[440],"Running \"intern:unit_testing\" (intern) task\n>> PASS: main -  -  strings (0ms)\n>> 0\u002F1 tests failed\n>> 0\u002F1 tests failed\n",[444,1567,1565],{"__ignoreMap":446},[429,1569,1571],{"id":1570},"summary","Summary",[419,1573,1574],{},"At this point we have configure:",[1576,1577,1578,1585,1588,1591,1594],"ul",{},[1579,1580,1581,1582,1584],"li",{},"REST application with ",[444,1583,656],{}," endpoint",[1579,1586,1587],{},"Server that hosts that application",[1579,1589,1590],{},"Configured task executor, and tasks configuration",[1579,1592,1593],{},"Configured test framework with unit suites",[1579,1595,1596],{},"Written first unit test which actually doesn't test application, but was made to check if everything works fine",[419,1598,1599],{},"Pretty much, isn't it?",[419,1601,1602],{},"#Implement business logic",[419,1604,1605],{},"At this point we have configured infrastructure that allows now to focus on business aspect of our application.\nWe will implement simple calculator service that will be called via http and return data as JSON. Mind that this method is no more REST as it focuses more on resources. I believe this way is more RPC.",[419,1607,1608],{},"I will follow best practices, so I will implement Calculator feature in TDD style. The sequence is:",[1610,1611,1612,1615,1618,1621,1624,1627],"ol",{},[1579,1613,1614],{},"Write interface that will deliver business contract \u002F signature",[1579,1616,1617],{},"Write simple test which uses business signature but doesn't pass as the method is not implemented",[1579,1619,1620],{},"Implement business method to pass existing test",[1579,1622,1623],{},"Write more complex test which doesn't pass",[1579,1625,1626],{},"Fix test by modifying implementation",[1579,1628,1629],{},"Refactor implementation",[429,1631,1614],{"id":1632},"write-interface-that-will-deliver-business-contract-signature",[419,1634,1635,1636,453],{},"Create business logic file ",[444,1637,1638],{},"src\u002Fcalculator.js",[437,1640,1642],{"className":456,"code":1641,"language":458,"meta":446,"style":446},"module.exports = {\n    \n    add: function(arg1, arg2){\n        return null;\n    },\n    subtract: function(arg1, arg2){\n        return null;\n    },\n    multiple: function(arg1, arg2){\n        return null;\n    },\n    divide: function(arg1, arg2){\n        return null;\n    }\n    \n}\n",[444,1643,1644,1652,1657,1679,1688,1693,1712,1718,1722,1741,1747,1751,1770,1776,1781,1785],{"__ignoreMap":446},[462,1645,1646,1648,1650],{"class":464,"line":465},[462,1647,778],{"class":468},[462,1649,781],{"class":468},[462,1651,681],{"class":468},[462,1653,1654],{"class":464,"line":472},[462,1655,1656],{"class":590},"    \n",[462,1658,1659,1662,1664,1666,1668,1671,1673,1676],{"class":464,"line":499},[462,1660,1661],{"class":597},"    add",[462,1663,453],{"class":468},[462,1665,664],{"class":586},[462,1667,601],{"class":468},[462,1669,1670],{"class":670},"arg1",[462,1672,661],{"class":468},[462,1674,1675],{"class":670}," arg2",[462,1677,1678],{"class":468},"){\n",[462,1680,1681,1685],{"class":464,"line":520},[462,1682,1684],{"class":1683},"s7zQu","        return",[462,1686,1687],{"class":468}," null;\n",[462,1689,1690],{"class":464,"line":535},[462,1691,1692],{"class":468},"    },\n",[462,1694,1695,1698,1700,1702,1704,1706,1708,1710],{"class":464,"line":707},[462,1696,1697],{"class":597},"    subtract",[462,1699,453],{"class":468},[462,1701,664],{"class":586},[462,1703,601],{"class":468},[462,1705,1670],{"class":670},[462,1707,661],{"class":468},[462,1709,1675],{"class":670},[462,1711,1678],{"class":468},[462,1713,1714,1716],{"class":464,"line":743},[462,1715,1684],{"class":1683},[462,1717,1687],{"class":468},[462,1719,1720],{"class":464,"line":752},[462,1721,1692],{"class":468},[462,1723,1724,1727,1729,1731,1733,1735,1737,1739],{"class":464,"line":775},[462,1725,1726],{"class":597},"    multiple",[462,1728,453],{"class":468},[462,1730,664],{"class":586},[462,1732,601],{"class":468},[462,1734,1670],{"class":670},[462,1736,661],{"class":468},[462,1738,1675],{"class":670},[462,1740,1678],{"class":468},[462,1742,1743,1745],{"class":464,"line":1271},[462,1744,1684],{"class":1683},[462,1746,1687],{"class":468},[462,1748,1749],{"class":464,"line":1280},[462,1750,1692],{"class":468},[462,1752,1753,1756,1758,1760,1762,1764,1766,1768],{"class":464,"line":1419},[462,1754,1755],{"class":597},"    divide",[462,1757,453],{"class":468},[462,1759,664],{"class":586},[462,1761,601],{"class":468},[462,1763,1670],{"class":670},[462,1765,661],{"class":468},[462,1767,1675],{"class":670},[462,1769,1678],{"class":468},[462,1771,1772,1774],{"class":464,"line":1428},[462,1773,1684],{"class":1683},[462,1775,1687],{"class":468},[462,1777,1778],{"class":464,"line":1433},[462,1779,1780],{"class":468},"    }\n",[462,1782,1783],{"class":464,"line":1456},[462,1784,1656],{"class":590},[462,1786,1787],{"class":464,"line":1461},[462,1788,538],{"class":468},[429,1790,1617],{"id":1791},"write-simple-test-which-uses-business-signature-but-doesnt-pass-as-the-method-is-not-implemented",[419,1793,1794,1795,453],{},"Create unit test file for business the file which holds the logic ",[444,1796,1797],{},"test\u002Funit\u002FcalculatorTest.js",[437,1799,1801],{"className":456,"code":1800,"language":458,"meta":446,"style":446},"define(function (require) {\n    var suite = require('intern!object');\n    var expect = require('intern\u002Fchai!expect');\n    var instance = require('intern\u002Fdojo\u002Fnode!..\u002F..\u002Fsrc\u002Fcalculator');\n\n\n    suite({\n        'should add 1 and 2 which equals 3': function () {\n            expect(instance.add(1,2)).to.equal(3);\n        }\n    });\n});\n",[444,1802,1803,1819,1841,1863,1887,1891,1895,1903,1920,1964,1968,1976],{"__ignoreMap":446},[462,1804,1805,1807,1809,1811,1813,1815,1817],{"class":464,"line":465},[462,1806,1126],{"class":597},[462,1808,601],{"class":590},[462,1810,1131],{"class":586},[462,1812,667],{"class":468},[462,1814,1136],{"class":670},[462,1816,612],{"class":468},[462,1818,681],{"class":468},[462,1820,1821,1823,1825,1827,1829,1831,1833,1835,1837,1839],{"class":464,"line":472},[462,1822,1145],{"class":586},[462,1824,1148],{"class":590},[462,1826,781],{"class":468},[462,1828,598],{"class":597},[462,1830,601],{"class":485},[462,1832,604],{"class":468},[462,1834,1159],{"class":478},[462,1836,604],{"class":468},[462,1838,612],{"class":485},[462,1840,615],{"class":468},[462,1842,1843,1845,1847,1849,1851,1853,1855,1857,1859,1861],{"class":464,"line":499},[462,1844,1145],{"class":586},[462,1846,1172],{"class":590},[462,1848,781],{"class":468},[462,1850,598],{"class":597},[462,1852,601],{"class":485},[462,1854,604],{"class":468},[462,1856,1183],{"class":478},[462,1858,604],{"class":468},[462,1860,612],{"class":485},[462,1862,615],{"class":468},[462,1864,1865,1867,1870,1872,1874,1876,1878,1881,1883,1885],{"class":464,"line":520},[462,1866,1145],{"class":586},[462,1868,1869],{"class":590}," instance",[462,1871,781],{"class":468},[462,1873,598],{"class":597},[462,1875,601],{"class":485},[462,1877,604],{"class":468},[462,1879,1880],{"class":478},"intern\u002Fdojo\u002Fnode!..\u002F..\u002Fsrc\u002Fcalculator",[462,1882,604],{"class":468},[462,1884,612],{"class":485},[462,1886,615],{"class":468},[462,1888,1889],{"class":464,"line":535},[462,1890,638],{"emptyLinePlaceholder":637},[462,1892,1893],{"class":464,"line":707},[462,1894,638],{"emptyLinePlaceholder":637},[462,1896,1897,1899,1901],{"class":464,"line":743},[462,1898,1202],{"class":597},[462,1900,601],{"class":485},[462,1902,469],{"class":468},[462,1904,1905,1907,1910,1912,1914,1916,1918],{"class":464,"line":752},[462,1906,1211],{"class":468},[462,1908,1909],{"class":485},"should add 1 and 2 which equals 3",[462,1911,604],{"class":468},[462,1913,453],{"class":468},[462,1915,664],{"class":586},[462,1917,1223],{"class":468},[462,1919,681],{"class":468},[462,1921,1922,1924,1926,1929,1931,1934,1936,1939,1941,1944,1947,1949,1951,1953,1955,1957,1960,1962],{"class":464,"line":775},[462,1923,1230],{"class":597},[462,1925,601],{"class":485},[462,1927,1928],{"class":590},"instance",[462,1930,646],{"class":468},[462,1932,1933],{"class":597},"add",[462,1935,601],{"class":485},[462,1937,1938],{"class":850},"1",[462,1940,661],{"class":468},[462,1942,1943],{"class":850},"2",[462,1945,1946],{"class":485},"))",[462,1948,646],{"class":468},[462,1950,1246],{"class":590},[462,1952,646],{"class":468},[462,1954,1251],{"class":597},[462,1956,601],{"class":485},[462,1958,1959],{"class":850},"3",[462,1961,612],{"class":485},[462,1963,615],{"class":468},[462,1965,1966],{"class":464,"line":1271},[462,1967,1268],{"class":468},[462,1969,1970,1972,1974],{"class":464,"line":1280},[462,1971,1011],{"class":468},[462,1973,612],{"class":485},[462,1975,615],{"class":468},[462,1977,1978,1980,1982],{"class":464,"line":1419},[462,1979,736],{"class":468},[462,1981,612],{"class":590},[462,1983,615],{"class":468},[419,1985,1986,1987,1989],{},"Now we must add this suite to the executions set in Grunt config file (",[444,1988,970],{},"):",[437,1991,1993],{"className":456,"code":1992,"language":458,"meta":446,"style":446},"module.exports = function (grunt) {\n\n    grunt.initConfig({\n        intern: {\n            unit_testing: {\n                options: {\n                    config: 'test\u002Fintern-config',\n                    suites: ['test\u002Funit\u002FappTest','test\u002Funit\u002FcalculatorTest']\n                }\n            }\n        }\n    });\n\n    grunt.loadNpmTasks('intern');\n\n    grunt.registerTask('default', ['test']);\n    grunt.registerTask('test', ['intern']);\n\n};\n",[444,1994,1995,2011,2015,2027,2035,2043,2051,2065,2090,2094,2098,2102,2110,2114,2134,2138,2168,2198,2202],{"__ignoreMap":446},[462,1996,1997,1999,2001,2003,2005,2007,2009],{"class":464,"line":465},[462,1998,778],{"class":468},[462,2000,781],{"class":468},[462,2002,664],{"class":586},[462,2004,667],{"class":468},[462,2006,988],{"class":670},[462,2008,612],{"class":468},[462,2010,681],{"class":468},[462,2012,2013],{"class":464,"line":472},[462,2014,638],{"emptyLinePlaceholder":637},[462,2016,2017,2019,2021,2023,2025],{"class":464,"line":499},[462,2018,997],{"class":590},[462,2020,646],{"class":468},[462,2022,1002],{"class":597},[462,2024,601],{"class":485},[462,2026,469],{"class":468},[462,2028,2029,2031,2033],{"class":464,"line":520},[462,2030,1344],{"class":485},[462,2032,453],{"class":468},[462,2034,681],{"class":468},[462,2036,2037,2039,2041],{"class":464,"line":535},[462,2038,1353],{"class":485},[462,2040,453],{"class":468},[462,2042,681],{"class":468},[462,2044,2045,2047,2049],{"class":464,"line":707},[462,2046,1362],{"class":485},[462,2048,453],{"class":468},[462,2050,681],{"class":468},[462,2052,2053,2055,2057,2059,2061,2063],{"class":464,"line":743},[462,2054,1371],{"class":485},[462,2056,453],{"class":468},[462,2058,728],{"class":468},[462,2060,1378],{"class":478},[462,2062,604],{"class":468},[462,2064,496],{"class":468},[462,2066,2067,2069,2071,2073,2075,2077,2079,2081,2083,2086,2088],{"class":464,"line":752},[462,2068,1387],{"class":485},[462,2070,453],{"class":468},[462,2072,1392],{"class":485},[462,2074,604],{"class":468},[462,2076,1397],{"class":478},[462,2078,604],{"class":468},[462,2080,661],{"class":468},[462,2082,604],{"class":468},[462,2084,2085],{"class":478},"test\u002Funit\u002FcalculatorTest",[462,2087,604],{"class":468},[462,2089,1402],{"class":485},[462,2091,2092],{"class":464,"line":775},[462,2093,1407],{"class":468},[462,2095,2096],{"class":464,"line":1271},[462,2097,1412],{"class":468},[462,2099,2100],{"class":464,"line":1280},[462,2101,1268],{"class":468},[462,2103,2104,2106,2108],{"class":464,"line":1419},[462,2105,1011],{"class":468},[462,2107,612],{"class":485},[462,2109,615],{"class":468},[462,2111,2112],{"class":464,"line":1428},[462,2113,638],{"emptyLinePlaceholder":637},[462,2115,2116,2118,2120,2122,2124,2126,2128,2130,2132],{"class":464,"line":1433},[462,2117,997],{"class":590},[462,2119,646],{"class":468},[462,2121,1440],{"class":597},[462,2123,601],{"class":485},[462,2125,604],{"class":468},[462,2127,1447],{"class":478},[462,2129,604],{"class":468},[462,2131,612],{"class":485},[462,2133,615],{"class":468},[462,2135,2136],{"class":464,"line":1456},[462,2137,638],{"emptyLinePlaceholder":637},[462,2139,2140,2142,2144,2146,2148,2150,2152,2154,2156,2158,2160,2162,2164,2166],{"class":464,"line":1461},[462,2141,997],{"class":590},[462,2143,646],{"class":468},[462,2145,1028],{"class":597},[462,2147,601],{"class":485},[462,2149,604],{"class":468},[462,2151,1035],{"class":478},[462,2153,604],{"class":468},[462,2155,661],{"class":468},[462,2157,1392],{"class":485},[462,2159,604],{"class":468},[462,2161,1484],{"class":478},[462,2163,604],{"class":468},[462,2165,1489],{"class":485},[462,2167,615],{"class":468},[462,2169,2170,2172,2174,2176,2178,2180,2182,2184,2186,2188,2190,2192,2194,2196],{"class":464,"line":1494},[462,2171,997],{"class":590},[462,2173,646],{"class":468},[462,2175,1028],{"class":597},[462,2177,601],{"class":485},[462,2179,604],{"class":468},[462,2181,1484],{"class":478},[462,2183,604],{"class":468},[462,2185,661],{"class":468},[462,2187,1392],{"class":485},[462,2189,604],{"class":468},[462,2191,1447],{"class":478},[462,2193,604],{"class":468},[462,2195,1489],{"class":485},[462,2197,615],{"class":468},[462,2199,2200],{"class":464,"line":1525},[462,2201,638],{"emptyLinePlaceholder":637},[462,2203,2204],{"class":464,"line":1530},[462,2205,1049],{"class":468},[419,2207,2208],{},"And we can execute all tests:",[437,2210,2212],{"className":2211,"code":1556,"language":442},[440],[444,2213,1556],{"__ignoreMap":446},[419,2215,2216],{},"Which results in exception:",[437,2218,2221],{"className":2219,"code":2220,"language":442},[440],"Running \"intern:unit_testing\" (intern) task\n>> PASS: main -  -  strings (0ms)\n>> 0\u002F1 tests failed\n>> FAIL: main -  - should add 1 and 2 which equals 3 (1ms)\nAssertionError: expected null to equal 3\n\n",[444,2222,2220],{"__ignoreMap":446},[419,2224,2225,2226,2228],{},"We expected that as we didn't implemented ",[444,2227,1933],{}," method yet. We must write test first to prevent us from false positive situation.",[429,2230,1620],{"id":2231},"implement-business-method-to-pass-existing-test",[419,2233,2234,2235,2237],{},"The simplest way to make test to pass is to return fixed 3. ",[444,2236,1638],{}," is now:",[437,2239,2241],{"className":456,"code":2240,"language":458,"meta":446,"style":446},"module.exports = {\n    \n    add: function(arg1, arg2){\n        return 3;\n    },\n    subtract: function(arg1, arg2){\n        return null;\n    },\n    multiple: function(arg1, arg2){\n        return null;\n    },\n    divide: function(arg1, arg2){\n        return null;\n    }\n    \n}\n",[444,2242,2243,2251,2255,2273,2282,2286,2304,2310,2314,2332,2338,2342,2360,2366,2370,2374],{"__ignoreMap":446},[462,2244,2245,2247,2249],{"class":464,"line":465},[462,2246,778],{"class":468},[462,2248,781],{"class":468},[462,2250,681],{"class":468},[462,2252,2253],{"class":464,"line":472},[462,2254,1656],{"class":590},[462,2256,2257,2259,2261,2263,2265,2267,2269,2271],{"class":464,"line":499},[462,2258,1661],{"class":597},[462,2260,453],{"class":468},[462,2262,664],{"class":586},[462,2264,601],{"class":468},[462,2266,1670],{"class":670},[462,2268,661],{"class":468},[462,2270,1675],{"class":670},[462,2272,1678],{"class":468},[462,2274,2275,2277,2280],{"class":464,"line":520},[462,2276,1684],{"class":1683},[462,2278,2279],{"class":850}," 3",[462,2281,615],{"class":468},[462,2283,2284],{"class":464,"line":535},[462,2285,1692],{"class":468},[462,2287,2288,2290,2292,2294,2296,2298,2300,2302],{"class":464,"line":707},[462,2289,1697],{"class":597},[462,2291,453],{"class":468},[462,2293,664],{"class":586},[462,2295,601],{"class":468},[462,2297,1670],{"class":670},[462,2299,661],{"class":468},[462,2301,1675],{"class":670},[462,2303,1678],{"class":468},[462,2305,2306,2308],{"class":464,"line":743},[462,2307,1684],{"class":1683},[462,2309,1687],{"class":468},[462,2311,2312],{"class":464,"line":752},[462,2313,1692],{"class":468},[462,2315,2316,2318,2320,2322,2324,2326,2328,2330],{"class":464,"line":775},[462,2317,1726],{"class":597},[462,2319,453],{"class":468},[462,2321,664],{"class":586},[462,2323,601],{"class":468},[462,2325,1670],{"class":670},[462,2327,661],{"class":468},[462,2329,1675],{"class":670},[462,2331,1678],{"class":468},[462,2333,2334,2336],{"class":464,"line":1271},[462,2335,1684],{"class":1683},[462,2337,1687],{"class":468},[462,2339,2340],{"class":464,"line":1280},[462,2341,1692],{"class":468},[462,2343,2344,2346,2348,2350,2352,2354,2356,2358],{"class":464,"line":1419},[462,2345,1755],{"class":597},[462,2347,453],{"class":468},[462,2349,664],{"class":586},[462,2351,601],{"class":468},[462,2353,1670],{"class":670},[462,2355,661],{"class":468},[462,2357,1675],{"class":670},[462,2359,1678],{"class":468},[462,2361,2362,2364],{"class":464,"line":1428},[462,2363,1684],{"class":1683},[462,2365,1687],{"class":468},[462,2367,2368],{"class":464,"line":1433},[462,2369,1780],{"class":468},[462,2371,2372],{"class":464,"line":1456},[462,2373,1656],{"class":590},[462,2375,2376],{"class":464,"line":1461},[462,2377,538],{"class":468},[419,2379,2380],{},"And all tests are passing:",[437,2382,2385],{"className":2383,"code":2384,"language":442},[440],">> PASS: main -  - testing strings (0ms)\n>> 0\u002F1 tests failed\n>> PASS: main -  - should add 1 and 2 which equals 3 (0ms)\n>> 0\u002F1 tests failed\n>> 0\u002F2 tests failed\n",[444,2386,2384],{"__ignoreMap":446},[419,2388,2389],{},"You might ask WTF? why? how? but this is fake, that's bullshit!!!\nI know I know, but this is first very important step that you shouldn't omit in TDD. We start from tiny detail and then it will evolve. Sometimes it's very hard to implement feature at once and this is first step to incremental development. Lets move forward.",[429,2391,1623],{"id":2392},"write-more-complex-test-which-doesnt-pass",[419,2394,2395],{},"Now we add another test case:",[437,2397,2399],{"className":456,"code":2398,"language":458,"meta":446,"style":446},"define(function (require) {\n    var suite = require('intern!object');\n    var expect = require('intern\u002Fchai!expect');\n    var instance = require('intern\u002Fdojo\u002Fnode!..\u002F..\u002Fsrc\u002Fcalculator');\n\n\n    suite({\n        'should add 1 and 2 which equals 3': function () {\n            expect(instance.add(1,2)).to.equal(3);\n        },\n        'should add 5 and 6 which equals 11': function () {\n            expect(instance.add(5,6)).to.equal(11);\n        }\n    });\n});\n\n",[444,2400,2401,2417,2439,2461,2483,2487,2491,2499,2515,2553,2558,2575,2616,2620,2628],{"__ignoreMap":446},[462,2402,2403,2405,2407,2409,2411,2413,2415],{"class":464,"line":465},[462,2404,1126],{"class":597},[462,2406,601],{"class":590},[462,2408,1131],{"class":586},[462,2410,667],{"class":468},[462,2412,1136],{"class":670},[462,2414,612],{"class":468},[462,2416,681],{"class":468},[462,2418,2419,2421,2423,2425,2427,2429,2431,2433,2435,2437],{"class":464,"line":472},[462,2420,1145],{"class":586},[462,2422,1148],{"class":590},[462,2424,781],{"class":468},[462,2426,598],{"class":597},[462,2428,601],{"class":485},[462,2430,604],{"class":468},[462,2432,1159],{"class":478},[462,2434,604],{"class":468},[462,2436,612],{"class":485},[462,2438,615],{"class":468},[462,2440,2441,2443,2445,2447,2449,2451,2453,2455,2457,2459],{"class":464,"line":499},[462,2442,1145],{"class":586},[462,2444,1172],{"class":590},[462,2446,781],{"class":468},[462,2448,598],{"class":597},[462,2450,601],{"class":485},[462,2452,604],{"class":468},[462,2454,1183],{"class":478},[462,2456,604],{"class":468},[462,2458,612],{"class":485},[462,2460,615],{"class":468},[462,2462,2463,2465,2467,2469,2471,2473,2475,2477,2479,2481],{"class":464,"line":520},[462,2464,1145],{"class":586},[462,2466,1869],{"class":590},[462,2468,781],{"class":468},[462,2470,598],{"class":597},[462,2472,601],{"class":485},[462,2474,604],{"class":468},[462,2476,1880],{"class":478},[462,2478,604],{"class":468},[462,2480,612],{"class":485},[462,2482,615],{"class":468},[462,2484,2485],{"class":464,"line":535},[462,2486,638],{"emptyLinePlaceholder":637},[462,2488,2489],{"class":464,"line":707},[462,2490,638],{"emptyLinePlaceholder":637},[462,2492,2493,2495,2497],{"class":464,"line":743},[462,2494,1202],{"class":597},[462,2496,601],{"class":485},[462,2498,469],{"class":468},[462,2500,2501,2503,2505,2507,2509,2511,2513],{"class":464,"line":752},[462,2502,1211],{"class":468},[462,2504,1909],{"class":485},[462,2506,604],{"class":468},[462,2508,453],{"class":468},[462,2510,664],{"class":586},[462,2512,1223],{"class":468},[462,2514,681],{"class":468},[462,2516,2517,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539,2541,2543,2545,2547,2549,2551],{"class":464,"line":775},[462,2518,1230],{"class":597},[462,2520,601],{"class":485},[462,2522,1928],{"class":590},[462,2524,646],{"class":468},[462,2526,1933],{"class":597},[462,2528,601],{"class":485},[462,2530,1938],{"class":850},[462,2532,661],{"class":468},[462,2534,1943],{"class":850},[462,2536,1946],{"class":485},[462,2538,646],{"class":468},[462,2540,1246],{"class":590},[462,2542,646],{"class":468},[462,2544,1251],{"class":597},[462,2546,601],{"class":485},[462,2548,1959],{"class":850},[462,2550,612],{"class":485},[462,2552,615],{"class":468},[462,2554,2555],{"class":464,"line":1271},[462,2556,2557],{"class":468},"        },\n",[462,2559,2560,2562,2565,2567,2569,2571,2573],{"class":464,"line":1280},[462,2561,1211],{"class":468},[462,2563,2564],{"class":485},"should add 5 and 6 which equals 11",[462,2566,604],{"class":468},[462,2568,453],{"class":468},[462,2570,664],{"class":586},[462,2572,1223],{"class":468},[462,2574,681],{"class":468},[462,2576,2577,2579,2581,2583,2585,2587,2589,2592,2594,2597,2599,2601,2603,2605,2607,2609,2612,2614],{"class":464,"line":1419},[462,2578,1230],{"class":597},[462,2580,601],{"class":485},[462,2582,1928],{"class":590},[462,2584,646],{"class":468},[462,2586,1933],{"class":597},[462,2588,601],{"class":485},[462,2590,2591],{"class":850},"5",[462,2593,661],{"class":468},[462,2595,2596],{"class":850},"6",[462,2598,1946],{"class":485},[462,2600,646],{"class":468},[462,2602,1246],{"class":590},[462,2604,646],{"class":468},[462,2606,1251],{"class":597},[462,2608,601],{"class":485},[462,2610,2611],{"class":850},"11",[462,2613,612],{"class":485},[462,2615,615],{"class":468},[462,2617,2618],{"class":464,"line":1428},[462,2619,1268],{"class":468},[462,2621,2622,2624,2626],{"class":464,"line":1433},[462,2623,1011],{"class":468},[462,2625,612],{"class":485},[462,2627,615],{"class":468},[462,2629,2630,2632,2634],{"class":464,"line":1456},[462,2631,736],{"class":468},[462,2633,612],{"class":590},[462,2635,615],{"class":468},[419,2637,2638],{},"which naturally doesn't pass:",[437,2640,2643],{"className":2641,"code":2642,"language":442},[440],">> PASS: main -  - testing strings (0ms)\n>> 0\u002F1 tests failed\n>> PASS: main -  - should add 1 and 2 which equals 3 (0ms)\n>> FAIL: main -  - should add 5 and 6 which equals 11 (1ms)\nAssertionError: expected 3 to equal 11\n",[444,2644,2642],{"__ignoreMap":446},[429,2646,1626],{"id":2647},"fix-test-by-modifying-implementation",[419,2649,2650,2651,2653],{},"We are no longer able to put fixed numbers, so we need to implement ",[444,2652,1933],{}," method as simply it's possible:",[437,2655,2657],{"className":456,"code":2656,"language":458,"meta":446,"style":446},"module.exports = {\n    \n    add: function(arg1, arg2){\n        return arg1+arg2;\n    },\n    subtract: function(arg1, arg2){\n        return null;\n    },\n    multiple: function(arg1, arg2){\n        return null;\n    },\n    divide: function(arg1, arg2){\n        return null;\n    }\n    \n}\n",[444,2658,2659,2667,2671,2689,2704,2708,2726,2732,2736,2754,2760,2764,2782,2788,2792,2796],{"__ignoreMap":446},[462,2660,2661,2663,2665],{"class":464,"line":465},[462,2662,778],{"class":468},[462,2664,781],{"class":468},[462,2666,681],{"class":468},[462,2668,2669],{"class":464,"line":472},[462,2670,1656],{"class":590},[462,2672,2673,2675,2677,2679,2681,2683,2685,2687],{"class":464,"line":499},[462,2674,1661],{"class":597},[462,2676,453],{"class":468},[462,2678,664],{"class":586},[462,2680,601],{"class":468},[462,2682,1670],{"class":670},[462,2684,661],{"class":468},[462,2686,1675],{"class":670},[462,2688,1678],{"class":468},[462,2690,2691,2693,2696,2699,2702],{"class":464,"line":520},[462,2692,1684],{"class":1683},[462,2694,2695],{"class":590}," arg1",[462,2697,2698],{"class":468},"+",[462,2700,2701],{"class":590},"arg2",[462,2703,615],{"class":468},[462,2705,2706],{"class":464,"line":535},[462,2707,1692],{"class":468},[462,2709,2710,2712,2714,2716,2718,2720,2722,2724],{"class":464,"line":707},[462,2711,1697],{"class":597},[462,2713,453],{"class":468},[462,2715,664],{"class":586},[462,2717,601],{"class":468},[462,2719,1670],{"class":670},[462,2721,661],{"class":468},[462,2723,1675],{"class":670},[462,2725,1678],{"class":468},[462,2727,2728,2730],{"class":464,"line":743},[462,2729,1684],{"class":1683},[462,2731,1687],{"class":468},[462,2733,2734],{"class":464,"line":752},[462,2735,1692],{"class":468},[462,2737,2738,2740,2742,2744,2746,2748,2750,2752],{"class":464,"line":775},[462,2739,1726],{"class":597},[462,2741,453],{"class":468},[462,2743,664],{"class":586},[462,2745,601],{"class":468},[462,2747,1670],{"class":670},[462,2749,661],{"class":468},[462,2751,1675],{"class":670},[462,2753,1678],{"class":468},[462,2755,2756,2758],{"class":464,"line":1271},[462,2757,1684],{"class":1683},[462,2759,1687],{"class":468},[462,2761,2762],{"class":464,"line":1280},[462,2763,1692],{"class":468},[462,2765,2766,2768,2770,2772,2774,2776,2778,2780],{"class":464,"line":1419},[462,2767,1755],{"class":597},[462,2769,453],{"class":468},[462,2771,664],{"class":586},[462,2773,601],{"class":468},[462,2775,1670],{"class":670},[462,2777,661],{"class":468},[462,2779,1675],{"class":670},[462,2781,1678],{"class":468},[462,2783,2784,2786],{"class":464,"line":1428},[462,2785,1684],{"class":1683},[462,2787,1687],{"class":468},[462,2789,2790],{"class":464,"line":1433},[462,2791,1780],{"class":468},[462,2793,2794],{"class":464,"line":1456},[462,2795,1656],{"class":590},[462,2797,2798],{"class":464,"line":1461},[462,2799,538],{"class":468},[419,2801,2802],{},"Now the test again passess:",[437,2804,2807],{"className":2805,"code":2806,"language":442},[440],"Running \"intern:unit_testing\" (intern) task\n>> PASS: main -  - testing strings (0ms)\n>> 0\u002F1 tests failed\n>> PASS: main -  - should add 1 and 2 which equals 3 (0ms)\n>> PASS: main -  - should add 5 and 6 which equals 11 (0ms)\n>> 0\u002F2 tests failed\n>> 0\u002F3 tests failed\n",[444,2808,2806],{"__ignoreMap":446},[429,2810,1629],{"id":2811},"refactor-implementation",[419,2813,2814],{},"If above code makes complex you should refactor it. If not implement the rest methods in the same way starting again from the 1'th point.\nIf all features are implemented we can start integrating calculator module with the rest of application.",[419,2816,2817],{},"#Integration",[419,2819,2820],{},"After implemented and tested code we can integrate it with other components of our application. Other components also should be unit tested. In this step we will expose our calculator method as a Web Service.",[419,2822,2823,2824,2826],{},"In ",[444,2825,576],{}," modify code:",[437,2828,2830],{"className":456,"code":2829,"language":458,"meta":446,"style":446},"var express = require('express');\nvar calculator = require('.\u002Fcalculator');\nvar app = express();\n\napp.get('\u002Ftest', function (req, res) {\n    console.log('hitting test');\n    res.json({status: 'ok'});\n});\n\napp.get('\u002Fcalculator\u002Fadd', function (req, res) {\n    \n    var param1Int = parseInt(req.query.arg1);\n    var param2Int = parseInt(req.query.arg2);\n    \n    var addResult = calculator.add(param1Int, param2Int);\n    \n    res.json({result: addResult});\n});\nconsole.log('App is configured');\nmodule.exports = app;\n",[444,2831,2832,2854,2878,2892,2896,2928,2948,2976,2984,2988,3021,3025,3054,3081,3085,3114,3118,3143,3151,3171],{"__ignoreMap":446},[462,2833,2834,2836,2838,2840,2842,2844,2846,2848,2850,2852],{"class":464,"line":465},[462,2835,587],{"class":586},[462,2837,591],{"class":590},[462,2839,594],{"class":468},[462,2841,598],{"class":597},[462,2843,601],{"class":590},[462,2845,604],{"class":468},[462,2847,607],{"class":478},[462,2849,604],{"class":468},[462,2851,612],{"class":590},[462,2853,615],{"class":468},[462,2855,2856,2858,2861,2863,2865,2867,2869,2872,2874,2876],{"class":464,"line":472},[462,2857,587],{"class":586},[462,2859,2860],{"class":590}," calculator ",[462,2862,594],{"class":468},[462,2864,598],{"class":597},[462,2866,601],{"class":590},[462,2868,604],{"class":468},[462,2870,2871],{"class":478},".\u002Fcalculator",[462,2873,604],{"class":468},[462,2875,612],{"class":590},[462,2877,615],{"class":468},[462,2879,2880,2882,2884,2886,2888,2890],{"class":464,"line":499},[462,2881,587],{"class":586},[462,2883,622],{"class":590},[462,2885,594],{"class":468},[462,2887,627],{"class":597},[462,2889,630],{"class":590},[462,2891,615],{"class":468},[462,2893,2894],{"class":464,"line":520},[462,2895,638],{"emptyLinePlaceholder":637},[462,2897,2898,2900,2902,2904,2906,2908,2910,2912,2914,2916,2918,2920,2922,2924,2926],{"class":464,"line":535},[462,2899,643],{"class":590},[462,2901,646],{"class":468},[462,2903,649],{"class":597},[462,2905,601],{"class":590},[462,2907,604],{"class":468},[462,2909,656],{"class":478},[462,2911,604],{"class":468},[462,2913,661],{"class":468},[462,2915,664],{"class":586},[462,2917,667],{"class":468},[462,2919,671],{"class":670},[462,2921,661],{"class":468},[462,2923,676],{"class":670},[462,2925,612],{"class":468},[462,2927,681],{"class":468},[462,2929,2930,2932,2934,2936,2938,2940,2942,2944,2946],{"class":464,"line":707},[462,2931,686],{"class":590},[462,2933,646],{"class":468},[462,2935,691],{"class":597},[462,2937,601],{"class":485},[462,2939,604],{"class":468},[462,2941,698],{"class":478},[462,2943,604],{"class":468},[462,2945,612],{"class":485},[462,2947,615],{"class":468},[462,2949,2950,2952,2954,2956,2958,2960,2962,2964,2966,2968,2970,2972,2974],{"class":464,"line":743},[462,2951,710],{"class":590},[462,2953,646],{"class":468},[462,2955,715],{"class":597},[462,2957,601],{"class":485},[462,2959,720],{"class":468},[462,2961,723],{"class":485},[462,2963,453],{"class":468},[462,2965,728],{"class":468},[462,2967,731],{"class":478},[462,2969,604],{"class":468},[462,2971,736],{"class":468},[462,2973,612],{"class":485},[462,2975,615],{"class":468},[462,2977,2978,2980,2982],{"class":464,"line":752},[462,2979,736],{"class":468},[462,2981,612],{"class":590},[462,2983,615],{"class":468},[462,2985,2986],{"class":464,"line":775},[462,2987,638],{"emptyLinePlaceholder":637},[462,2989,2990,2992,2994,2996,2998,3000,3003,3005,3007,3009,3011,3013,3015,3017,3019],{"class":464,"line":1271},[462,2991,643],{"class":590},[462,2993,646],{"class":468},[462,2995,649],{"class":597},[462,2997,601],{"class":590},[462,2999,604],{"class":468},[462,3001,3002],{"class":478},"\u002Fcalculator\u002Fadd",[462,3004,604],{"class":468},[462,3006,661],{"class":468},[462,3008,664],{"class":586},[462,3010,667],{"class":468},[462,3012,671],{"class":670},[462,3014,661],{"class":468},[462,3016,676],{"class":670},[462,3018,612],{"class":468},[462,3020,681],{"class":468},[462,3022,3023],{"class":464,"line":1280},[462,3024,1656],{"class":485},[462,3026,3027,3029,3032,3034,3037,3039,3041,3043,3046,3048,3050,3052],{"class":464,"line":1419},[462,3028,1145],{"class":586},[462,3030,3031],{"class":590}," param1Int",[462,3033,781],{"class":468},[462,3035,3036],{"class":597}," parseInt",[462,3038,601],{"class":485},[462,3040,671],{"class":590},[462,3042,646],{"class":468},[462,3044,3045],{"class":590},"query",[462,3047,646],{"class":468},[462,3049,1670],{"class":590},[462,3051,612],{"class":485},[462,3053,615],{"class":468},[462,3055,3056,3058,3061,3063,3065,3067,3069,3071,3073,3075,3077,3079],{"class":464,"line":1428},[462,3057,1145],{"class":586},[462,3059,3060],{"class":590}," param2Int",[462,3062,781],{"class":468},[462,3064,3036],{"class":597},[462,3066,601],{"class":485},[462,3068,671],{"class":590},[462,3070,646],{"class":468},[462,3072,3045],{"class":590},[462,3074,646],{"class":468},[462,3076,2701],{"class":590},[462,3078,612],{"class":485},[462,3080,615],{"class":468},[462,3082,3083],{"class":464,"line":1433},[462,3084,1656],{"class":485},[462,3086,3087,3089,3092,3094,3097,3099,3101,3103,3106,3108,3110,3112],{"class":464,"line":1456},[462,3088,1145],{"class":586},[462,3090,3091],{"class":590}," addResult",[462,3093,781],{"class":468},[462,3095,3096],{"class":590}," calculator",[462,3098,646],{"class":468},[462,3100,1933],{"class":597},[462,3102,601],{"class":485},[462,3104,3105],{"class":590},"param1Int",[462,3107,661],{"class":468},[462,3109,3060],{"class":590},[462,3111,612],{"class":485},[462,3113,615],{"class":468},[462,3115,3116],{"class":464,"line":1461},[462,3117,1656],{"class":485},[462,3119,3120,3122,3124,3126,3128,3130,3133,3135,3137,3139,3141],{"class":464,"line":1494},[462,3121,710],{"class":590},[462,3123,646],{"class":468},[462,3125,715],{"class":597},[462,3127,601],{"class":485},[462,3129,720],{"class":468},[462,3131,3132],{"class":485},"result",[462,3134,453],{"class":468},[462,3136,3091],{"class":590},[462,3138,736],{"class":468},[462,3140,612],{"class":485},[462,3142,615],{"class":468},[462,3144,3145,3147,3149],{"class":464,"line":1525},[462,3146,736],{"class":468},[462,3148,612],{"class":590},[462,3150,615],{"class":468},[462,3152,3153,3155,3157,3159,3161,3163,3165,3167,3169],{"class":464,"line":1530},[462,3154,755],{"class":590},[462,3156,646],{"class":468},[462,3158,691],{"class":597},[462,3160,601],{"class":590},[462,3162,604],{"class":468},[462,3164,766],{"class":478},[462,3166,604],{"class":468},[462,3168,612],{"class":590},[462,3170,615],{"class":468},[462,3172,3174,3176,3178,3180],{"class":464,"line":3173},20,[462,3175,778],{"class":468},[462,3177,781],{"class":468},[462,3179,784],{"class":590},[462,3181,615],{"class":468},[419,3183,3184],{},"As you can see we are using calculator instead having business logic inside endpoints handlers. Benefits:",[1576,3186,3187,3190,3193],{},[1579,3188,3189],{},"Business logic is encapsulated in own module",[1579,3191,3192],{},"The module is covered with unit tests",[1579,3194,3195],{},"The module can be reused in other parts of the application",[414,3197,1571],{"id":3198},"summary-1",[419,3200,3201],{},"In this post I demonstrated how to set up testing environment for NodeJS application using Intern framework and Grunt task runner.\nLiterally just with few lines of code we can have tested our application with unit tests which are almost equally important as production code.\nThe next step is to test if our integration was success, but this will be covered in the next post.",[419,3203,3204,3205],{},"Source code: ",[3206,3207,3208],"a",{"href":3208,"rel":3209},"https:\u002F\u002Fgithub.com\u002Fkospiotr\u002Fhello-js\u002Ftree\u002Fmaster\u002Fintern-unit-tests",[3210],"nofollow",[3212,3213,3214],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":446,"searchDepth":472,"depth":472,"links":3216},[3217,3218,3222,3223,3227,3231,3232,3236,3237,3238,3239,3240,3241,3242],{"id":431,"depth":472,"text":432},{"id":541,"depth":472,"text":542,"children":3219},[3220,3221],{"id":546,"depth":499,"text":547},{"id":556,"depth":499,"text":557},{"id":799,"depth":472,"text":800},{"id":934,"depth":472,"text":935,"children":3224},[3225,3226],{"id":941,"depth":499,"text":942},{"id":963,"depth":499,"text":964},{"id":1064,"depth":472,"text":1065,"children":3228},[3229,3230],{"id":1068,"depth":499,"text":1069},{"id":1081,"depth":499,"text":1082},{"id":1103,"depth":472,"text":1104},{"id":1289,"depth":472,"text":1290,"children":3233},[3234,3235],{"id":1296,"depth":499,"text":1297},{"id":1548,"depth":499,"text":1549},{"id":1570,"depth":472,"text":1571},{"id":1632,"depth":472,"text":1614},{"id":1791,"depth":472,"text":1617},{"id":2231,"depth":472,"text":1620},{"id":2392,"depth":472,"text":1623},{"id":2647,"depth":472,"text":1626},{"id":2811,"depth":472,"text":1629},"2015-03-01","Unit tests in TDD with Intern","md",{"layout":3247},"post","\u002Fblog\u002F2015-03-01-unit-tests-with-intern",{"title":408,"description":3244},"2.blog\u002F2015-03-01-unit-tests-with-intern","vhHRarXM8a1t-1GrT97uBysbcZp1sapeu5tjBxJiQls",[3253,3258],{"title":3254,"path":3255,"stem":3256,"description":3257,"children":-1},"Super Dev Mode recompile with shortcut","\u002Fblog\u002F2014-03-22-super-dev-mode-recompile-with-shortcut","2.blog\u002F2014-03-22-super-dev-mode-recompile-with-shortcut","How to use keyboard shortcut to recompile GWT application in Super Dev Mode",{"title":3259,"path":3260,"stem":3261,"description":3262,"children":-1},"REST end to end testing Node applications with Intern framework","\u002Fblog\u002F2015-03-03-end-to-end-tests-with-intern","2.blog\u002F2015-03-03-end-to-end-tests-with-intern","Testing REST with Intern",1788257054920]