<commit_before># -*- coding: utf-8 -*-

from __future__ import print_function

import unittest
import time
import os
import csv

from globalvalues import RPI
if RPI:
    import RPi.GPIO as GPIO

import sensor
import sender
import auxiliaries
import manager
import cust_crypt

from auxiliaries import get_data
from manager import Manager

from globalvalues import POWER_LED_PIN, NETWORK_LED_PIN, COUNTS_LED_PIN
from globalvalues import DEFAULT_CONFIG, DEFAULT_PUBLICKEY
from globalvalues import ANSI_RESET, ANSI_GR, ANSI_RED
from globalvalues import DEFAULT_DATALOG, DEFAULT_TEST_DATALOG

if RPI:
    test_config_path = DEFAULT_CONFIG
    test_publickey_path = DEFAULT_PUBLICKEY
    configs_present = True
else:
    # obviously, for security, the config and public key should NOT be
    #   included in the (public) repo!
    # these paths are for Brian's LBL desktop, but you could put them
    #   here for other machines too.
    test_config_path = './testconfig/test1.csv'
    test_publickey_path = './testconfig/id_rsa_lbl.pub'
    if (os.path.exists(test_config_path) and
            os.path.exists(test_publickey_path)):
        configs_present = True
    else:
        configs_present = False

TEST_LOGFILE = 'test.log'

class TestVerbosity(unittest.TestCase):

    class Verbosity1(object):
        def __init__(self, vlevel=1):
            auxiliaries.set_verbosity(self, verbosity=vlevel)

    def setUp(self):
        self.verbose_obj = TestVerbosity.Verbosity1(vlevel=1)
        print('Testing set_verbosity()')

    def test_verbosity(self):
        print('Two words of {}green text{} should appear here: '.format(
            ANSI_GR, ANSI_RESET))
        self.verbose_obj.vprint(0, '{}one{}'.format(ANSI_GR, ANSI_RESET))
        self.verbose_obj.vprint(1, '{}two{}'.format(ANSI_GR, ANSI_RESET))
        self.verbose_obj.vprint(2, '{}three{}'.format(ANSI_RED, ANSI_RESET))
        self.verbose_obj.vprint(3, '{}four{}'.format(ANSI_RED, ANSI_RESET))
        print()
        self.assertTrue(True)

    def tearDown(self):
        del(self.verbose_obj)
        print()

class TestLogging(unittest.TestCase):

    class Verbosity2(object):
        def __init__(self, vlevel=1, logfile=TEST_LOGFILE):
            try:
                os.remove(logfile)
            except OSError:
                pass
            auxiliaries.set_verbosity(self, verbosity=vlevel, logfile=logfile)

    def setUp(self):
        self.verbose_obj = TestLogging.Verbosity2(vlevel=1)
        print('Testing logging')

    def test_logging(self):
        print('Two words of {}green text{} should appear here: '.format(
            ANSI_GR, ANSI_RESET))
        textlines = [
            '{}one{}'.format(ANSI_GR, ANSI_RESET),
            '{}two{}'.format(ANSI_GR, ANSI_RESET),
            '{}three{}'.format(ANSI_RED, ANSI_RESET),
            '{}four{}'.format(ANSI_RED, ANSI_RESET)
        ]
        [self.verbose_obj.vprint(i, textlines[i]) for i in range(4)]
        print()
        with open(TEST_LOGFILE, 'r') as f:
            fline = f.readline()
            self.assertTrue(fline.endswith(textlines[0] + '\n'))
            fline = f.readline()
            self.assertTrue(fline.endswith(textlines[1] + '\n'))
            fline = f.readline()
            self.assertFalse(fline)

    def tearDown(self):
        del(self.verbose_obj)
        try:
            os.remove(TEST_LOGFILE)
        except OSError:
            pass
        print()

@unittest.skipUnless(RPI, "LED test only runs on a Raspberry Pi")
class TestLEDs(unittest.TestCase):

    def setUp(self):
        pins = (POWER_LED_PIN, NETWORK_LED_PIN, COUNTS_LED_PIN)
        self.LEDs = [auxiliaries.LED(pin=p) for p in pins]
        print('Testing LEDs',)

    def test_LED(self):
        print('on')
        [LED.on() for LED in self.LEDs]
        time.sleep(1)

        print('off')
        [LED.off() for LED in self.LEDs]
        time.sleep(1)

        print('flash')
        [LED.flash() for LED in self.LEDs]
        time.sleep(1)

        print('start blink')
        [LED.start_blink(interval=0.5) for LED in self.LEDs]
        time.sleep(3)

        print('stop blink')
        [LED.stop_blink() for LED in self.LEDs]
        time.sleep(1)

    def tearDown(self):
        GPIO.cleanup()
        print()

class TestNetworkStatus(unittest.TestCase):
    """
    Doesn't use the auto pinging subprocess - just manually run methods
    """

    good_hostname = 'www.google.com'
    bad_hostname = 'asnbdfmnasdbf.dosenet.dhcp.lbl.gov'

    def setUp(self):
        if RPI:
            self.LED = auxiliaries.LED(pin=NETWORK_LED_PIN)
        else:
            self.LED = None
        print('Testing NetworkStatus')

        self.net = auxiliaries.NetworkStatus(
            hostname=self.good_hostname,
            network_led=self.LED,
            pinging=False,
            verbosity=2)

    def test_is_up(self):
        self.net.update()
        self.assertTrue(self.net)

    def test_is_down(self):
        # give an invalid hostname
        self.net.hostname = self.bad_hostname
        self.net.update()

        self.assertFalse(self.net)

        self.net.hostname = self.good_hostname
        self.net.update()

    def tearDown(self):
        if RPI:
            GPIO.cleanup()
        del(self.net)
        print()

@unittest.skipUnless(
    RPI, "NetworkStatus live test only operates on a Raspberry Pi")
class TestNetworkStatusLive(TestNetworkStatus):
    """
    check the subprocess that pings at intervals
    also check LED behavior
    """

    # inherit good_hostname, bad_hostname
    # overwrite setUp(), tearDown(), test_is_up(), test_is_down()

    def setUp(self):
        self.LED = auxiliaries.LED(pin=NETWORK_LED_PIN)
        print('Testing NetworkStatus (live)')

        self.net = auxiliaries.NetworkStatus(
            hostname=self.good_hostname,
            up_interval_s=3,
            down_interval_s=1,
            network_led=self.LED,
            pinging=True,
            verbosity=2)

    def test_is_up(self):
        print('test_is_up (live)...')
        time.sleep(2)
        self.assertTrue(self.net)
        time.sleep(6)
        self.assertTrue(self.net)

    @unittest.skip(
        ("test_is_down (live) doesn't work until I can " +
         "hack the system network settings..."))
    def test_is_down(self):
        print('test_is_down (live)...')
        # give an invalid hostname
        self.net.hostname = self.bad_hostname

        time.sleep(3)
        self.assertFalse(self.net)
        time.sleep(3)

        # restore connection
        self.net.hostname = self.good_hostname

        time.sleep(1)
        self.assertTrue(self.net)
        time.sleep(3)
        self.assertTrue(self.net)

    def tearDown(self):
        self.net.stop_pinging()
        GPIO.cleanup()

@unittest.skipUnless(configs_present, "Config test requires config files")
class TestConfig(unittest.TestCase):

    def test(self):
        config = auxiliaries.Config(test_config_path, verbosity=2)
        self.assertIsNotNone(config.ID)
        self.assertIsNotNone(config.hash)
        self.assertIsNotNone(config.lat)
        self.assertIsNotNone(config.long)

@unittest.skipUnless(configs_present, "PublicKey test requires config files")
class TestPublicKey(unittest.TestCase):

    def setUp(self):
        self.publickey = auxiliaries.PublicKey(
            test_publickey_path, verbosity=2)
        self.assertIsInstance(
            self.publickey.encrypter, cust_crypt.PublicDEncrypt)

    def test_encrypt(self):
        test_packet = 'This is a string with which we are testing encryption'
        encrypted_packet = self.publickey.encrypter.encrypt_message(
            test_packet)[0]
        self.assertIsInstance(encrypted_packet, str)

class TestSensor(unittest.TestCase):

    def setUp(self):
        # fake sensor - only simulating counts
        self.sensor = sensor.Sensor(max_accumulation_time_s=2, use_gpio=False)

    def tearDown(self):
        self.sensor.cleanup()
        self.sensor = None

    def test_basic_counts(self):
        self.assertEqual(len(self.sensor.get_all_counts()), 0)
        n = 3
        [self.sensor.count() for _ in xrange(n)]
        self.assertEqual(len(self.sensor.get_all_counts()), n)

    def test_max_accum(self):
        self.assertEqual(len(self.sensor.get_all_counts()), 0)

        n1 = 3
        [self.sensor.count() for _ in xrange(n1)]
        self.assertEqual(len(self.sensor.get_all_counts()), n1)

        time.sleep(1)
        n2 = 4
        [self.sensor.count() for _ in xrange(n2)]
        self.assertEqual(len(self.sensor.get_all_counts()), n1 + n2)

        time.sleep(1.5)
        self.assertEqual(len(self.sensor.get_all_counts()), n2)

        time.sleep(1)
        self.assertEqual(len(self.sensor.get_all_counts()), 0)

class TestSender(unittest.TestCase):

    def test_missing_config(self):
        ss = sender.ServerSender(
            manager=None,
            network_status=None,
            config=None,
            publickey=None,
            verbosity=4)
        with self.assertRaises(sender.MissingFile):
            ss.send_cpm(0, 0)

    @unittest.skipUnless(configs_present, "Sender tests require config files")
    def test_missing_publickey(self):
        ss = sender.ServerSender(
            manager=None,
            network_status=None,
            config=auxiliaries.Config(test_config_path),
            publickey=None,
            verbosity=4)
        with self.assertRaises(sender.MissingFile):
            ss.send_cpm(0, 0)

