SlideShare a Scribd company logo
1 of 21
Download to read offline
Generating Headless Javascript
    Tests for Validations

             js.chi
         2009/06/25
        Kurt Stephens
        CashNetUSA

    http://kurtstephens.com/
 files/headless_js_testing.pdf
Problem

   Many Views.
   Many Abstract Data Types (ADT).
   Many Models that the same ADTs.
   Many different validations on each ADT
    depending on the context (localization).
   Client and Server-side validation required.
   Client and Server are different platforms (JS
    .vs. RoR).
   Traditional JS testing in a browser eats humans
    alive.
Issues and Tech

   MVC
   Ruby and Rails
   JavaScript (aka ECMAScript)
   Localization
   Client-side and Server-side validations
   Rspec
   Seamonkey Stand-alone interpreter
       apt-get install smjs
Overview

   Server- and Client-side Validations
   Widgets
   Localization
   Validations and Regular Expressions
   Translating Ruby Regexp to JS RegExp
   Test generation and Execution
Layers
Server-Side Validation

  Controller              3. flash[:error] << person.errors
                                   4. view.render
                                                              HTML
           1. person.valid?                                 <input ...>
                                                     <span class=”error”>...</>

   Model                           View



      2. current.convert.phone.valid?(self.phone_number)



CnuLocale                                                 CnuControl
Many Views beget Widgets

  Controller             Model                 View

     1. cnu_control(person, :home_phone, ...)
  2. get_config(model.class, :home_phone)

cnu_control.yml:                                           HTML
person:                                     CnuControl   <input ...>
 home_phone:
  type: phone

    3. rx = current.convert.phone.rx
                                                             JS
                           4. js << rx.to_js



   CnuLocale                   Cnu::Ecmascript::Regexp
Overkill?
Localization

   CnuLocale
       ADTs
            Phone Number, Date, Money, Passport, etc.
       Validations
            Is user input valid?
            Uses Regexp, but can be programatic.
       Normalization
            ”+61 02 1234 5678” => ”161212345678”
       Presentation
            ”161212345678” => AU ”(02) 1234 5678”
            ”161212345678” => US ”+1 61212345678”
