Permalink
Browse files

tests yo

  • Loading branch information...
1 parent fc984a5 commit 3e7fb10a004f6fd85556e8c5091a0dad6576f515 @al3x committed Mar 2, 2009
View
5 TODO.txt
@@ -1,5 +0,0 @@
-Fix failure cases:
- http://downforeveryoneorjustme.com/mail.google.com - "looks down from here"
- http://downforeveryoneorjustme.com/cse.ohio-state.edu - "doesn't look like a site on the interwho"
- "http://" makes URLs not be a site on the interwho
- Amazon doesn't work
View
3 app.yaml
@@ -17,5 +17,8 @@ handlers:
- url: /javascripts
static_dir: javascripts
+- url: /test.*
+ script: gaeunit.py
+
- url: .*
script: main.py
View
474 gaeunit.py
@@ -0,0 +1,474 @@
+#!/usr/bin/env python
+'''
+GAEUnit: Google App Engine Unit Test Framework
+
+Usage:
+
+1. Put gaeunit.py into your application directory. Modify 'app.yaml' by
+ adding the following mapping below the 'handlers:' section:
+
+ - url: /test.*
+ script: gaeunit.py
+
+2. Write your own test cases by extending unittest.TestCase.
+
+3. Launch the development web server. To run all tests, point your browser to:
+
+ http://localhost:8080/test (Modify the port if necessary.)
+
+ For plain text output add '?format=plain' to the above URL.
+ See README.TXT for information on how to run specific tests.
+
+4. The results are displayed as the tests are run.
+
+Visit http://code.google.com/p/gaeunit for more information and updates.
+
+------------------------------------------------------------------------------
+Copyright (c) 2008, George Lei and Steven R. Farley. All rights reserved.
+
+Distributed under the following BSD license:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+------------------------------------------------------------------------------
+'''
+
+__author__ = "George Lei and Steven R. Farley"
+__email__ = "George.Z.Lei@Gmail.com"
+__version__ = "#Revision: 1.2.2 $"[11:-2]
+__copyright__= "Copyright (c) 2008, George Lei and Steven R. Farley"
+__license__ = "BSD"
+__url__ = "http://code.google.com/p/gaeunit"
+
+import sys
+import os
+import unittest
+import StringIO
+import time
+import re
+import logging
+from google.appengine.ext import webapp
+from google.appengine.api import apiproxy_stub_map
+from google.appengine.api import datastore_file_stub
+from google.appengine.ext.webapp.util import run_wsgi_app
+
+_DEFAULT_TEST_DIR = 'test'
+
+
+##############################################################################
+# Main request handler
+##############################################################################
+
+
+class MainTestPageHandler(webapp.RequestHandler):
+ def get(self):
+ unknown_args = [arg for arg in self.request.arguments()
+ if arg not in ("format", "package", "name")]
+ if len(unknown_args) > 0:
+ errors = []
+ for arg in unknown_args:
+ errors.append(_log_error("The request parameter '%s' is not valid." % arg))
+ self.error(404)
+ self.response.out.write(" ".join(errors))
+ return
+
+ format = self.request.get("format", "html")
+ if format == "html":
+ self._render_html()
+ elif format == "plain":
+ self._render_plain()
+ else:
+ error = _log_error("The format '%s' is not valid." % format)
+ self.error(404)
+ self.response.out.write(error)
+
+ def _render_html(self):
+ suite, error = _create_suite(self.request)
+ if not error:
+ self.response.out.write(_MAIN_PAGE_CONTENT % _test_suite_to_json(suite))
+ else:
+ self.error(404)
+ self.response.out.write(error)
+
+ def _render_plain(self):
+ self.response.headers["Content-Type"] = "text/plain"
+ runner = unittest.TextTestRunner(self.response.out)
+ suite, error = _create_suite(self.request)
+ if not error:
+ self.response.out.write("====================\n" \
+ "GAEUnit Test Results\n" \
+ "====================\n\n")
+ _run_test_suite(runner, suite)
+ else:
+ self.error(404)
+ self.response.out.write(error)
+
+
+##############################################################################
+# JSON test classes
+##############################################################################
+
+
+class JsonTestResult(unittest.TestResult):
+ def __init__(self):
+ unittest.TestResult.__init__(self)
+ self.testNumber = 0
+
+ def render_to(self, stream):
+ stream.write('{')
+ stream.write('"runs":"%d", "total":"%d", "errors":"%d", "failures":"%d",' % \
+ (self.testsRun, self.testNumber,
+ len(self.errors), len(self.failures)))
+ stream.write('"details":')
+ self._render_errors(stream)
+ stream.write('}')
+
+ def _render_errors(self, stream):
+ stream.write('{')
+ self._render_error_list('errors', self.errors, stream)
+ stream.write(',')
+ self._render_error_list('failures', self.failures, stream)
+ stream.write('}')
+
+ def _render_error_list(self, flavour, errors, stream):
+ stream.write('"%s":[' % flavour)
+ for test, err in errors:
+ stream.write('{"desc":"%s", "detail":"%s"},' %
+ (self._description(test), self._escape(err)))
+ if len(errors):
+ stream.seek(-1, 2)
+ stream.write("]")
+
+ def _description(self, test):
+ return test.shortDescription() or str(test)
+
+ def _escape(self, s):
+ newstr = re.sub('"', '"', s)
+ newstr = re.sub('\n', '<br/>', newstr)
+ return newstr
+
+
+class JsonTestRunner:
+ def run(self, test):
+ self.result = JsonTestResult()
+ self.result.testNumber = test.countTestCases()
+ startTime = time.time()
+ test(self.result)
+ stopTime = time.time()
+ timeTaken = stopTime - startTime
+ return self.result
+
+
+class JsonTestRunHandler(webapp.RequestHandler):
+ def get(self):
+ test_name = self.request.get("name")
+ _load_default_test_modules()
+ suite = unittest.defaultTestLoader.loadTestsFromName(test_name)
+ runner = JsonTestRunner()
+ _run_test_suite(runner, suite)
+ runner.result.render_to(self.response.out)
+
+
+# This is not used by the HTML page, but it may be useful for other client test runners.
+class JsonTestListHandler(webapp.RequestHandler):
+ def get(self):
+ suite, error = _create_suite(self.request)
+ if not error:
+ self.response.out.write(_test_suite_to_json(suite))
+ else:
+ self.error(404)
+ self.response.out.write(error)
+
+
+##############################################################################
+# Module helper functions
+##############################################################################
+
+
+def _create_suite(request):
+ package_name = request.get("package")
+ test_name = request.get("name")
+
+ loader = unittest.defaultTestLoader
+ suite = unittest.TestSuite()
+
+ if not package_name and not test_name:
+ modules = _load_default_test_modules()
+ for module in modules:
+ suite.addTest(loader.loadTestsFromModule(module))
+ elif test_name:
+ try:
+ _load_default_test_modules()
+ suite.addTest(loader.loadTestsFromName(test_name))
+ except:
+ pass
+ elif package_name:
+ try:
+ package = reload(__import__(package_name))
+ module_names = package.__all__
+ for module_name in module_names:
+ suite.addTest(loader.loadTestsFromName('%s.%s' % (package_name, module_name)))
+ except:
+ pass
+ if suite.countTestCases() == 0:
+ error = _log_error("'%s' is not found or does not contain any tests." % \
+ (test_name or package_name))
+ else:
+ error = None
+ return (suite, error)
+
+
+def _load_default_test_modules():
+ if not _DEFAULT_TEST_DIR in sys.path:
+ sys.path.append(_DEFAULT_TEST_DIR)
+ module_names = [mf[0:-3] for mf in os.listdir(_DEFAULT_TEST_DIR) if mf.endswith(".py")]
+ return [reload(__import__(name)) for name in module_names]
+
+
+def _get_tests_from_suite(suite, tests):
+ for test in suite:
+ if isinstance(test, unittest.TestSuite):
+ _get_tests_from_suite(test, tests)
+ else:
+ tests.append(test)
+
+
+def _test_suite_to_json(suite):
+ tests = []
+ _get_tests_from_suite(suite, tests)
+ test_tuples = [(type(test).__module__, type(test).__name__, test._testMethodName) \
+ for test in tests]
+ test_dict = {}
+ for test_tuple in test_tuples:
+ module_name, class_name, method_name = test_tuple
+ if module_name not in test_dict:
+ mod_dict = {}
+ method_list = []
+ method_list.append(method_name)
+ mod_dict[class_name] = method_list
+ test_dict[module_name] = mod_dict
+ else:
+ mod_dict = test_dict[module_name]
+ if class_name not in mod_dict:
+ method_list = []
+ method_list.append(method_name)
+ mod_dict[class_name] = method_list
+ else:
+ method_list = mod_dict[class_name]
+ method_list.append(method_name)
+
+ # Python's dictionary and list string representations happen to match JSON formatting.
+ return str(test_dict)
+
+
+def _run_test_suite(runner, suite):
+ """Run the test suite.
+
+ Preserve the current development apiproxy, create a new apiproxy and
+ replace the datastore with a temporary one that will be used for this
+ test suite, run the test suite, and restore the development apiproxy.
+ This isolates the test datastore from the development datastore.
+
+ """
+ original_apiproxy = apiproxy_stub_map.apiproxy
+ try:
+ apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
+ temp_stub = datastore_file_stub.DatastoreFileStub('GAEUnitDataStore', None, None)
+ apiproxy_stub_map.apiproxy.RegisterStub('datastore', temp_stub)
+ # Allow the other services to be used as-is for tests.
+ for name in ['user', 'urlfetch', 'mail', 'memcache', 'images']:
+ apiproxy_stub_map.apiproxy.RegisterStub(name, original_apiproxy.GetStub(name))
+ runner.run(suite)
+ finally:
+ apiproxy_stub_map.apiproxy = original_apiproxy
+
+
+def _log_error(s):
+ logging.warn(s)
+ return s
+
+
+################################################
+# Browser HTML, CSS, and Javascript
+################################################
+
+
+# This string uses Python string formatting, so be sure to escape percents as %%.
+_MAIN_PAGE_CONTENT = """
+<html>
+<head>
+ <style>
+ body {font-family:arial,sans-serif; text-align:center}
+ #title {font-family:"Times New Roman","Times Roman",TimesNR,times,serif; font-size:28px; font-weight:bold; text-align:center}
+ #version {font-size:87%%; text-align:center;}
+ #weblink {font-style:italic; text-align:center; padding-top:7px; padding-bottom:7px}
+ #results {padding-top:20px; margin:0pt auto; text-align:center; font-weight:bold}
+ #testindicator {width:750px; height:16px; border-style:solid; border-width:2px 1px 1px 2px; background-color:#f8f8f8;}
+ #footerarea {text-align:center; font-size:83%%; padding-top:25px}
+ #errorarea {padding-top:25px}
+ .error {border-color: #c3d9ff; border-style: solid; border-width: 2px 1px 2px 1px; width:750px; padding:1px; margin:0pt auto; text-align:left}
+ .errtitle {background-color:#c3d9ff; font-weight:bold}
+ </style>
+ <script language="javascript" type="text/javascript">
+ var testsToRun = eval("(" + "%s" + ")"); // JSON-formatted (see _test_suite_to_json)
+ var totalRuns = 0;
+ var totalErrors = 0;
+ var totalFailures = 0;
+
+ function newXmlHttp() {
+ try { return new XMLHttpRequest(); } catch(e) {}
+ try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
+ try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
+ alert("XMLHttpRequest not supported");
+ return null;
+ }
+
+ function requestTestRun(moduleName, className, methodName) {
+ var methodSuffix = "";
+ if (methodName) {
+ methodSuffix = "." + methodName;
+ }
+ var xmlHttp = newXmlHttp();
+ xmlHttp.open("GET", "/testrun?name=" + moduleName + "." + className + methodSuffix, true);
+ xmlHttp.onreadystatechange = function() {
+ if (xmlHttp.readyState != 4) {
+ return;
+ }
+ if (xmlHttp.status == 200) {
+ var result = eval("(" + xmlHttp.responseText + ")");
+ totalRuns += parseInt(result.runs);
+ totalErrors += parseInt(result.errors);
+ totalFailures += parseInt(result.failures);
+ document.getElementById("testran").innerHTML = totalRuns;
+ document.getElementById("testerror").innerHTML = totalErrors;
+ document.getElementById("testfailure").innerHTML = totalFailures;
+ if (totalErrors == 0 && totalFailures == 0) {
+ testSucceed();
+ } else {
+ testFailed();
+ }
+ var errors = result.details.errors;
+ var failures = result.details.failures;
+ var details = "";
+ for(var i=0; i<errors.length; i++) {
+ details += '<p><div class="error"><div class="errtitle">ERROR ' +
+ errors[i].desc +
+ '</div><div class="errdetail"><pre>'+errors[i].detail +
+ '</pre></div></div></p>';
+ }
+ for(var i=0; i<failures.length; i++) {
+ details += '<p><div class="error"><div class="errtitle">FAILURE ' +
+ failures[i].desc +
+ '</div><div class="errdetail"><pre>' +
+ failures[i].detail +
+ '</pre></div></div></p>';
+ }
+ var errorArea = document.getElementById("errorarea");
+ errorArea.innerHTML += details;
+ } else {
+ document.getElementById("errorarea").innerHTML = xmlHttp.responseText;
+ testFailed();
+ }
+ };
+ xmlHttp.send(null);
+ }
+
+ function testFailed() {
+ document.getElementById("testindicator").style.backgroundColor="red";
+ }
+
+ function testSucceed() {
+ document.getElementById("testindicator").style.backgroundColor="green";
+ }
+
+ function runTests() {
+ // Run each test asynchronously (concurrently).
+ var totalTests = 0;
+ for (var moduleName in testsToRun) {
+ var classes = testsToRun[moduleName];
+ for (var className in classes) {
+ // TODO: Optimize for the case where tests are run by class so we don't
+ // have to always execute each method separately. This should be
+ // possible when we have a UI that allows the user to select tests
+ // by module, class, and method.
+ //requestTestRun(moduleName, className);
+ methods = classes[className];
+ for (var i = 0; i < methods.length; i++) {
+ totalTests += 1;
+ var methodName = methods[i];
+ requestTestRun(moduleName, className, methodName);
+ }
+ }
+ }
+ document.getElementById("testtotal").innerHTML = totalTests;
+ }
+
+ </script>
+ <title>GAEUnit: Google App Engine Unit Test Framework</title>
+</head>
+<body onload="runTests()">
+ <div id="headerarea">
+ <div id="title">GAEUnit: Google App Engine Unit Test Framework</div>
+ <div id="version">Version 1.2.4</div>
+ </div>
+ <div id="resultarea">
+ <table id="results"><tbody>
+ <tr><td colspan="3"><div id="testindicator"> </div></td</tr>
+ <tr>
+ <td>Runs: <span id="testran">0</span>/<span id="testtotal">0</span></td>
+ <td>Errors: <span id="testerror">0</span></td>
+ <td>Failures: <span id="testfailure">0</span></td>
+ </tr>
+ </tbody></table>
+ </div>
+ <div id="errorarea"></div>
+ <div id="footerarea">
+ <div id="weblink">
+ <p>
+ Please visit the <a href="http://code.google.com/p/gaeunit">project home page</a>
+ for the latest version or to report problems.
+ </p>
+ <p>
+ Copyright 2008 <a href="mailto:George.Z.Lei@Gmail.com">George Lei</a>
+ and <a href="mailto:srfarley@gmail.com>Steven R. Farley</a>
+ </p>
+ </div>
+ </div>
+</body>
+</html>
+"""
+
+
+##############################################################################
+# Script setup and execution
+##############################################################################
+
+
+application = webapp.WSGIApplication([('/test', MainTestPageHandler),
+ ('/testrun', JsonTestRunHandler),
+ ('/testlist', JsonTestListHandler)],
+ debug=True)
+
+def main():
+ run_wsgi_app(application)
+
+if __name__ == '__main__':
+ main()
View
23 test/.svn/all-wcprops
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/svn/!svn/ver/56/tags/release-1.2.5/sample_app/test
+END
+web_tests.py
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/svn/!svn/ver/56/tags/release-1.2.5/sample_app/test/web_tests.py
+END
+unit_tests.py
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/svn/!svn/ver/56/tags/release-1.2.5/sample_app/test/unit_tests.py
+END
+appengine_api_tests.py
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/svn/!svn/ver/56/tags/release-1.2.5/sample_app/test/appengine_api_tests.py
+END
View
64 test/.svn/entries
@@ -0,0 +1,64 @@
+8
+
+dir
+56
+https://gaeunit.googlecode.com/svn/tags/release-1.2.5/sample_app/test
+https://gaeunit.googlecode.com/svn
+
+
+
+2008-09-27T03:09:56.710471Z
+39
+srfarley
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+c3911fd6-fc52-0410-b77b-4923be2ec7be
+
+web_tests.py
+file
+
+
+
+
+2008-10-17T02:00:29.000000Z
+aeb534e9d04650032f2af83fbb5989eb
+2008-09-22T12:10:37.322559Z
+36
+srfarley
+
+unit_tests.py
+file
+
+
+
+
+2008-10-17T02:00:29.000000Z
+48adc9b9756c5106db99167fd63c419c
+2008-09-22T11:47:59.796298Z
+33
+srfarley
+
+appengine_api_tests.py
+file
+
+
+
+
+2008-10-17T02:00:29.000000Z
+10cb6a2c28ff2995235d7a77d547ec21
+2008-09-27T03:09:56.710471Z
+39
+srfarley
+
View
1 test/.svn/format
@@ -0,0 +1 @@
+8
View
10 test/.svn/text-base/appengine_api_tests.py.svn-base
@@ -0,0 +1,10 @@
+import unittest
+from google.appengine.api import urlfetch
+
+
+class AppEngineAPITest(unittest.TestCase):
+
+ def test_urlfetch(self):
+ response = urlfetch.fetch('http://www.google.com')
+ self.assertEquals(0, response.content.find('<html>'))
+
View
51 test/.svn/text-base/unit_tests.py.svn-base
@@ -0,0 +1,51 @@
+import unittest
+import logging
+from google.appengine.ext import db
+import model
+
+class SuccessFailError(unittest.TestCase):
+
+ def setUp(self):
+ logging.info('In setUp()')
+
+ def tearDown(self):
+ logging.info('In tearDown()')
+
+ def test_success(self):
+ logging.info('Running test_success()')
+ self.assertTrue(True)
+
+ def test_failure(self):
+ logging.info('Running test_failure()')
+ self.assertTrue(False)
+
+ def test_error(self):
+ logging.info('Running test_error()')
+ raise Exception('expected exception')
+
+
+class ModelTest(unittest.TestCase):
+
+ def setUp(self):
+ # Populate test entities.
+ entity = model.MyEntity(name='Bar')
+ self.setup_key = entity.put()
+
+ def tearDown(self):
+ # There is no need to delete test entities.
+ pass
+
+ def test_new_entity(self):
+ entity = model.MyEntity(name='Foo')
+ self.assertEqual('Foo', entity.name)
+
+ def test_saved_enitity(self):
+ entity = model.MyEntity(name='Foo')
+ key = entity.put()
+ self.assertEqual('Foo', db.get(key).name)
+
+ def test_setup_entity(self):
+ entity = db.get(self.setup_key)
+ self.assertEqual('Bar', entity.name)
+
+
View
21 test/.svn/text-base/web_tests.py.svn-base
@@ -0,0 +1,21 @@
+import unittest
+from webtest import TestApp
+from google.appengine.ext import webapp
+import index
+
+class IndexTest(unittest.TestCase):
+
+ def setUp(self):
+ self.application = webapp.WSGIApplication([('/', index.IndexHandler)], debug=True)
+
+ def test_default_page(self):
+ app = TestApp(self.application)
+ response = app.get('/')
+ self.assertEqual('200 OK', response.status)
+ self.assertTrue('Hello, World!' in response)
+
+ def test_page_with_param(self):
+ app = TestApp(self.application)
+ response = app.get('/?name=Bob')
+ self.assertEqual('200 OK', response.status)
+ self.assertTrue('Hello, Bob!' in response)
View
9 test/appengine_api_tests.py
@@ -0,0 +1,9 @@
+import unittest
+from google.appengine.api import urlfetch
+
+class AppEngineAPITest(unittest.TestCase):
+
+ def test_urlfetch(self):
+ response = urlfetch.fetch('http://www.google.com')
+ self.assertEquals(0, response.content.find('<html>'))
+
View
48 test/unit_tests.py
@@ -0,0 +1,48 @@
+import logging
+import unittest
+
+from google.appengine.ext import db
+
+#class SuccessFailError(unittest.TestCase):
+# def setUp(self):
+# logging.info('In setUp()')
+#
+# def tearDown(self):
+# logging.info('In tearDown()')
+#
+# def test_success(self):
+# logging.info('Running test_success()')
+# self.assertTrue(True)
+#
+# def test_failure(self):
+# logging.info('Running test_failure()')
+# self.assertTrue(False)
+#
+# def test_error(self):
+# logging.info('Running test_error()')
+# raise Exception('expected exception')
+#
+#
+#class ModelTest(unittest.TestCase):
+# def setUp(self):
+# # Populate test entities.
+# pass
+#
+# def tearDown(self):
+# # There is no need to delete test entities.
+# pass
+#
+# def test_new_entity(self):
+# entity = model.MyEntity(name='Foo')
+# self.assertEqual('Foo', entity.name)
+#
+# def test_saved_enitity(self):
+# entity = model.MyEntity(name='Foo')
+# key = entity.put()
+# self.assertEqual('Foo', db.get(key).name)
+#
+# def test_setup_entity(self):
+# entity = db.get(self.setup_key)
+# self.assertEqual('Bar', entity.name)
+
+
View
42 test/web_tests.py
@@ -0,0 +1,42 @@
+import main
+import unittest
+
+from google.appengine.ext import webapp
+from webtest import TestApp
+
+class MainTest(unittest.TestCase):
+ def setUp(self):
+ self.application = webapp.WSGIApplication([('/', main.FrontPage)], debug=True)
+
+ def test_default_page(self):
+ app = TestApp(self.application)
+ response = app.get('/')
+ self.assertEqual('200 OK', response.status)
+ self.assertTrue('down for everyone' in response)
+
+ def test_page_with_param(self):
+ app = TestApp(self.application)
+ response = app.get('/?q=google.com')
+ self.assertEqual('200 OK', response.status)
+ self.assertTrue('google.com' in response)
+
+ def test_subdomain(self):
+ app = TestApp(self.application)
+ response = app.get('/?q=cse.ohio-state.edu')
+ self.assertEqual('200 OK', response.status)
+ self.assertTrue('cse.ohio-state.edu' in response)
+ self.assertFalse('interwho' in response)
+
+ def test_amazon(self):
+ app = TestApp(self.application)
+ response = app.get('/?q=amazon.com')
+ self.assertEqual('200 OK', response.status)
+ self.assertTrue('amazon.com' in response)
+ self.assertFalse('interwho' in response)
+
+ def test_amazon(self):
+ app = TestApp(self.application)
+ response = app.get('/?q=http://google.com')
+ self.assertEqual('200 OK', response.status)
+ self.assertTrue('google.com' in response)
+ self.assertFalse('interwho' in response)

0 comments on commit 3e7fb10

Please sign in to comment.