Upgrade to Pro — share decks privately, control downloads, hide ads and more …

eval everything - Running Student Code at Code School

eval everything - Running Student Code at Code School

Talk originally given at JSConf 2014, My 30, 2014 at 16:30 in track B.

Adam Fortuna

May 30, 2014
Tweet

More Decks by Adam Fortuna

Other Decks in Technology

Transcript

  1. eval everything
    Running Student Code at Code School
    Adam Fortuna

    View Slide

  2. Body Level One

    View Slide

  3. View Slide

  4. +

    View Slide

  5. A Case Study

    View Slide

  6. Title

    View Slide

  7. View Slide

  8. Multiple Tasks
    2 ways to get help

    View Slide

  9. Dynamic Feedback
    angular.module('banana', []);

    View Slide

  10. Extra Help
    angular.module('banana', []);

    View Slide

  11. Targeted Editor

    View Slide

  12. Live Preview

    View Slide

  13. iframes
    Preview

    View Slide

  14. This is why W3Schools did it 15 years ago

    View Slide

  15. iframe
    var iframe;
    !
    $(function() {
    var iFrameEl = $('iframe')[0];
    iFrameEl.sandbox = 'allow-scripts';
    iframe = iFrameEl.contentDocument;
    !
    !
    !
    !
    !
    !
    !
    });
    allow-scripts
    allow-same-origin
    allow-forms
    allow-popups
    $('textarea').on('keyup', function() {
    iframe.innerHTML = '';
    iframe.open();
    iframe.write($(this).val());
    iframe.close();
    });

    View Slide

  16. Preview DSL
    window.angular = null;

    <br/><source-file file='app.js'><br/>
    DSL for creating previews

    View Slide

  17. Web Workers
    JSHint Feedback

    View Slide

  18. self.onmessage = function(message) {
    !
    !
    !
    };
    var worker = new Worker('worker.js');
    $('textarea').on('change', function() {
    worker.postMessage({ code: $(this).val() });
    });
    worker.onmessage = function(message) {
    // message.data.errors
    };
    JSHINT(message.data.code);
    importScripts('jshint.js');
    self.postMessage({
    errors: JSHINT.errors
    });
    app.js
    worker.js

    View Slide

  19. No DOM access
    No access to parent page
    Web Workers
    Background processing
    Math/Computation Heavy
    Compression
    Games & Graphics

    View Slide

  20. Client Side Execution

    View Slide

  21. Custom Error Messages

    View Slide

  22. Custom Error Message === Failing Test

    View Slide

  23. describe('angular module', function() {
    it('Make sure to create an Angular module using the
    `angular.module` method.', function() { … });
    });

    View Slide

  24. var app;
    Sound like a lot of iFrames?
    Mocha Test Suite
    Test

    View Slide

  25. If iframes aren’t working for you, then you
    aren’t using enough of them.

    View Slide

  26. var app;
    Mocha Test Suite
    Test
    Trusted

    View Slide

  27. var app;
    Mocha Test suite
    Test
    Placeholder iframe
    (on other domain)
    Untrusted

    View Slide

  28. View Slide

  29. Browserify
    chai & sinon & jshint
    Mocha Custom Tests
    + +
    test runner
    question specific
    Stuff.js +
    transport

    View Slide

  30. 30
    60
    90
    120
    November January March May
    Use of Browserify Uses of Wow!

    View Slide

  31. Mocha
    var code = 'var app;';
    !
    describe('angular module', function() {
    it('Make sure to create an Angular module using the
    `angular.module` method.', function() {
    });
    });
    Shown only when incorrect in this way

    View Slide

  32. Don’t Really eval
    eval would contaminate all tests
    eval(code);
    var code = 'var app;';
    it('Make sure to create an Angular module using the
    `angular.module` method.', function() {
    });
    });
    describe('angular module', function() {

    View Slide

  33. Libraries
    Browserify in some libraries
    var assert = require('chai').assert,
    sinon = require('sinon'),
    angular = require('angular'),
    sandbox = require('javascript-sandbox');
    var code = 'var app;';
    describe('angular module', function() {
    it('Make sure to create an Angular module using the
    `angular.module` method.', function() {
    });
    });

    View Slide

  34. ok, eval in an iframe
    !
    !
    !
    var sandbox, spy;
    before(function() {
    spy = sinon.spy(angular, 'module');
    sandbox = new Sandbox({
    variables: { 'angular': angular }
    });
    sandbox.evaluate(code);
    });
    it(…); Setup an iframe and pass student code in
    var code = 'var app;';

    describe('angular module', function() {
    });

    View Slide

  35. it('Make sure to create an Angular module using the
    `angular.module` method.', function() {
    !
    });
    spy
    !
    !
    !

    !
    assert(spy.callCount > 0);
    !
    Let the stub do the work
    var code = 'var app;';
    describe('angular module', function() {
    });

    !
    !

    View Slide

  36. Dynamic Messages
    You created a module named banana, but we’re looking for one named gemStore.
    var code = 'var app = angular.module(\'banana\', [])';
    it('Not used message', function() {
    });
    var moduleName = spy.getCall(0).args[0];
    assert(moduleName == "gemStore", "You created a
    module named `" + moduleName + "` but we're looking for
    a module named `gemStore`.”);

    View Slide

  37. View Slide

  38. Combines stuff.js,
    browserify and mocha

    View Slide

  39. while(true) {
    alert('You shall not pass!');
    }
    Don’t stall the browser

    View Slide

  40. alert = function() {};
    console.log
    alert
    prompt

    View Slide

  41. Infinite Loop Protection
    github.com/Constellation/escodegen
    !
    while(true) {
    !
    alert('You shall not pass!');
    !
    }
    github.com/benjamn/recast
    var iteration = 0;
    iteration++;
    if(iteration > 100000) { throw "Infinite Loop Error"; }

    View Slide

  42. What’s Next?

    View Slide

  43. https://twitter.com/seriouspony/status/454327888657932288

    View Slide

  44. Thanks,
    !
    Adam Fortuna
    Technical Director Code School
    @adamfortuna
    5 Minutes of JavaScript Podcast
    fivejs.envylabs.com
    Code School
    codeschool.com

    View Slide