diff --git a/CHANGES.txt b/CHANGES.txt
index 76191fe12..f4a24c4c3 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,13 @@
Pyxform Changelog
+# v1.4.0, 2021-02-23
+
+* #514 Fix circular reference error raised when converting an XLSX form with multiple languages to JSON
+ * Davis Raymond @DavisRayM (Ona)
+* #519 Add support for odk:recordaudio
+ * Callum Stott @seadowg (ODK)
+
# v1.3.4, 2021-01-15
* #510 Show a more helpful error message is section name is equal to form name
diff --git a/README.rst b/README.rst
index 967d0d259..6da4a48b4 100644
--- a/README.rst
+++ b/README.rst
@@ -1,5 +1,5 @@
===============
-pyxform v1.3.4
+pyxform v1.4.0
===============
|circleci| |appveyor| |codecov| |black|
diff --git a/pyxform/__init__.py b/pyxform/__init__.py
index ba446e28e..0fc9d6e99 100644
--- a/pyxform/__init__.py
+++ b/pyxform/__init__.py
@@ -4,7 +4,7 @@
Collect easy.
"""
-__version__ = "1.3.4"
+__version__ = "1.4.0"
from pyxform.builder import (
SurveyElementBuilder,
diff --git a/pyxform/tests_v1/test_dynamic_default.py b/pyxform/tests_v1/test_dynamic_default.py
index 48f56bb11..e12fafc8f 100644
--- a/pyxform/tests_v1/test_dynamic_default.py
+++ b/pyxform/tests_v1/test_dynamic_default.py
@@ -19,7 +19,7 @@ def test_handling_dynamic_default(self):
| survey | | | | |
| | type | name | label | default |
| | text | last_name | Last name | not_func$ |
- | | integer | age | Your age | some_rando_func() |
+ | | integer | age | Your age | random() |
"""
self.assertPyxformXform(
@@ -29,7 +29,7 @@ def test_handling_dynamic_default(self):
model__contains=[
"not_func$",
"",
- '',
+ '',
],
)
@@ -44,12 +44,12 @@ def test_handling_dynamic_default(self):
self.assertContains(survey_xml, "", 1)
self.assertContains(
survey_xml,
- '',
+ '',
1,
)
self.assertNotContains(
survey_xml,
- '',
+ '',
)
def test_static_defaults(self):
@@ -75,7 +75,7 @@ def test_handling_dynamic_default_in_repeat(self):
| survey | | | | |
| | type | name | label | default |
| | begin repeat | household | Households | |
- | | integer | age | Your age | some_rando_func() |
+ | | integer | age | Your age | random() |
| | text | feeling | Your feeling | not_func$ |
| | end repeat | household | | |
"""
@@ -86,10 +86,10 @@ def test_handling_dynamic_default_in_repeat(self):
id_string="id",
model__contains=["", "not_func$"],
model__excludes=[
- ''
+ ''
],
xml__contains=[
- ''
+ ''
],
)
@@ -104,12 +104,12 @@ def test_handling_dynamic_default_in_repeat(self):
self.assertContains(survey_xml, "", 2)
self.assertContains(
survey_xml,
- '',
+ '',
1,
)
self.assertNotContains(
survey_xml,
- '',
+ '',
)
def test_dynamic_default_in_group(self):
@@ -227,7 +227,7 @@ def test_handling_arithmetic_expression(self):
| | type | name | label | default |
| | text | expr_1 | First expr | 2 + 3 * 4 |
| | text | expr_2 | Second expr | 5 div 5 - 5 |
- | | integer | expr_3 | Third expr | expr() + 2 * 5 |
+ | | integer | expr_3 | Third expr | random() + 2 * 5 |
"""
self.assertPyxformXform(
@@ -240,7 +240,7 @@ def test_handling_arithmetic_expression(self):
"",
'',
'',
- '',
+ '',
],
)
diff --git a/pyxform/tests_v1/test_last_saved.py b/pyxform/tests_v1/test_last_saved.py
index 424454223..a8be6e928 100644
--- a/pyxform/tests_v1/test_last_saved.py
+++ b/pyxform/tests_v1/test_last_saved.py
@@ -149,6 +149,7 @@ def test_last_saved_in_repeat(self):
| | end repeat | my-repeat | | |
| | calculate | baz | | ${foo} + ${last-saved#foo} |
""",
+ run_odk_validate=False, # This test is more for documentation. The unqualified ref fails Validate.
xml__contains=[
'',
'calculate=" ../foo + instance(\'__last-saved\')/last-saved/my-repeat/foo " nodeset="/last-saved/my-repeat/bar"',
diff --git a/setup.py b/setup.py
index 5e6d10ff7..f90df6130 100644
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,7 @@
setup(
name="pyxform",
- version="1.3.4",
+ version="1.4.0",
author="github.com/xlsform",
author_email="info@xlsform.org",
packages=find_packages(),