This Can Happen To You!
Australian Phone Number
def phone_number_au
  @@phone_number_au ||=
    begin
      sep = "[-.s]"
    /
    # +CC: +61 | 61 | b
    ((?:+|b)s*((?# country_code) 61)#{sep}?)?
    # m[:digits] will contain digits and formatting, without the + country code.
    ((?# digits)
    # 04 1234 5678      => 04 1234 5678
    # 0412345678        => 04 1234 5678
      ((?# area_code) 0?[234578]) #{sep}?((?# prefix) d{4})#{sep}?((?# suffix) d{4})
    |
    # (04) 1234 5678    => 04 1234 5678
    # (04)12345678      => 04 1234 5678
    (((?# area_code) 0?[234578]))#{sep}?((?# prefix) d{4})#{sep}?((?# suffix) d{4})
    |
    # 0412 345 678      => 04 1234 5678
    # 0412 345678       => 04 1234 5678
      ((?# area_code) 0?[234578])((?# prefix) d{2} #{sep} d{2})((?# suffix) d{1}#{sep}?d{3})
    |
    # (0412) 345 678    => 04 1234 5678
    # (0412)345 678     => 04 1234 5678
    # (0412)345678      => 04 1234 5678
    (((?# area_code) 0?[234578])((?# prefix) d{2})#{sep}?d{2})((?# suffix) d{1}#{sep}?d{3})
    |
    # 1800 123 456      => 1800 123 456
    # 1800123456        => 1800 123 456
      ((?# area_code) 1[38]00) #{sep}?((?# prefix) d{3})#{sep}?((?# suffix) d{3})
    |
    # ... A BUNCH MORE HERE! ...
    # 18 1234           => 18 '' 1234
    # 181234            => 18 '' 1234
      ((?# area_code) 1[38]) #{sep}?((?# prefix) )((?# suffix) d{4})
    )
    b
    /x.tag!
    end
end
Keeping it Managable
Elements of Style

   Optional '+' and or country code prefix:
    
        /((?:+|b)s*((?# country_code) 61)#{sep}?)?/

   Zero-length non-word assertions:
    
        /b((?# digits) d+)b/

   Tagged Captures:
    
        /((?# area_code) 0?[234578])   #{sep}?((?# prefix) d{4})#{sep}?((?#
        suffix) d{4})/

   Extended Syntax:
    
        /something else/x

   Tag Transformation:
    
        (”foo1234bar” =~ /foo((?# digits) d+)bar/.tag!)[:digits] => ”1234”
Standards: Everyone's Got One

   Ruby Regexp
       Handles (?# comments).
       Use ((?# tag) captured expr) for naming captures.
       //x enables insignificant whitespace and #
        comments.
   JS RegExp
       Does not handle //x or comments.
       b does not match BOL and EOL.
JS Regexp
   NO: b also matches $ and ^
   NO: internal comments.
   NO: extended syntax prefix.
   NO: extended syntax comments (e.g.: "n# foo barn")
   YES: non-capturing groups.
   YES: pattern multiplicity: (e.g.: /d{3}/ => /ddd/)
   NO: /A/ or /Z/
   YES: /b/ zero-width word-boundary assertion.
   YES: /B/ zero-width non-word-boundary assertion.
   YES: look-ahead assertions
   NO: look-behind assertions
Basics
Regexp in the Wild
   CnuControl
       Generate JS and executed server-side validation
        for HTML widgets for ADT values.
   CnuLocale
       Regexp with tagged captures to find relevant ADT
        data in user input.
       Normalize relevant user input to ADT.
   Cnu::Ecmascript::Regexp
       Converts Ruby Regexp objects to JS RegExp code.
       Ruby /bfoob/.to_js => JS expr "(new
        RegExp("(?:b|^|$)foo(?:b|^|$)", ""))"
My Wookie is Also My Bookie




   http://www.morningstar.nildram.co.uk/A_New_Sith.html
Testing

   Rspec test helper:
       Tests Ruby Regexp for match/not match on a string
        literal.
       Generates JS expression that is the same test on a
        JS Regexp generated from the Ruby Regexp.
       Executes the test using smjs (seamonkey JS
        interpreter)
Rspec

it "converts Regexp.phone_number_au" do
    rx = Regexp.phone_number_au
    check_rx(rx, "", false)
    check_rx(rx, "foobar", false)
    check_rx(rx, "61 (03) 1234 5678", true)
    check_rx(rx, "+61.(03).1234.5678", true)
end
Generated Ruby and JS Tests

check_rx(rx, “foobar”, false) =>


 (rx === “foobar”).should == nil


 cnu_assert(
  "(new RegExp("...", "")).test("foobar") == false",
  (new RegExp("((?:+|(?:b|^|$))s*(61)[-.s]?)?((0?[234578])[-.s]?
(d{4})[-.s]?(d{4})|((0?[234578]))[-.s]?(d{4})[-.s]?
(d{4})|(0?[234578])(d{2}[-.s]d{2})(d{1}[-.s]?d{3})|((0?
[234578])(d{2})[-.s]?d{2})(d{1}[-.s]?d{3})|(1[38]00)[-.s]?
(d{3})[-.s]?(d{3})|((1[38]00))[-.s]?(d{3})[-.s]?(d{3})|
(1[38]0)[-.s]?()(d{4})|((1[38]0))[-.s]?()(d{4})|((1[38]))
[-.s]?()(d{4})|(1[38])[-.s]?()(d{4}))(?:b|^|$)",
"")).test("foobar"),
  "==",
  false);

More Related Content

What's hot

JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the ASTJarrod Overson
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced JavascriptAdieu
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5 Wildan Maulana
 
eXo SEA - JavaScript Introduction Training
eXo SEA - JavaScript Introduction TrainingeXo SEA - JavaScript Introduction Training
eXo SEA - JavaScript Introduction TrainingHoat Le
 
A Re-Introduction to JavaScript
A Re-Introduction to JavaScriptA Re-Introduction to JavaScript
A Re-Introduction to JavaScriptSimon Willison
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code DevelopmentPeter Gfader
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSVisual Engineering
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationKirill Chebunin
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
Hardened JavaScript
Hardened JavaScriptHardened JavaScript
Hardened JavaScriptKrisKowal2
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 

What's hot (20)

JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
eXo SEA - JavaScript Introduction Training
eXo SEA - JavaScript Introduction TrainingeXo SEA - JavaScript Introduction Training
eXo SEA - JavaScript Introduction Training
 
A Re-Introduction to JavaScript
A Re-Introduction to JavaScriptA Re-Introduction to JavaScript
A Re-Introduction to JavaScript
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code Development
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
ES2015 workflows
ES2015 workflowsES2015 workflows
ES2015 workflows
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJS
 
JavaScript Basics and Trends
JavaScript Basics and TrendsJavaScript Basics and Trends
JavaScript Basics and Trends
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Hardened JavaScript
Hardened JavaScriptHardened JavaScript
Hardened JavaScript
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Java script -23jan2015
Java script -23jan2015Java script -23jan2015
Java script -23jan2015
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 

Similar to Headless Js Testing

Maharashtra state board Hsc IT Chap 3.pdf
Maharashtra state board Hsc IT Chap 3.pdfMaharashtra state board Hsc IT Chap 3.pdf
Maharashtra state board Hsc IT Chap 3.pdfAAFREEN SHAIKH
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersRick Beerendonk
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Introzhang tao
 
The Dynamic Language is not Enough
The Dynamic Language is not EnoughThe Dynamic Language is not Enough
The Dynamic Language is not EnoughLukas Renggli
 
ClojureScript: The Good Parts
ClojureScript: The Good PartsClojureScript: The Good Parts
ClojureScript: The Good PartsKent Ohashi
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
Beyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisBeyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisFastly
 
The Art Of Readable Code
The Art Of Readable CodeThe Art Of Readable Code
The Art Of Readable CodeBaidu, Inc.
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
IT2255 Web Essentials - Unit III Client-Side Processing and Scripting
IT2255 Web Essentials - Unit III Client-Side Processing and ScriptingIT2255 Web Essentials - Unit III Client-Side Processing and Scripting
IT2255 Web Essentials - Unit III Client-Side Processing and Scriptingpkaviya
 
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...BradNeuberg
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Plataformatec
 
Oracle APEX migration to 5.1 - Our experience
Oracle APEX migration to 5.1 - Our experienceOracle APEX migration to 5.1 - Our experience
Oracle APEX migration to 5.1 - Our experienceLino Schildenfeld
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperGiordano Scalzo
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceJesse Vincent
 

Similar to Headless Js Testing (20)

Maharashtra state board Hsc IT Chap 3.pdf
Maharashtra state board Hsc IT Chap 3.pdfMaharashtra state board Hsc IT Chap 3.pdf
Maharashtra state board Hsc IT Chap 3.pdf
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
Wt unit 2 ppts client side technology
Wt unit 2 ppts client side technologyWt unit 2 ppts client side technology
Wt unit 2 ppts client side technology
 
Wt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technologyWt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technology
 
bluespec talk
bluespec talkbluespec talk
bluespec talk
 
The Dynamic Language is not Enough
The Dynamic Language is not EnoughThe Dynamic Language is not Enough
The Dynamic Language is not Enough
 
Little Big Ruby
Little Big RubyLittle Big Ruby
Little Big Ruby
 
ClojureScript: The Good Parts
ClojureScript: The Good PartsClojureScript: The Good Parts
ClojureScript: The Good Parts
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Beyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisBeyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic Analysis
 
The Art Of Readable Code
The Art Of Readable CodeThe Art Of Readable Code
The Art Of Readable Code
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
IT2255 Web Essentials - Unit III Client-Side Processing and Scripting
IT2255 Web Essentials - Unit III Client-Side Processing and ScriptingIT2255 Web Essentials - Unit III Client-Side Processing and Scripting
IT2255 Web Essentials - Unit III Client-Side Processing and Scripting
 
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
 
Oracle APEX migration to 5.1 - Our experience
Oracle APEX migration to 5.1 - Our experienceOracle APEX migration to 5.1 - Our experience
Oracle APEX migration to 5.1 - Our experience
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapper
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 

More from Brian Moschel

A Very Biased Comparison of MVC Libraries
A Very Biased Comparison of MVC LibrariesA Very Biased Comparison of MVC Libraries
A Very Biased Comparison of MVC LibrariesBrian Moschel
 
Comet: an Overview and a New Solution Called Jabbify
Comet: an Overview and a New Solution Called JabbifyComet: an Overview and a New Solution Called Jabbify
Comet: an Overview and a New Solution Called JabbifyBrian Moschel
 
Comet, Simplified, with Jabbify Comet Service
Comet, Simplified, with Jabbify Comet ServiceComet, Simplified, with Jabbify Comet Service
Comet, Simplified, with Jabbify Comet ServiceBrian Moschel
 
Building an App with jQuery and JAXER
Building an App with jQuery and JAXERBuilding an App with jQuery and JAXER
Building an App with jQuery and JAXERBrian Moschel
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript FunctionsBrian Moschel
 
Basic inheritance in JavaScript
Basic inheritance in JavaScriptBasic inheritance in JavaScript
Basic inheritance in JavaScriptBrian Moschel
 
Things to avoid in JavaScript
Things to avoid in JavaScriptThings to avoid in JavaScript
Things to avoid in JavaScriptBrian Moschel
 

More from Brian Moschel (11)

A Very Biased Comparison of MVC Libraries
A Very Biased Comparison of MVC LibrariesA Very Biased Comparison of MVC Libraries
A Very Biased Comparison of MVC Libraries
 
FuncUnit
FuncUnitFuncUnit
FuncUnit
 
Comet: an Overview and a New Solution Called Jabbify
Comet: an Overview and a New Solution Called JabbifyComet: an Overview and a New Solution Called Jabbify
Comet: an Overview and a New Solution Called Jabbify
 
Web 2.0 Expo Notes
Web 2.0 Expo NotesWeb 2.0 Expo Notes
Web 2.0 Expo Notes
 
Comet, Simplified, with Jabbify Comet Service
Comet, Simplified, with Jabbify Comet ServiceComet, Simplified, with Jabbify Comet Service
Comet, Simplified, with Jabbify Comet Service
 
Building an App with jQuery and JAXER
Building an App with jQuery and JAXERBuilding an App with jQuery and JAXER
Building an App with jQuery and JAXER
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
Ajax3
Ajax3Ajax3
Ajax3
 
Basic inheritance in JavaScript
Basic inheritance in JavaScriptBasic inheritance in JavaScript
Basic inheritance in JavaScript
 
Things to avoid in JavaScript
Things to avoid in JavaScriptThings to avoid in JavaScript
Things to avoid in JavaScript
 
Javascript and DOM
Javascript and DOMJavascript and DOM
Javascript and DOM
 

Recently uploaded

Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxMasterG
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch TuesdayIvanti
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptxFIDO Alliance
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...panagenda
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?Mark Billinghurst
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform EngineeringMarcus Vechiato
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuidePixlogix Infotech
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGDSC PJATK
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsLeah Henrickson
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024Lorenzo Miniero
 
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...marcuskenyatta275
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Skynet Technologies
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightSafe Software
 
Oauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftOauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftshyamraj55
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...FIDO Alliance
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireExakis Nelite
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewDianaGray10
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityVictorSzoltysek
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Paige Cruz
 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Hiroshi SHIBATA
 

Recently uploaded (20)

Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate Guide
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
Oauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftOauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoft
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - Questionnaire
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024
 

Headless Js Testing

  • 1. Generating Headless Javascript Tests for Validations js.chi 2009/06/25 Kurt Stephens CashNetUSA http://kurtstephens.com/ files/headless_js_testing.pdf
  • 2. Problem  Many Views.  Many Abstract Data Types (ADT).  Many Models that the same ADTs.  Many different validations on each ADT depending on the context (localization).  Client and Server-side validation required.  Client and Server are different platforms (JS .vs. RoR).  Traditional JS testing in a browser eats humans alive.
  • 3. Issues and Tech  MVC  Ruby and Rails  JavaScript (aka ECMAScript)  Localization  Client-side and Server-side validations  Rspec  Seamonkey Stand-alone interpreter  apt-get install smjs
  • 4. Overview  Server- and Client-side Validations  Widgets  Localization  Validations and Regular Expressions  Translating Ruby Regexp to JS RegExp  Test generation and Execution
  • 6. Server-Side Validation Controller 3. flash[:error] << person.errors 4. view.render HTML 1. person.valid? <input ...> <span class=”error”>...</> Model View 2. current.convert.phone.valid?(self.phone_number) CnuLocale CnuControl
  • 7. Many Views beget Widgets Controller Model View 1. cnu_control(person, :home_phone, ...) 2. get_config(model.class, :home_phone) cnu_control.yml: HTML person: CnuControl <input ...> home_phone: type: phone 3. rx = current.convert.phone.rx JS 4. js << rx.to_js CnuLocale Cnu::Ecmascript::Regexp
  • 9. Localization  CnuLocale  ADTs  Phone Number, Date, Money, Passport, etc.  Validations  Is user input valid?  Uses Regexp, but can be programatic.  Normalization  ”+61 02 1234 5678” => ”161212345678”  Presentation  ”161212345678” => AU ”(02) 1234 5678”  ”161212345678” => US ”+1 61212345678”
  • 10. This Can Happen To You!
  • 11. Australian Phone Number def phone_number_au @@phone_number_au ||= begin sep = "[-.s]" / # +CC: +61 | 61 | b ((?:+|b)s*((?# country_code) 61)#{sep}?)? # m[:digits] will contain digits and formatting, without the + country code. ((?# digits) # 04 1234 5678 => 04 1234 5678 # 0412345678 => 04 1234 5678 ((?# area_code) 0?[234578]) #{sep}?((?# prefix) d{4})#{sep}?((?# suffix) d{4}) | # (04) 1234 5678 => 04 1234 5678 # (04)12345678 => 04 1234 5678 (((?# area_code) 0?[234578]))#{sep}?((?# prefix) d{4})#{sep}?((?# suffix) d{4}) | # 0412 345 678 => 04 1234 5678 # 0412 345678 => 04 1234 5678 ((?# area_code) 0?[234578])((?# prefix) d{2} #{sep} d{2})((?# suffix) d{1}#{sep}?d{3}) | # (0412) 345 678 => 04 1234 5678 # (0412)345 678 => 04 1234 5678 # (0412)345678 => 04 1234 5678 (((?# area_code) 0?[234578])((?# prefix) d{2})#{sep}?d{2})((?# suffix) d{1}#{sep}?d{3}) | # 1800 123 456 => 1800 123 456 # 1800123456 => 1800 123 456 ((?# area_code) 1[38]00) #{sep}?((?# prefix) d{3})#{sep}?((?# suffix) d{3}) | # ... A BUNCH MORE HERE! ... # 18 1234 => 18 '' 1234 # 181234 => 18 '' 1234 ((?# area_code) 1[38]) #{sep}?((?# prefix) )((?# suffix) d{4}) ) b /x.tag! end end
  • 13. Elements of Style  Optional '+' and or country code prefix:  /((?:+|b)s*((?# country_code) 61)#{sep}?)?/  Zero-length non-word assertions:  /b((?# digits) d+)b/  Tagged Captures:  /((?# area_code) 0?[234578]) #{sep}?((?# prefix) d{4})#{sep}?((?# suffix) d{4})/  Extended Syntax:  /something else/x  Tag Transformation:  (”foo1234bar” =~ /foo((?# digits) d+)bar/.tag!)[:digits] => ”1234”
  • 14. Standards: Everyone's Got One  Ruby Regexp  Handles (?# comments).  Use ((?# tag) captured expr) for naming captures.  //x enables insignificant whitespace and # comments.  JS RegExp  Does not handle //x or comments.  b does not match BOL and EOL.
  • 15. JS Regexp  NO: b also matches $ and ^  NO: internal comments.  NO: extended syntax prefix.  NO: extended syntax comments (e.g.: "n# foo barn")  YES: non-capturing groups.  YES: pattern multiplicity: (e.g.: /d{3}/ => /ddd/)  NO: /A/ or /Z/  YES: /b/ zero-width word-boundary assertion.  YES: /B/ zero-width non-word-boundary assertion.  YES: look-ahead assertions  NO: look-behind assertions
  • 17. Regexp in the Wild  CnuControl  Generate JS and executed server-side validation for HTML widgets for ADT values.  CnuLocale  Regexp with tagged captures to find relevant ADT data in user input.  Normalize relevant user input to ADT.  Cnu::Ecmascript::Regexp  Converts Ruby Regexp objects to JS RegExp code.  Ruby /bfoob/.to_js => JS expr "(new RegExp("(?:b|^|$)foo(?:b|^|$)", ""))"
  • 18. My Wookie is Also My Bookie http://www.morningstar.nildram.co.uk/A_New_Sith.html
  • 19. Testing  Rspec test helper:  Tests Ruby Regexp for match/not match on a string literal.  Generates JS expression that is the same test on a JS Regexp generated from the Ruby Regexp.  Executes the test using smjs (seamonkey JS interpreter)
  • 20. Rspec it "converts Regexp.phone_number_au" do rx = Regexp.phone_number_au check_rx(rx, "", false) check_rx(rx, "foobar", false) check_rx(rx, "61 (03) 1234 5678", true) check_rx(rx, "+61.(03).1234.5678", true) end
  • 21. Generated Ruby and JS Tests check_rx(rx, “foobar”, false) => (rx === “foobar”).should == nil cnu_assert( "(new RegExp("...", "")).test("foobar") == false", (new RegExp("((?:+|(?:b|^|$))s*(61)[-.s]?)?((0?[234578])[-.s]? (d{4})[-.s]?(d{4})|((0?[234578]))[-.s]?(d{4})[-.s]? (d{4})|(0?[234578])(d{2}[-.s]d{2})(d{1}[-.s]?d{3})|((0? [234578])(d{2})[-.s]?d{2})(d{1}[-.s]?d{3})|(1[38]00)[-.s]? (d{3})[-.s]?(d{3})|((1[38]00))[-.s]?(d{3})[-.s]?(d{3})| (1[38]0)[-.s]?()(d{4})|((1[38]0))[-.s]?()(d{4})|((1[38])) [-.s]?()(d{4})|(1[38])[-.s]?()(d{4}))(?:b|^|$)", "")).test("foobar"), "==", false);