Beispiel #1
0
class TestImporter (TestCase):

    def setUp(self):
        TestCase.setUp(self)
        self.fs = TempFS()
        self.importer = Importer()
        
    def test_finds_index_file_in_a_subdirectory(self):
        self.fs.makedir("directory")
        self.fs.setcontents("directory/file.txt", "test")
        index_file = self.importer._find_index_file(self.fs, ["*.txt"])
        assert_equals("directory/file.txt", index_file)
Beispiel #2
0
class TestFUSE(unittest.TestCase,FSTestCases):

    def setUp(self):
        self.temp_fs = TempFS()
        self.temp_fs.makedir("root")
        self.temp_fs.makedir("mount")
        self.mounted_fs = self.temp_fs.opendir("root")
        self.mount_point = self.temp_fs.getsyspath("mount")
        self.fs = OSFS(self.temp_fs.getsyspath("mount"))
        self.mount_proc = fuse.mount(self.mounted_fs,self.mount_point)

    def tearDown(self):
        self.mount_proc.unmount()
        self.temp_fs.close()

    def check(self,p):
        return self.mounted_fs.exists(p)
Beispiel #3
0
 def test_remove_all(self):
     """Test remove_all function"""
     fs = TempFS()
     fs.setcontents("f1", "file 1")
     fs.setcontents("f2", "file 2")
     fs.setcontents("f3", "file 3")
     fs.makedir("foo/bar", recursive=True)
     fs.setcontents("foo/bar/fruit", "apple")        
     fs.setcontents("foo/baz", "baz")
     
     utils.remove_all(fs, "foo/bar")
     self.assert_(not fs.exists("foo/bar/fruit"))
     self.assert_(fs.exists("foo/bar"))
     self.assert_(fs.exists("foo/baz"))
     utils.remove_all(fs,  "")
     self.assert_(not fs.exists("foo/bar/fruit"))
     self.assert_(not fs.exists("foo/bar/baz"))
     self.assert_(not fs.exists("foo/baz"))
     self.assert_(not fs.exists("foo"))
     self.assert_(not fs.exists("f1"))
     self.assert_(fs.isdirempty('/'))
Beispiel #4
0
    class TestFUSE(unittest.TestCase, FSTestCases, ThreadingTestCases):
        def setUp(self):
            self.temp_fs = TempFS()
            self.temp_fs.makedir("root")
            self.temp_fs.makedir("mount")
            self.mounted_fs = self.temp_fs.opendir("root")
            self.mount_point = self.temp_fs.getsyspath("mount")
            self.fs = OSFS(self.temp_fs.getsyspath("mount"))
            self.mount_proc = fuse.mount(self.mounted_fs, self.mount_point)

        def tearDown(self):
            self.mount_proc.unmount()
            try:
                self.temp_fs.close()
            except OSError:
                # Sometimes FUSE hangs onto the mountpoint if mount_proc is
                # forcibly killed.  Shell out to fusermount to make sure.
                fuse.unmount(self.mount_point)
                self.temp_fs.close()

        def check(self, p):
            return self.mounted_fs.exists(p)
    class TestFUSE(unittest.TestCase,FSTestCases,ThreadingTestCases):

        def setUp(self):
            self.temp_fs = TempFS()            
            self.temp_fs.makedir("root")
            self.temp_fs.makedir("mount")
            self.mounted_fs = self.temp_fs.opendir("root")
            self.mount_point = self.temp_fs.getsyspath("mount")
            self.fs = OSFS(self.temp_fs.getsyspath("mount"))
            self.mount_proc = fuse.mount(self.mounted_fs,self.mount_point)

        def tearDown(self):
            self.mount_proc.unmount()
            try:
                self.temp_fs.close()
            except OSError:
                # Sometimes FUSE hangs onto the mountpoint if mount_proc is
                # forcibly killed.  Shell out to fusermount to make sure.
                fuse.unmount(self.mount_point)
                self.temp_fs.close()

        def check(self,p):
            return self.mounted_fs.exists(p)
Beispiel #6
0
                    #write(wrap_prefix(prefix[:-1] + '       ') + wrap_error('max recursion levels reached'))
                else:
                    print_dir(fs, pathjoin(path, item), levels[:] + [is_last_item])
            else:
                write('%s %s' % (wrap_prefix(prefix + char_line), wrap_filename(item)))

        return len(dir_listing)

    print_dir(fs, path)
    return dircount[0], filecount[0]


