Skip to content

Commit

Permalink
Add more tests for ContactlessFrontend
Browse files Browse the repository at this point in the history
  • Loading branch information
nehpetsde committed Mar 30, 2017
1 parent 4344bee commit 4e37b5f
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 7 deletions.
14 changes: 7 additions & 7 deletions src/nfc/clf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,13 +501,13 @@ def on_release(tag):
card_options = options.get('card')

try:
assert not rdwr_options or isinstance(rdwr_options, dict), "rdwr"
assert not llcp_options or isinstance(llcp_options, dict), "llcp"
assert not card_options or isinstance(card_options, dict), "card"
assert isinstance(rdwr_options, (dict, type(None))), "rdwr"
assert isinstance(llcp_options, (dict, type(None))), "llcp"
assert isinstance(card_options, (dict, type(None))), "card"
except AssertionError as error:
raise TypeError("argument '%s' must be dictionary type" % error)
raise TypeError("argument '%s' must be a dictionary" % error)

if llcp_options:
if llcp_options is not None:
llcp_options = dict(llcp_options)
llcp_options.setdefault('on-startup', lambda llc: llc)
llcp_options.setdefault('on-connect', lambda llc: True)
Expand All @@ -521,7 +521,7 @@ def on_release(tag):
log.debug("removing llcp_options after on-startup")
llcp_options = None

if rdwr_options:
if rdwr_options is not None:
def on_discover(target):
if target.sel_res and target.sel_res[0] & 0x40:
return False
Expand All @@ -548,7 +548,7 @@ def on_discover(target):
log.debug("removing rdwr_options after on-startup")
rdwr_options = None

if card_options:
if card_options is not None:
card_options = dict(card_options)
card_options.setdefault('on-startup', lambda target: None)
card_options.setdefault('on-discover', lambda target: True)
Expand Down
5 changes: 5 additions & 0 deletions src/nfc/clf/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ def chipset_name(self):
def path(self):
return self._path

def close(self):
fname = "close"
cname = self.__class__.__module__ + '.' + self.__class__.__name__
raise NotImplementedError("%s.%s() is required" % (cname, fname))

def mute(self):
"""Mutes all existing communication, most notably the device will no
longer generate a 13.56 MHz carrier signal when operating as
Expand Down
119 changes: 119 additions & 0 deletions tests/test_clf_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
import nfc
import nfc.clf

import errno
import pytest
from pytest_mock import mocker # noqa: F401

import logging
logging.basicConfig(level=logging.DEBUG)
logging_level = logging.getLogger().getEffectiveLevel()
logging.getLogger("nfc.clf").setLevel(logging_level)


def HEX(s):
return bytearray.fromhex(s)
Expand All @@ -18,6 +24,119 @@ def test_print_data():
assert nfc.clf.print_data(bytearray.fromhex('01')) == '01'


class TestContactlessFrontend(object):
@pytest.fixture() # noqa: F811
def device_connect(self, mocker):
return mocker.patch('nfc.clf.device.connect')

@pytest.fixture() # noqa: F811
def device(self, mocker):
return mocker.Mock(spec=nfc.clf.device.Device)

@pytest.fixture() # noqa: F811
def clf(self, device_connect, device):
device_connect.return_value = device
clf = nfc.clf.ContactlessFrontend('test')
device_connect.assert_called_once_with('test')
assert isinstance(clf, nfc.clf.ContactlessFrontend)
assert isinstance(clf.device, nfc.clf.device.Device)
return clf

@pytest.fixture() # noqa: F811
def terminate(self, mocker):
return mocker.Mock(return_value=True)

def test_init(self, device_connect):
device_connect.return_value = None
with pytest.raises(IOError) as excinfo:
nfc.clf.ContactlessFrontend('test')
assert excinfo.value.errno == errno.ENODEV

def test_open(self, device_connect, device):
device_connect.return_value = None
assert nfc.clf.ContactlessFrontend().open('test') is False

device_connect.return_value = device
assert nfc.clf.ContactlessFrontend().open('test') is True

with pytest.raises(TypeError) as excinfo:
nfc.clf.ContactlessFrontend().open(int())
assert str(excinfo.value) == "expecting a string type argument *path*"

with pytest.raises(ValueError) as excinfo:
nfc.clf.ContactlessFrontend().open('')
assert str(excinfo.value) == "argument *path* must not be empty"

def test_close(self, clf):
clf.device.close.side_effect = IOError
clf.close()

def test_connect_without_device(self, clf):
clf.device = None
with pytest.raises(IOError) as excinfo:
clf.connect()
assert excinfo.value.errno == errno.ENODEV

@pytest.mark.parametrize("options, errstr", [
({'rdwr': str()}, "'rdwr' must be a dictionary"),
({'llcp': int()}, "'llcp' must be a dictionary"),
({'card': set()}, "'card' must be a dictionary"),
])
def test_connect_with_invalid_options(self, clf, options, errstr):
with pytest.raises(TypeError) as excinfo:
clf.connect(**options)
assert str(excinfo.value) == "argument " + errstr

def test_connect_with_empty_options(self, clf):
assert clf.connect() is None

def test_connect_with_startup_false(self, clf):
assert clf.connect(llcp={'on-startup': lambda llc: False}) is None
assert clf.connect(rdwr={'on-startup': lambda llc: False}) is None
assert clf.connect(card={'on-startup': lambda llc: False}) is None

def test_connect_with_terminate_true(self, clf, terminate):
assert clf.connect(llcp={}, terminate=terminate) is None
assert clf.connect(rdwr={}, terminate=terminate) is None
assert clf.connect(card={}, terminate=terminate) is None

def test_connect_llcp_initiator(self, clf, terminate):
terminate.side_effect = [False, True]
clf.device.sense_tta.return_value = None
clf.device.sense_ttb.return_value = None
clf.device.sense_ttf.return_value = None
clf.device.sense_dep.return_value = None
llcp_options = {'role': 'initiator'}
assert clf.connect(llcp=llcp_options, terminate=terminate) is None

def test_connect_rdwr_defaults(self, clf, terminate):
terminate.side_effect = [False, True]
clf.device.sense_tta.return_value = None
clf.device.sense_ttb.return_value = None
clf.device.sense_ttf.return_value = None
rdwr_options = {'iterations': 1}
assert clf.connect(rdwr=rdwr_options, terminate=terminate) is None

def test_connect_card_defaults(self, clf, terminate):
terminate.side_effect = [False, True]
clf.device.listen_tta.return_value = None
clf.device.listen_ttb.return_value = None
clf.device.listen_ttf.return_value = None
card_options = {'on-startup': lambda _: nfc.clf.LocalTarget('212F')}
assert clf.connect(card=card_options, terminate=terminate) is None

@pytest.mark.parametrize("error", [
IOError, nfc.clf.UnsupportedTargetError, KeyboardInterrupt,
])
def test_connect_false_on_error(self, clf, error):
clf.device.sense_tta.side_effect = error
clf.device.sense_ttb.side_effect = error
clf.device.sense_ttf.side_effect = error
clf.device.sense_dep.side_effect = error
llcp_options = {'role': 'initiator'}
assert clf.connect(llcp=llcp_options) is False


class TestRemoteTarget(object):
@pytest.mark.parametrize("brty, send, recv, kwargs", [
('106A', '106A', '106A', {}),
Expand Down

0 comments on commit 4e37b5f

Please sign in to comment.