Skip to content

Commit

Permalink
Merge branch 'feature/unittests' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
solarnz committed Jun 8, 2014
2 parents 0a9a418 + d1810a7 commit d102249
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 23 deletions.
2 changes: 1 addition & 1 deletion nose_watcher/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

__author__ = 'Chris Trotman'
__email__ = 'chris@trotman.io'
__version__ = '0.1.0'
__version__ = '0.1.1'
30 changes: 24 additions & 6 deletions nose_watcher/nose_watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ class WatcherPlugin(Plugin):
# The name of the plugin
name = PLUGIN_NAME

# The arguments we want to run nose with again.
args = [a for a in sys.argv if a != '--with-%s' % PLUGIN_NAME]

# The inotify events we want to listen for
inotify_events = (
inotify.IN_ATTRIB | inotify.IN_CLOSE_WRITE | inotify.IN_CREATE |
Expand All @@ -28,9 +25,25 @@ class WatcherPlugin(Plugin):

# Files ending with these suffixes will cause us to run nostests again.
python_files = ('.py', '.pyx')
testing = False

def call(self):
Popen(self.args).wait()
args = self.get_commandline_arguments()
Popen(args).wait()

def check_files(self, files):
return any(f.endswith(self.python_files) for f in files)

def get_commandline_arguments(self, argv=None):
if argv is None:
argv = sys.argv

# The arguments we want to run nose with again.
args = [a for a in argv if a != '--with-%s' % PLUGIN_NAME]
return args

def print_status(self): # pragma:nocover
print('Watching for changes...\n')

def finalize(self, result):
watcher = inotify.watcher.AutoWatcher()
Expand All @@ -45,6 +58,8 @@ def finalize(self, result):
threshold = inotify.watcher.Threshold(watcher, 512)
timeout = None

self.print_status()

while True:
events = poll.poll(timeout)
files = set()
Expand All @@ -54,11 +69,14 @@ def finalize(self, result):
files.add(event.fullpath)

if files:
if any(f.endswith(self.python_files) for f in files):
if self.check_files(files):
self.call()

self.print_status()
timeout = None
poll.register(watcher, select.POLLIN)
else:
timeout = 1000
poll.unregister(watcher)

if self.testing:
break
1 change: 1 addition & 0 deletions requirements-testing.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
wheel
nose
mock
2 changes: 1 addition & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
126 changes: 111 additions & 15 deletions tests/test_nose_watcher.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,121 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
test_nose-watcher
----------------------------------
Tests for `nose-watcher` module.
"""

from collections import namedtuple
import sys
import unittest

from nose_watcher import nose_watcher
from mock import Mock, patch

from nose_watcher.nose_watcher import WatcherPlugin


class TestNoseWatcher(unittest.TestCase):

def setUp(self):
pass
self.plugin = WatcherPlugin()
self.plugin.testing = True
self.plugin.call = Mock()


class TestFileTypes(TestNoseWatcher):
def test_file_types_py(self):
self.assertTrue(self.plugin.check_files({'test.py'}))

def test_file_types_pyx(self):
self.assertTrue(self.plugin.check_files({'test.pyx'}))

def test_file_types_pyc(self):
self.assertFalse(self.plugin.check_files({'test.pyc'}))

def test_file_types_py_and_pyc(self):
self.assertTrue(self.plugin.check_files({'test.py', 'test.pyc'}))

def test_file_types_pyc_and_txt(self):
self.assertFalse(self.plugin.check_files({'test.txt', 'test.pyc'}))


class TestArgumentParsing(TestNoseWatcher):
def test_arguments(self):
args_in = ['laa', '--with-%s' % WatcherPlugin.name, '--with-cover']
args_out = self.plugin.get_commandline_arguments(args_in)

self.assertEqual(
args_out,
['laa', '--with-cover']
)

def test_argument_parsing_from_sys_argv(self):
self.assertEqual(
self.plugin.get_commandline_arguments(),
[a for a in sys.argv if a != '--with-watcher']
)


class TestWatching(TestNoseWatcher):
@patch('inotify.watcher.AutoWatcher')
@patch('inotify.watcher.Threshold')
@patch('select.poll')
def test_watch_no_files_modified(self, poll_mock, threshold_patch,
watcher_mock):
threshold = Mock()
threshold_patch.return_value = threshold
threshold.return_value = True
self.plugin.finalize(None)

self.assertFalse(self.plugin.call.called)

@patch('inotify.watcher.AutoWatcher')
@patch('inotify.watcher.Threshold')
@patch('select.poll')
def test_watch_no_files_watched(self, poll_mock, threshold_patch,
watcher_mock):
threshold = Mock()
threshold_patch.return_value = threshold
threshold.return_value = True

watcher = Mock()
watcher_mock.return_value = watcher

watcher.num_watches.return_value = False
self.plugin.finalize(None)

self.assertFalse(self.plugin.call.called)

@patch('inotify.watcher.AutoWatcher')
@patch('inotify.watcher.Threshold')
@patch('select.poll')
def test_watch_python_files_modified(self, poll_mock, threshold_patch,
watcher_mock):
threshold = Mock()
threshold_patch.return_value = threshold
threshold.return_value = True

watcher = Mock()
watcher_mock.return_value = watcher

Event = namedtuple('Event', ['fullpath'])
watcher.read.return_value = [
Event('aaa/python.py')
]
self.plugin.finalize(None)

self.assertTrue(self.plugin.call.called)

@patch('inotify.watcher.AutoWatcher')
@patch('inotify.watcher.Threshold')
@patch('select.poll')
def test_watch_text_files_modified(self, poll_mock, threshold_patch,
watcher_mock):
threshold = Mock()
threshold_patch.return_value = threshold
threshold.return_value = True

watcher = Mock()
watcher_mock.return_value = watcher

def test_something(self):
pass
Event = namedtuple('Event', ['fullpath'])
watcher.read.return_value = [
Event('aaa/python.txt')
]
self.plugin.finalize(None)

def tearDown(self):
pass
self.assertFalse(self.plugin.call.called)

0 comments on commit d102249

Please sign in to comment.