Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Testing: add vote unit test and coverage script
Browse files Browse the repository at this point in the history
  • Loading branch information
KeyserSosa committed Jan 21, 2016
1 parent fc2841a commit af49fa3
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 8 deletions.
2 changes: 1 addition & 1 deletion install/travis.sh
Expand Up @@ -85,7 +85,7 @@ $RUNDIR/install_cassandra.sh
###############################################################################

[ -x "$(which pip)" ] || easy_install pip
pip install -U pip wheel setuptools
pip install -U pip wheel setuptools coverage
pushd $REDDIT_CODE/r2
sudo python setup.py build
python setup.py develop
Expand Down
55 changes: 55 additions & 0 deletions r2/coverage.sh
@@ -0,0 +1,55 @@
#!/bin/bash
set -e

BASEDIR=$(readlink -f $(dirname $0))
cd $BASEDIR

VERSION=$(git rev-parse HEAD)
COVERDIR="$BASEDIR/build/cover-$VERSION"

function usage() {
echo "Run unit tests and coverage reports on reddit codebase with optional"
echo "http server to the report"
echo
echo "Usage: `basename $0` [options]";
echo
echo " -h show this message"
echo " -p \$PORT run an simple http server on \$PORT to view results"
echo " -v verbose mode (set -x)"
echo
}

while getopts ":vhp:" opt; do
case $opt in
p) PORT="$OPTARG" ;;
v) set -x ;;
h)
usage
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
usage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done

nosetests \
--with-coverage \
--cover-html \
--cover-html-dir=$COVERDIR \
--cover-erase \
--cover-package=r2

if [ "$PORT" != "" ]; then
echo "Starting http server on :$PORT (^C to exit)"
pushd $COVERDIR
python -m SimpleHTTPServer $PORT || echo "Done."
popd
fi
rm -r $COVERDIR
10 changes: 9 additions & 1 deletion r2/r2/lib/app_globals.py
Expand Up @@ -477,7 +477,15 @@ def __getattr__(self, name):
raise AttributeError("g has no attr %r" % name)

def setup(self):
self.env = 'unit_test' if 'test' in sys.argv[0] else ''
self.env = ''
if (
# handle direct invocation of "nosetests"
"test" in sys.argv[0] or
# handle "setup.py test" and all permutations thereof.
"setup.py" in sys.argv[0] and "test" in sys.argv[1:]
):
self.env = "unit_test"

self.queues = queues.declare_queues(self)

self.extension_subdomains = dict(
Expand Down
7 changes: 7 additions & 0 deletions r2/r2/tests/__init__.py
Expand Up @@ -97,3 +97,10 @@ def assert_same_dict(self, data, expected_data, prefix=None):
".".join(current_prefix), got, want
)
)

def autopatch(self, obj, attr, *a, **kw):
"""Helper method to patch an object and automatically cleanup."""
p = patch.object(obj, attr, *a, **kw)
m = p.start()
self.addCleanup(p.stop)
return m
51 changes: 51 additions & 0 deletions r2/r2/tests/unit/models/vote_test.py
@@ -0,0 +1,51 @@
from mock import patch, MagicMock
from datetime import datetime

import pytz

from r2.models.vote import Vote
from r2.tests import RedditTestCase


class TestVoteValidator(RedditTestCase):

def setUp(self):
self.user = MagicMock(name="user")
self.thing = MagicMock(name="thing")
self.vote_data = {}
super(RedditTestCase, self).setUp()

def cast_vote(self, **kw):
kw.setdefault("date", datetime.now(pytz.UTC))
kw.setdefault("direction", Vote.DIRECTIONS.up)
kw.setdefault("get_previous_vote", False)
kw.setdefault("data", self.vote_data)
return Vote(
user=self.user,
thing=self.thing,
**kw
)

def assert_vote_effects(
self, vote, affects_score, affects_karma,
affected_thing_attr, *notes
):
self.assertEqual(vote.effects.affects_score, affects_score)
self.assertEqual(vote.effects.affects_karma, affects_karma)
self.assertEqual(vote.affected_thing_attr, affected_thing_attr)
self.assertEqual(set(vote.effects.notes), set(notes))
return vote

def test_upvote_effects(self):
vote = self.cast_vote()
self.assertTrue(vote.is_upvote)
self.assertFalse(vote.is_downvote)
self.assertFalse(vote.is_self_vote)
self.assert_vote_effects(vote, True, True, "_ups")

def test_downvote_effects(self):
vote = self.cast_vote(direction=Vote.DIRECTIONS.down)
self.assertFalse(vote.is_upvote)
self.assertTrue(vote.is_downvote)
self.assertFalse(vote.is_self_vote)
self.assert_vote_effects(vote, True, True, "_downs")
9 changes: 3 additions & 6 deletions r2/setup.py
Expand Up @@ -85,12 +85,9 @@
"webob",
"webtest",
],
# Extra dependencies that aren't needed for running the app.
# * https://pythonhosted.org/setuptools/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies
# * https://github.com/pypa/sampleproject/blob/300f04dc44df51492deb859ac98ba521d2c7a17a/setup.py#L71-L77
extras_require={
'test': ['mock', 'nose'],
},
# setup tests (allowing for "python setup.py test")
tests_require=['mock', 'nose', 'coverage'],
test_suite="nose.collector",
dependency_links=[
"https://github.com/reddit/snudown/archive/v1.1.3.tar.gz#egg=snudown-1.1.3",
"https://s3.amazonaws.com/code.reddit.com/pycaptcha-0.4.tar.gz#egg=pycaptcha-0.4",
Expand Down

0 comments on commit af49fa3

Please sign in to comment.