class TestDataLog(unittest.TestCase):

    def setUp(self):
        print('Checking local data')

    def test_get_data(self):
        """
        Checks the data log functionality.

        Creates a test data log, simulates 2 counts,
        checks that the test data log was created,
        checks that there are 2 counts, and then deletes the test datalog.
        """
        mgr = Manager(test=True, datalog=DEFAULT_TEST_DATALOG)

        now = time.time()
        mgr.handle_cpm(now - 10, now)
        [mgr.sensor.count() for _ in xrange(2)]
        mgr.handle_cpm(now, now + 10)
        output = get_data(DEFAULT_TEST_DATALOG)
        print(output)

        mgr.takedown()

        self.assertIsNotNone(output)
        self.assertEqual(len(output), 2)

    def tearDown(self):
        os.remove(DEFAULT_TEST_DATALOG)
        print()

    # ...

if __name__ == '__main__':
    unittest.main()
<commit_msg>Bug fixing: GPIO cleanup stuff<commit_after># -*- coding: utf-8 -*-

from __future__ import print_function

import unittest
import time
import os
import csv

from globalvalues import RPI
if RPI:
    import RPi.GPIO as GPIO

import sensor
import sender
import auxiliaries
import manager
import cust_crypt

from auxiliaries import get_data
from manager import Manager

from globalvalues import POWER_LED_PIN, NETWORK_LED_PIN, COUNTS_LED_PIN
from globalvalues import DEFAULT_CONFIG, DEFAULT_PUBLICKEY
from globalvalues import ANSI_RESET, ANSI_GR, ANSI_RED
from globalvalues import DEFAULT_DATALOG, DEFAULT_TEST_DATALOG

if RPI:
    test_config_path = DEFAULT_CONFIG
    test_publickey_path = DEFAULT_PUBLICKEY
    configs_present = True
else:
    # obviously, for security, the config and public key should NOT be
    #   included in the (public) repo!
    # these paths are for Brian's LBL desktop, but you could put them
    #   here for other machines too.
    test_config_path = './testconfig/test1.csv'
    test_publickey_path = './testconfig/id_rsa_lbl.pub'
    if (os.path.exists(test_config_path) and
            os.path.exists(test_publickey_path)):
        configs_present = True
    else:
        configs_present = False

TEST_LOGFILE = 'test.log'

class TestVerbosity(unittest.TestCase):

    class Verbosity1(object):
        def __init__(self, vlevel=1):
            auxiliaries.set_verbosity(self, verbosity=vlevel)

    def setUp(self):
        self.verbose_obj = TestVerbosity.Verbosity1(vlevel=1)
        print('Testing set_verbosity()')

    def test_verbosity(self):
        print('Two words of {}green text{} should appear here: '.format(
            ANSI_GR, ANSI_RESET))
        self.verbose_obj.vprint(0, '{}one{}'.format(ANSI_GR, ANSI_RESET))
        self.verbose_obj.vprint(1, '{}two{}'.format(ANSI_GR, ANSI_RESET))
        self.verbose_obj.vprint(2, '{}three{}'.format(ANSI_RED, ANSI_RESET))
        self.verbose_obj.vprint(3, '{}four{}'.format(ANSI_RED, ANSI_RESET))
        print()
        self.assertTrue(True)

    def tearDown(self):
        del(self.verbose_obj)
        print()

class TestLogging(unittest.TestCase):

    class Verbosity2(object):
        def __init__(self, vlevel=1, logfile=TEST_LOGFILE):
            try:
                os.remove(logfile)
            except OSError:
                pass
            auxiliaries.set_verbosity(self, verbosity=vlevel, logfile=logfile)

    def setUp(self):
        self.verbose_obj = TestLogging.Verbosity2(vlevel=1)
        print('Testing logging')

    def test_logging(self):
        print('Two words of {}green text{} should appear here: '.format(
            ANSI_GR, ANSI_RESET))
        textlines = [
            '{}one{}'.format(ANSI_GR, ANSI_RESET),
            '{}two{}'.format(ANSI_GR, ANSI_RESET),
            '{}three{}'.format(ANSI_RED, ANSI_RESET),
            '{}four{}'.format(ANSI_RED, ANSI_RESET)
        ]
        [self.verbose_obj.vprint(i, textlines[i]) for i in range(4)]
        print()
        with open(TEST_LOGFILE, 'r') as f:
            fline = f.readline()
            self.assertTrue(fline.endswith(textlines[0] + '\n'))
            fline = f.readline()
            self.assertTrue(fline.endswith(textlines[1] + '\n'))
            fline = f.readline()
            self.assertFalse(fline)

    def tearDown(self):
        del(self.verbose_obj)
        try:
            os.remove(TEST_LOGFILE)
        except OSError:
            pass
        print()

@unittest.skipUnless(RPI, "LED test only runs on a Raspberry Pi")
class TestLEDs(unittest.TestCase):

    def setUp(self):
        pins = (POWER_LED_PIN, NETWORK_LED_PIN, COUNTS_LED_PIN)
        self.LEDs = [auxiliaries.LED(pin=p) for p in pins]
        print('Testing LEDs',)

    def test_LED(self):
        print('on')
        [LED.on() for LED in self.LEDs]
        time.sleep(1)

        print('off')
        [LED.off() for LED in self.LEDs]
        time.sleep(1)

        print('flash')
        [LED.flash() for LED in self.LEDs]
        time.sleep(1)

        print('start blink')
        [LED.start_blink(interval=0.5) for LED in self.LEDs]
        time.sleep(3)

        print('stop blink')
        [LED.stop_blink() for LED in self.LEDs]
        time.sleep(1)

    def tearDown(self):
        GPIO.cleanup()
        print()

class TestNetworkStatus(unittest.TestCase):
    """
    Doesn't use the auto pinging subprocess - just manually run methods
    """

    good_hostname = 'www.google.com'
    bad_hostname = 'asnbdfmnasdbf.dosenet.dhcp.lbl.gov'

    def setUp(self):
        if RPI:
            self.LED = auxiliaries.LED(pin=NETWORK_LED_PIN)
        else:
            self.LED = None
        print('Testing NetworkStatus')

        self.net = auxiliaries.NetworkStatus(
            hostname=self.good_hostname,
            network_led=self.LED,
            pinging=False,
            verbosity=2)

    def test_is_up(self):
        self.net.update()
        self.assertTrue(self.net)

    def test_is_down(self):
        # give an invalid hostname
        self.net.hostname = self.bad_hostname
        self.net.update()

        self.assertFalse(self.net)

        self.net.hostname = self.good_hostname
        self.net.update()

    def tearDown(self):
        if RPI:
            GPIO.cleanup()
        del(self.net)
        print()

@unittest.skipUnless(
    RPI, "NetworkStatus live test only operates on a Raspberry Pi")
class TestNetworkStatusLive(TestNetworkStatus):
    """
    check the subprocess that pings at intervals
    also check LED behavior
    """

    # inherit good_hostname, bad_hostname
    # overwrite setUp(), tearDown(), test_is_up(), test_is_down()

    def setUp(self):
        self.LED = auxiliaries.LED(pin=NETWORK_LED_PIN)
        print('Testing NetworkStatus (live)')

        self.net = auxiliaries.NetworkStatus(
            hostname=self.good_hostname,
            up_interval_s=3,
            down_interval_s=1,
            network_led=self.LED,
            pinging=True,
            verbosity=2)

    def test_is_up(self):
        print('test_is_up (live)...')
        time.sleep(2)
        self.assertTrue(self.net)
        time.sleep(6)
        self.assertTrue(self.net)

    @unittest.skip(
        ("test_is_down (live) doesn't work until I can " +
         "hack the system network settings..."))
    def test_is_down(self):
        print('test_is_down (live)...')
        # give an invalid hostname
        self.net.hostname = self.bad_hostname

        time.sleep(3)
        self.assertFalse(self.net)
        time.sleep(3)

        # restore connection
        self.net.hostname = self.good_hostname

        time.sleep(1)
        self.assertTrue(self.net)
        time.sleep(3)
        self.assertTrue(self.net)

    def tearDown(self):
        self.net.stop_pinging()
        GPIO.cleanup()

@unittest.skipUnless(configs_present, "Config test requires config files")
class TestConfig(unittest.TestCase):

    def test(self):
        config = auxiliaries.Config(test_config_path, verbosity=2)
        self.assertIsNotNone(config.ID)
        self.assertIsNotNone(config.hash)
        self.assertIsNotNone(config.lat)
        self.assertIsNotNone(config.long)

@unittest.skipUnless(configs_present, "PublicKey test requires config files")
class TestPublicKey(unittest.TestCase):

    def setUp(self):
        self.publickey = auxiliaries.PublicKey(
            test_publickey_path, verbosity=2)
        self.assertIsInstance(
            self.publickey.encrypter, cust_crypt.PublicDEncrypt)

    def test_encrypt(self):
        test_packet = 'This is a string with which we are testing encryption'
        encrypted_packet = self.publickey.encrypter.encrypt_message(
            test_packet)[0]
        self.assertIsInstance(encrypted_packet, str)

class TestSensor(unittest.TestCase):

    def setUp(self):
        # fake sensor - only simulating counts
        self.sensor = sensor.Sensor(max_accumulation_time_s=2, use_gpio=False)

    def tearDown(self):
        self.sensor.cleanup()
        self.sensor = None

    def test_basic_counts(self):
        self.assertEqual(len(self.sensor.get_all_counts()), 0)
        n = 3
        [self.sensor.count() for _ in xrange(n)]
        self.assertEqual(len(self.sensor.get_all_counts()), n)

    def test_max_accum(self):
        self.assertEqual(len(self.sensor.get_all_counts()), 0)

        n1 = 3
        [self.sensor.count() for _ in xrange(n1)]
        self.assertEqual(len(self.sensor.get_all_counts()), n1)

        time.sleep(1)
        n2 = 4
        [self.sensor.count() for _ in xrange(n2)]
        self.assertEqual(len(self.sensor.get_all_counts()), n1 + n2)

        time.sleep(1.5)
        self.assertEqual(len(self.sensor.get_all_counts()), n2)

        time.sleep(1)
        self.assertEqual(len(self.sensor.get_all_counts()), 0)

