Skip to content

Commit

Permalink
Ensure an empty config file load as an empty dict
Browse files Browse the repository at this point in the history
  • Loading branch information
okomestudio committed Apr 22, 2020
1 parent c82b323 commit 1346f3f
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 27 deletions.
17 changes: 15 additions & 2 deletions src/resconfig/io/json.py
@@ -1,2 +1,15 @@
from json import dump # noqa
from json import load # noqa
from json import dump as _dump
from json import load as _load
from json.decoder import JSONDecodeError


def dump(content, f):
return _dump(content, f)


def load(f):
try:
content = _load(f)
except JSONDecodeError:
content = {}
return content
7 changes: 1 addition & 6 deletions src/resconfig/io/paths.py
Expand Up @@ -21,12 +21,7 @@ def dump(self, content):

def load(self):
with open(self) as f:
try:
content = self.module.load(f) or {}
except Exception:
log.exception("Error occured loading from %s; assume empty...", self)
content = {}
return content
return self.module.load(f)

@classmethod
def from_extension(cls, filename: FilePath) -> "ConfigPath":
Expand Down
3 changes: 2 additions & 1 deletion src/resconfig/io/yaml.py
Expand Up @@ -21,4 +21,5 @@ def _dict_representer(dumper, data):


def load(stream, **kwargs):
return yaml.load(stream, yaml.FullLoader, **kwargs)
content = yaml.load(stream, yaml.FullLoader, **kwargs)
return content if content else {}
10 changes: 10 additions & 0 deletions tests/resconfig/io/bases.py
@@ -0,0 +1,10 @@
from io import StringIO


class BaseTestLoad:
module = None

def test_empty(self):
stream = StringIO("")
loaded = self.module.load(stream)
assert loaded == {}, "Blank file should load as an empty dict"
20 changes: 11 additions & 9 deletions tests/resconfig/io/test_ini.py
@@ -1,9 +1,10 @@
import io
from io import StringIO

import pytest

from resconfig.io.ini import dump
from resconfig.io.ini import load
from resconfig.io import ini

from .bases import BaseTestLoad

content = """
[DEFAULT]
Expand All @@ -27,23 +28,24 @@

@pytest.fixture
def stream():
yield io.StringIO(content)
yield StringIO(content)


@pytest.fixture
def loaded(stream):
yield load(stream)
yield ini.load(stream)


@pytest.fixture
def dumped(loaded):
stream = io.StringIO()
dump(loaded, stream)
def dumped(loaded, stream):
ini.dump(loaded, stream)
stream.seek(0)
yield stream.read()


class TestLoad:
class TestLoad(BaseTestLoad):
module = ini

def test_default_pass_through(self, loaded):
assert loaded[r"bitbucket\.org"]["serveraliveinterval"] == "45"

Expand Down
80 changes: 80 additions & 0 deletions tests/resconfig/io/test_json.py
@@ -0,0 +1,80 @@
from io import StringIO

import pytest

from resconfig.io import json

from .bases import BaseTestLoad

content = """
{
"str": "str",
"int": 10,
"bool": true,
"null": null,
"array": [0, 1, 2],
"nested": {
"str": "mystr",
"int": 10
}
}
"""


@pytest.fixture
def stream():
yield StringIO(content)


@pytest.fixture
def loaded(stream):
yield json.load(stream)


@pytest.fixture
def dumped(loaded, stream):
json.dump(loaded, stream)
stream.seek(0)
yield stream.read()


class TestLoad(BaseTestLoad):
module = json

def test_integer(self, loaded):
assert loaded["int"] == 10

def test_string(self, loaded):
assert loaded["str"] == "str"

def test_bool(self, loaded):
assert loaded["bool"] is True

def test_null(self, loaded):
assert loaded["null"] is None

def test_array(self, loaded):
assert loaded["array"] == [0, 1, 2]

def test_nested(self, loaded):
assert loaded["nested"]["int"] == 10


class TestDump:
def test_string(self, dumped):
assert '"str": "str"' in dumped

def test_integer(self, dumped):
assert '"int": 10' in dumped

def test_bool(self, dumped):
assert '"bool": true' in dumped

def test_null(self, dumped):
assert '"null": null' in dumped

def test_array(self, dumped):
assert '"array": [0, 1, 2]' in dumped

def test_nested(self, dumped):
assert '"nested": {' in dumped
20 changes: 11 additions & 9 deletions tests/resconfig/io/test_toml.py
@@ -1,12 +1,13 @@
import io
from datetime import datetime
from datetime import timedelta
from datetime import timezone
from io import StringIO

import pytest

from resconfig.io.toml import dump
from resconfig.io.toml import load
from resconfig.io import toml

from .bases import BaseTestLoad

content = """
title = "TOML Example"
Expand Down Expand Up @@ -46,23 +47,24 @@

@pytest.fixture
def stream():
yield io.StringIO(content)
yield StringIO(content)


@pytest.fixture
def loaded(stream):
yield load(stream)
yield toml.load(stream)


@pytest.fixture
def dumped(loaded):
stream = io.StringIO()
dump(loaded, stream)
def dumped(loaded, stream):
toml.dump(loaded, stream)
stream.seek(0)
yield stream.read()


class TestLoad:
class TestLoad(BaseTestLoad):
module = toml

def test_no_section(self, loaded):
assert loaded["title"] == "TOML Example"

Expand Down
78 changes: 78 additions & 0 deletions tests/resconfig/io/test_yaml.py
@@ -0,0 +1,78 @@
from io import StringIO

import pytest

from resconfig.io import yaml

from .bases import BaseTestLoad

content = """
---
str: str
int: 10
bool: true
null: null
array: [0, 1, 2]
nested:
str: mystr
int: 10
"""


@pytest.fixture
def stream():
yield StringIO(content)


@pytest.fixture
def loaded(stream):
yield yaml.load(stream)


@pytest.fixture
def dumped(loaded, stream):
yaml.dump(loaded, stream)
stream.seek(0)
yield stream.read()


class TestLoad(BaseTestLoad):
module = yaml

def test_integer(self, loaded):
assert loaded["int"] == 10

def test_string(self, loaded):
assert loaded["str"] == "str"

def test_bool(self, loaded):
assert loaded["bool"] is True

def test_null(self, loaded):
assert loaded[None] is None

def test_array(self, loaded):
assert loaded["array"] == [0, 1, 2]

def test_nested(self, loaded):
assert loaded["nested"]["int"] == 10


class TestDump:
def test_string(self, dumped):
assert "str: str" in dumped

def test_integer(self, dumped):
assert "int: 10" in dumped

def test_bool(self, dumped):
assert "bool: true" in dumped

def test_null(self, dumped):
assert "null: null" in dumped

def test_array(self, dumped):
assert "array:\n- 0\n- 1\n- 2\n" in dumped

def test_nested(self, dumped):
assert "nested:" in dumped

0 comments on commit 1346f3f

Please sign in to comment.