Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit 19991df

Browse files
authored
Merge branch 'master' into layout_fixes
2 parents 74e9529 + deba664 commit 19991df

24 files changed

Lines changed: 2011 additions & 7 deletions

runestone/activecode/js/activecode_sql.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,13 @@ export default class SQLActiveCode extends ActiveCode {
4040
} else {
4141
if (allDburls[self.dburl].status == "loading") {
4242
allDburls[self.dburl].xWaitFor.done(function () {
43-
self.db = new SQL.Database(
44-
allDburls[self.dburl].db
45-
);
43+
self.db = allDburls[self.dburl].dbObject;
4644
$(self.runButton).removeAttr("disabled");
4745
$(self.runButton).text(buttonText);
4846
});
4947
return;
5048
}
51-
self.db = new SQL.Database(allDburls[self.dburl].db);
49+
self.db = allDburls[self.dburl].dbObject;
5250
$(self.runButton).removeAttr("disabled");
5351
$(self.runButton).text(buttonText);
5452
return;
@@ -60,6 +58,7 @@ export default class SQLActiveCode extends ActiveCode {
6058
xhr.onload = (e) => {
6159
var uInt8Array = new Uint8Array(xhr.response);
6260
self.db = new SQL.Database(uInt8Array);
61+
allDburls[self.dburl].dbObject = self.db;
6362
$(self.runButton).text(buttonText);
6463
$(self.runButton).removeAttr("disabled");
6564
allDburls[self.dburl].db = uInt8Array;

runestone/activecode/js/skulpt-stdlib.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runestone/activecode/js/skulpt.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
-2 Bytes
Binary file not shown.

runestone/activecode/js/skulpt.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runestone/activecode/test/_sources/index.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,15 @@ Support for SQL in the browser ? Yes!
233233

234234
select * from test;
235235

236+
.. activecode:: test_activecode_6b
237+
:language: sql
238+
:autograde: unittest
239+
:dburl: /_static/test.db
240+
241+
select * from created_table;
242+
243+
=====
244+
assert 0,0 == itworks
236245

237246
.. activecode:: sql3
238247
:language: sql

runestone/activecode/test/test_activecode.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,26 @@ def test_sql_activecode(selenium_utils_get):
140140
out = selenium_utils_get.driver.find_element_by_id(f"{div_id}_stdout")
141141
assert "" == out.text.strip()
142142

143+
div_id = "test_activecode_6"
144+
t1 = find_ac(selenium_utils_get, div_id)
145+
click_run(selenium_utils_get, t1)
146+
ta = t1.find_element_by_class_name("cm-s-default")
147+
assert ta
148+
selenium_utils_get.driver.execute_script(
149+
f"""window.edList['{div_id}'].editor.setValue("CREATE TABLE created_table (x TEXT); INSERT INTO created_table VALUES ('itworks');")"""
150+
)
151+
click_run(selenium_utils_get, t1)
152+
153+
div_id = "test_activecode_6b"
154+
t2 = find_ac(selenium_utils_get, div_id)
155+
# TODO: We don't yet have a way for async operations in ActiveCode constructors to signal when they're complete. So, insert a delay to guesstimate when the async load of the SQL WASM code and other async functions complete.
156+
time.sleep(2)
157+
click_run(selenium_utils_get, t2)
158+
selenium_utils_get.wait.until(EC.text_to_be_present_in_element((By.ID, f"{div_id}_stdout"), "You"))
159+
res = selenium_utils_get.driver.find_element_by_id(f"{div_id}_sql_out")
160+
assert res
161+
out = selenium_utils_get.driver.find_element_by_id(f"{div_id}_stdout")
162+
assert "You passed 1 out of 1 tests" in out.text
143163

144164
@pytest.fixture
145165
def selenium_utils_sf(selenium_utils):

runestone/cellbotics/__init__.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# .. Copyright (C) 2021 Bryan A. Jones.
2+
#
3+
# *********************************************************
4+
# |docname| - A Runestone extension supporting cellbotics
5+
# *********************************************************
6+
# This extension provides one new directive, ``ble-pair-button``, to add the Bluetooth Low Energy "Pair" button and status display to a page where users will be using the Cellbotics Python module and associated BLE functionality. The extension also includes all the supporting JavaScript files needed for the Cellbotics Python module.
7+
#
8+
#
9+
# Imports
10+
# =======
11+
# These are listed in the order prescribed by `PEP 8
12+
# <http://www.python.org/dev/peps/pep-0008/#imports>`_.
13+
#
14+
# Standard library
15+
# ----------------
16+
# None.
17+
#
18+
# Third-party imports
19+
# -------------------
20+
from docutils import nodes
21+
from docutils.parsers.rst import Directive
22+
23+
# Local imports
24+
# -------------
25+
# None
26+
27+
28+
# Code
29+
# ====
30+
class BlePairNode(nodes.General, nodes.Element):
31+
pass
32+
33+
34+
def visit_ble_pair_node(self, node):
35+
self.body.append(
36+
'<div data-component="ble">\n'
37+
' <script>runestone_import("ble");</script>\n'
38+
' <button id="ble_pair_button" type="button" disabled>Pair</button>\n'
39+
' <span id="ble_pair_status"></span>\n'
40+
'</div>\n'
41+
)
42+
43+
44+
def depart_ble_pair_node(self, node):
45+
pass
46+
47+
48+
class BlePairDirective(Directive):
49+
has_content = False
50+
required_arguments = 0
51+
optional_arguments = 0
52+
option_spec = {}
53+
54+
def run(self):
55+
return [BlePairNode()]
56+
57+
58+
def setup(app):
59+
# Add the Pair button directive.
60+
app.add_node(BlePairNode, html=(visit_ble_pair_node, depart_ble_pair_node))
61+
app.add_directive('ble-pair-button', BlePairDirective)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// .. Copyright (C) 2012-2020 Bryan A. Jones.
2+
//
3+
// This file is part of the CellBotics system.
4+
//
5+
// The CellBotics system is free software: you can redistribute it and/or
6+
// modify it under the terms of the GNU General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
//
10+
// The CellBotics system is distributed in the hope that it will be
11+
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12+
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
// General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with the CellBotics system. If not, see
17+
// <http://www.gnu.org/licenses/>.
18+
//
19+
// *********************************************************
20+
// |docname| - Automatically bind methods to their instances
21+
// *********************************************************
22+
23+
"use strict";
24+
25+
26+
// The following two functions were taken from https://github.com/sindresorhus/auto-bind/blob/master/index.js and lightly modified. They provide an easy way to bind all callable methods to their instance. See `Binding Methods to Class Instance Objects <https://ponyfoo.com/articles/binding-methods-to-class-instance-objects>`_ for more discussion on this crazy JavaScript necessity.
27+
//
28+
// Gets all non-builtin properties up the prototype chain
29+
const getAllProperties = object => {
30+
const properties = new Set();
31+
32+
do {
33+
for (const key of Reflect.ownKeys(object)) {
34+
properties.add([object, key]);
35+
}
36+
} while ((object = Reflect.getPrototypeOf(object)) && object !== Object.prototype);
37+
38+
return properties;
39+
};
40+
41+
42+
// Invoke this in the constructor of an object.
43+
export function auto_bind(self) {
44+
for (const [object, key] of getAllProperties(self.constructor.prototype)) {
45+
if (key === 'constructor') {
46+
continue;
47+
}
48+
49+
const descriptor = Reflect.getOwnPropertyDescriptor(object, key);
50+
if (descriptor && typeof descriptor.value === 'function') {
51+
self[key] = self[key].bind(self);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)