class TestSender(unittest.TestCase):

    def test_missing_config(self):
        ss = sender.ServerSender(
            manager=None,
            network_status=None,
            config=None,
            publickey=None,
            verbosity=4)
        with self.assertRaises(sender.MissingFile):
            ss.send_cpm(0, 0)

    @unittest.skipUnless(configs_present, "Sender tests require config files")
    def test_missing_publickey(self):
        ss = sender.ServerSender(
            manager=None,
            network_status=None,
            config=auxiliaries.Config(test_config_path),
            publickey=None,
            verbosity=4)
        with self.assertRaises(sender.MissingFile):
            ss.send_cpm(0, 0)

class TestDataLog(unittest.TestCase):

    def setUp(self):
        print('Checking local data')

    def test_get_data(self):
        """
        Checks the data log functionality.

        Creates a test data log, simulates 2 counts,
        checks that the test data log was created,
        checks that there are 2 counts, and then deletes the test datalog.
        """
        mgr = Manager(test=True, datalog=DEFAULT_TEST_DATALOG)

        now = time.time()
        mgr.handle_cpm(now - 10, now)
        [mgr.sensor.count() for _ in xrange(2)]
        mgr.handle_cpm(now, now + 10)
        output = get_data(DEFAULT_TEST_DATALOG)
        print(output)

        GPIO.cleanup()
        del(mgr)
        #mgr.takedown()

        self.assertIsNotNone(output)
        self.assertEqual(len(output), 2)

    def tearDown(self):
        os.remove(DEFAULT_TEST_DATALOG)
        print()

    # ...

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>from __future__ import unicode_literals

import os
from collections import namedtuple
from unittest import TestCase

from postgres import Postgres, TooFew, TooMany
from psycopg2.extras import NamedTupleCursor

DATABASE_URL = os.environ['DATABASE_URL']

# harnesses
# =========

class WithSchema(TestCase):

    def setUp(self):
        self.db = Postgres(DATABASE_URL)
        self.db.run("DROP SCHEMA IF EXISTS public CASCADE")
        self.db.run("CREATE SCHEMA public")

    def tearDown(self):
        self.db.run("DROP SCHEMA IF EXISTS public CASCADE")
        del self.db

class WithData(WithSchema):

    def setUp(self):
        WithSchema.setUp(self)
        self.db.run("CREATE TABLE foo (bar text)")
        self.db.run("INSERT INTO foo VALUES ('baz')")
        self.db.run("INSERT INTO foo VALUES ('buz')")

# db.run
# ======

class TestRun(WithSchema):

    def test_run_runs(self):
        self.db.run("CREATE TABLE foo (bar text)")
        actual = self.db.all("SELECT tablename FROM pg_tables "
                             "WHERE schemaname='public'")
        assert actual == [{"tablename": "foo"}]

    def test_run_inserts(self):
        self.db.run("CREATE TABLE foo (bar text)")
        self.db.run("INSERT INTO foo VALUES ('baz')")
        actual = len(self.db.one("SELECT * FROM foo ORDER BY bar"))
        assert actual == 1

# db.one
# ======
# With all the combinations of strict_one and strict, we end up with a number
# of tests here. Since the behavior of the one method with a strict parameter
# of True or False is expected to be the same regardless of what strict_one is
# set to, we can write those once and then use the TestOne TestCase as the base
# class for other TestCases that vary the strict_one attribute. The TestOne
# tests will be re-run in each new context.

class TestNotOneException(WithData):

    def test_TooFew_message_is_helpful(self):
        try:
            self.db.one("SELECT * FROM foo WHERE bar='blah'", strict=True)
        except TooFew as exc:
            actual = str(exc)
            assert actual == "Got 0 rows instead of 1."

    def test_TooMany_message_is_helpful(self):
        try:
            self.db.one("SELECT * FROM foo", strict=True)
        except TooMany as exc:
            actual = str(exc)
            assert actual == "Got 2 rows instead of 1."

