Slide 1

Slide 1 text

eval everything Running Student Code at Code School Adam Fortuna

Slide 2

Slide 2 text

Body Level One

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

+

Slide 5

Slide 5 text

A Case Study

Slide 6

Slide 6 text

Title

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Multiple Tasks 2 ways to get help

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Targeted Editor

Slide 12

Slide 12 text

Live Preview

Slide 13

Slide 13 text

iframes Preview

Slide 14

Slide 14 text

This is why W3Schools did it 15 years ago

Slide 15

Slide 15 text

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(); });

Slide 16

Slide 16 text

Preview DSL window.angular = null; <source-file file='app.js'> DSL for creating previews

Slide 17

Slide 17 text

Web Workers JSHint Feedback

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

Client Side Execution

Slide 21

Slide 21 text

Custom Error Messages

Slide 22

Slide 22 text

Custom Error Message === Failing Test

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

var app; Mocha Test Suite Test Trusted

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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() {

Slide 33

Slide 33 text

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() { }); });

Slide 34

Slide 34 text

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() { });

Slide 35

Slide 35 text

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() { }); … ! ! …

Slide 36

Slide 36 text

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`.”);

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

Combines stuff.js, browserify and mocha

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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"; }

Slide 42

Slide 42 text

What’s Next?

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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