diff --git a/.gitignore b/.gitignore index 9d80f26..13ccd15 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,6 @@ results npm-debug.log node_modules public/index.html -public/main.css -public/main.css.map -public/main.js \ No newline at end of file +public/style.css +public/style.css.map +public/script.js \ No newline at end of file diff --git a/clientSrc/corpus.js b/clientSrc-old/corpus.js similarity index 100% rename from clientSrc/corpus.js rename to clientSrc-old/corpus.js diff --git a/clientSrc/editor.js b/clientSrc-old/editor.js similarity index 100% rename from clientSrc/editor.js rename to clientSrc-old/editor.js diff --git a/clientSrc/keycode.js b/clientSrc-old/keycode.js similarity index 100% rename from clientSrc/keycode.js rename to clientSrc-old/keycode.js diff --git a/clientSrc/log.js b/clientSrc-old/log.js similarity index 100% rename from clientSrc/log.js rename to clientSrc-old/log.js diff --git a/clientSrc/main.js b/clientSrc-old/main.js similarity index 100% rename from clientSrc/main.js rename to clientSrc-old/main.js diff --git a/clientSrc/main.less b/clientSrc-old/main.less similarity index 100% rename from clientSrc/main.less rename to clientSrc-old/main.less diff --git a/clientSrc/menu.js b/clientSrc-old/menu.js similarity index 100% rename from clientSrc/menu.js rename to clientSrc-old/menu.js diff --git a/clientSrc/navigate.js b/clientSrc-old/navigate.js similarity index 100% rename from clientSrc/navigate.js rename to clientSrc-old/navigate.js diff --git a/clientSrc/render-term.js b/clientSrc-old/render-term.js similarity index 100% rename from clientSrc/render-term.js rename to clientSrc-old/render-term.js diff --git a/clientSrc/render-validity.js b/clientSrc-old/render-validity.js similarity index 100% rename from clientSrc/render-validity.js rename to clientSrc-old/render-validity.js diff --git a/clientSrc/view.js b/clientSrc-old/view.js similarity index 100% rename from clientSrc/view.js rename to clientSrc-old/view.js diff --git a/clientSrc/TODO.js b/clientSrc/TODO.js deleted file mode 100644 index 6ace329..0000000 --- a/clientSrc/TODO.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -/** @constructor */ -var TodoException = function (message) { - this.message = message || '(unfinished code)'; -}; - -TodoException.prototype.toString = function () { - return 'TODO: ' + this.message; -}; - -var TODO = function (message) { - throw new TodoException(message); -}; - -module.exports = TODO; diff --git a/clientSrc/app/app.js b/clientSrc/app/app.js new file mode 100644 index 0000000..2fb25ba --- /dev/null +++ b/clientSrc/app/app.js @@ -0,0 +1,41 @@ +'use strict'; + +//This is an entry point into application. +//App consists of folowing modules: +//Corpus - corpus binding REST/Socket <=> HTML DOM + updates from either side. +//Logger - +//Navigator - + + +var angular = require('angular'); +var uiRouter = require('angular-ui-router'); +var socket = global.io = require('socket.io-client')(); +var debug = global.debug = require('debug'); +var log = debug('puddle:client:init'); + +//this will register ng-modules into angular namespace. +require('angular-socket-io'); +require('./corpus.js'); + + +//require all modules. +var puddle = angular.module('puddle', [uiRouter, 'corpus']); + +//Define default route where to redirect all unknown URL's +//Outher routes defined witin other modules. +puddle.config(function ($stateProvider, $urlRouterProvider) { + $urlRouterProvider.otherwise('/corpus'); +}); + + +socket.on('connect', function () { + log('Socket IO connection estabilished'); +}); +socket.on('corpus', function (method, args) { + log('Corpus API incoming call: ', method, args); +}); + +socket.emit('corpus', 'findAll'); +socket.emit('corpus', 'findById', ['540448b62711b16e9a6c7132']); + +log('Puddle init complete.'); \ No newline at end of file diff --git a/clientSrc/app/corpus.js b/clientSrc/app/corpus.js new file mode 100644 index 0000000..7f725f3 --- /dev/null +++ b/clientSrc/app/corpus.js @@ -0,0 +1,47 @@ +'use strict'; + + +var log = require('debug')('puddle:client:corpus'); +var angular = require('angular'); +var _ = require('lodash'); +var uiRouter = require('angular-ui-router'); +var corpus = angular.module('corpus', [uiRouter, 'btford.socket-io']); + +corpus.config(function ($stateProvider) { + $stateProvider + .state('corpus', { + url: '/corpus', + templateUrl: 'corpus.html', + controller: 'corpus' + }); +}); + +corpus.factory('Socket', function (socketFactory) { + return socketFactory(); +}); + +corpus.controller('corpus', function ($scope, CorpusDB) { + $scope.corpus = CorpusDB.corpus; +}); + +corpus.factory('CorpusDB', function (Socket) { + var codes = []; + Socket.on('corpus', function (method, args) { + switch (method) { + case 'findAll': + var corpus = args[0]; + if (_.isArray(corpus)) { + codes.length = 0; + corpus.forEach(function (a) { + codes.push(a); + }); + } + break; + } + }); + + return {corpus: codes}; +}); + +log('Corpus module init complete'); + diff --git a/clientSrc/assert.js b/clientSrc/assert.js deleted file mode 100644 index 7f84896..0000000 --- a/clientSrc/assert.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; - -var _ = require('underscore'); - -/** @constructor */ -var AssertException = function (message) { - this.message = message || '(unspecified)'; -}; - -AssertException.prototype.toString = function () { - return 'Assertion Failed: ' + this.message; -}; - -var assert = function (condition, message) { - if (!condition) { - throw new AssertException(message); - } -}; - -assert.Exception = AssertException; - -// This is better than node's builtin assert comparison -assert.equal = function (actual, expected, message) { - assert(_.isEqual(actual, expected), - (message || '') + - '\n actual = ' + JSON.stringify(actual) + - '\n expected = ' + JSON.stringify(expected)); -}; - -module.exports = assert; diff --git a/clientSrc/index.html b/clientSrc/index.html index b0207e6..b118f8f 100755 --- a/clientSrc/index.html +++ b/clientSrc/index.html @@ -1,14 +1,21 @@ - + Pomagma Editor - - - + + + + + + + -
- +Corpus editor + +
diff --git a/clientSrc/styles/style.less b/clientSrc/styles/style.less new file mode 100644 index 0000000..e69de29 diff --git a/doc/using.md b/doc/using.md index 7b90744..4689639 100644 --- a/doc/using.md +++ b/doc/using.md @@ -15,7 +15,7 @@ To start a server that: - builds with JS sourcemaps - npm run dev # alias for gulp serve --dev=true + npm run dev # alias for gulp develop ## Debugging Puddle @@ -24,9 +24,12 @@ To run headless unit tests in various debug modes: npm test DEBUG=* npm test DEBUG=express:*,puddle:* npm test + +## To debug browserside -To run in-browser unit tests, start Pomagam+Puddle servers as above and -navigate to http://localhost:34934#test +Run following command in console. + + debug.enable('puddle:*') ## Continous testing and code quality diff --git a/gulpfile.js b/gulpfile.js index 77c5bc5..729d84d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,6 +2,7 @@ var gulp = require('gulp'); var gulpif = require('gulp-if'); +var ngAnnotate = require('gulp-ng-annotate'); var uglify = require('gulp-uglify'); var jshint = require('gulp-jshint'); var gutil = require('gulp-util'); @@ -11,6 +12,7 @@ var nodemon = require('gulp-nodemon'); var less = require('gulp-less-sourcemap'); var exec = require('child_process').exec; var LIVERELOAD_PORT = 34939; +var rename = require('gulp-rename'); var lr = require('tiny-lr')(); var watcher = function (tasks, paths) { @@ -19,7 +21,8 @@ var watcher = function (tasks, paths) { gulp.watch(paths, tasks) .on('change', function (event) { gutil.log( - 'File ' + event.path + ' was ' + event.type + ', refreshing' + 'File ' + event.path + ' was ' + event.type + + ', refreshing' ); }).on('error', function swallowError() { this.emit('end'); @@ -45,7 +48,7 @@ gulp.task('mocha', function (cb) { gulp.task('less', function () { //process LESS -> CSS - return gulp.src('./clientSrc/main.less') + return gulp.src('./clientSrc/styles/style.less') .pipe(less()) .pipe(gulp.dest('./public')); }); @@ -58,13 +61,14 @@ gulp.task('copyHtml', function () { gulp.task('browserify', function () { //Browserify - return gulp.src('./clientSrc/main.js') + return gulp.src('./clientSrc/app/app.js') .pipe(browserify({ - insertGlobals: true, exclude: ['mocha'], debug: argv.dev })) + .pipe(ngAnnotate()) .pipe(gulpif(!argv.dev, uglify())) + .pipe(rename('script.js')) .pipe(gulp.dest('./public')); }); @@ -99,9 +103,10 @@ gulp.task('startLiveReload', function () { gulp.task('nodemon', function () { nodemon({ - script: 'server.js', + script: './server/server.js', ext: 'js', - watch: ['./lib', 'server.js'] + args: argv.dev ? ['--withLiveReload=true'] : null, + watch: ['./server'] }).on('restart', function () { console.log('Restarted server'); }); @@ -109,10 +114,24 @@ gulp.task('nodemon', function () { gulp.task('trackLiveReload', ['default'], function () { lr.changed({body: { - files: ['main.js', 'index.html', 'main.css'] + files: ['static/script.js', 'static/index.html', 'static/style.css'] }}); }); -gulp.task('serve', ['startLiveReload', 'default', 'nodemon'], function () { - watcher(['trackLiveReload'], ['./clientSrc/**/*'])(); +gulp.task('serve', ['default'], function () { + require('./server/server'); }); + +gulp.task('develop', function () { + argv.dev = true; + gulp.start('developStart'); +}); + +gulp.task('developStart', ['startLiveReload', 'default' , 'nodemon'], + function () { + watcher(['trackLiveReload'], [ + './clientSrc/**/*.js', + './clientSrc/**/*.html', + './clientSrc/**/*.less' + ])(); + }); diff --git a/lib/corpus.js b/lib/corpus.js deleted file mode 100644 index 7eb1c6a..0000000 --- a/lib/corpus.js +++ /dev/null @@ -1,100 +0,0 @@ -/* jshint node:true */ -'use strict'; - -var debug = require('debug')('puddle:corpus'); -var assert = require('assert'); -var path = require('path'); -var fs = require('fs'); -var _ = require('underscore'); - -var DUMP_FILE = path.join(__dirname, '..', 'corpus.dump'); -var TEMP_FILE = path.join(__dirname, '..', 'temp.corpus.dump'); - -var statements = {}; -var nextId = 0; - -var loadStatement = (function () { - var switch_ = { - 'ASSERT': function (body) { - return {'name': null, 'code': body}; - }, - 'DEFINE': function (body) { - var varName = body.split(' ', 2); - assert.deepEqual(varName[0], 'VAR'); - var name = varName[1]; - var code = body.slice(4 + name.length + 1); - return {'name': name, 'code': code}; - } - }; - return function (string) { - var prefix = string.split(' ', 1)[0]; - var body = string.slice(prefix.length + 1); - return switch_[prefix](body); - }; -})(); - -var dumpStatement = function (statement) { - if (statement.name === null) { - return 'ASSERT ' + statement.code; - } else { - return 'DEFINE VAR ' + statement.name + ' ' + statement.code; - } -}; - - -var load = function () { - debug('loading corpus...'); - statements = {}; - nextId = 0; - fs.readFileSync(DUMP_FILE).toString().split('\n').forEach(function (line) { - line = line.replace(/#.*/, '').trim(); - if (line) { - var statement = loadStatement(line); - statements[nextId++] = statement; - } - }); - debug('...corpus loaded'); -}; - -var dump = function () { - debug('dumping corpus...'); - var lines = _.map(statements, dumpStatement); - lines.sort(); - lines.splice(0, 0, '# this file is managed by corpus.js'); - fs.writeFileSync(TEMP_FILE, lines.join('\n')); - fs.renameSync(TEMP_FILE, DUMP_FILE); - debug('...corpus dumped'); - return lines.join('\n'); -}; - - -exports.load = load; -exports.dump = dump; - -exports.findAll = function () { - return _.map(statements, function (value, id) { - var line = _.clone(value); - line.id = id; - return line; - }); -}; - -exports.findOne = function (id) { - return _.clone(statements[id]); -}; - -exports.create = function (statement) { - var id = nextId++; - statements[id] = statement; - return id; -}; - -exports.update = function (id, statement) { - assert(_.has(statements, id), 'object cannot be set'); - statements[id] = _.clone(statement); -}; - -exports.remove = function (id) { - assert(_.has(statements, id), 'object cannot be set'); - delete statements[id]; -}; diff --git a/package.json b/package.json index c5437a5..fbe3f85 100644 --- a/package.json +++ b/package.json @@ -2,32 +2,39 @@ "name": "puddle", "version": "0.1.8", "description": "A responsive editor built on Pomagma", - "main": "server.js", + "main": "server/server.js", "dependencies": { - "amdefine": "=0.1.0", + "angular": "^1.2.21", + "angular-socket-io": "^0.6.0", + "angular-ui-router": "^0.2.10", "body-parser": "^1.6.1", "debug": "^1.0.4", "express": "^4.8.3", - "gulp": "^3.8.7", - "gulp-browserify": "^0.5.0", - "gulp-if": "^1.2.4", - "gulp-jshint": "^1.8.4", - "gulp-less-sourcemap": "^1.3.3", - "gulp-nodemon": "^1.0.4", - "gulp-uglify": "^0.3.1", - "jquery": "^2.1.1", "less": "^1.7.4", + "lodash": "^2.4.1", "mongoose": "~3.8.15", "pomagma": ">=0.1.8", "puddle-syntax": "~0.1.0", + "q": "^1.0.1", "socket.io": "^1.0.6", "socket.io-client": "^1.0.6", "underscore": "^1.6.0", "yargs": "^1.3.1" }, "devDependencies": { + "chai": "^1.9.1", + "chai-as-promised": "^4.1.1", "connect-livereload": "^0.4.0", + "gulp": "^3.8.7", + "gulp-browserify": "^0.5.0", + "gulp-if": "^1.2.4", + "gulp-jshint": "^1.8.4", + "gulp-less-sourcemap": "^1.3.3", "gulp-mocha": "^1.0.0", + "gulp-ng-annotate": "^0.3.0", + "gulp-nodemon": "^1.0.4", + "gulp-rename": "^1.2.0", + "gulp-uglify": "^0.3.1", "gulp-util": "^3.0.0", "jshint": "^2.5.4", "karma": "^0.12.22", @@ -36,6 +43,7 @@ "karma-mocha": "^0.1.9", "karma-phantomjs-launcher": "^0.1.4", "mocha": "^1.21.4", + "mockgoose": "^1.10.2", "phantomjs": "^1.9.7-15", "rewire": "^2.1.0", "sinon": "^1.10.3", @@ -48,7 +56,7 @@ "mocha": "./node_modules/gulp/bin/gulp.js mocha", "test": "npm run gulp && npm run lint && npm run mocha", "start": "./node_modules/gulp/bin/gulp.js serve", - "dev": "./node_modules/gulp/bin/gulp.js serve --dev=true", + "dev": "./node_modules/gulp/bin/gulp.js develop", "clean": "cd public && rm -f index.html main.css* main.js" }, "repository": { diff --git a/server/lib/corpus.js b/server/lib/corpus.js new file mode 100644 index 0000000..ad69a03 --- /dev/null +++ b/server/lib/corpus.js @@ -0,0 +1,35 @@ +'use strict'; + +var debug = require('debug')('puddle:corpus'); +var assert = require('chai').assert; + +module.exports = function (mongoose) { + assert(mongoose); + debug('Corpus init'); + + var Corpus = mongoose.model('Corpus', mongoose.Schema({ + code: String + })); + + return { + findAll: function () { + return Corpus.find({}).exec(); + }, + findById: function (id) { + return Corpus.findById(id).exec(); + }, + create: function (code) { + assert.isString(code); + return Corpus.create({code: code}); + }, + update: function (id, code) { + assert.isString(code); + return Corpus.findByIdAndUpdate(id, {code: code}).exec(); + }, + remove: function (id) { + return Corpus.findByIdAndRemove(id).exec(); + } + }; +}; + + diff --git a/corpus.dump b/server/main.corpus similarity index 100% rename from corpus.dump rename to server/main.corpus diff --git a/server.js b/server/server.js similarity index 63% rename from server.js rename to server/server.js index d69ff63..23eb0f1 100644 --- a/server.js +++ b/server/server.js @@ -3,13 +3,13 @@ var debug = require('debug')('puddle:server'); var assert = require('assert'); var path = require('path'); -var _ = require('underscore'); +var _ = require('lodash'); +var argv = require('yargs').argv; var express = require('express'); -var bodyParser = require('body-parser'); -var corpus = require('./lib/corpus'); var pomagma = require('pomagma'); var socketio = require('socket.io'); var mongoose = require('mongoose'); +var corpus = require('./lib/corpus')(mongoose); var db = mongoose.connection; var LIVERELOAD_PORT = 34939; var liveReload = require('connect-livereload')({port: LIVERELOAD_PORT}); @@ -32,43 +32,11 @@ db.once('open', function () { }); var app = express(); -app.use(liveReload); -app.use(bodyParser.urlencoded({extended: false})); -app.use('/', express.static(path.join(__dirname, 'public'))); // HACK for index -app.use('/static', express.static(path.join(__dirname, 'public'))); +if (argv.withLiveReload) { + app.use(liveReload); +} +app.use('/', express.static(path.join(__dirname, '../public'))); -app.get('/corpus/lines', function (req, res) { - debug('GET lines'); - res.send({'data': corpus.findAll()}); -}); - -app.get('/corpus/line/:id', function (req, res) { - debug('GET line ' + req.params.id); - res.send({'data': corpus.findOne(req.params.id)}); -}); - -app.post('/corpus/line', function (req, res) { - debug('POST ' + JSON.stringify(req.body)); - var line = req.body; - var statement = { - 'name': line.name, - 'code': line.code - }; - var id = corpus.create(statement); - res.send({'id': id}); -}); - -app.put('/corpus/line/:id', function (req, res) { - debug('PUT line ' + req.params.id + ': ' + JSON.stringify(req.body)); - corpus.update(req.params.id, req.body); - res.status(200).end(); -}); - -app.delete('/corpus/line/:id', function (req, res) { - debug('DELETE line ' + req.params.id); - corpus.remove(req.params.id); - res.status(200).end(); -}); app.get('/corpus/validities', function (req, res) { debug('GET validities'); @@ -88,10 +56,9 @@ app.get('/corpus/validities', function (req, res) { }); }); -corpus.load(); + process.on('SIGINT', function () { analyst.close(); - corpus.dump(); process.exit(); }); @@ -118,13 +85,34 @@ var userId = 0; io.on('connection', function (socket) { var id = userId++; var logAction = function (action) { - console.log('Logger: user:', id, ' action:', action); + debug('Logger: user:', id, ' action:', action); var log = new Log({user: id, action: action}); log.save(); }; - logAction('connected'); - socket.on('disconnect', function () { - logAction('disconnected'); + + //send user whatever latest corpus we have; + corpus.findAll().then(function (corpus) { + socket.emit('corpusUpdate', corpus); }); - socket.on('action', logAction); + + //define methods of API + var serverAPI = { + 'log': logAction, + 'disconnect': function () { + logAction('disconnected'); + }, + 'corpus': function (method, args) { + debug('Socket method: ', method, ' called'); + corpus[method].apply(null, args).then(function () { + socket.emit('corpus', method, _.toArray(arguments)); + }); + } + }; + + //bind methods of API + _.each(serverAPI, function (method, event) { + socket.on(event, method); + }); + + logAction('connected'); }); diff --git a/test/server/corpusTest.js b/test/server/corpusTest.js index 87b800c..a31756c 100644 --- a/test/server/corpusTest.js +++ b/test/server/corpusTest.js @@ -1,63 +1,134 @@ 'use strict'; -var assert = require('assert'); -var sinon = require('sinon'); -var rewire = require('rewire'); - -//Note that below it is 'rewire' not 'require' ! -var corpus = rewire('../../lib/corpus'); - - -describe('Server', function () { - describe('Corpus', function () { - var corpusFile = [ - '# this file is managed by corpus.js', - 'ASSERT EQUAL APP APP C APP APP C' + - ' VAR util.pair BOT VAR util.join I', - 'ASSERT EQUAL APP APP C APP VAR util.pair BOT VAR util.join I'] - .join('\n'); - - it('initialised with empty array', function () { - assert.equal(corpus.findAll().length, 0); - }); - - it('.load() tries to read from file', function () { - var spy = sinon.stub().returns(corpusFile); - var revert = corpus.__set__('fs', {readFileSync: spy}); - - corpus.load(); - assert(spy.calledOnce); - - revert(); - }); - - it('After .load(), findAll() returns right amount of lines', - function () { - assert.equal(corpus.findAll().length, 2); - }); - - describe('.dump()', function () { - var writeSpy = sinon.stub(); - var renameSpy = sinon.stub(); - var revert = corpus.__set__('fs', { - writeFileSync: writeSpy, - renameSync: renameSpy - }); - var lines; - - before(function () { - lines = corpus.dump(); - revert(); - }); - - it('writes to the file and moves it', function () { - assert(writeSpy.calledOnce); - assert(renameSpy.calledOnce); - }); - - it('writes correct data to the file', function () { - assert.equal(lines, corpusFile); - }); - - }); - }); -}); \ No newline at end of file +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); +chai.use(chaiAsPromised); +var assert = chai.assert; +var Q = require('q'); +var _ = require('lodash'); +var testData = require('./testData'); +var debug = require('debug')('puddle:mocha'); +debug.log = function () { + //workaround for debug library to add newline char for each string; + console.log.apply(console, + ['\n'].concat(Array.prototype.slice.call(arguments)) + ); +}; +var Mongoose = require('mongoose'); + +debug('Testing server:'); + + +describe('Corpus', function () { + var mongoose; + var corpusUninitialized; + var corpus; + var mockgoose = require('mockgoose'); + + beforeEach(function () { + debug('Reinit mongoose'); + mongoose = new Mongoose.Mongoose(); + mockgoose(mongoose); + corpusUninitialized = require('../../server/lib/corpus'); + }); + + describe('initialiszation', + function () { + it('throws if not passed a mongoose as init parameter', + function () { + assert.throws(function () { + corpusUninitialized(); + }); + }); + it('returns an object if passed a mongoose', function () { + assert.isObject(corpusUninitialized(mongoose)); + }); + }); + + describe('after init ', function () { + beforeEach(function () { + debug('Reset DB data'); + corpus = corpusUninitialized(mongoose); + mockgoose.reset(); + }); + + it('.create() returns created object', + function () { + return assert.eventually.equal( + corpus.create(testData.codes[1]).then(function (code) { + return code.code; + }), + testData.codes[1] + ); + }); + + it('.create() throws if not string given', function () { + assert.throws(function () { + corpus.create(1); + }); + assert.throws(function () { + corpus.create([]); + }); + assert.throws(function () { + corpus.create({}); + }); + }); + + describe('given test data', function () { + beforeEach(function () { + debug('Add test data to DB'); + return Q.all(testData.codes.map(function (code) { + return corpus.create(code); + })); + }); + + it('.findAll() returns correct amount of lines', + function () { + return assert.eventually.equal( + corpus.findAll().then(function (codes) { + return codes.length; + }), testData.codes.length + ); + } + ); + it('.findAll() returns an array', + function () { + return assert.eventually.isArray(corpus.findAll()); + } + ); + it('.findAll() return objects with ID and code', + function () { + return assert.eventually.ok(corpus.findAll().then( + function (codes) { + return _.all(codes, function (code) { + return _.isString(code.id.toString()) && + _.isString(code.code); + }); + }) + ); + } + ); + describe('and known ID', + function () { + var id; + beforeEach(function (done) { + corpus.create(testData.codes[1]).then(function (code) { + id = code.id; + done(); + }); + }); + it('.findById() returns object', function () { + return assert.eventually.isObject(corpus.findById(id)); + }); + it('.remove() removes an object', function () { + return assert.eventually.isObject(corpus.remove(id)); + }); + it('.update() returns new object', function () { + return assert.eventually.isObject( + corpus.update(id, testData.codes[1]) + ); + }); + } + ); + }); + }); +}); diff --git a/test/server/testData.js b/test/server/testData.js new file mode 100644 index 0000000..eae1f30 --- /dev/null +++ b/test/server/testData.js @@ -0,0 +1,12 @@ +module.exports = { + codes: [ + 'ASSERT EQUAL APP VAR types.semi I I', + 'DEFINE VAR types.div APP VAR types.type K', + 'DEFINE VAR types.forall.push APP APP C I TOP', + 'DEFINE VAR util.join J', + 'ASSERT EQUAL APP APP C APP VAR util.pair BOT VAR' + + ' util.join I', + 'ASSERT EQUAL APP APP C APP APP C VAR util.pair' + + ' BOT VAR util.join I' + ] +}; \ No newline at end of file