Add a function for writing to a JavaScript file
- ID
047f653- date
2024-08-16 21:23:43+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
8be8cda- message
Add a function for writing to a JavaScript file- changed files
3 files, 55 additions, 2 deletions
Changed files
README.md (486) → README.md (554)
diff --git a/README.md b/README.md
index 1b3e83b..8c55b91 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# python-js-files
-This is a collection of Python functions for manipulating JavaScript "data files" -- that is, JavaScript files that have a single variable that defines a JSON value.
+This is a collection of Python functions for manipulating JavaScript "data files" -- that is, JavaScript files that define a single variable with a JSON value.
This is an example of a JavaScript data file:
@@ -13,6 +13,7 @@ Think of this module as the JSON module, but for JavaScript files.
## API
* You can read a JavaScript file with `read_js(path, varname)`
+* You can write a JavaScript file with `write_js(path, value, varname)`
## Why not use JSON files?
src/javascript/__init__.py (940) → src/javascript/__init__.py (1565)
diff --git a/src/javascript/__init__.py b/src/javascript/__init__.py
index ad71cd6..1d8a43d 100644
--- a/src/javascript/__init__.py
+++ b/src/javascript/__init__.py
@@ -34,3 +34,24 @@ def read_js(p: pathlib.Path | str, *, varname: str) -> typing.Any:
json_string = contents.replace(f"const {varname} = ", "").rstrip().rstrip(";")
return json.loads(json_string)
+
+
+def write_js(p: pathlib.Path | str, *, value: typing.Any, varname: str) -> None:
+ """
+ Write a JavaScript "data file".
+
+ Example:
+
+ >>> red_pentagon = {'sides': 5, 'colour': 'red'}
+ >>> write_js('shape.js', value=red_pentagon, varname='redPentagon')
+ >>> open('shape.js').read()
+ 'const redPentagon = {\n "sides": 5,\n "colour": "red"\n};\n'
+
+ """
+ json_string = json.dumps(value, indent=2)
+ js_string = f"const {varname} = {json_string};\n"
+
+ pathlib.Path(p).parent.mkdir(exist_ok=True, parents=True)
+
+ with open(p, "w") as out_file:
+ out_file.write(js_string)
tests/test_javascript.py (1569) → tests/test_javascript.py (2611)
diff --git a/tests/test_javascript.py b/tests/test_javascript.py
index afb03a8..cc2e94d 100644
--- a/tests/test_javascript.py
+++ b/tests/test_javascript.py
@@ -2,7 +2,7 @@ import pathlib
import pytest
-from javascript import read_js
+from javascript import read_js, write_js
class TestReadJs:
@@ -42,3 +42,34 @@ class TestReadJs:
with pytest.raises(ValueError, match="does not end with a trailing semicolon"):
read_js(js_path, varname="redPentagon")
+
+
+class TestWriteJs:
+ def test_can_write_file(self, tmp_path: pathlib.Path) -> None:
+ js_path = tmp_path / "shape.js"
+ red_pentagon = {"sides": 5, "colour": "red"}
+
+ write_js(js_path, value=red_pentagon, varname="redPentagon")
+
+ assert (
+ js_path.read_text()
+ == 'const redPentagon = {\n "sides": 5,\n "colour": "red"\n};\n'
+ )
+
+ def test_fails_if_cannot_write_file(self) -> None:
+ red_pentagon = {"sides": 5, "colour": "red"}
+
+ with pytest.raises(FileExistsError):
+ write_js("/", value=red_pentagon, varname="redPentagon")
+
+ def test_creates_parent_directory(self, tmp_path: pathlib.Path) -> None:
+ js_path = tmp_path / "1/2/3/shape.js"
+ red_pentagon = {"sides": 5, "colour": "red"}
+
+ write_js(js_path, value=red_pentagon, varname="redPentagon")
+
+ assert js_path.exists()
+ assert (
+ js_path.read_text()
+ == 'const redPentagon = {\n "sides": 5,\n "colour": "red"\n};\n'
+ )