class TestOne(WithData):

    def test_with_strict_True_one_raises_TooFew(self):
        self.assertRaises( TooFew
                         , self.db.one
                         , "SELECT * FROM foo WHERE bar='blah'"
                         , strict=True
                          )

    def test_with_strict_True_one_fetches_the_one(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='baz'", strict=True)
        assert actual == {"bar": "baz"}

    def test_with_strict_True_one_raises_TooMany(self):
        self.assertRaises( TooMany
                         , self.db.one
                         , "SELECT * FROM foo"
                         , strict=True
                          )

    def test_with_strict_False_one_returns_None_if_theres_none(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='nun'", strict=False)
        assert actual is None

    def test_with_strict_False_one_fetches_the_first_one(self):
        actual = self.db.one("SELECT * FROM foo ORDER BY bar", strict=False)
        assert actual == {"bar": "baz"}

class TestOne_StrictOneNone(TestOne):

    def setUp(self):
        WithData.setUp(self)
        self.db.strict_one = None

    def test_one_raises_TooFew(self):
        self.assertRaises( TooFew
                         , self.db.one
                         , "SELECT * FROM foo WHERE bar='nun'"
                          )

    def test_one_returns_one(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='baz'")
        assert actual == {"bar": "baz"}

    def test_one_raises_TooMany(self):
        self.assertRaises(TooMany, self.db.one, "SELECT * FROM foo")

class TestOne_StrictOneFalse(TestOne):

    def setUp(self):
        WithData.setUp(self)
        self.db.strict_one = False

    def test_one_returns_None(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='nun'")
        assert actual is None

    def test_one_returns_one(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='baz'")
        assert actual == {"bar": "baz"}

    def test_one_returns_first_one(self):
        actual = self.db.one("SELECT * FROM foo ORDER BY bar")
        assert actual == {"bar": "baz"}

class TestOne_StrictOneTrue(TestOne):

    def setUp(self):
        WithData.setUp(self)
        self.db.strict_one = True

    def test_one_raises_TooFew(self):
        self.assertRaises( TooFew
                         , self.db.one
                         , "SELECT * FROM foo WHERE bar='nun'"
                          )

    def test_one_returns_one(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='baz'")
        assert actual == {"bar": "baz"}

    def test_one_raises_TooMany(self):
        self.assertRaises(TooMany, self.db.one, "SELECT * FROM foo")

# db.all
# ======

class TestRows(WithData):

    def test_rows_fetches_all_rows(self):
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

    def test_bind_parameters_as_dict_work(self):
        params = {"bar": "baz"}
        actual = self.db.all("SELECT * FROM foo WHERE bar=%(bar)s", params)
        assert actual == [{"bar": "baz"}]

    def test_bind_parameters_as_tuple_work(self):
        actual = self.db.all("SELECT * FROM foo WHERE bar=%s", ("baz",))
        assert actual == [{"bar": "baz"}]

# db.get_cursor
# =============

class TestCursor(WithData):

    def test_get_cursor_gets_a_cursor(self):
        with self.db.get_cursor() as cursor:
            cursor.execute("SELECT * FROM foo ORDER BY bar")
            actual = cursor.fetchall()
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

    def test_we_can_use_cursor_rowcount(self):
        with self.db.get_cursor() as cursor:
            cursor.execute("SELECT * FROM foo ORDER BY bar")
            actual = cursor.rowcount
        assert actual == 2

    def test_we_can_use_cursor_closed(self):
        with self.db.get_cursor() as cursor:
            cursor.execute("SELECT * FROM foo ORDER BY bar")
            actual = cursor.closed
        assert not actual

# db.get_transaction
# ==================

class TestTransaction(WithData):

    def test_get_transaction_gets_a_transaction(self):
        with self.db.get_transaction() as txn:
            txn.execute("INSERT INTO foo VALUES ('blam')")
            txn.execute("SELECT * FROM foo ORDER BY bar")
            actual = txn.fetchall()
        assert actual == [{"bar": "baz"}, {"bar": "blam"}, {"bar": "buz"}]

    def test_transaction_is_isolated(self):
        with self.db.get_transaction() as txn:
            txn.execute("INSERT INTO foo VALUES ('blam')")
            txn.execute("SELECT * FROM foo ORDER BY bar")
            actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

    def test_transaction_commits_on_success(self):
        with self.db.get_transaction() as txn:
            txn.execute("INSERT INTO foo VALUES ('blam')")
            txn.execute("SELECT * FROM foo ORDER BY bar")
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == [{"bar": "baz"}, {"bar": "blam"}, {"bar": "buz"}]

    def test_transaction_rolls_back_on_failure(self):
        class Heck(Exception): pass
        try:
            with self.db.get_transaction() as txn:
                txn.execute("INSERT INTO foo VALUES ('blam')")
                txn.execute("SELECT * FROM foo ORDER BY bar")
                raise Heck
        except Heck:
            pass
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

# db.get_connection
# =================

class TestConnection(WithData):

    def test_get_connection_gets_a_connection(self):
        with self.db.get_connection() as conn:
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM foo ORDER BY bar")
            actual = cursor.fetchall()
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

# cursor_factory
# ==============

class TestCursorFactory(WithData):

    def setUp(self):                    # override
        self.db = Postgres(DATABASE_URL, cursor_factory=NamedTupleCursor)
        self.db.run("DROP SCHEMA IF EXISTS public CASCADE")
        self.db.run("CREATE SCHEMA public")
        self.db.run("CREATE TABLE foo (bar text)")
        self.db.run("INSERT INTO foo VALUES ('baz')")
        self.db.run("INSERT INTO foo VALUES ('buz')")

    def test_NamedDictCursor_results_in_namedtuples(self):
        Record = namedtuple("Record", ["bar"])
        expected = [Record(bar="baz"), Record(bar="buz")]
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == expected

    def test_NamedDictCursor_results_in_namedtuples(self):
        Record = namedtuple("Record", ["bar"])
        expected = [Record(bar="baz"), Record(bar="buz")]
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == expected
<commit_msg>Write tests for one_or_zero; #19<commit_after>from __future__ import unicode_literals

import os
from collections import namedtuple
from unittest import TestCase

from postgres import Postgres, TooFew, TooMany
from psycopg2.extras import NamedTupleCursor

DATABASE_URL = os.environ['DATABASE_URL']

# harnesses
# =========

class WithSchema(TestCase):

    def setUp(self):
        self.db = Postgres(DATABASE_URL)
        self.db.run("DROP SCHEMA IF EXISTS public CASCADE")
        self.db.run("CREATE SCHEMA public")

    def tearDown(self):
        self.db.run("DROP SCHEMA IF EXISTS public CASCADE")
        del self.db

class WithData(WithSchema):

    def setUp(self):
        WithSchema.setUp(self)
        self.db.run("CREATE TABLE foo (bar text)")
        self.db.run("INSERT INTO foo VALUES ('baz')")
        self.db.run("INSERT INTO foo VALUES ('buz')")

# db.run
# ======

class TestRun(WithSchema):

    def test_run_runs(self):
        self.db.run("CREATE TABLE foo (bar text)")
        actual = self.db.all("SELECT tablename FROM pg_tables "
                             "WHERE schemaname='public'")
        assert actual == [{"tablename": "foo"}]

    def test_run_inserts(self):
        self.db.run("CREATE TABLE foo (bar text)")
        self.db.run("INSERT INTO foo VALUES ('baz')")
        actual = len(self.db.one("SELECT * FROM foo ORDER BY bar"))
        assert actual == 1

# db.all
# ======

class TestRows(WithData):

    def test_rows_fetches_all_rows(self):
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

    def test_bind_parameters_as_dict_work(self):
        params = {"bar": "baz"}
        actual = self.db.all("SELECT * FROM foo WHERE bar=%(bar)s", params)
        assert actual == [{"bar": "baz"}]

    def test_bind_parameters_as_tuple_work(self):
        actual = self.db.all("SELECT * FROM foo WHERE bar=%s", ("baz",))
        assert actual == [{"bar": "baz"}]

# db.one
# ======
# With all the combinations of strict_one and strict, we end up with a number
# of tests here. Since the behavior of the one method with a strict parameter
# of True or False is expected to be the same regardless of what strict_one is
# set to, we can write those once and then use the TestOne TestCase as the base
# class for other TestCases that vary the strict_one attribute. The TestOne
# tests will be re-run in each new context.

class TestNotOneException(WithData):

    def test_TooFew_message_is_helpful(self):
        try:
            self.db.one("SELECT * FROM foo WHERE bar='blah'", strict=True)
        except TooFew as exc:
            actual = str(exc)
            assert actual == "Got 0 rows instead of 1."

    def test_TooMany_message_is_helpful(self):
        try:
            self.db.one("SELECT * FROM foo", strict=True)
        except TooMany as exc:
            actual = str(exc)
            assert actual == "Got 2 rows instead of 1."

class TestOne(WithData):

    def test_with_strict_True_one_raises_TooFew(self):
        self.assertRaises( TooFew
                         , self.db.one
                         , "SELECT * FROM foo WHERE bar='blah'"
                         , strict=True
                          )

    def test_with_strict_True_one_fetches_the_one(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='baz'", strict=True)
        assert actual == {"bar": "baz"}

    def test_with_strict_True_one_raises_TooMany(self):
        self.assertRaises( TooMany
                         , self.db.one
                         , "SELECT * FROM foo"
                         , strict=True
                          )

    def test_with_strict_False_one_returns_None_if_theres_none(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='nun'", strict=False)
        assert actual is None

    def test_with_strict_False_one_fetches_the_first_one(self):
        actual = self.db.one("SELECT * FROM foo ORDER BY bar", strict=False)
        assert actual == {"bar": "baz"}

class TestOne_StrictOneNone(TestOne):

    def setUp(self):
        WithData.setUp(self)
        self.db.strict_one = None

    def test_one_raises_TooFew(self):
        self.assertRaises( TooFew
                         , self.db.one
                         , "SELECT * FROM foo WHERE bar='nun'"
                          )

    def test_one_returns_one(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='baz'")
        assert actual == {"bar": "baz"}

    def test_one_raises_TooMany(self):
        self.assertRaises(TooMany, self.db.one, "SELECT * FROM foo")

class TestOne_StrictOneFalse(TestOne):

    def setUp(self):
        WithData.setUp(self)
        self.db.strict_one = False

    def test_one_returns_None(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='nun'")
        assert actual is None

    def test_one_returns_one(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='baz'")
        assert actual == {"bar": "baz"}

    def test_one_returns_first_one(self):
        actual = self.db.one("SELECT * FROM foo ORDER BY bar")
        assert actual == {"bar": "baz"}

class TestOne_StrictOneTrue(TestOne):

    def setUp(self):
        WithData.setUp(self)
        self.db.strict_one = True

    def test_one_raises_TooFew(self):
        self.assertRaises( TooFew
                         , self.db.one
                         , "SELECT * FROM foo WHERE bar='nun'"
                          )

    def test_one_returns_one(self):
        actual = self.db.one("SELECT * FROM foo WHERE bar='baz'")
        assert actual == {"bar": "baz"}

    def test_one_raises_TooMany(self):
        self.assertRaises(TooMany, self.db.one, "SELECT * FROM foo")

# db.one_or_zero
# ==============

class TestOneOrZero(WithData):

    def test_one_or_zero_raises_TooFew(self):
        self.assertRaises( TooFew
                         , self.db.one_or_zero
                         , "CREATE TABLE foux (baar text)"
                          )

    def test_one_or_zero_returns_None(self):
        actual = self.db.one_or_zero("SELECT * FROM foo WHERE bar='blam'")
        assert actual is None

    def test_one_or_zero_returns_one(self):
        actual = self.db.one_or_zero("SELECT * FROM foo WHERE bar='baz'")
        assert actual == {"bar": "baz"}

    def test_with_strict_True_one_raises_TooMany(self):
        self.assertRaises(TooMany, self.db.one_or_zero, "SELECT * FROM foo")

# db.get_cursor
# =============

class TestCursor(WithData):

    def test_get_cursor_gets_a_cursor(self):
        with self.db.get_cursor() as cursor:
            cursor.execute("SELECT * FROM foo ORDER BY bar")
            actual = cursor.fetchall()
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

    def test_we_can_use_cursor_rowcount(self):
        with self.db.get_cursor() as cursor:
            cursor.execute("SELECT * FROM foo ORDER BY bar")
            actual = cursor.rowcount
        assert actual == 2

    def test_we_can_use_cursor_closed(self):
        with self.db.get_cursor() as cursor:
            cursor.execute("SELECT * FROM foo ORDER BY bar")
            actual = cursor.closed
        assert not actual

# db.get_transaction
# ==================

class TestTransaction(WithData):

    def test_get_transaction_gets_a_transaction(self):
        with self.db.get_transaction() as txn:
            txn.execute("INSERT INTO foo VALUES ('blam')")
            txn.execute("SELECT * FROM foo ORDER BY bar")
            actual = txn.fetchall()
        assert actual == [{"bar": "baz"}, {"bar": "blam"}, {"bar": "buz"}]

    def test_transaction_is_isolated(self):
        with self.db.get_transaction() as txn:
            txn.execute("INSERT INTO foo VALUES ('blam')")
            txn.execute("SELECT * FROM foo ORDER BY bar")
            actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

    def test_transaction_commits_on_success(self):
        with self.db.get_transaction() as txn:
            txn.execute("INSERT INTO foo VALUES ('blam')")
            txn.execute("SELECT * FROM foo ORDER BY bar")
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == [{"bar": "baz"}, {"bar": "blam"}, {"bar": "buz"}]

    def test_transaction_rolls_back_on_failure(self):
        class Heck(Exception): pass
        try:
            with self.db.get_transaction() as txn:
                txn.execute("INSERT INTO foo VALUES ('blam')")
                txn.execute("SELECT * FROM foo ORDER BY bar")
                raise Heck
        except Heck:
            pass
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

# db.get_connection
# =================

class TestConnection(WithData):

    def test_get_connection_gets_a_connection(self):
        with self.db.get_connection() as conn:
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM foo ORDER BY bar")
            actual = cursor.fetchall()
        assert actual == [{"bar": "baz"}, {"bar": "buz"}]

# cursor_factory
# ==============

class TestCursorFactory(WithData):

    def setUp(self):                    # override
        self.db = Postgres(DATABASE_URL, cursor_factory=NamedTupleCursor)
        self.db.run("DROP SCHEMA IF EXISTS public CASCADE")
        self.db.run("CREATE SCHEMA public")
        self.db.run("CREATE TABLE foo (bar text)")
        self.db.run("INSERT INTO foo VALUES ('baz')")
        self.db.run("INSERT INTO foo VALUES ('buz')")

    def test_NamedDictCursor_results_in_namedtuples(self):
        Record = namedtuple("Record", ["bar"])
        expected = [Record(bar="baz"), Record(bar="buz")]
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == expected

    def test_NamedDictCursor_results_in_namedtuples(self):
        Record = namedtuple("Record", ["bar"])
        expected = [Record(bar="baz"), Record(bar="buz")]
        actual = self.db.all("SELECT * FROM foo ORDER BY bar")
        assert actual == expected
<|endoftext|>


<commit_before>from fixerpy import Converter

def testLatestRates():
    c = Converter()
    latestRates = c.getLatestRates()
    if latestRates:
        assert True
    else:
        assert False, "Current forex rates not retrieved."
    if 'date' in latestRates:
        assert True
    else:
        assert False, "The date is missing."
    if latestRates['base'] == 'EUR':
        assert True
    else:
        assert False, "The base rate is not EUR."
    if 'rates' in latestRates:
        assert True
    else:
        assert False, "The exchange rates are missing."
<commit_msg>Added another test case for getting forex rates with another currency as the base.<commit_after>from fixerpy import Converter

def testLatestRates():
    c = Converter()
    latestRates = c.getLatestRates()
    if latestRates:
        assert True
    else:
        assert False, "Current forex rates not retrieved."
    if 'date' in latestRates:
        assert True
    else:
        assert False, "The date is missing."
    if latestRates['base'] == 'EUR':
        assert True
    else:
        assert False, "The base rate is not EUR."
    if 'rates' in latestRates:
        assert True
    else:
        assert False, "The exchange rates are missing."

def testLatestRatesWithBase():
    c = Converter()
    latestRates = c.getLatestRates(baseCurrency='USD')
    if latestRates:
        assert True
    else:
        assert False, "Current forex rates not retrieved."
    if 'date' in latestRates:
        assert True
    else:
        assert False, "The date is missing."
    if latestRates['base'] == 'USD':
        assert True
    else:
        assert False, "The base rate is USD, overriding the default EUR."
    if 'rates' in latestRates:
        assert True
    else:
        assert False, "The exchange rates are missing."
<|endoftext|>


<commit_before>import unittest
import fulltext
import logging

from fulltext.util import ShellError

from six import add_metaclass

TEXT_WITH_NEWLINES = u"Lorem ipsum\ndolor sit amet, consectetur adipiscing e" \
                     u"lit. Nunc ipsum augue, iaculis quis\nauctor eu, adipi" \
                     u"scing non est. Nullam id sem diam, eget varius dui. E" \
                     u"tiam\nsollicitudin sapien nec odio elementum sit amet" \
                     u" luctus magna volutpat. Ut\ncommodo nulla neque. Aliq" \
                     u"uam erat volutpat. Integer et nunc augue.\nPellentesq" \
                     u"ue habitant morbi tristique senectus et netus et male" \
                     u"suada fames\nac turpis egestas. Quisque at enim nulla" \
                     u", vel tincidunt urna. Nam leo\naugue, elementum ut vi" \
                     u"verra eget, scelerisque in purus. In arcu orci, porta" \
                     u"\nnec aliquet quis, pretium a sem. In fermentum nisl " \
                     u"id diam luctus viverra.\nNullam semper, metus at euis" \
                     u"mod vulputate, orci odio dignissim urna, quis\niaculi" \
                     u"s neque lacus ut tortor. Ut a justo non dolor venenat" \
                     u"is accumsan.\nProin dolor eros, aliquam id condimentu" \
                     u"m et, aliquam quis metus. Vivamus\neget purus diam."

TEXT = TEXT_WITH_NEWLINES.replace('\n', ' ')

TEXT_FOR_OCR = (
    (
        u"Sherlock Holmes and Doctor Watson lived at 2211) Baker Street " \
        u"between 1881-1904,\n"
    ),
    (
        u"Step back in time, and when you visit London, remember to visit "
        u"the world's most\n"
        u"famous address!"
    )
)

FORMATS = (
    'txt', 'odt', 'docx', 'pptx', 'ods', 'xls', 'xlsx', 'html', 'xml', 'zip',
    'txt', 'rtf', 'test', 'hwp',
)

class FullText(unittest.TestCase):
    def test_missing_default(self):
        "Ensure a missing file returns default instead of exception."
        self.assertEqual(fulltext.get('non-existent-file.pdf', 'canary'),
                         'canary')

    def test_missing(self):
        "Ensure a missing file without a default raises an exception."
        # In this case we hit the pdf backend which runs a command, the
        # command fails because the file does not exist resulting in
        # ShellError.
        self.assertRaises(ShellError, fulltext.get, 'non-existent-file.pdf')

    def test_unknown_default(self):
        "Ensure unknown file type returns default instead of exception."
        self.assertEqual(fulltext.get('unknown-file.foobar', 'canary'),
                         'canary')

    def test_unknown(self):
        "Ensure unknown file type without a default raises an exception."
        # This is nearly a duplicate of test_missing, but in this case we hit
        # the default text backend, which attempts to open the file resulting
        # in an IOError.
        self.assertRaises(IOError, fulltext.get, 'unknown-file.foobar')

    def test_default_none(self):
        "Ensure None is a valid value to pass as default."
        self.assertEqual(fulltext.get('unknown-file.foobar', None), None)

class FullTextFilesMeta(type):
    "Tests various file types using disk file method."

    def __new__(cls, name, bases, attrs):
        for fmt in FORMATS:
            path = 'files/test.%s' % fmt
            attrs['test_%s_path' % fmt] = cls._test_path(path, fmt)
            attrs['test_%s_file' % fmt] = cls._test_file(path, fmt)
        return super(FullTextFilesMeta, cls).__new__(cls, name, bases, attrs)

    @classmethod
    def _test_file(cls, path, fmt):
        def inner(self):
            with open(path, 'rb') as f:
                text = fulltext.get(f, backend=fmt)
                self.assertEqual(text, TEXT)
        return inner

    @classmethod
    def _test_path(cls, path, fmt):
        def inner(self):
            text = fulltext.get(path, backend=fmt)
            self.assertEqual(text, TEXT)
        return inner

@add_metaclass(FullTextFilesMeta)
class FullTextFiles(unittest.TestCase):
    def assertStartsWith(self, prefix, body):
        self.assertTrue(body.startswith(prefix))

    def test_doc_file(self):
        "Antiword performs wrapping, so we need to allow newlines."
        with open('files/test.doc', 'rb') as f:
            text = fulltext.get(f, backend='doc')
            self.assertEqual(text, TEXT_WITH_NEWLINES)

    def test_doc_path(self):
        "Antiword performs wrapping, so we need to allow newlines."
        text = fulltext.get('files/test.doc', backend='doc')
        self.assertEqual(text, TEXT_WITH_NEWLINES)

    def test_old_doc_file(self):
        "Antiword does not support older Word documents."
        with open('files/test.old.doc', 'rb') as f:
            text = fulltext.get(f, backend='doc')
            self.assertStartsWith('eZ-Audit', text)

    def test_old_doc_path(self):
        "Antiword does not support older Word documents."
        text = fulltext.get('files/test.old.doc', backend='doc')
        self.assertStartsWith('eZ-Audit', text)

    def test_png_file(self):
        with open('files/test.png', 'rb') as f:
            text = fulltext.get(f)
            self.assertTrue(text.startswith (TEXT_FOR_OCR[0]))
            self.assertTrue(text.endswith (TEXT_FOR_OCR[1]))

    def test_png_path(self):
        text = fulltext.get('files/test.png')
        self.assertTrue(text.startswith (TEXT_FOR_OCR[0]))
        self.assertTrue(text.endswith (TEXT_FOR_OCR[1]))

    def test_csv_file(self):
        with open('files/test.csv', 'rb') as f:
            text = fulltext.get(f)
            self.assertStartsWith('Lorem', text)

    def test_csv_path(self):
        text = fulltext.get('files/test.csv')
        self.assertStartsWith('Lorem', text)

if __name__ == '__main__':
    unittest.main()
<commit_msg>increase test verbosity; makes hwp tests optional<commit_after>import unittest
import fulltext
import logging

from fulltext.util import ShellError
from fulltext.util import which

from six import add_metaclass

TEXT_WITH_NEWLINES = u"Lorem ipsum\ndolor sit amet, consectetur adipiscing e" \
                     u"lit. Nunc ipsum augue, iaculis quis\nauctor eu, adipi" \
                     u"scing non est. Nullam id sem diam, eget varius dui. E" \
                     u"tiam\nsollicitudin sapien nec odio elementum sit amet" \
                     u" luctus magna volutpat. Ut\ncommodo nulla neque. Aliq" \
                     u"uam erat volutpat. Integer et nunc augue.\nPellentesq" \
                     u"ue habitant morbi tristique senectus et netus et male" \
                     u"suada fames\nac turpis egestas. Quisque at enim nulla" \
                     u", vel tincidunt urna. Nam leo\naugue, elementum ut vi" \
                     u"verra eget, scelerisque in purus. In arcu orci, porta" \
                     u"\nnec aliquet quis, pretium a sem. In fermentum nisl " \
                     u"id diam luctus viverra.\nNullam semper, metus at euis" \
                     u"mod vulputate, orci odio dignissim urna, quis\niaculi" \
                     u"s neque lacus ut tortor. Ut a justo non dolor venenat" \
                     u"is accumsan.\nProin dolor eros, aliquam id condimentu" \
                     u"m et, aliquam quis metus. Vivamus\neget purus diam."

TEXT = TEXT_WITH_NEWLINES.replace('\n', ' ')

TEXT_FOR_OCR = (
    (
        u"Sherlock Holmes and Doctor Watson lived at 2211) Baker Street " \
        u"between 1881-1904,\n"
    ),
    (
        u"Step back in time, and when you visit London, remember to visit "
        u"the world's most\n"
        u"famous address!"
    )
)

FORMATS = [
    'txt', 'odt', 'docx', 'pptx', 'ods', 'xls', 'xlsx', 'html', 'xml', 'zip',
    'txt', 'rtf', 'test',
]
if which('pyhwp'):
    FORMATS.append('hwp')

class FullText(unittest.TestCase):

    def test_missing_default(self):
        "Ensure a missing file returns default instead of exception."
        self.assertEqual(fulltext.get('non-existent-file.pdf', 'canary'),
                         'canary')

    def test_missing(self):
        "Ensure a missing file without a default raises an exception."
        # In this case we hit the pdf backend which runs a command, the
        # command fails because the file does not exist resulting in
        # ShellError.
        self.assertRaises(ShellError, fulltext.get, 'non-existent-file.pdf')

    def test_unknown_default(self):
        "Ensure unknown file type returns default instead of exception."
        self.assertEqual(fulltext.get('unknown-file.foobar', 'canary'),
                         'canary')

    def test_unknown(self):
        "Ensure unknown file type without a default raises an exception."
        # This is nearly a duplicate of test_missing, but in this case we hit
        # the default text backend, which attempts to open the file resulting
        # in an IOError.
        self.assertRaises(IOError, fulltext.get, 'unknown-file.foobar')

    def test_default_none(self):
        "Ensure None is a valid value to pass as default."
        self.assertEqual(fulltext.get('unknown-file.foobar', None), None)

class FullTextFilesMeta(type):
    "Tests various file types using disk file method."

    def __new__(cls, name, bases, attrs):
        for fmt in FORMATS:
            path = 'files/test.%s' % fmt
            attrs['test_%s_path' % fmt] = cls._test_path(path, fmt)
            attrs['test_%s_file' % fmt] = cls._test_file(path, fmt)
        return super(FullTextFilesMeta, cls).__new__(cls, name, bases, attrs)

    @classmethod
    def _test_file(cls, path, fmt):
        def inner(self):
            with open(path, 'rb') as f:
                text = fulltext.get(f, backend=fmt)
                self.assertEqual(text, TEXT)
        return inner

    @classmethod
    def _test_path(cls, path, fmt):
        def inner(self):
            text = fulltext.get(path, backend=fmt)
            self.assertEqual(text, TEXT)
        return inner

@add_metaclass(FullTextFilesMeta)
class FullTextFiles(unittest.TestCase):
    def assertStartsWith(self, prefix, body):
        self.assertTrue(body.startswith(prefix))

    def test_doc_file(self):
        "Antiword performs wrapping, so we need to allow newlines."
        with open('files/test.doc', 'rb') as f:
            text = fulltext.get(f, backend='doc')
            self.assertEqual(text, TEXT_WITH_NEWLINES)

    def test_doc_path(self):
        "Antiword performs wrapping, so we need to allow newlines."
        text = fulltext.get('files/test.doc', backend='doc')
        self.assertEqual(text, TEXT_WITH_NEWLINES)

    def test_old_doc_file(self):
        "Antiword does not support older Word documents."
        with open('files/test.old.doc', 'rb') as f:
            text = fulltext.get(f, backend='doc')
            self.assertStartsWith('eZ-Audit', text)

    def test_old_doc_path(self):
        "Antiword does not support older Word documents."
        text = fulltext.get('files/test.old.doc', backend='doc')
        self.assertStartsWith('eZ-Audit', text)

    def test_png_file(self):
        with open('files/test.png', 'rb') as f:
            text = fulltext.get(f)
            self.assertTrue(text.startswith (TEXT_FOR_OCR[0]))
            self.assertTrue(text.endswith (TEXT_FOR_OCR[1]))

    def test_png_path(self):
        text = fulltext.get('files/test.png')
        self.assertTrue(text.startswith (TEXT_FOR_OCR[0]))
        self.assertTrue(text.endswith (TEXT_FOR_OCR[1]))

    def test_csv_file(self):
        with open('files/test.csv', 'rb') as f:
            text = fulltext.get(f)
            self.assertStartsWith('Lorem', text)

    def test_csv_path(self):
        text = fulltext.get('files/test.csv')
        self.assertStartsWith('Lorem', text)

if __name__ == '__main__':
    unittest.main(verbosity=2)
<|endoftext|>


<commit_before>from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _

from courses.models import Course
from results.models import Result

class Discipline(ObjectBaseClass):
    name = models.CharField(_('Название дисциплины'), max_length=256, blank=False, default='')
    courses = models.ManyToManyField(Course, verbose_name=_("Варианты реализации дисциплины"))
    results = models.ManyToManyField(Result, verbose_name=_("Результаты обучения"))
    results_text = models.TextField(_("Результаты обучения"), max_length=16384, blank=True, default="")

    class Meta:
        verbose_name = 'дисциплина'
        verbose_name_plural = 'дисциплины'

    def __str__(self):
        return self.name

    def get_all(self):
        return "\n".join([str(course)for course in self.courses.all()])<commit_msg>discipline fields blank=True<commit_after>from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _

from courses.models import Course
from results.models import Result

class Discipline(ObjectBaseClass):
    name = models.CharField(_('Название дисциплины'), max_length=256, blank=False, default='')
    courses = models.ManyToManyField(Course, verbose_name=_("Варианты реализации дисциплины"), blank=True)
    results = models.ManyToManyField(Result, verbose_name=_("Результаты обучения"), blank=True)
    results_text = models.TextField(_("Результаты обучения"), max_length=16384, blank=True, default="")

    class Meta:
        verbose_name = 'дисциплина'
        verbose_name_plural = 'дисциплины'

    def __str__(self):
        return self.name

    def get_all(self):
        return "\n".join([str(course)for course in self.courses.all()])<|endoftext|>


<commit_before>import uuid
import json
from django.db import models
from django.utils.safestring import mark_safe
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField

from results.models import Result

class Discipline(ObjectBaseClass):
    FORMS = (
        ('e', _('Экзамен')),
        ('z', _('Зачет'))
        )
    title = models.CharField(_('Название дисциплины'), max_length=256, blank=False, default='')
    description = models.TextField(_("Короткое описание"), max_length=16384, blank=True, null=True)
    module = models.ForeignKey("modules.Module", blank=True, null=True)
    labor = models.PositiveIntegerField(_("зачётных единиц"), blank=False, default=0)
    period = models.IntegerField(_("Период освоения в модуле"), default=1)
    form = models.CharField(_("Форма контроля"), max_length=1, choices=FORMS, default='z')
    results = models.ManyToManyField(Result, verbose_name=_("Результаты обучения"), blank=True)
    results_text = models.TextField(_("Результаты обучения"), max_length=16384, blank=True, default="")

    uni_uid = models.CharField(max_length=256, blank=True, null=True)
    uni_discipline = models.CharField(max_length=256, blank=True, null=True)
    uni_number = models.CharField(max_length=256, blank=True, null=True)
    uni_section = models.CharField(max_length=256, blank=True, null=True)
    uni_file = models.CharField(max_length=256, blank=True, null=True)

    class Meta:
        verbose_name = 'дисциплина'
        verbose_name_plural = 'дисциплины'

    def __str__(self):
        return self.title

    def num_courses(self):
        return len(self.courses.all())

class TrainingTerms(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование срока обучения'), max_length=256, blank=False, default='')
    limit = models.PositiveIntegerField(_("Лимит ЗЕ в год"), default=0)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'срок обучения'
        verbose_name_plural = 'сроки обучения'

class Semester(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline")
    program = models.ForeignKey("programs.Program")
    year = models.PositiveIntegerField(_("Год поступления"), default=1970)
    admission_semester = models.PositiveIntegerField(_("Семестр поступления"), default=0)
    training_semester = models.PositiveIntegerField(_("Семестр изучения"), default=0)
    term = models.ForeignKey("TrainingTerms", blank=True, null=True)

    def __str__(self):
        return f"{self.program} - {self.discipline} - {self.year} - {self.training_semester} сем."

    class Meta:
        verbose_name = 'семестр изучения дисциплины'
        verbose_name_plural = 'семестры изучения дисциплины'

class Variant(ObjectBaseClass):
    def __str__(self):
        return f"{self.id} - {self.discipline.title}"

    class Meta:
        verbose_name = 'вариант реализации дисциплин'
        verbose_name_plural = 'варианты реализации дисциплин'

    PARITY = (('1', 'Осенний'), ('2', 'Весенний'), ('3', 'Любой'))

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline", null=True, blank=True)
    program = models.ForeignKey("programs.Program", null=True, blank=True)
    diagram = models.ForeignKey("Diagram", null=True, blank=True)
    technology = models.ForeignKey("Technology", null=True, blank=True)
    course = models.ForeignKey("courses.Course", null=True, blank=True)
    semester = models.ForeignKey("Semester", null=True, blank=True)
    parity = models.CharField(_("Четность семестра дисциплины"), max_length=2, choices=PARITY, null=True, blank=True)
    link = models.CharField(_("Ссылка на страницу дисциплины"), max_length=512, blank=True, null=True)

class Diagram(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'график варианта'
        verbose_name_plural = 'графики варианта'

    title = models.CharField(_("Название графика"), max_length=512)
    diagram = JSONField(verbose_name=_("График"), null=True, blank=True)

    def get_diagram(self):
        lists = []
        for row in self.diagram:
            lists.append(list(row.values()))
        response = list(zip(*lists))
        response.insert(0, list(WorkingType.objects.all().values_list("color", flat=True)))
        return json.dumps(response)

    def get_diagram_display(self):
        lists = []
        for row in self.diagram:
            lists.append(list(row.values()))
        response = list(zip(*lists))
        response.insert(0, list(WorkingType.objects.all().values_list("color", flat=True)))

        r = """

            """.format(data=json.dumps(response), id=self.id)
        return mark_safe(r)

    get_diagram_display.allow_tags = True

class WorkingType(models.Model):
    title = models.CharField(_("Название вида работы"), max_length=512)
    color = models.CharField(_("Цвет вида работы"), max_length=16, blank=True, null=True)

class Technology(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'технология'
        verbose_name_plural = 'технологии'

    def get_color(self):
        return f"

"

    get_color.allow_tags = True
    get_color.short_description = _("Цвет технологии")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_("Название технологии"), max_length=512)
    description = models.TextField(_("Описание технологии"), max_length=16384, blank=True, null=True)
    contact_work_category = models.CharField(_("Категория контактной работы"), max_length=512, blank=True, null=True)
    color = models.CharField(_("Цвет технологии"), max_length=16, blank=True, null=True)
<commit_msg>diagram_display#30<commit_after>import uuid
import json
from django.db import models
from django.utils.safestring import mark_safe
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField

from results.models import Result

class Discipline(ObjectBaseClass):
    FORMS = (
        ('e', _('Экзамен')),
        ('z', _('Зачет'))
        )
    title = models.CharField(_('Название дисциплины'), max_length=256, blank=False, default='')
    description = models.TextField(_("Короткое описание"), max_length=16384, blank=True, null=True)
    module = models.ForeignKey("modules.Module", blank=True, null=True)
    labor = models.PositiveIntegerField(_("зачётных единиц"), blank=False, default=0)
    period = models.IntegerField(_("Период освоения в модуле"), default=1)
    form = models.CharField(_("Форма контроля"), max_length=1, choices=FORMS, default='z')
    results = models.ManyToManyField(Result, verbose_name=_("Результаты обучения"), blank=True)
    results_text = models.TextField(_("Результаты обучения"), max_length=16384, blank=True, default="")

    uni_uid = models.CharField(max_length=256, blank=True, null=True)
    uni_discipline = models.CharField(max_length=256, blank=True, null=True)
    uni_number = models.CharField(max_length=256, blank=True, null=True)
    uni_section = models.CharField(max_length=256, blank=True, null=True)
    uni_file = models.CharField(max_length=256, blank=True, null=True)

    class Meta:
        verbose_name = 'дисциплина'
        verbose_name_plural = 'дисциплины'

    def __str__(self):
        return self.title

    def num_courses(self):
        return len(self.courses.all())

class TrainingTerms(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование срока обучения'), max_length=256, blank=False, default='')
    limit = models.PositiveIntegerField(_("Лимит ЗЕ в год"), default=0)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'срок обучения'
        verbose_name_plural = 'сроки обучения'

class Semester(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline")
    program = models.ForeignKey("programs.Program")
    year = models.PositiveIntegerField(_("Год поступления"), default=1970)
    admission_semester = models.PositiveIntegerField(_("Семестр поступления"), default=0)
    training_semester = models.PositiveIntegerField(_("Семестр изучения"), default=0)
    term = models.ForeignKey("TrainingTerms", blank=True, null=True)

    def __str__(self):
        return f"{self.program} - {self.discipline} - {self.year} - {self.training_semester} сем."

    class Meta:
        verbose_name = 'семестр изучения дисциплины'
        verbose_name_plural = 'семестры изучения дисциплины'

class Variant(ObjectBaseClass):
    def __str__(self):
        return f"{self.id} - {self.discipline.title}"

    class Meta:
        verbose_name = 'вариант реализации дисциплин'
        verbose_name_plural = 'варианты реализации дисциплин'

    PARITY = (('1', 'Осенний'), ('2', 'Весенний'), ('3', 'Любой'))

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline", null=True, blank=True)
    program = models.ForeignKey("programs.Program", null=True, blank=True)
    diagram = models.ForeignKey("Diagram", null=True, blank=True)
    technology = models.ForeignKey("Technology", null=True, blank=True)
    course = models.ForeignKey("courses.Course", null=True, blank=True)
    semester = models.ForeignKey("Semester", null=True, blank=True)
    parity = models.CharField(_("Четность семестра дисциплины"), max_length=2, choices=PARITY, null=True, blank=True)
    link = models.CharField(_("Ссылка на страницу дисциплины"), max_length=512, blank=True, null=True)

class Diagram(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'график варианта'
        verbose_name_plural = 'графики варианта'

    title = models.CharField(_("Название графика"), max_length=512)
    diagram = JSONField(verbose_name=_("График"), null=True, blank=True)

    def get_diagram(self):
        lists = []
        for row in self.diagram:
            lists.append(list(row.values()))
        response = list(zip(*lists))
        response.insert(0, list(WorkingType.objects.all().values_list("color", flat=True)))
        return json.dumps(response)

    def get_diagram_display(self):
        lists = []
        for row in self.diagram:
            lists.append(list(row.values()))
        response = list(zip(*lists))
        response.insert(0, list(WorkingType.objects.all().values_list("color", flat=True)))

        r = """

            """.format(data=json.dumps(response), id=self.id)
        return mark_safe(r)

    get_diagram_display.allow_tags = True

class WorkingType(models.Model):
    title = models.CharField(_("Название вида работы"), max_length=512)
    color = models.CharField(_("Цвет вида работы"), max_length=16, blank=True, null=True)

class Technology(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'технология'
        verbose_name_plural = 'технологии'

    def get_color(self):
        return f"

"

    get_color.allow_tags = True
    get_color.short_description = _("Цвет технологии")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_("Название технологии"), max_length=512)
    description = models.TextField(_("Описание технологии"), max_length=16384, blank=True, null=True)
    contact_work_category = models.CharField(_("Категория контактной работы"), max_length=512, blank=True, null=True)
    color = models.CharField(_("Цвет технологии"), max_length=16, blank=True, null=True)
<|endoftext|>


<commit_before>import uuid
from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField

from results.models import Result

class Discipline(ObjectBaseClass):
    FORMS = (
        ('e', _('Экзамен')),
        ('z', _('Зачет'))
        )
    title = models.CharField(_('Название дисциплины'), max_length=256, blank=False, default='')
    description = models.TextField(_("Короткое описание"), max_length=16384, blank=True, null=True)
    module = models.ForeignKey("modules.Module", blank=True, null=True)
    labor = models.PositiveIntegerField(_("зачётных единиц"), blank=False, default=0)
    period = models.IntegerField(_("Период освоения в модуле"), default=1)
    form = models.CharField(_("Форма контроля"), max_length=1, choices=FORMS, default='z')
    results = models.ManyToManyField(Result, verbose_name=_("Результаты обучения"), blank=True)
    results_text = models.TextField(_("Результаты обучения"), max_length=16384, blank=True, default="")

    uni_uid = models.CharField(max_length=256, blank=True, null=True)
    uni_discipline = models.CharField(max_length=256, blank=True, null=True)
    uni_number = models.CharField(max_length=256, blank=True, null=True)
    uni_section = models.CharField(max_length=256, blank=True, null=True)
    uni_file = models.CharField(max_length=256, blank=True, null=True)

    class Meta:
        verbose_name = 'дисциплина'
        verbose_name_plural = 'дисциплины'

    def __str__(self):
        return self.title

    def num_courses(self):
        return len(self.courses.all())

class TrainingTerms(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование срока обучения'), max_length=256, blank=False, default='')
    limit = models.PositiveIntegerField(_("Лимит ЗЕ в год"), default=0)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'срок обучения'
        verbose_name_plural = 'сроки обучения'

class Semester(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline")
    program = models.ForeignKey("programs.Program")
    year = models.PositiveIntegerField(_("Год поступления"), default=1970)
    admission_semester = models.PositiveIntegerField(_("Семестр поступления"), default=0)
    training_semester = models.PositiveIntegerField(_("Семестр изучения"), default=0)
    term = models.ForeignKey("TrainingTerms", blank=True, null=True)

    def __str__(self):
        return f"{self.program} - {self.discipline} - {self.year}"

    class Meta:
        verbose_name = 'семестр изучения дисциплины'
        verbose_name_plural = 'семестры изучения дисциплины'

class Variant(ObjectBaseClass):
    def __str__(self):
        return f"{self.id} - {self.discipline.title} - {self.training_semester} сем."

    class Meta:
        verbose_name = 'вариант реализации дисциплин'
        verbose_name_plural = 'варианты реализации дисциплин'

    PARITY = (('1', 'Нечетный'), ('2', 'Четный'))

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline", null=True, blank=True)
    program = models.ForeignKey("programs.Program", null=True, blank=True)
    diagram = models.ForeignKey("Diagram", null=True, blank=True)
    technology = models.ForeignKey("Technology", null=True, blank=True)
    course = models.ForeignKey("courses.Course", null=True)
    semester = models.ForeignKey("Semester", null=True)
    parity = models.CharField(_("Четность семестра дисциплины"), max_length=2, choices=PARITY, null=True, blank=True)
    link = models.CharField(_("Ссылка на страницу дисциплины"), max_length=512, blank=True, null=True)

class Diagram(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'график варианта'
        verbose_name_plural = 'графики варианта'

    title = models.CharField(_("Название графика"), max_length=512)
    diagram = JSONField(verbose_name=_("График"), null=True, blank=True)

class Technology(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'технология'
        verbose_name_plural = 'технологии'

    def get_color(self):
        return f"

"

    get_color.allow_tags = True
    get_color.short_description = _("Цвет технологии")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_("Название технологии"), max_length=512)
    description = models.TextField(_("Описание технологии"), max_length=16384, blank=True, null=True)
    contact_work_category = models.CharField(_("Категория контактной работы"), max_length=512, blank=True, null=True)
    color = models.CharField(_("Цвет технологии"), max_length=16, blank=True, null=True)
<commit_msg>change_discipline_semester#12<commit_after>import uuid
from django.db import models
from base.models import ObjectBaseClass
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField

from results.models import Result

class Discipline(ObjectBaseClass):
    FORMS = (
        ('e', _('Экзамен')),
        ('z', _('Зачет'))
        )
    title = models.CharField(_('Название дисциплины'), max_length=256, blank=False, default='')
    description = models.TextField(_("Короткое описание"), max_length=16384, blank=True, null=True)
    module = models.ForeignKey("modules.Module", blank=True, null=True)
    labor = models.PositiveIntegerField(_("зачётных единиц"), blank=False, default=0)
    period = models.IntegerField(_("Период освоения в модуле"), default=1)
    form = models.CharField(_("Форма контроля"), max_length=1, choices=FORMS, default='z')
    results = models.ManyToManyField(Result, verbose_name=_("Результаты обучения"), blank=True)
    results_text = models.TextField(_("Результаты обучения"), max_length=16384, blank=True, default="")

    uni_uid = models.CharField(max_length=256, blank=True, null=True)
    uni_discipline = models.CharField(max_length=256, blank=True, null=True)
    uni_number = models.CharField(max_length=256, blank=True, null=True)
    uni_section = models.CharField(max_length=256, blank=True, null=True)
    uni_file = models.CharField(max_length=256, blank=True, null=True)

    class Meta:
        verbose_name = 'дисциплина'
        verbose_name_plural = 'дисциплины'

    def __str__(self):
        return self.title

    def num_courses(self):
        return len(self.courses.all())

class TrainingTerms(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_('Наименование срока обучения'), max_length=256, blank=False, default='')
    limit = models.PositiveIntegerField(_("Лимит ЗЕ в год"), default=0)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'срок обучения'
        verbose_name_plural = 'сроки обучения'

class Semester(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline")
    program = models.ForeignKey("programs.Program")
    year = models.PositiveIntegerField(_("Год поступления"), default=1970)
    admission_semester = models.PositiveIntegerField(_("Семестр поступления"), default=0)
    training_semester = models.PositiveIntegerField(_("Семестр изучения"), default=0)
    term = models.ForeignKey("TrainingTerms", blank=True, null=True)

    def __str__(self):
        return f"{self.program} - {self.discipline} - {self.year} - {self.training_semester} сем."

    class Meta:
        verbose_name = 'семестр изучения дисциплины'
        verbose_name_plural = 'семестры изучения дисциплины'

class Variant(ObjectBaseClass):
    def __str__(self):
        return f"{self.id} - {self.discipline.title}"

    class Meta:
        verbose_name = 'вариант реализации дисциплин'
        verbose_name_plural = 'варианты реализации дисциплин'

    PARITY = (('1', 'Нечетный'), ('2', 'Четный'))

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    discipline = models.ForeignKey("Discipline", null=True, blank=True)
    program = models.ForeignKey("programs.Program", null=True, blank=True)
    diagram = models.ForeignKey("Diagram", null=True, blank=True)
    technology = models.ForeignKey("Technology", null=True, blank=True)
    course = models.ForeignKey("courses.Course", null=True)
    semester = models.ForeignKey("Semester", null=True)
    parity = models.CharField(_("Четность семестра дисциплины"), max_length=2, choices=PARITY, null=True, blank=True)
    link = models.CharField(_("Ссылка на страницу дисциплины"), max_length=512, blank=True, null=True)

class Diagram(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'график варианта'
        verbose_name_plural = 'графики варианта'

    title = models.CharField(_("Название графика"), max_length=512)
    diagram = JSONField(verbose_name=_("График"), null=True, blank=True)

class Technology(ObjectBaseClass):
    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'технология'
        verbose_name_plural = 'технологии'

    def get_color(self):
        return f"

"

    get_color.allow_tags = True
    get_color.short_description = _("Цвет технологии")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_("Название технологии"), max_length=512)
    description = models.TextField(_("Описание технологии"), max_length=16384, blank=True, null=True)
    contact_work_category = models.CharField(_("Категория контактной работы"), max_length=512, blank=True, null=True)
    color = models.CharField(_("Цвет технологии"), max_length=16, blank=True, null=True)
<|endoftext|>


<commit_before>""" Yes, just one file for tests will do. """
import unittest
import json
import random
import re
from string import printable
import sender_policy_flattener as spf

class FlattenerTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        with open('fixtures.json') as f:
            cls.fixtures = json.load(f)
        cls.dns_answer = re.compile(r'ANSWER\n(?P<answers>[^;]+)')
        cls.ip_address = re.compile(r'(?<=ip[46]:)\S+')
        cls.a_record = re.compile(r'((?:\d{1,3}\.){3}\d{1,3})')
        cls.spf_include = re.compile(r'(?P<type>include|a|mx(?: \d+)? ?|ptr|cname ?)[:](?P<hostname>[^\s\'\"]+\w)', flags=re.IGNORECASE)
        cls.response = cls.fixtures['dns_regex']['response']
        cls.answer = cls.fixtures['dns_regex']['answer_section']

    def test_hashseq_produces_consistent_hash(self):
        jumbled = random.sample(printable, len(printable))
        self.assertTrue(spf.hashed_sequence(jumbled) == spf.hashed_sequence(printable))

    def test_answer_section_is_extracted_from_dns_response(self):
        expected = self.fixtures['dns_regex']['answer_section']
        match = self.dns_answer.search(self.response).group()
        self.assertEqual(match, expected)

    def test_ipaddresses_are_extracted_from_regex_search(self):
        expected = self.fixtures['dns_regex']['ips']
        match = self.ip_address.findall(self.answer)
        self.assertEqual(match, expected)

    def test_a_records_are_extracted_from_regex_search(self):
        expected = self.fixtures['dns_regex']['a_record']
        match = self.a_record.findall(self.answer)
        self.assertEqual(match, expected)

    def test_cname_records_are_extracted_from_regex_search(self):
        pass

    def test_includes_are_extracted_from_regex_search(self):
        expected = self.fixtures['dns_regex']['includes']
        match = self.spf_include.findall(self.answer)  # Tuple(Tuple(Str, Str), ...)
        match = [list(l) for l in match]
        self.assertListEqual(match, expected)

    def test_ipaddresses_are_separated_correctly(self):
        ips = self.fixtures['flattening']['ips']
        ipblocks, lastrec = spf.separate_into_450bytes(ips)
        ipblocks = [list(x) for x in ipblocks]
        ipblocks = spf.hashed_sequence(repr(ipblocks))

        expected_ipblocks = self.fixtures['flattening']['separated']
        expected_ipblocks = spf.hashed_sequence(repr(expected_ipblocks))
        expected_lastrec = self.fixtures['flattening']['lastrec']

        self.assertEqual(ipblocks, expected_ipblocks)
        self.assertEqual(lastrec, expected_lastrec)

class SettingsTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        with open('settings.json') as f:
            cls.settings = json.load(f)

    def test_settings_contains_min_details(self):
        min_keys = ['sending domains', 'email', 'output']
        for key in min_keys:
            self.assertIn(key, self.settings.keys())

    def test_email_settings_contains_min_details(self):
        min_keys = ['to', 'from', 'subject', 'server']
        for key in min_keys:
            self.assertIn(key, self.settings['email'].keys())
<commit_msg>Try printing inside a unit test<commit_after>""" Yes, just one file for tests will do. """
import unittest
import json
import random
import re
from string import printable
import sender_policy_flattener as spf

class FlattenerTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        with open('fixtures.json') as f:
            cls.fixtures = json.load(f)
        cls.dns_answer = re.compile(r'ANSWER\n(?P<answers>[^;]+)')
        cls.ip_address = re.compile(r'(?<=ip[46]:)\S+')
        cls.a_record = re.compile(r'((?:\d{1,3}\.){3}\d{1,3})')
        cls.spf_include = re.compile(r'(?P<type>include|a|mx(?: \d+)? ?|ptr|cname ?)[:](?P<hostname>[^\s\'\"]+\w)', flags=re.IGNORECASE)
        cls.response = cls.fixtures['dns_regex']['response']
        cls.answer = cls.fixtures['dns_regex']['answer_section']

    def test_hashseq_produces_consistent_hash(self):
        jumbled = random.sample(printable, len(printable))
        self.assertTrue(spf.hashed_sequence(jumbled) == spf.hashed_sequence(printable))
        print('{0} == {1}'.format(repr(spf.hashed_sequence(jumbled)), repr(spf.hashed_sequence(printable))))

    def test_answer_section_is_extracted_from_dns_response(self):
        expected = self.fixtures['dns_regex']['answer_section']
        match = self.dns_answer.search(self.response).group()
        self.assertEqual(match, expected)

    def test_ipaddresses_are_extracted_from_regex_search(self):
        expected = self.fixtures['dns_regex']['ips']
        match = self.ip_address.findall(self.answer)
        self.assertEqual(match, expected)

    def test_a_records_are_extracted_from_regex_search(self):
        expected = self.fixtures['dns_regex']['a_record']
        match = self.a_record.findall(self.answer)
        self.assertEqual(match, expected)

    def test_cname_records_are_extracted_from_regex_search(self):
        pass

    def test_includes_are_extracted_from_regex_search(self):
        expected = self.fixtures['dns_regex']['includes']
        match = self.spf_include.findall(self.answer)  # Tuple(Tuple(Str, Str), ...)
        match = [list(l) for l in match]
        self.assertListEqual(match, expected)

    def test_ipaddresses_are_separated_correctly(self):
        ips = self.fixtures['flattening']['ips']
        ipblocks, lastrec = spf.separate_into_450bytes(ips)
        ipblocks = [list(x) for x in ipblocks]
        ipblocks = spf.hashed_sequence(repr(ipblocks))

        expected_ipblocks = self.fixtures['flattening']['separated']
        expected_ipblocks = spf.hashed_sequence(repr(expected_ipblocks))
        expected_lastrec = self.fixtures['flattening']['lastrec']

        self.assertEqual(ipblocks, expected_ipblocks)
        self.assertEqual(lastrec, expected_lastrec)

class SettingsTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        with open('settings.json') as f:
            cls.settings = json.load(f)

    def test_settings_contains_min_details(self):
        min_keys = ['sending domains', 'email', 'output']
        for key in min_keys:
            self.assertIn(key, self.settings.keys())

    def test_email_settings_contains_min_details(self):
        min_keys = ['to', 'from', 'subject', 'server']
        for key in min_keys:
            self.assertIn(key, self.settings['email'].keys())
<|endoftext|>