summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2018-06-17 09:12:52 -0400
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2018-06-17 09:12:52 -0400
commit095c2640aa2070ed4e2765875238d5e6e6673856 (patch)
tree9306beb3fef29a99d9436dc00e2d8c57fb3e0c7b /tests
parent8c58ba2e1db6e97ca1f18fd9ca52ffead53e4a4f (diff)
parent34eb9eba9a724433f9c37c39cf43e9e10cf55220 (diff)
Merge branch 'upstream' into dfsg_clean20180616+dfsg
Diffstat (limited to 'tests')
-rw-r--r--tests/DynChannel.py20
-rw-r--r--tests/Makefile26
-rw-r--r--tests/aborter.py11
-rw-r--r--tests/aborter.urp1
-rw-r--r--tests/aborter2.py11
-rw-r--r--tests/active.py14
-rw-r--r--tests/activeBlock.py20
-rw-r--r--tests/activeBlock.ur2
-rw-r--r--tests/activeEmpty.py12
-rw-r--r--tests/activeFocus.py18
-rw-r--r--tests/activeFocus.ur2
-rw-r--r--tests/agg.py8
-rw-r--r--tests/agg.ur20
-rw-r--r--tests/ahead.py15
-rw-r--r--tests/alert.py11
-rw-r--r--tests/alert.ur2
-rw-r--r--tests/align.py11
-rw-r--r--tests/appjs.py11
-rw-r--r--tests/appjs.ur2
-rw-r--r--tests/ascdesc.py11
-rw-r--r--tests/ascdesc.ur14
-rw-r--r--tests/ascdesc.urp3
-rw-r--r--tests/attrMangle.py11
-rw-r--r--tests/attrs_escape.py10
-rw-r--r--tests/attrs_escape.ur10
-rw-r--r--tests/autocomp.py15
-rw-r--r--tests/autocomp.ur8
-rw-r--r--tests/babySpawn.py12
-rw-r--r--tests/base.py29
-rw-r--r--tests/bindpat.py9
-rw-r--r--tests/bindpat.ur7
-rw-r--r--tests/cradio.py33
-rw-r--r--tests/cradio.ur26
-rw-r--r--tests/cradio.urp (renamed from tests/alert.urp)2
-rw-r--r--tests/cradio.urs1
-rw-r--r--tests/dbupload.urp1
-rw-r--r--tests/dbuploadOpt.ur27
-rw-r--r--tests/dbuploadOpt.urp7
-rwxr-xr-xtests/driver.sh25
-rw-r--r--tests/entities.py14
-rw-r--r--tests/entities.ur6
-rw-r--r--tests/fact.py10
-rw-r--r--tests/fake_types2
-rw-r--r--tests/filter.py9
-rw-r--r--tests/filter.ur17
-rw-r--r--tests/jsbspace.py11
-rw-r--r--tests/jsbspace.ur12
-rw-r--r--tests/jsonTest.py16
-rw-r--r--tests/jsonTest.ur5
-rw-r--r--tests/listGroupBy.ur13
-rw-r--r--tests/listGroupBy.urp4
-rw-r--r--tests/mimeTypesDirective.ur0
-rw-r--r--tests/mimeTypesDirective.urp6
-rw-r--r--tests/pairUnify.ur6
-rw-r--r--tests/slashform.ur9
-rw-r--r--tests/slashform.urs1
-rw-r--r--tests/unurlify2.ur16
57 files changed, 600 insertions, 35 deletions
diff --git a/tests/DynChannel.py b/tests/DynChannel.py
new file mode 100644
index 00000000..7af5ea78
--- /dev/null
+++ b/tests/DynChannel.py
@@ -0,0 +1,20 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start('DynChannel/main')
+
+ # initial state: only Register is visible
+ reg = self.xpath('button')
+ reg.click()
+ # and we get two another state: either Register or Send visible
+ send = self.xpath('span/button')
+ send.click()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("Got something from the channel", alert.text)
+ alert.accept()
+ # we got the message back
+ span = self.xpath('span/span')
+ self.assertEqual("blabla", span.text)
diff --git a/tests/Makefile b/tests/Makefile
index 5313d12d..ecf5557b 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -2,3 +2,29 @@ all: test.o
test.o: test.c
gcc -c test.c -o test.o
+###
+
+simple::
+ ./driver.sh aborter2
+ ./driver.sh aborter
+ ./driver.sh activeBlock
+ ./driver.sh activeFocus
+ ./driver.sh active
+ ./driver.sh agg
+ ./driver.sh ahead
+ ./driver.sh alert
+ ./driver.sh align
+ ./driver.sh appjs
+ ./driver.sh ascdesc
+ echo ./driver.sh attrMangle
+ ./driver.sh attrs_escape
+ echo ./driver.sh attrs
+ ./driver.sh autocomp
+ ./driver.sh babySpawn
+ ./driver.sh bindpat
+ ./driver.sh DynChannel
+ ./driver.sh jsonTest
+ ./driver.sh entities
+ ./driver.sh fact
+ ./driver.sh filter
+ ./driver.sh jsbspace
diff --git a/tests/aborter.py b/tests/aborter.py
new file mode 100644
index 00000000..8379c656
--- /dev/null
+++ b/tests/aborter.py
@@ -0,0 +1,11 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start('Aborter/main')
+ self.assertEqual("Fatal Error", self.driver.title)
+ txt = self.body_text()
+ self.assertEqual("Fatal error: :0:0-0:0: No way, Jose!", txt)
+
diff --git a/tests/aborter.urp b/tests/aborter.urp
index fc1925ae..8c971440 100644
--- a/tests/aborter.urp
+++ b/tests/aborter.urp
@@ -1,4 +1,5 @@
database dbname=aborter
sql aborter.sql
+safeGet Aborter/main
aborter
diff --git a/tests/aborter2.py b/tests/aborter2.py
new file mode 100644
index 00000000..c3f1e10e
--- /dev/null
+++ b/tests/aborter2.py
@@ -0,0 +1,11 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start('Aborter2/main')
+ self.assertEqual("", self.driver.title)
+ txt = self.body_text()
+ self.assertEqual("Result: 0", txt)
+
diff --git a/tests/active.py b/tests/active.py
new file mode 100644
index 00000000..08846ac5
--- /dev/null
+++ b/tests/active.py
@@ -0,0 +1,14 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ b1 = self.xpath('span[1]/button')
+ b2 = self.xpath('span[2]/button')
+ for _ in range(3):
+ b1.click()
+ for _ in range(5):
+ b2.click()
+ self.assertEqual("3\n5", self.body_text())
diff --git a/tests/activeBlock.py b/tests/activeBlock.py
new file mode 100644
index 00000000..d0e43fdb
--- /dev/null
+++ b/tests/activeBlock.py
@@ -0,0 +1,20 @@
+import unittest
+import base
+import time
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("Error: May not 'sleep' in main thread of 'code' for <active>", alert.text)
+ alert.accept()
+ time.sleep(0.1)
+ alert = self.driver.switch_to.alert
+ self.assertEqual("Hi!", alert.text)
+ alert.accept()
+ button = self.xpath('span[1]/button')
+ button.click()
+ txt = self.body_text()
+ self.assertEqual("Hi! Click me! Success", txt)
+
diff --git a/tests/activeBlock.ur b/tests/activeBlock.ur
index 5560edda..bced4af3 100644
--- a/tests/activeBlock.ur
+++ b/tests/activeBlock.ur
@@ -1,7 +1,7 @@
fun main () : transaction page = return <xml><body>
<active code={s <- source ""; return <xml>
<dyn signal={s <- signal s; return (txt s)}/>
- <button onclick={fn _ => set s "Hi!"}/>
+ <button onclick={fn _ => set s "Hi!"}>Click me!</button>
</xml>}/>
<active code={sleep 1; return <xml>Hi!</xml>}/>
diff --git a/tests/activeEmpty.py b/tests/activeEmpty.py
new file mode 100644
index 00000000..8872833a
--- /dev/null
+++ b/tests/activeEmpty.py
@@ -0,0 +1,12 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("Howdy, neighbor!", alert.text)
+ alert.accept()
+ txt = self.body_text()
+ self.assertEqual("This one ain't empty.", txt)
diff --git a/tests/activeFocus.py b/tests/activeFocus.py
new file mode 100644
index 00000000..47b9a921
--- /dev/null
+++ b/tests/activeFocus.py
@@ -0,0 +1,18 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ uw0 = self.xpath('input[2]')
+ active = self.driver.switch_to.active_element
+ self.assertEqual(uw0, active)
+ def test_2(self):
+ """Test case 2"""
+ self.start('dynamic')
+ btn = self.xpath('button')
+ btn.click()
+ uw1 = self.xpath('span/input[2]')
+ active = self.driver.switch_to.active_element
+ self.assertEqual(uw1, active)
diff --git a/tests/activeFocus.ur b/tests/activeFocus.ur
index 94d465e9..82d2c0c9 100644
--- a/tests/activeFocus.ur
+++ b/tests/activeFocus.ur
@@ -14,5 +14,5 @@ fun dynamic () : transaction page =
<ctextbox/>
<ctextbox id={i}/>
<active code={giveFocus i; return <xml>Done</xml>}/>
- </xml>}/>
+ </xml>}>Click</button>
</body></xml>
diff --git a/tests/agg.py b/tests/agg.py
new file mode 100644
index 00000000..0b421d37
--- /dev/null
+++ b/tests/agg.py
@@ -0,0 +1,8 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start('Agg/main')
+ self.assertEqual("0;1;2;\na, 50;", self.body_text())
diff --git a/tests/agg.ur b/tests/agg.ur
index 19a8644b..2d8eed43 100644
--- a/tests/agg.ur
+++ b/tests/agg.ur
@@ -1,13 +1,23 @@
table t1 : {A : int, B : string, C : float}
table t2 : {A : float, D : int, E : option string}
-val q1 : sql_query [] _ _ = (SELECT COUNT( * ) FROM t1)
-val q2 : sql_query [] _ _ = (SELECT AVG(t1.A) FROM t1)
-val q3 : sql_query [] _ _ = (SELECT SUM(t1.C) FROM t1)
-val q4 : sql_query [] _ _ = (SELECT MIN(t1.B), MAX(t1.A) FROM t1)
-val q5 : sql_query [] _ _ = (SELECT SUM(t1.A) FROM t1 GROUP BY t1.B)
+val q1 : sql_query [] [] _ _ = (SELECT COUNT( * ) FROM t1)
+val q2 : sql_query [] [] _ _ = (SELECT AVG(t1.A) FROM t1)
+val q3 : sql_query [] [] _ _ = (SELECT SUM(t1.C) FROM t1)
+val q4 : sql_query [] [] _ _ = (SELECT MIN(t1.B), MAX(t1.A) FROM t1)
+val q5 : sql_query [] [] _ _ = (SELECT SUM(t1.A) FROM t1 GROUP BY t1.B)
val q6 = (SELECT COUNT(t2.E) FROM t2 GROUP BY t2.D)
+task initialize = fn () =>
+ dml (INSERT INTO t1 (A, B, C) VALUES (1, 'a', 1.0));
+ dml (INSERT INTO t1 (A, B, C) VALUES (2, 'b', 2.0));
+ dml (INSERT INTO t1 (A, B, C) VALUES (50, 'c', 99.0));
+ dml (INSERT INTO t2 (A, D, E) VALUES (1.0, 1, NULL));
+ dml (INSERT INTO t2 (A, D, E) VALUES (1.0, 2, {[Some "a"]}));
+ dml (INSERT INTO t2 (A, D, E) VALUES (1.0, 3, NULL));
+ dml (INSERT INTO t2 (A, D, E) VALUES (1.0, 3, {[Some "b"]}));
+ dml (INSERT INTO t2 (A, D, E) VALUES (1.0, 3, {[Some "c"]}))
+
fun main () : transaction page =
xml <- queryX q6 (fn r => <xml>{[r.1]};</xml>);
xml2 <- queryX q4 (fn r => <xml>{[r.1]}, {[r.2]};</xml>);
diff --git a/tests/ahead.py b/tests/ahead.py
new file mode 100644
index 00000000..6e767948
--- /dev/null
+++ b/tests/ahead.py
@@ -0,0 +1,15 @@
+import unittest
+import base
+import time
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("Hi!", alert.text)
+ alert.accept()
+ time.sleep(0.1)
+ alert = self.driver.switch_to.alert
+ self.assertEqual("Bye!", alert.text)
+ alert.accept()
diff --git a/tests/alert.py b/tests/alert.py
new file mode 100644
index 00000000..4b783d50
--- /dev/null
+++ b/tests/alert.py
@@ -0,0 +1,11 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ el = self.xpath('a')
+ el.click()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("You clicked it! That's some fancy shooting!", alert.text)
diff --git a/tests/alert.ur b/tests/alert.ur
index 3fe68d75..7a290921 100644
--- a/tests/alert.ur
+++ b/tests/alert.ur
@@ -1,3 +1,3 @@
fun main () : transaction page = return <xml><body>
- <a onclick={alert "You clicked it! That's some fancy shooting!"}>Click Me!</a>
+ <a onclick={fn _ => alert "You clicked it! That's some fancy shooting!"}>Click Me!</a>
</body></xml>
diff --git a/tests/align.py b/tests/align.py
new file mode 100644
index 00000000..525ab4e6
--- /dev/null
+++ b/tests/align.py
@@ -0,0 +1,11 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ el = self.xpath('p[@align="left"]')
+ self.assertEqual("Left", el.text)
+ el = self.xpath('p[@align="right"]')
+ self.assertEqual("Right", el.text)
diff --git a/tests/appjs.py b/tests/appjs.py
new file mode 100644
index 00000000..02ac2193
--- /dev/null
+++ b/tests/appjs.py
@@ -0,0 +1,11 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ el = self.xpath('button')
+ el.click()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("3", alert.text)
diff --git a/tests/appjs.ur b/tests/appjs.ur
index 01e9f345..403b0b4e 100644
--- a/tests/appjs.ur
+++ b/tests/appjs.ur
@@ -1,5 +1,5 @@
fun id n = if n = 0 then 0 else 1 + id (n - 1)
fun main () : transaction page = return <xml><body>
- <button onclick={alert (show (id 3))}/>
+ <button onclick={fn _ => alert (show (id 3))}/>
</body></xml>
diff --git a/tests/ascdesc.py b/tests/ascdesc.py
new file mode 100644
index 00000000..6b514f4e
--- /dev/null
+++ b/tests/ascdesc.py
@@ -0,0 +1,11 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start('Ascdesc/main')
+ el = self.xpath('p[1]')
+ self.assertEqual("1; 2; 3;", el.text)
+ el = self.xpath('p[2]')
+ self.assertEqual("3; 2; 1;", el.text)
diff --git a/tests/ascdesc.ur b/tests/ascdesc.ur
index 59dd0169..fadac27d 100644
--- a/tests/ascdesc.ur
+++ b/tests/ascdesc.ur
@@ -4,7 +4,15 @@ fun sortEm b =
queryX1 (SELECT * FROM t ORDER BY t.A {if b then sql_asc else sql_desc})
(fn r => <xml>{[r.A]}; </xml>)
-fun main () : transaction page = return <xml><body>
- <a link={sortEm True}>Ascending</a><br/>
- <a link={sortEm False}>Descending</a>
+task initialize = fn () =>
+ dml (INSERT INTO t (A) VALUES (1));
+ dml (INSERT INTO t (A) VALUES (2));
+ dml (INSERT INTO t (A) VALUES (3))
+
+fun main () : transaction page =
+ p1 <- sortEm True;
+ p2 <- sortEm False;
+ return <xml><body>
+ <p>{p1}</p>
+ <p>{p2}</p>
</body></xml>
diff --git a/tests/ascdesc.urp b/tests/ascdesc.urp
index 3e0b075d..a1c4124e 100644
--- a/tests/ascdesc.urp
+++ b/tests/ascdesc.urp
@@ -1,4 +1,3 @@
-database dbname=test
-sql ascdesc.sql
+database dbname=ascdesc
ascdesc \ No newline at end of file
diff --git a/tests/attrMangle.py b/tests/attrMangle.py
new file mode 100644
index 00000000..d3b24244
--- /dev/null
+++ b/tests/attrMangle.py
@@ -0,0 +1,11 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ el = self.xpath('goofy[@name eq "beppo" and @data-role eq "excellence"]')
+ el.click()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("You clicked it! That's some fancy shooting!", alert.text)
diff --git a/tests/attrs_escape.py b/tests/attrs_escape.py
new file mode 100644
index 00000000..fc9f91b5
--- /dev/null
+++ b/tests/attrs_escape.py
@@ -0,0 +1,10 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ el = self.xpath('form/input')
+ val = el.get_attribute('value')
+ self.assertEqual("\"Well hey\"\nWow", val)
diff --git a/tests/attrs_escape.ur b/tests/attrs_escape.ur
index 12de101e..87d554fe 100644
--- a/tests/attrs_escape.ur
+++ b/tests/attrs_escape.ur
@@ -1,4 +1,6 @@
-val main = fn () => <html><body>
- <font face="\"Well hey\"
-Wow">Welcome</font>
-</body></html>
+fun main () : transaction page = return <xml><body>
+<form>
+ <submit value="\"Well hey\"
+Wow"/>
+</form>
+</body></xml>
diff --git a/tests/autocomp.py b/tests/autocomp.py
new file mode 100644
index 00000000..28c3b7d2
--- /dev/null
+++ b/tests/autocomp.py
@@ -0,0 +1,15 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ txt = self.xpath('div')
+ self.assertEqual('/', txt.text)
+ inp = self.xpath('/input')
+ inp.send_keys('hello there')
+ self.assertEqual('hello there /', txt.text)
+ btn = self.xpath('button')
+ btn.click()
+ self.assertEqual("hello there / hello there", txt.text)
diff --git a/tests/autocomp.ur b/tests/autocomp.ur
index d4e6a287..753318f7 100644
--- a/tests/autocomp.ur
+++ b/tests/autocomp.ur
@@ -2,10 +2,10 @@ fun main () : transaction page =
a <- source "";
b <- source "";
return <xml><body>
- <form>
- <textbox{#A} source={a}/>
- <button onclick={x <- get a; set b x}/>
+ <ctextbox source={a}/>
+ <button onclick={fn _ => x <- get a; set b x}>click me</button>
+ <div>
<dyn signal={v <- signal a; return <xml>{[v]}</xml>}/>
/ <dyn signal={v <- signal b; return <xml>{[v]}</xml>}/>
- </form>
+ </div>
</body></xml>
diff --git a/tests/babySpawn.py b/tests/babySpawn.py
new file mode 100644
index 00000000..6693e969
--- /dev/null
+++ b/tests/babySpawn.py
@@ -0,0 +1,12 @@
+import unittest
+import base
+import time
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ btn = self.xpath('button')
+ btn.click()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("Hi", alert.text)
diff --git a/tests/base.py b/tests/base.py
new file mode 100644
index 00000000..b9a026f2
--- /dev/null
+++ b/tests/base.py
@@ -0,0 +1,29 @@
+# use pip install selenium first
+# ensure you have both chome driver & chrome installed
+
+import unittest
+from selenium import webdriver
+from selenium.common.exceptions import NoSuchElementException
+
+class Base(unittest.TestCase):
+ """Include test cases on a given url"""
+
+ def start(self, path='main'):
+ self.driver.get('http://localhost:8080/' + path)
+ def xpath(self, path):
+ return self.driver.find_element_by_xpath('/html/body/'+path)
+ def body_text(self):
+ return self.driver.find_element_by_xpath('/html/body').text
+
+ def setUp(self):
+ """Start web driver"""
+ chrome_options = webdriver.ChromeOptions()
+ chrome_options.add_argument('--no-sandbox')
+ chrome_options.add_argument('--headless')
+ chrome_options.add_argument('--disable-gpu')
+ self.driver = webdriver.Chrome(options=chrome_options)
+ self.driver.implicitly_wait(10)
+
+ def tearDown(self):
+ """Stop web driver"""
+ self.driver.quit()
diff --git a/tests/bindpat.py b/tests/bindpat.py
new file mode 100644
index 00000000..6c33f52f
--- /dev/null
+++ b/tests/bindpat.py
@@ -0,0 +1,9 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.driver.get('http://localhost:8080/main')
+ el = self.driver.find_element_by_xpath('/html/body')
+ self.assertEqual("1, 2, hi, 2.34, 8, 9", el.text)
diff --git a/tests/bindpat.ur b/tests/bindpat.ur
index bca4bd41..8fd6eb39 100644
--- a/tests/bindpat.ur
+++ b/tests/bindpat.ur
@@ -1,6 +1,9 @@
fun main () : transaction page =
(a, b) <- return (1, 2);
{C = c, ...} <- return {C = "hi", D = False};
- d <- return 2.34;
- {1 = e, 2 = f} <- return (8, 9);
+ let
+ val d = 2.34
+ val {1 = e, 2 = f} = (8, 9)
+ in
return <xml>{[a]}, {[b]}, {[c]}, {[d]}, {[e]}, {[f]}</xml>
+ end \ No newline at end of file
diff --git a/tests/cradio.py b/tests/cradio.py
new file mode 100644
index 00000000..cc075593
--- /dev/null
+++ b/tests/cradio.py
@@ -0,0 +1,33 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start("Cradio/main")
+ txt = self.xpath('div[1]').text
+ self.assertEqual("Hello, I'm B. I'll be your waiter for this evening.", txt)
+ txt2 = self.xpath('div[2]').text
+ self.assertEqual('Value:', txt2)
+ el1 = self.xpath('label[1]/input')
+ el2 = self.xpath('label[2]/input')
+ self.assertEqual(False, el1.is_selected())
+ self.assertEqual(True, el2.is_selected())
+ el1.click()
+ alert = self.driver.switch_to.alert
+ self.assertEqual("Now it's A", alert.text)
+ alert.accept()
+ self.assertEqual(True, el1.is_selected())
+ self.assertEqual(False, el2.is_selected())
+ txt = self.xpath('div[1]').text
+ self.assertEqual("Hello, I'm A. I'll be your waiter for this evening.", txt)
+ txt2 = self.xpath('div[2]').text
+ self.assertEqual('Value:', txt2)
+ # now check that the second radio group works as well
+ el3 = self.xpath('label[4]/input')
+ el3.click()
+ alert = self.driver.switch_to.alert
+ alert.accept()
+ txt2 = self.xpath('div[2]').text
+ self.assertEqual('Value: Y', txt2)
+ self.assertEqual("Hello, I'm A. I'll be your waiter for this evening.", txt)
diff --git a/tests/cradio.ur b/tests/cradio.ur
new file mode 100644
index 00000000..48c04f1e
--- /dev/null
+++ b/tests/cradio.ur
@@ -0,0 +1,26 @@
+fun main () =
+s <- source (Some "B");
+r <- source None;
+let
+ val onc = v <- get s; alert ("Now it's " ^ show v)
+ val onc_r = v <- get r; alert ("Changed to " ^ show v)
+in
+ return <xml><body>
+ <h1>First group</h1>
+
+ <label>Wilbur <cradio source={s} value="A" onchange={onc}/></label>
+ <label>Walbur <cradio source={s} value="B" onchange={onc}/></label>
+
+ <div>
+ Hello, I'm <dyn signal={s <- signal s; return <xml>{[s]}</xml>}/>. I'll be your waiter for this evening.
+ </div>
+
+ <h1>Second group</h1>
+
+ <label>X <cradio source={r} value="X" onchange={onc_r}/></label>
+ <label>Y <cradio source={r} value="Y" onchange={onc_r}/></label>
+ <label>Z <cradio source={r} value="Z" onchange={onc_r}/></label>
+
+ <div>Value: <dyn signal={r <- signal r; return <xml>{[r]}</xml>}/></div>
+ </body></xml>
+end
diff --git a/tests/alert.urp b/tests/cradio.urp
index 3976e9b0..0681ab21 100644
--- a/tests/alert.urp
+++ b/tests/cradio.urp
@@ -1,3 +1,3 @@
debug
-alert
+cradio
diff --git a/tests/cradio.urs b/tests/cradio.urs
new file mode 100644
index 00000000..6ac44e0b
--- /dev/null
+++ b/tests/cradio.urs
@@ -0,0 +1 @@
+val main : unit -> transaction page
diff --git a/tests/dbupload.urp b/tests/dbupload.urp
index dd8417d1..daa68e2c 100644
--- a/tests/dbupload.urp
+++ b/tests/dbupload.urp
@@ -2,5 +2,6 @@ database dbname=dbupload
sql dbupload.sql
allow mime *
rewrite all Dbupload/*
+filecache /tmp/files
dbupload
diff --git a/tests/dbuploadOpt.ur b/tests/dbuploadOpt.ur
new file mode 100644
index 00000000..466b49f3
--- /dev/null
+++ b/tests/dbuploadOpt.ur
@@ -0,0 +1,27 @@
+table t : { Id : int, Blob : option blob, MimeType : string }
+sequence s
+
+fun getImage id : transaction page =
+ r <- oneRow1 (SELECT t.Blob, t.MimeType
+ FROM t
+ WHERE t.Id = {[id]});
+ case r.Blob of
+ None => error <xml>Oh no!</xml>
+ | Some blob => returnBlob blob (blessMime r.MimeType)
+
+fun main () : transaction page =
+ let
+ fun handle r =
+ id <- nextval s;
+ dml (INSERT INTO t (Id, Blob, MimeType)
+ VALUES ({[id]}, {[if fileMimeType r.File = "image/jpeg" then Some (fileData r.File) else None]}, {[fileMimeType r.File]}));
+ main ()
+ in
+ x <- queryX1 (SELECT t.Id FROM t)
+ (fn r => <xml><img src={url (getImage r.Id)}/><br/></xml>);
+ return <xml><body>
+ <form><upload{#File}/> <submit action={handle}/></form>
+ <hr/>
+ {x}
+ </body></xml>
+ end
diff --git a/tests/dbuploadOpt.urp b/tests/dbuploadOpt.urp
new file mode 100644
index 00000000..816bcea1
--- /dev/null
+++ b/tests/dbuploadOpt.urp
@@ -0,0 +1,7 @@
+database dbname=dbuploadOpt
+sql dbuploadOpt.sql
+allow mime *
+rewrite all DbuploadOpt/*
+filecache /tmp/files
+
+dbuploadOpt
diff --git a/tests/driver.sh b/tests/driver.sh
new file mode 100755
index 00000000..879c093d
--- /dev/null
+++ b/tests/driver.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+if [[ $# -eq 0 ]] ; then
+ echo 'Supply at least one argument'
+ exit 1
+fi
+
+TESTDB=/tmp/$1.db
+TESTSQL=/tmp/$1.sql
+TESTPID=/tmp/$1.pid
+TESTSRV=./$1.exe
+
+rm -f $TESTDB $TESTSQL $TESTPID $TESTSRV
+../bin/urweb -debug -boot -noEmacs -dbms sqlite -db $TESTDB -sql $TESTSQL "$1" || exit 1
+
+if [ -e $TESTSQL ]
+then
+ sqlite3 $TESTDB < $TESTSQL
+fi
+
+$TESTSRV -q -a 127.0.0.1 &
+echo $! >> $TESTPID
+sleep 1
+python3 -m unittest $1.py
+kill `cat $TESTPID`
diff --git a/tests/entities.py b/tests/entities.py
new file mode 100644
index 00000000..d9087cbf
--- /dev/null
+++ b/tests/entities.py
@@ -0,0 +1,14 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ p = self.xpath('p[1]')
+ self.assertEqual('Hello world! & so on, © me today (8 €)', p.text)
+ p = self.xpath('p[2]')
+ self.assertEqual('♠ ♣ ♥ ♦', p.text)
+ p = self.xpath('p[3]')
+ self.assertEqual('† DANGER †', p.text)
+
diff --git a/tests/entities.ur b/tests/entities.ur
index 8b78edbc..1f45520d 100644
--- a/tests/entities.ur
+++ b/tests/entities.ur
@@ -1,5 +1,5 @@
fun main () : transaction page = return <xml><body>
- Hello world! &amp; so on, &copy; me today (8 &euro;)<br/>
- &spades; &clubs; &hearts; &diams;<br/>
- &dagger; DANGER &dagger;
+ <p>Hello world! &amp; so on, &copy; me today (8 &euro;)</p>
+ <p>&spades; &clubs; &hearts; &diams;</p>
+ <p>&dagger; DANGER &dagger;</p>
</body></xml>
diff --git a/tests/fact.py b/tests/fact.py
new file mode 100644
index 00000000..3dcd6f71
--- /dev/null
+++ b/tests/fact.py
@@ -0,0 +1,10 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ b = self.driver.find_element_by_xpath('/html/body')
+ self.assertEqual('3628800, 3628800', b.text)
+
diff --git a/tests/fake_types b/tests/fake_types
new file mode 100644
index 00000000..405e9d1d
--- /dev/null
+++ b/tests/fake_types
@@ -0,0 +1,2 @@
+horrible_idea/blorpapalooza txt
+whoa/yowza html
diff --git a/tests/filter.py b/tests/filter.py
new file mode 100644
index 00000000..f68f8f88
--- /dev/null
+++ b/tests/filter.py
@@ -0,0 +1,9 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start('Filter/main')
+ tx = self.body_text()
+ self.assertEqual("4, 4; 44, 4.4;", tx)
diff --git a/tests/filter.ur b/tests/filter.ur
index efd326c3..2691a939 100644
--- a/tests/filter.ur
+++ b/tests/filter.ur
@@ -1,9 +1,16 @@
-fun filter [fs ::: {Type}] [ks] (t : sql_table fs ks) (p : sql_exp [T = fs] [] [] bool)
- : sql_query [T = fs] [] =
+fun filter [fs ::: {Type}] [ks] (t : sql_table fs ks) (p : sql_exp [T = fs] [] [] bool) =
(SELECT * FROM t WHERE {p})
table t : { A : int, B : float }
-fun main () =
- queryX (filter t (WHERE t.A > 3))
- (fn r => <xml>{[r.T.A]}, {[r.T.B]}</xml>)
+task initialize = fn () =>
+ dml (INSERT INTO t (A, B) VALUES (1, 2.0));
+ dml (INSERT INTO t (A, B) VALUES (2, 1.0));
+ dml (INSERT INTO t (A, B) VALUES (3, 3.0));
+ dml (INSERT INTO t (A, B) VALUES (4, 4.0));
+ dml (INSERT INTO t (A, B) VALUES (44, 4.4))
+
+fun main () : transaction page =
+ r <- queryX (filter t (WHERE t.A > 3))
+ (fn r => <xml>{[r.T.A]}, {[r.T.B]}; </xml>);
+ return <xml><body>{r}</body></xml>
diff --git a/tests/jsbspace.py b/tests/jsbspace.py
new file mode 100644
index 00000000..b29d44b9
--- /dev/null
+++ b/tests/jsbspace.py
@@ -0,0 +1,11 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+ el = self.xpath('button')
+ el.click()
+ alert = self.driver.switch_to.alert
+ self.assertEqual('Some \btext', alert.text)
diff --git a/tests/jsbspace.ur b/tests/jsbspace.ur
new file mode 100644
index 00000000..bf4b824f
--- /dev/null
+++ b/tests/jsbspace.ur
@@ -0,0 +1,12 @@
+fun main () : transaction page =
+let
+ fun onclick (): transaction unit =
+ (* this function runs on the client *)
+ alert "Some \btext"
+in
+return <xml>
+ <body>
+ <button onclick={fn _ => onclick()}>Click me!</button>
+ </body>
+</xml>
+end \ No newline at end of file
diff --git a/tests/jsonTest.py b/tests/jsonTest.py
new file mode 100644
index 00000000..d9147511
--- /dev/null
+++ b/tests/jsonTest.py
@@ -0,0 +1,16 @@
+import unittest
+import base
+
+class Suite(base.Base):
+ def test_1(self):
+ """Test case 1"""
+ self.start()
+
+ pre = self.xpath('pre[1]')
+ self.assertEqual('line 1\nline 2', pre.text)
+
+ pre = self.xpath('pre[2]')
+ self.assertEqual('1 :: 2 :: 3 :: []', pre.text)
+
+ pre = self.xpath('pre[3]')
+ self.assertEqual('["hi","bye\\"","hehe"]', pre.text)
diff --git a/tests/jsonTest.ur b/tests/jsonTest.ur
index 97898de8..bce269bd 100644
--- a/tests/jsonTest.ur
+++ b/tests/jsonTest.ur
@@ -1,6 +1,7 @@
open Json
fun main () : transaction page = return <xml><body>
- {[fromJson "[1, 2, 3]" : list int]}<br/>
- {[toJson ("hi" :: "bye\"" :: "hehe" :: [])]}
+ <pre>{[ fromJson "\"\\\\line \/ 1\\nline 2\"" : string ]}</pre><br/>
+ <pre>{[fromJson "[1, 2, 3]" : list int]}</pre><br/>
+ <pre>{[toJson ("hi" :: "bye\"" :: "hehe" :: [])]}</pre>
</body></xml>
diff --git a/tests/listGroupBy.ur b/tests/listGroupBy.ur
new file mode 100644
index 00000000..c2419ce1
--- /dev/null
+++ b/tests/listGroupBy.ur
@@ -0,0 +1,13 @@
+fun lister () = List.tabulateM (fn _ => n <- rand; return (n % 100)) 8
+
+fun main () : transaction page =
+ inp <- source [];
+ return <xml><body>
+ <button value="Compute" onclick={fn _ =>
+ ls <- rpc (lister ());
+ set inp ls}/>
+
+ <dyn signal={inp <- signal inp; return (txt inp)}/>
+ -&gt;
+ <dyn signal={inp <- signal inp; return (txt (List.groupBy (fn n m => n % 2 = m % 2) inp))}/>
+ </body></xml>
diff --git a/tests/listGroupBy.urp b/tests/listGroupBy.urp
new file mode 100644
index 00000000..1a63a89d
--- /dev/null
+++ b/tests/listGroupBy.urp
@@ -0,0 +1,4 @@
+rewrite all ListGroupBy/*
+
+$/list
+listGroupBy \ No newline at end of file
diff --git a/tests/mimeTypesDirective.ur b/tests/mimeTypesDirective.ur
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/mimeTypesDirective.ur
diff --git a/tests/mimeTypesDirective.urp b/tests/mimeTypesDirective.urp
new file mode 100644
index 00000000..43f06a00
--- /dev/null
+++ b/tests/mimeTypesDirective.urp
@@ -0,0 +1,6 @@
+mimeTypes fake_types
+file /hello.txt hello.txt
+file /hello.html hello.html
+file /hello2.txt hello.txt gadzooks/yippie
+
+mimeTypesDirective
diff --git a/tests/pairUnify.ur b/tests/pairUnify.ur
new file mode 100644
index 00000000..1c9f9759
--- /dev/null
+++ b/tests/pairUnify.ur
@@ -0,0 +1,6 @@
+datatype a = A
+datatype b = B
+
+val x : a * b = (A, B)
+
+val y : b = x
diff --git a/tests/slashform.ur b/tests/slashform.ur
new file mode 100644
index 00000000..63591886
--- /dev/null
+++ b/tests/slashform.ur
@@ -0,0 +1,9 @@
+fun handler f = return <xml>{[f.F1]} {[f.F2]} {[f.F3]}</xml>
+
+val main = return <xml><body><form>
+ <textbox{#F1}/>
+ <textarea{#F2}/>
+ <checkbox{#F3}/>
+ <upload{#File}/>
+ <submit action={handler}/>
+</form></body></xml>
diff --git a/tests/slashform.urs b/tests/slashform.urs
new file mode 100644
index 00000000..61778b87
--- /dev/null
+++ b/tests/slashform.urs
@@ -0,0 +1 @@
+val main : transaction page
diff --git a/tests/unurlify2.ur b/tests/unurlify2.ur
new file mode 100644
index 00000000..2e82928d
--- /dev/null
+++ b/tests/unurlify2.ur
@@ -0,0 +1,16 @@
+datatype bugged = Nothing | Something of int
+datatype myDt = One | Two
+type myRecord = {Bugged: bugged
+ , MyDt : myDt}
+
+fun rpcTarget (t: myRecord) = return ()
+
+val good = {Bugged = Something 4, MyDt = One}
+val bad = {Bugged = Nothing, MyDt = One}
+
+fun main () : transaction page = return <xml>
+ <body>
+ <button onclick={fn _ => rpc (rpcTarget good)}>rpc with good</button>
+ <button onclick={fn _ => rpc (rpcTarget bad)}>rpc with bad</button>
+ </body>
+</xml>