if __name__ == "__main__":
    from fs.tempfs import TempFS
    from six import b
    t1 = TempFS()
    t1.setcontents("foo", b("test"))
    t1.makedir("bar")
    t1.setcontents("bar/baz", b("another test"))

    t1.tree()

    t2 = TempFS()
    print t2.listdir()
    movedir(t1, t2)

    print t2.listdir()
    t1.tree()
    t2.tree()

Beispiel #7
0
                else:
                    print_dir(fs, pathjoin(path, item),
                              levels[:] + [is_last_item])
            else:
                write('%s %s' %
                      (wrap_prefix(prefix + char_line), wrap_filename(item)))

        return len(dir_listing)

    print_dir(fs, path)
    return dircount[0], filecount[0]


if __name__ == "__main__":
    from fs.tempfs import TempFS
    from six import b
    t1 = TempFS()
    t1.setcontents("foo", b("test"))
    t1.makedir("bar")
    t1.setcontents("bar/baz", b("another test"))

    t1.tree()

    t2 = TempFS()
    print t2.listdir()
    movedir(t1, t2)

    print t2.listdir()
    t1.tree()
    t2.tree()
Beispiel #8
0
class TestCOWFS(FSTestCases, unittest.TestCase):
    def make_fs(self) -> COWFS:
        self.tempfs = TempFS()
        return COWFS(self.tempfs)

    def test_makedir_bug(self) -> None:
        # These two commands disclosed a bug in COWFS.makedir().  This
        # serves as a regression test.
        self.tempfs.makedir("/b$")
        self.fs.makedir("/b$/c$")
        self.fs.invariant()

    def test_openbin_bug(self) -> None:
        # These two commands disclosed a bug in COWFS.openbin().  This
        # serves as a regression test.
        self.tempfs.makedir("/b$")
        self.fs.writetext("/b$/c.txt", "Buggy?")
        self.fs.invariant()

    def test_listdir_bug(self) -> None:
        # Removing a file disclosed a bug in COWFS.listdir().  This
        # serves as a regression test.
        self.tempfs.makedirs("/b/d")
        self.tempfs.writetext("/b/d/c1.txt", "hmmm")
        self.tempfs.writetext("/b/d/c2.txt", "hmmm")
        self.tempfs.writetext("/b/d/c3.txt", "hmmm")
        self.fs.remove("/b/d/c1.txt")
        self.assertEqual({"c2.txt", "c3.txt"}, set(self.fs.listdir("/b/d")))

    def test_listdir(self) -> None:
        fs = MemoryFS()
        fs.makedirs("/b$")
        fs.makedirs("/b$/dir1")
        fs.makedirs("/b$/dir2")
        fs.writetext("/b$/file1.txt", "file1")
        fs.writetext("/b$/file2.txt", "file2")
        fs.writetext("/b$/dir1/file1.txt", "file1")
        fs.writetext("/b$/dir1/file2.txt", "file2")
        fs.writetext("/b$/dir2/file1.txt", "file1")
        fs.writetext("/b$/dir2/file2.txt", "file2")

        c = COWFS(fs)
        path = "/b$/dir1/file2.txt"
        c.writetext(path, "xxxx")

        # Now the COW version is different.  But it should still have
        # the old unchanged files.

        self.assertTrue(c.exists("/b$/dir1/file1.txt"))  # Yes, but...
        self.assertEqual({"dir1", "dir2", "file1.txt", "file2.txt"},
                         set(c.listdir("/b$")))

    def test_getsyspath(self) -> None:
        dirpath = "/b$/dir1"
        self.tempfs.makedirs(dirpath)
        filepath = fs.path.join(dirpath, "foo.txt")
        self.tempfs.writetext(filepath, "original contents")

        # syspath for a filepath is the same as the syspath in the
        # basefs.
        self.assertEqual(self.fs.base_fs.getsyspath(filepath),
                         self.fs.getsyspath(filepath))

        # After writing to it, the syspath is now the same as the
        # syspath in the additions_fs.
        self.fs.writetext(filepath, "replacement contents")
        self.assertEqual(self.fs.additions_fs.getsyspath(filepath),
                         self.fs.getsyspath(filepath))

        # root raises an exception
        with self.assertRaises(fs.errors.NoSysPath):
            self.fs.getsyspath("/")
Beispiel #9
0
class COWFS(FS):
    def __init__(
        self,
        base_fs: FS,
        additions_fs: Optional[FS] = None,
        deletions_fs: Optional[FS] = None,
    ) -> None:
        FS.__init__(self)
        if additions_fs:
            self.additions_fs = additions_fs
        else:
            self.additions_fs = TempFS()

        if deletions_fs:
            _deletions_invariant(deletions_fs)
            self.deletions_fs = deletions_fs
        else:
            self.deletions_fs = TempFS()

        self.original_base_fs = base_fs
        self.base_fs = fs.wrap.read_only(base_fs)

        self.invariant()

    @staticmethod
    def create_cowfs(base_fs: FS,
                     read_write_layer: FS,
                     recreate: bool = False) -> "COWFS":
        additions_fs = read_write_layer.makedir("/additions",
                                                recreate=recreate)
        deletions_fs = read_write_layer.makedir("/deletions",
                                                recreate=recreate)

        return COWFS(base_fs, additions_fs, deletions_fs)

    def __str__(self) -> str:
        return (f"COWFS({self.original_base_fs}, "
                f"{self.additions_fs}, "
                f"{self.deletions_fs})")

    def __repr__(self) -> str:
        return (f"COWFS({self.original_base_fs!r}, "
                f"{self.additions_fs!r}, "
                f"{self.deletions_fs!r})")

    ############################################################

    def invariant(self) -> bool:
        if not self.additions_fs:
            raise ValueError(f"Invalid additions_fs: {self.additions_fs}.")
        if not self.deletions_fs:
            raise ValueError(f"Invalid deletions_fs: {self.additions_fs}.")
        if not self.base_fs:
            raise ValueError(f"Invalid base_fs: {self.base_fs}.")

        _deletions_invariant(self.deletions_fs)

        additions_paths = set(paths(self.additions_fs))
        deletions_paths = {
            fs.path.dirname(file)
            for file in self.deletions_fs.walk.files()
        }
        if additions_paths > deletions_paths:
            raise ValueError(f"Additions_paths {additions_paths} " +
                             "is not a subset of deletions_path " +
                             f"{deletions_paths}. Extras are " +
                             f"{additions_paths - deletions_paths}.")

        return True

    def is_deletion(self, path: str) -> bool:
        """
        Is the path marked in the deletions_fs"
        """
        return self.deletions_fs.exists(del_path(path))

    def mark_deletion(self, path: str) -> None:
        """
        Mark the path in the deletions_fs.
        """
        self.deletions_fs.makedirs(path, None, True)
        self.deletions_fs.touch(del_path(path))

    def makedirs_mark_deletion(
        self,
        path: str,
        permissions: Optional[Permissions] = None,
        recreate: bool = False,
    ) -> None:
        for p in fs.path.recursepath(path)[:-1]:
            self.additions_fs.makedirs(p,
                                       permissions=permissions,
                                       recreate=True)
            self.mark_deletion(p)
        self.additions_fs.makedir(path,
                                  permissions=permissions,
                                  recreate=recreate)
        self.mark_deletion(path)

    def layer(self, path: str) -> int:
        """
        Get the layer on which the file lives, or ROOT_LAYER if it's the
        root path.
        """

        if path == "/":
            return ROOT_LAYER
        if self.additions_fs.exists(path):
            return ADD_LAYER
        elif self.is_deletion(path):
            return NO_LAYER
        elif self.base_fs.exists(path):
            return BASE_LAYER
        else:
            return NO_LAYER

    def copy_up(self, path: str) -> None:
        """
        Copy the file from the base_fs to additions_fs.
        """
        self.makedirs_mark_deletion(fs.path.dirname(path))
        self.mark_deletion(path)
        fs.copy.copy_file(self.base_fs, path, self.additions_fs, path)

    def triple_tree(self) -> None:
        print("base_fs ------------------------------")
        self.base_fs.tree()
        print("additions_fs ------------------------------")
        self.additions_fs.tree()
        print("deletions_fs ------------------------------")
        self.deletions_fs.tree()

    ############################################################
    def getmeta(self, namespace: str = "standard") -> Mapping[str, object]:
        return self.base_fs.getmeta(namespace)

    def getinfo(self,
                path: str,
                namespaces: Optional[Collection[str]] = None) -> Info:
        self.check()
        self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            return self.base_fs.getinfo(path, namespaces)
        elif layer == ADD_LAYER:
            return self.additions_fs.getinfo(path, namespaces)
        elif layer == ROOT_LAYER:
            # TODO implement this
            raw_info = {}
            if namespaces is None or "basic" in namespaces:
                raw_info["basic"] = {"name": "", "is_dir": True}
            return Info(raw_info)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def getsyspath(self, path: str) -> str:
        self.check()
        # self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.NoSysPath(path=path)
        elif layer == BASE_LAYER:
            return self.base_fs.getsyspath(path)
        elif layer == ADD_LAYER:
            return self.additions_fs.getsyspath(path)
        elif layer == ROOT_LAYER:
            raise fs.errors.NoSysPath(path=path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def listdir(self, path: str) -> List[str]:
        self.check()
        self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            return [
                name for name in self.base_fs.listdir(path)
                if self.layer(fs.path.join(path, name)) != NO_LAYER
            ]
        elif layer == ADD_LAYER:
            # Get the listing on the additions layer
            names = set(self.additions_fs.listdir(path))
            # Add in the listing on the base layer (if it exists)
            if self.base_fs.isdir(path):
                names |= set(self.base_fs.listdir(path))
            # Return the entries that actually exist
            return [
                name for name in list(names)
                if self.layer(fs.path.join(path, name)) != NO_LAYER
            ]
        elif layer == ROOT_LAYER:
            # Get the listing of the root on the additions layer and
            # the base layer.
            names = set(self.additions_fs.listdir("/"))
            names |= set(self.base_fs.listdir("/"))
            # Return the entries that actually exist.
            return [
                name for name in list(names) if self.layer(name) != NO_LAYER
            ]
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def makedir(
        self,
        path: str,
        permissions: Optional[Permissions] = None,
        recreate: bool = False,
    ) -> SubFS["COWFS"]:
        self.check()
        self.validatepath(path)

        # Check if it *can* be created.

        # get a normalized parent_dir path.
        parent_dir = fs.path.dirname(fs.path.forcedir(path)[:-1])
        if not parent_dir:
            parent_dir = "/"

        if not self.isdir(parent_dir):
            raise fs.errors.ResourceNotFound(path)

        layer = self.layer(path)
        if layer == NO_LAYER:
            self.makedirs_mark_deletion(path,
                                        permissions=permissions,
                                        recreate=recreate)
            return SubFS(self, path)
        elif layer in [BASE_LAYER, ADD_LAYER, ROOT_LAYER]:
            if recreate:
                return SubFS(self, path)
            else:
                # I think this is wrong.  What if it's a file?
                raise fs.errors.DirectoryExists(path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def openbin(self,
                path: str,
                mode: str = "r",
                buffering: int = -1,
                **options: Any) -> BinaryIO:
        self.check()
        self.validatepath(path)

        parent_dir = fs.path.dirname(fs.path.forcedir(path)[:-1])
        if not parent_dir:
            parent_dir = "/"

        if not self.isdir(parent_dir):
            raise fs.errors.ResourceNotFound(path)

        mode_obj = Mode(mode)
        layer = self.layer(path)
        if layer == NO_LAYER:
            if mode_obj.create:
                for p in fs.path.recursepath(path)[:-1]:
                    self.additions_fs.makedirs(p, recreate=True)
                    self.mark_deletion(p)
                self.mark_deletion(path)
                return self.additions_fs.openbin(path, mode, buffering,
                                                 **options)
            else:
                raise fs.errors.ResourceNotFound(path)
        elif layer == ADD_LAYER:
            self.mark_deletion(path)
            return self.additions_fs.openbin(path, mode, buffering, **options)
        elif layer == BASE_LAYER:
            if mode_obj.writing:
                self.copy_up(path)
                return self.additions_fs.openbin(path, mode, buffering,
                                                 **options)
            else:
                return self.base_fs.openbin(path, mode, buffering, **options)
        elif layer == ROOT_LAYER:
            raise fs.errors.FileExpected(path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def remove(self, path: str) -> None:
        self.check()
        self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            if self.base_fs.isfile(path):
                self.mark_deletion(path)
            else:
                raise fs.errors.FileExpected(path)
        elif layer == ADD_LAYER:
            self.additions_fs.remove(path)
            self.mark_deletion(path)
        elif layer == ROOT_LAYER:
            raise fs.errors.FileExpected(path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def removedir(self, path: str) -> None:
        self.check()
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            if self.base_fs.isdir(path):
                self.mark_deletion(path)
            else:
                raise fs.errors.FileExpected(path)
        elif layer == ADD_LAYER:
            if self.additions_fs.isdir(path):
                self.additions_fs.removedir(path)
                self.mark_deletion(path)
            else:
                raise fs.errors.DirectoryExpected(path)
        elif layer == ROOT_LAYER:
            raise fs.errors.RemoveRootError(path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def setinfo(self, path: str, info: _INFO_DICT) -> None:
        self.check()
        self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            self.copy_up(path)
            self.additions_fs.setinfo(path, info)
        elif layer == ADD_LAYER:
            self.additions_fs.setinfo(path, info)
        elif layer == ROOT_LAYER:
            pass
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    ############################################################

    def makedirs(
        self,
        path: str,
        permissions: Optional[Permissions] = None,
        recreate: bool = False,
    ) -> SubFS[FS]:
        return FS.makedirs(self,
                           path,
                           permissions=permissions,
                           recreate=recreate)
Beispiel #10
0
class TestSuperMemoQAImport (TestCase):

    def setUp(self):
        TestCase.setUp(self)
        self.fs = TempFS()
        factory = m.ImportedInstanceFactory(self, field_types={    
            'question': 'html',
            'answer': 'html'                                    
        })      
        self.importer = SuperMemoQAImporter(self.fs, factory, m.HTMLMarkupImporter(self))
        self.cos = []
        self.images = []
        self.sounds = []
 
    def test_single_card(self):
        data = u"Q: question 1\nA: answer 1"
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(unicode, type(self.cos[0]['question']))
        assert_equals(unicode, type(self.cos[0]['answer']))        
        assert_equals(u"question 1", self.cos[0]['question'])
        assert_equals(u"answer 1", self.cos[0]['answer'])
        
    def test_windows_line_endings(self):
        data = u"Q: question 1\r\nA: answer 1"
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"question 1", self.cos[0]['question'])
        assert_equals(u"answer 1", self.cos[0]['answer'])
        
    def test_multiple_cards(self):
        data = """Q: question
A: answer

Q: question 2
A: answer 2"""
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(2, len(self.cos))
        assert_equals(u"question", self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])
        assert_equals(u"question 2", self.cos[1]['question'])
        assert_equals(u"answer 2", self.cos[1]['answer'])
        
    def test_content_is_right_trimmed(self):
        data = u"Q: question   \nA: answer   \n"
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"question", self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])            
 
    def test_multiline_question_and_answer(self):
        data = """Q: question
Q: end of question
A: answer
A: end of answer"""
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"question\nend of question", self.cos[0]['question'])
        assert_equals(u"answer\nend of answer", self.cos[0]['answer'])            
        
    def test_multiline_question_and_answer_lines_are_rtrimmed(self):
        data = "Q: question  \nQ: end of question  \nA: answer  \nA: end of answer  "
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"question\nend of question", self.cos[0]['question'])
        assert_equals(u"answer\nend of answer", self.cos[0]['answer'])            
 
    def test_custom_encoding(self):
        data = (u"Q: być szczerym\nA: to be frank").encode('cp1250')
        self.fs.setcontents('cards.txt', data)
        self.importer.encoding = 'cp1250'
        self.importer()        
        assert_equals(1, len(self.cos))
        assert_equals(unicode, type(self.cos[0]['question']))
        assert_equals(unicode, type(self.cos[0]['answer']))
        assert_equals(u"być szczerym", self.cos[0]['question'])
        assert_equals(u"to be frank", self.cos[0]['answer']) 
               
    def test_html_tags_are_preserved(self):
        data = """Q: hist: When did we <b>land on the moon</b>?
A: 1969 <i>(July 20)</i>"""
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(u"hist: When did we <b>land on the moon</b>?", self.cos[0]['question'])
        assert_equals(u"1969 <i>(July 20)</i>", self.cos[0]['answer'])
        
    def test_card_with_image(self):
        data = u"""Q: <img src="image.jpg" />
A: answer"""
        self.fs.setcontents('index.txt', data)
        image_data = self.data.getcontents('small.jpg')
        self.fs.setcontents('image.jpg', image_data)
        self.importer()

        assert_equals(1, len(self.cos))
        assert_equals(u'<img src="/images/image.jpg"/>', self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])

        assert_equals(1, len(self.images))
        assert_equals('image.jpg', self.images[0]['filename'])
        assert_equals('image/jpeg', self.images[0]['mime_type'])
        assert_true(image_data == self.images[0]['data'])
        
    def test_card_with_index_in_subdirectory_and_image(self):
        data = u'Q: <img src="image.jpg" />\nA: answer'
        self.fs.makedir('dir')
        self.fs.setcontents('dir/index.txt', data)
        image_data = self.data.getcontents('small.jpg')
        self.fs.setcontents('dir/image.jpg', image_data)
        self.importer()

        assert_equals(1, len(self.cos))
        assert_equals(u'<img src="/images/image.jpg"/>', self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])

        assert_equals(1, len(self.images))
        assert_equals('image.jpg', self.images[0]['filename'])
        assert_equals('image/jpeg', self.images[0]['mime_type'])
        assert_true(image_data == self.images[0]['data'])     
        
    def test_card_with_audio(self):
        data = u"""Q: <span class="audio autoplay"><a href="button.mp3" /></span>
A: answer"""
        self.fs.setcontents('index.txt', data)
                
        sound_data = self.data.getcontents('button.mp3')
        self.fs.setcontents('button.mp3', sound_data)

        self.importer()

        assert_equals(1, len(self.cos))
        assert_equals(u'<span class="audio autoplay"><a href="/sounds/button.mp3"/></span>', self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])

        assert_equals(1, len(self.sounds))
        assert_equals('button.mp3', self.sounds[0]['filename'])
        assert_equals('audio/mpeg', self.sounds[0]['mime_type'])
        assert_true(sound_data == self.sounds[0]['data'])
                       
    def test_byte_order_mark_in_utf8_files_is_removed(self):
        data = u'\ufeffQ: \uac00\uac8c\r\nA: store'
        self.fs.setcontents('index.txt', data.encode('utf8'))
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"\uac00\uac8c", self.cos[0]['question'])
        assert_equals(u"store", self.cos[0]['answer'])   
        
    def test_invalid_xml_results_in_input_error(self):
        data = u'Q: <b>question\nA: answer'
        self.fs.setcontents('index.txt', data)
        assert_raises(ConversionFailure, self.importer)        
        
    def test_invalid_fields_number_in_input_error(self):
        data = u'Q: question'
        self.fs.setcontents('index.txt', data)
        assert_raises(ConversionFailure, self.importer)                                
Beispiel #11
0
class TestSuperMemoQAImport(TestCase):
    def setUp(self):
        TestCase.setUp(self)
        self.fs = TempFS()
        factory = m.ImportedInstanceFactory(self,
                                            field_types={
                                                'question': 'html',
                                                'answer': 'html'
                                            })
        self.importer = SuperMemoQAImporter(self.fs, factory,
                                            m.HTMLMarkupImporter(self))
        self.cos = []
        self.images = []
        self.sounds = []

    def test_single_card(self):
        data = u"Q: question 1\nA: answer 1"
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(unicode, type(self.cos[0]['question']))
        assert_equals(unicode, type(self.cos[0]['answer']))
        assert_equals(u"question 1", self.cos[0]['question'])
        assert_equals(u"answer 1", self.cos[0]['answer'])

    def test_windows_line_endings(self):
        data = u"Q: question 1\r\nA: answer 1"
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"question 1", self.cos[0]['question'])
        assert_equals(u"answer 1", self.cos[0]['answer'])

    def test_multiple_cards(self):
        data = """Q: question
A: answer

Q: question 2
A: answer 2"""
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(2, len(self.cos))
        assert_equals(u"question", self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])
        assert_equals(u"question 2", self.cos[1]['question'])
        assert_equals(u"answer 2", self.cos[1]['answer'])

    def test_content_is_right_trimmed(self):
        data = u"Q: question   \nA: answer   \n"
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"question", self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])

    def test_multiline_question_and_answer(self):
        data = """Q: question
Q: end of question
A: answer
A: end of answer"""
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"question\nend of question", self.cos[0]['question'])
        assert_equals(u"answer\nend of answer", self.cos[0]['answer'])

    def test_multiline_question_and_answer_lines_are_rtrimmed(self):
        data = "Q: question  \nQ: end of question  \nA: answer  \nA: end of answer  "
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"question\nend of question", self.cos[0]['question'])
        assert_equals(u"answer\nend of answer", self.cos[0]['answer'])

    def test_custom_encoding(self):
        data = (u"Q: być szczerym\nA: to be frank").encode('cp1250')
        self.fs.setcontents('cards.txt', data)
        self.importer.encoding = 'cp1250'
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(unicode, type(self.cos[0]['question']))
        assert_equals(unicode, type(self.cos[0]['answer']))
        assert_equals(u"być szczerym", self.cos[0]['question'])
        assert_equals(u"to be frank", self.cos[0]['answer'])

    def test_html_tags_are_preserved(self):
        data = """Q: hist: When did we <b>land on the moon</b>?
A: 1969 <i>(July 20)</i>"""
        self.fs.setcontents('cards.txt', data)
        self.importer()
        assert_equals(u"hist: When did we <b>land on the moon</b>?",
                      self.cos[0]['question'])
        assert_equals(u"1969 <i>(July 20)</i>", self.cos[0]['answer'])

    def test_card_with_image(self):
        data = u"""Q: <img src="image.jpg" />
A: answer"""
        self.fs.setcontents('index.txt', data)
        image_data = self.data.getcontents('small.jpg')
        self.fs.setcontents('image.jpg', image_data)
        self.importer()

        assert_equals(1, len(self.cos))
        assert_equals(u'<img src="/images/image.jpg"/>',
                      self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])

        assert_equals(1, len(self.images))
        assert_equals('image.jpg', self.images[0]['filename'])
        assert_equals('image/jpeg', self.images[0]['mime_type'])
        assert_true(image_data == self.images[0]['data'])

    def test_card_with_index_in_subdirectory_and_image(self):
        data = u'Q: <img src="image.jpg" />\nA: answer'
        self.fs.makedir('dir')
        self.fs.setcontents('dir/index.txt', data)
        image_data = self.data.getcontents('small.jpg')
        self.fs.setcontents('dir/image.jpg', image_data)
        self.importer()

        assert_equals(1, len(self.cos))
        assert_equals(u'<img src="/images/image.jpg"/>',
                      self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])

        assert_equals(1, len(self.images))
        assert_equals('image.jpg', self.images[0]['filename'])
        assert_equals('image/jpeg', self.images[0]['mime_type'])
        assert_true(image_data == self.images[0]['data'])

    def test_card_with_audio(self):
        data = u"""Q: <span class="audio autoplay"><a href="button.mp3" /></span>
A: answer"""
        self.fs.setcontents('index.txt', data)

        sound_data = self.data.getcontents('button.mp3')
        self.fs.setcontents('button.mp3', sound_data)

        self.importer()

        assert_equals(1, len(self.cos))
        assert_equals(
            u'<span class="audio autoplay"><a href="/sounds/button.mp3"/></span>',
            self.cos[0]['question'])
        assert_equals(u"answer", self.cos[0]['answer'])

        assert_equals(1, len(self.sounds))
        assert_equals('button.mp3', self.sounds[0]['filename'])
        assert_equals('audio/mpeg', self.sounds[0]['mime_type'])
        assert_true(sound_data == self.sounds[0]['data'])

    def test_byte_order_mark_in_utf8_files_is_removed(self):
        data = u'\ufeffQ: \uac00\uac8c\r\nA: store'
        self.fs.setcontents('index.txt', data.encode('utf8'))
        self.importer()
        assert_equals(1, len(self.cos))
        assert_equals(u"\uac00\uac8c", self.cos[0]['question'])
        assert_equals(u"store", self.cos[0]['answer'])

    def test_invalid_xml_results_in_input_error(self):
        data = u'Q: <b>question\nA: answer'
        self.fs.setcontents('index.txt', data)
        assert_raises(ConversionFailure, self.importer)

    def test_invalid_fields_number_in_input_error(self):
        data = u'Q: question'
        self.fs.setcontents('index.txt', data)
        assert_raises(ConversionFailure, self.importer)