Commit 8d7ca6a8 authored by *Kim's avatar *Kim 🦎

Very basic simulator

parent 2bf34cc2
const { app, BrowserWindow } = require('electron');
const { app, BrowserWindow, ipcMain: ipc } = require('electron');
const { Kymera, Display } = require('@kymera/core');
const liblouis = require('liblouis');
const path = require('path');
const appRoot = require('app-root-path').toString();
liblouis.enableOnDemandTableLoading(path.join(appRoot, 'node_modules', 'liblouis-build', 'tables'));
ipc.on('ready', ({ sender: render }) => {
Display.prototype._write = Display.prototype.write;
Display.prototype.write = function write(text) {
render.send('Display#write', {
untranslated: text,
translated: liblouis.translateString(this.tables, text),
});
return this._write(text);
};
const ky = new Kymera({
displayGPIO: [
{ write: bit => render.send('GPIO:0', bit) },
{ write: bit => render.send('GPIO:1', bit) },
{ write: bit => render.send('GPIO:2', bit) },
{ write: bit => render.send('GPIO:3', bit) },
{ write: bit => render.send('GPIO:4', bit) },
{ write: bit => render.send('GPIO:5', bit) },
{ write: bit => render.send('GPIO:6', bit) },
{ write: bit => render.send('GPIO:7', bit) },
],
});
});
app.on('ready', () => {
win = new BrowserWindow({
let win = new BrowserWindow({
width: 800,
height: 600,
show: process.env.npm_lifecycle_event !== 'test',
......
<!doctype html>
<title>Test</title>
<h1>Hello World!</h1>
<title>Kymera Simulator</title>
<div class="untranslated"></div>
<div class="translated"></div>
<div class="display">
<div id="gpio-0"></div> <div id="gpio-3"></div>
<div id="gpio-1"></div> <div id="gpio-4"></div>
<div id="gpio-2"></div> <div id="gpio-5"></div>
<div id="gpio-6"></div> <div id="gpio-7"></div>
</div>
<script src="sim.js"></script>
<link rel="stylesheet" href="sim.css">
.display {
width: 60px;
}
.display [id*=gpio] {
width: 30px;
height: 30px;
border-radius: 30px;
background: #000;
}
.display [id*=gpio]:after {
color: #fff;
line-height: 30px;
width: 30px;
text-align: center;
display: block;
}
.display [id*="0"]:after {
content: '0';
}
.display [id*="1"]:after {
content: '1';
}
.display [id*="2"]:after {
content: '2';
}
.display [id*="3"]:after {
content: '3';
}
.display [id*="4"]:after {
content: '4';
}
.display [id*="5"]:after {
content: '5';
}
.display [id*="6"]:after {
content: '6';
}
.display [id*="7"]:after {
content: '7';
}
.display [id*=gpio]:nth-child(2n-1) {
float: left;
}
.display [id*=gpio]:nth-child(2n) {
float: right;
}
.display [id*=gpio].active {
background: #00f;
}
const { ipcRenderer: ipc } = require('electron');
const $ = q => document.querySelector(q);
ipc.send('ready');
ipc.on('Display#write', (event, { untranslated, translated }) => {
$('.untranslated').innerText = untranslated;
$('.translated').innerText = translated;
});
ipc.on('GPIO:0', (event, bit) => $('#gpio-0').className = bit ? 'active' : '');
ipc.on('GPIO:1', (event, bit) => $('#gpio-1').className = bit ? 'active' : '');
ipc.on('GPIO:2', (event, bit) => $('#gpio-2').className = bit ? 'active' : '');
ipc.on('GPIO:3', (event, bit) => $('#gpio-3').className = bit ? 'active' : '');
ipc.on('GPIO:4', (event, bit) => $('#gpio-4').className = bit ? 'active' : '');
ipc.on('GPIO:5', (event, bit) => $('#gpio-5').className = bit ? 'active' : '');
ipc.on('GPIO:6', (event, bit) => $('#gpio-6').className = bit ? 'active' : '');
ipc.on('GPIO:7', (event, bit) => $('#gpio-7').className = bit ? 'active' : '');
......@@ -8,13 +8,15 @@
"license": "MPL-2.0",
"scripts": {
"start": "electron .",
"start:watch": "nodemon -e js,css,html -w app --exec 'yarn start'",
"start:watch": "nodemon -e js,css,html -i test --exec 'yarn start'",
"test": "mocha",
"test:watch": "nodemon -e js,css,html -w app -w test --exec 'yarn test'"
"test:watch": "nodemon -e js,css,html --exec 'yarn test'"
},
"dependencies": {
"@kymera/core": "*",
"electron": "^3.0.9"
"app-root-path": "^2.1.0",
"electron": "^3.0.9",
"liblouis": "^0.4.0",
"onoff": "^3.2.2"
},
"devDependencies": {
"chai": "^4.2.0",
......
......@@ -13,21 +13,26 @@ const app = new Application({
chai.use(require('chai-as-promised'));
chai.use(chaiSpectron(app));
describe('Test', function() {
describe('App', function() {
this.timeout(20000);
beforeEach(async () => await app.start());
afterEach(async () => await app.stop());
it('should run a test', () => {
expect(true).to.equal(true);
it('should see app title', async () => {
await expect(app.client.getTitle()).to.eventually.equal('Kymera Simulator');
});
it('should see test title', async () => {
await expect(app.client.getTitle()).to.eventually.equal('Test');
});
describe('Display', () => {
it('should display data');
it('should display translated braille text', async () => {
await expect('.translated').dom.to.exist;
await expect('.translated').dom.to.have.text(/./);
});
it('should see "Hello World!"', async () => {
await expect('h1').dom.to.have.text('Hello World!');
await expect('h1').dom.to.exist;
it('should display a time value', async () => {
await expect('.untranslated').dom.to.exist;
await expect('.untranslated').dom.to.have.text(/\d+:\d+/);
});
});
});
......@@ -24,9 +24,11 @@ module.exports = function chaiSpectron(app) {
const textArray = (getText instanceof Array) ? getText : [ getText ];
this.assert(
textArray.some(text => text === expected),
`Expected element <${selector}> to contain text "${expected}", but only found: ${textArray}`,
`Expected element <${selector}> not to contain text "${expected}", but found: ${textArray}`,
expected instanceof RegExp ?
textArray.some(text => expected.test(text)) :
textArray.some(text => text === expected),
`Expected element <${selector}> to contain text "${expected}" but only found: ${textArray}`,
`Expected element <${selector}> not to contain text "${expected}" but found: ${textArray}`,
);
});
......
......@@ -59,6 +59,11 @@ [email protected]^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
[email protected]^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a"
integrity sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo=
[email protected]^1.0.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
......@@ -220,6 +225,11 @@ [email protected]^1.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14"
integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==
[email protected]^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5"
integrity sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==
[email protected]^1.0.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
......@@ -810,6 +820,14 @@ [email protected]^1.0.0:
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=
[email protected]^2.0.4:
version "2.0.7"
resolved "https://registry.yarnpkg.com/epoll/-/epoll-2.0.7.tgz#7eb126fac722eab83c3ac486fa8ef46d6a238290"
integrity sha512-oCj9Prru+JVvxXAuYjcJqp9a5aefj5ZLKyTQ01AKniYls7dAoEDRxsAC7J2CP7pZ5sXbY/qBeToZmVT+L/CYNg==
dependencies:
bindings "^1.3.1"
nan "^2.12.1"
[email protected]^1.2.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
......@@ -1651,6 +1669,18 @@ [email protected]^1.0.0:
dependencies:
readable-stream "^2.0.5"
[email protected]*:
version "3.2.0-rc"
resolved "https://registry.yarnpkg.com/liblouis-build/-/liblouis-build-3.2.0-rc.tgz#77489c398ea5232878a2bd27ffa359499e056a75"
integrity sha1-d0icOY6lIyh4or0n/6NZSZ4FanU=
[email protected]^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/liblouis/-/liblouis-0.4.0.tgz#6228c331e18f4644a476a82fa19fe297f17657a4"
integrity sha512-ViuoMFbSbf39RyXYU/Q9IeQ5IYUdJVPrgz5nmXjkNkK5rmorivDDWRZLibPhEaip0Dpt00CG+NX1WQGHWCa+ow==
dependencies:
liblouis-build "*"
[email protected]~3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
......@@ -1865,6 +1895,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
[email protected]^2.12.1:
version "2.12.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==
[email protected]^2.9.2:
version "2.11.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766"
......@@ -2065,6 +2100,14 @@ [email protected]^2.0.0:
dependencies:
mimic-fn "^1.0.0"
[email protected]^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/onoff/-/onoff-3.2.2.tgz#f2d5118c29d6e11ef9d4a6b60aac160a303427a2"
integrity sha512-wLxeB03QLSsbIhIqR24Ia137uyCKNR7O8SEnUhN4kmsrDrhZNVpSWfOC7Tp1bvz7qKLwfYICGYbPMjzun4opLg==
dependencies:
epoll "^2.0.4"
lodash.debounce "^4.0.8"
[email protected]~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment