# Path: cjktools/tests/_common.py
# def to_unicode_stream(x):
#     o = StringIO(x)
# 
#     if isinstance(x, binary_type):
#         o = codecs.getreader('utf8')(o)
# 
#     return o
# 
# def to_string_stream(x):
#     """
#     For modules that require a encoding as ``str`` in both Python 2 and
#     Python 3, we can't just encode automatically. 
#     """
#     if PY2 and isinstance(x, text_type):
#         x = x.encode('utf-8')
# 
#     return StringIO(x)
# 
# Path: cjktools/resources/tatoeba.py
# class TatoebaDict(Mapping):
# class TatoebaReader(TatoebaDict):
# class TatoebaSentenceReader(TatoebaReader):
# class TatoebaLinksReader(TatoebaReader):
# class TanakaWord(object):
# class TatoebaIndexReader(TatoebaReader):
# class MissingDataError(ValueError):
# class InvalidFileError(ValueError):
# class InvalidIDError(KeyError):
# class InvalidEntryError(ValueError):
#     def __getitem__(self, key):
#     def __iter__(self):
#     def __len__(self):
#     def __init__(self, *args, **kwargs):
#     def load_file(self, fpath_or_buf, **csv_kwargs):
#     def _get_src_repr(self, src):
#     def __init__(self, sentences, languages=None):
#     def language(self, sent_id):
#     def sentence(self, sent_id):
#     def details(self, sent_id):
#     def sentences(self):
#     def sentences(self, src):
#     def sentence_ids(self):
#     def _base_dict(self):
#     def parse_date(self, dtstr):
#     def filter_row(self, row):
#     def __repr__(self):
#     def __init__(self, links, sentence_ids=None, sentence_ids_filter='both'):
#     def group(self, sent_id):
#     def groups(self):
#     def links(self):
#     def links(self, src):
#     def sentence_ids_filter(self):
#     def _sentence_ids_filter(self, valstr):
#     def sentence_id_subset(self):
#     def _sentence_id_subset(self, value):
#     def _base_dict(self):
#     def __getitem__(self, key):
#     def __repr__(self):
#     def __init__(self, headword, reading, sense, display, example):
#     def from_text(cls, text):
#     def resolve_display(self):
#     def __str__(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __init__(self, jpn_indices, edict=None, sentence_ids=None):
#     def link(self, sent_id):
#     def jpn_indices(self):
#     def jpn_indices(self, src):
#     def parse_sentence(self, text):
#     def adjust_details(self, sentence):
#     def sentence_id_subset(self):
#     def sentence_id_subset(self, value):
#     def _base_dict(self):
# 
# Path: cjktools/resources/auto_format.py
# def detect_format(header):
# def load_dictionary(istream):
# def iter_entries(istream):
# 
# Path: cjktools/resources/cjkdata.py
# SEARCH_PATHS = [
#     '~/.cjkdata',
#     '/usr/share/data/cjkdata',
#     '/usr/local/share/data/cjkdata',
# ]
# def find_path():
# def get_resource(name):
# class MissingCJKDataError(Exception):
# 
# Path: cjktools/common.py
# def sopen(filename, mode='rb', encoding='utf8'):
#     """
#     Transparently uses compression on the given file based on file
#     extension.
# 
#     :param filename:
#         The filename to use for the file handle.
#     
#     :param mode:
#         The mode to open the file in, e.g. ``'r'`` for read, ``'w'`` for
#         write, ``'a'`` for append.
#     
#     :param encoding:
#         The encoding to use. Can be set to None to avoid
#         using unicode at all.
#     """
#     read_mode = 'r' in mode
#     if read_mode and 'w' in mode:
#         raise Exception("Must be either read mode or write, but not both")
# 
#     # Do this before any streams are opened to hopefully minimize the potential
#     # for failing while resources are open.
#     if encoding not in (None, 'byte') and six.PY2:
#         if read_mode:
#             streamhandler = codecs.getreader(encoding)
#         else:
#             streamhandler = codecs.getwriter(encoding)
#     else:
#         streamhandler = lambda x: x
# 
#     if filename.endswith('.bz2'):
#         stream = bz2.BZ2File(filename, mode)
#     elif filename.endswith('.gz'):
#         stream = gzip.GzipFile(filename, mode)
#     elif filename == '-':
#         if read_mode:
#             stream = sys.stdin
#         else:
#             stream = sys.stdout
#     else:
#         stream = open(filename, mode)
# 
#     return streamhandler(stream)


import os
import unittest
from .._common import to_unicode_stream, to_string_stream
from six import text_type
from functools import partial
from datetime import datetime
from cjktools.resources import tatoeba, auto_format, cjkdata
from cjktools.common import sopen
from nose_parameterized import parameterized

        actual = sorted(lr.groups(), key=lambda x: min(x))

        self.assertEqual(groups, actual)
    
    def test_links(self):
        lr = self.load_file()

        self.assertEqual(lr.links, self.resource_fpath())

    def test_repr(self):
        lr = self.load_file()

        expected_fmt = "TatoebaLinksReader(links='{}')"
        expected = expected_fmt.format(self.resource_fpath())

        self.assertEqual(repr(lr), expected)


class TatoebaLinksReaderMiscTests(unittest.TestCase):
    @parameterized.expand([
        # Too few columns
        ('too_few', '3444\n3949\n'),
        # Too many columns
        ('too_many', '3444\teng\tThe boy ate a tiger\tMB'),
        # Too many columns, with unicode
        ('too_many', '3444\teng\tThe boy ate a tiger (虎)\tMB'),
    ])
    def test_invalid_file(self, name, rowstr):
        # Too few columns

# Path: cjktools/tests/_common.py
# def to_unicode_stream(x):
#     o = StringIO(x)
# 
#     if isinstance(x, binary_type):
#         o = codecs.getreader('utf8')(o)
# 
#     return o
# 
# def to_string_stream(x):
#     """
#     For modules that require a encoding as ``str`` in both Python 2 and
#     Python 3, we can't just encode automatically. 
#     """
#     if PY2 and isinstance(x, text_type):
#         x = x.encode('utf-8')
# 
#     return StringIO(x)
# 
# Path: cjktools/resources/tatoeba.py
# class TatoebaDict(Mapping):
# class TatoebaReader(TatoebaDict):
# class TatoebaSentenceReader(TatoebaReader):
# class TatoebaLinksReader(TatoebaReader):
# class TanakaWord(object):
# class TatoebaIndexReader(TatoebaReader):
# class MissingDataError(ValueError):
# class InvalidFileError(ValueError):
# class InvalidIDError(KeyError):
# class InvalidEntryError(ValueError):
#     def __getitem__(self, key):
#     def __iter__(self):
#     def __len__(self):
#     def __init__(self, *args, **kwargs):
#     def load_file(self, fpath_or_buf, **csv_kwargs):
#     def _get_src_repr(self, src):
#     def __init__(self, sentences, languages=None):
#     def language(self, sent_id):
#     def sentence(self, sent_id):
#     def details(self, sent_id):
#     def sentences(self):
#     def sentences(self, src):
#     def sentence_ids(self):
#     def _base_dict(self):
#     def parse_date(self, dtstr):
#     def filter_row(self, row):
#     def __repr__(self):
#     def __init__(self, links, sentence_ids=None, sentence_ids_filter='both'):
#     def group(self, sent_id):
#     def groups(self):
#     def links(self):
#     def links(self, src):
#     def sentence_ids_filter(self):
#     def _sentence_ids_filter(self, valstr):
#     def sentence_id_subset(self):
#     def _sentence_id_subset(self, value):
#     def _base_dict(self):
#     def __getitem__(self, key):
#     def __repr__(self):
#     def __init__(self, headword, reading, sense, display, example):
#     def from_text(cls, text):
#     def resolve_display(self):
#     def __str__(self):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __init__(self, jpn_indices, edict=None, sentence_ids=None):
#     def link(self, sent_id):
#     def jpn_indices(self):
#     def jpn_indices(self, src):
#     def parse_sentence(self, text):
#     def adjust_details(self, sentence):
#     def sentence_id_subset(self):
#     def sentence_id_subset(self, value):
#     def _base_dict(self):
# 
# Path: cjktools/resources/auto_format.py
# def detect_format(header):
# def load_dictionary(istream):
# def iter_entries(istream):
# 
# Path: cjktools/resources/cjkdata.py
# SEARCH_PATHS = [
#     '~/.cjkdata',
#     '/usr/share/data/cjkdata',
#     '/usr/local/share/data/cjkdata',
# ]
# def find_path():
# def get_resource(name):
# class MissingCJKDataError(Exception):
# 
# Path: cjktools/common.py
# def sopen(filename, mode='rb', encoding='utf8'):
#     """
#     Transparently uses compression on the given file based on file
#     extension.
# 
#     :param filename:
#         The filename to use for the file handle.
#     
#     :param mode:
#         The mode to open the file in, e.g. ``'r'`` for read, ``'w'`` for
#         write, ``'a'`` for append.
#     
#     :param encoding:
#         The encoding to use. Can be set to None to avoid
#         using unicode at all.
#     """
#     read_mode = 'r' in mode
#     if read_mode and 'w' in mode:
#         raise Exception("Must be either read mode or write, but not both")
# 
#     # Do this before any streams are opened to hopefully minimize the potential
#     # for failing while resources are open.
#     if encoding not in (None, 'byte') and six.PY2:
#         if read_mode:
#             streamhandler = codecs.getreader(encoding)
#         else:
#             streamhandler = codecs.getwriter(encoding)
#     else:
#         streamhandler = lambda x: x
# 
#     if filename.endswith('.bz2'):
#         stream = bz2.BZ2File(filename, mode)
#     elif filename.endswith('.gz'):
#         stream = gzip.GzipFile(filename, mode)
#     elif filename == '-':
#         if read_mode:
#             stream = sys.stdin
#         else:
#             stream = sys.stdout
#     else:
#         stream = open(filename, mode)
# 
#     return streamhandler(stream)


# Path: cjktools/tests/resources/test_tatoeba.py
import os
import unittest
from .._common import to_unicode_stream, to_string_stream
from six import text_type
from functools import partial
from datetime import datetime
from cjktools.resources import tatoeba, auto_format, cjkdata
from cjktools.common import sopen
from nose_parameterized import parameterized


        actual = sorted(lr.groups(), key=lambda x: min(x))

        self.assertEqual(groups, actual)
    
    def test_links(self):
        lr = self.load_file()

        self.assertEqual(lr.links, self.resource_fpath())

    def test_repr(self):
        lr = self.load_file()

        expected_fmt = "TatoebaLinksReader(links='{}')"
        expected = expected_fmt.format(self.resource_fpath())

        self.assertEqual(repr(lr), expected)


class TatoebaLinksReaderMiscTests(unittest.TestCase):
    @parameterized.expand([
        # Too few columns
        ('too_few', '3444\n3949\n'),
        # Too many columns
        ('too_many', '3444\teng\tThe boy ate a tiger\tMB'),
        # Too many columns, with unicode
        ('too_many', '3444\teng\tThe boy ate a tiger (虎)\tMB'),
    ])
    def test_invalid_file(self, name, rowstr):
        # Too few columns

        invalid = to_string_stream(rowstr)