Exemple #1
0
    def test_help_output(self):
        err, out = StringIO(), StringIO()
        cmd = EmptyCmd(
            err=err,
            out=out,
            environ={},
            list_volumes=no_volumes,
            now=None,
            file_reader=FileSystemReader(),
            getuid=None,
            file_remover=None,
            version=None,
        )
        cmd.run('trash-empty', '--help')
        assert_equal(
            out.getvalue(),
            dedent("""\
            Usage: trash-empty [days]

            Purge trashed files.

            Options:
              --version   show program's version number and exit
              -h, --help  show this help message and exit

            Report bugs to https://github.com/andreafrancia/trash-cli/issues
            """))
Exemple #2
0
class TestEmpty_on_invalid_option(unittest.TestCase):
    def setUp(self):
        self.err, self.out = StringIO(), StringIO()
        self.cmd = EmptyCmd(
            err=self.err,
            out=self.out,
            environ={},
            list_volumes=no_volumes,
            now=None,
            file_reader=FileSystemReader(),
            getuid=None,
            file_remover=None,
            version=None,
        )

    def test_it_should_fail(self):
        self.exit_code = self.cmd.run('trash-empty', '-2')

        exit_code_for_command_line_usage = 64
        assert exit_code_for_command_line_usage == self.exit_code

    def test_it_should_complain_to_the_standard_error(self):
        self.exit_code = self.cmd.run('trash-empty', '-2')

        assert self.err.getvalue() == dedent("""\
                trash-empty: invalid option -- '2'
                """)

    def test_with_a_different_option(self):
        self.cmd.run('trash-empty', '-3')

        assert self.err.getvalue() == dedent("""\
                trash-empty: invalid option -- '3'
                """)
class TestTrashEmptyCmd(unittest.TestCase):
    def setUp(self):
        self.tmp_dir = MyPath.make_temp_dir()
        self.unreadable_dir = self.tmp_dir / 'data/Trash/files/unreadable'
        self.volumes_listing = Mock(spec=VolumesListing)
        self.volumes_listing.list_volumes.return_value = [self.unreadable_dir]
        self.err=StringIO()
        self.empty = EmptyCmd(
            out=StringIO(),
            err=self.err,
            environ={'XDG_DATA_HOME':self.tmp_dir / 'data'},
            volumes_listing=self.volumes_listing,
            now=None,
            file_reader=FileSystemReader(),
            getuid=lambda: 123,
            file_remover=FileRemover(),
            version=None,
            volume_of=lambda x: "volume_of %s" % x
        )

    def test_trash_empty_will_skip_unreadable_dir(self):
        make_unreadable_dir(self.unreadable_dir)

        self.empty.run('trash-empty')

        assert ("trash-empty: cannot remove %s\n"  % self.unreadable_dir ==
                     self.err.getvalue())

    def tearDown(self):
        make_readable(self.unreadable_dir)
        self.tmp_dir.clean_up()
Exemple #4
0
    def setUp(self):
        self.empty_all_trashdirs = Mock()
        self.empty_trashdir = Mock()

        self.cmd = EmptyCmd(None, None, None, None, None, None, None, None,
                            None)
        self.cmd.empty_all_trashdirs = self.empty_all_trashdirs
        self.cmd.empty_trashdir = self.empty_trashdir
 def setUp(self):
     require_empty_dir('topdir')
     self.empty=EmptyCmd(
             out          = StringIO(),
             err          = StringIO(),
             environ      = {},
             list_volumes = lambda: ['topdir'],
             now          = None,
             file_reader  = FileSystemReader(),
             getuid       = lambda: 123,
             file_remover = FileRemover(),
             version      = None,
     )
 def setUp(self):
     self.err, self.out = StringIO(), StringIO()
     self.cmd = EmptyCmd(
                    err = self.err,
                    out = self.out,
                    environ = {},
                    list_volumes = no_volumes,
                    now = None,
                    file_reader = FileSystemReader(),
                    getuid = None,
                    file_remover = None,
                    version = None,
                    )
Exemple #7
0
 def setUp(self):
     self.temp_dir = MyPath.make_temp_dir()
     self.top_dir = self.temp_dir / 'topdir'
     require_empty_dir(self.top_dir)
     self.empty = EmptyCmd(
         out=StringIO(),
         err=StringIO(),
         environ={},
         list_volumes=lambda: [self.top_dir],
         now=None,
         file_reader=FileSystemReader(),
         getuid=lambda: 123,
         file_remover=FileRemover(),
         version=None,
     )
    def test_trash_empty_last_line(self):
        from trashcli.empty import EmptyCmd
        from trashcli.trash import FileSystemReader

        cmd = EmptyCmd(self.out, StringIO(), [], lambda:[],
                       now = None,
                       file_reader = FileSystemReader(),
                       getuid = None,
                       file_remover = None,
                       version = None,
                       )
        cmd.run('', '--help')

        self.assert_last_line_of_output_is(
                'Report bugs to https://github.com/andreafrancia/trash-cli/issues')
    def setUp(self):
        self.empty_all_trashdirs = Mock()
        self.empty_trashdir = Mock()

        self.cmd = EmptyCmd(None, None, None, None, None, None, None, None, None)
        self.cmd.empty_all_trashdirs = self.empty_all_trashdirs
        self.cmd.empty_trashdir = self.empty_trashdir
 def test_it_print_version(self):
     err, out = StringIO(), StringIO()
     cmd = EmptyCmd(err = err,
                    out = out,
                    environ = {},
                    list_volumes = no_volumes,
                    now = None,
                    file_reader = FileSystemReader(),
                    getuid = None,
                    file_remover = None,
                    version = '1.2.3',
                    )
     cmd.run('trash-empty', '--version')
     assert_equals(out.getvalue(), dedent("""\
         trash-empty 1.2.3
         """))
 def setUp(self):
     require_empty_dir('XDG_DATA_HOME')
     self.xdg_data_home   = 'XDG_DATA_HOME'
     self.environ = {'XDG_DATA_HOME':'XDG_DATA_HOME'}
     self.now = MagicMock(side_effect=RuntimeError)
     self.empty_cmd=EmptyCmd(
         out = StringIO(),
         err = StringIO(),
         environ = self.environ,
         list_volumes = no_volumes,
         now = self.now,
         file_reader = FileSystemReader(),
         getuid = None,
         file_remover = FileRemover(),
         version = None,
     )
 def test_it_print_version(self):
     err, out = StringIO(), StringIO()
     cmd = EmptyCmd(err = err,
                    out = out,
                    environ = {},
                    list_volumes = no_volumes,
                    now = None,
                    file_reader = FileSystemReader(),
                    getuid = None,
                    file_remover = None,
                    version = '1.2.3',
                    )
     cmd.run('trash-empty', '--version')
     assert_equal(out.getvalue(), dedent("""\
         trash-empty 1.2.3
         """))
 def setUp(self):
     require_empty_dir('XDG_DATA_HOME')
     self.info_dir_path   = 'XDG_DATA_HOME/Trash/info'
     self.files_dir_path  = 'XDG_DATA_HOME/Trash/files'
     self.environ = {'XDG_DATA_HOME':'XDG_DATA_HOME'}
     now = MagicMock(side_effect=RuntimeError)
     self.empty_cmd = EmptyCmd(
         out = StringIO(),
         err = StringIO(),
         environ = self.environ,
         list_volumes = no_volumes,
         now = now,
         file_reader = FileSystemReader(),
         getuid = None,
         file_remover = FileRemover(),
         version = None,
     )
 def setUp(self):
     self.temp_dir = MyPath.make_temp_dir()
     self.top_dir = self.temp_dir / 'topdir'
     self.volumes_listing = Mock(spec=VolumesListing)
     self.volumes_listing.list_volumes.return_value = [self.top_dir]
     require_empty_dir(self.top_dir)
     self.empty = EmptyCmd(
         out=StringIO(),
         err=StringIO(),
         environ={},
         volumes_listing=self.volumes_listing,
         now=None,
         file_reader=FileSystemReader(),
         getuid=lambda: 123,
         file_remover=FileRemover(),
         version=None,
         volume_of=lambda x: "volume_of %s" % x
     )
 def setUp(self):
     self.tmp_dir = MyPath.make_temp_dir()
     self.unreadable_dir = self.tmp_dir / 'data/Trash/files/unreadable'
     self.volumes_listing = Mock(spec=VolumesListing)
     self.volumes_listing.list_volumes.return_value = [self.unreadable_dir]
     self.err=StringIO()
     self.empty = EmptyCmd(
         out=StringIO(),
         err=self.err,
         environ={'XDG_DATA_HOME':self.tmp_dir / 'data'},
         volumes_listing=self.volumes_listing,
         now=None,
         file_reader=FileSystemReader(),
         getuid=lambda: 123,
         file_remover=FileRemover(),
         version=None,
         volume_of=lambda x: "volume_of %s" % x
     )
    def test_trash_empty_last_line(self):
        from trashcli.empty import EmptyCmd
        from trashcli.fs import FileSystemReader

        cmd = EmptyCmd(
            self.out,
            StringIO(),
            [],
            lambda: [],
            now=None,
            file_reader=FileSystemReader(),
            getuid=None,
            file_remover=None,
            version=None,
        )
        cmd.run('', '--help')

        self.assert_last_line_of_output_is(
            'Report bugs to https://github.com/andreafrancia/trash-cli/issues')
Exemple #17
0
class TestTrashEmptyCmd:
    def setUp(self):
        self.empty_all_trashdirs = Mock()
        self.empty_trashdir = Mock()

        self.cmd = EmptyCmd(None, None, None, None, None, None, None, None, None)
        self.cmd.empty_all_trashdirs = self.empty_all_trashdirs
        self.cmd.empty_trashdir = self.empty_trashdir

    def test_default_behaviour_is_emtpy_all_trashdirs(self):
        self.cmd.run('trash-empty')

        assert_equals([call()], self.empty_all_trashdirs.mock_calls)
        assert_equals([], self.empty_trashdir.mock_calls)

    def test(self):
        self.cmd.run('trash-empty', '--trash-dir', 'specific')

        assert_equals([], self.empty_all_trashdirs.mock_calls)
        assert_equals([call('specific')], self.empty_trashdir.mock_calls)
Exemple #18
0
class TestTrashEmptyCmd:
    def setUp(self):
        self.empty_all_trashdirs = Mock()
        self.empty_trashdir = Mock()

        self.cmd = EmptyCmd(None, None, None, None, None, None, None, None,
                            None)
        self.cmd.empty_all_trashdirs = self.empty_all_trashdirs
        self.cmd.empty_trashdir = self.empty_trashdir

    def test_default_behaviour_is_emtpy_all_trashdirs(self):
        self.cmd.run('trash-empty')

        assert_equals([call()], self.empty_all_trashdirs.mock_calls)
        assert_equals([], self.empty_trashdir.mock_calls)

    def test(self):
        self.cmd.run('trash-empty', '--trash-dir', 'specific')

        assert_equals([], self.empty_all_trashdirs.mock_calls)
        assert_equals([call('specific')], self.empty_trashdir.mock_calls)
Exemple #19
0
class TestTrashEmptyCmd(unittest.TestCase):
    def setUp(self):
        self.empty_all_trashdirs = Mock()
        self.empty_trashdir = Mock()

        self.cmd = EmptyCmd(None, None, None, None, None, None, None, None,
                            None)
        self.cmd.empty_all_trashdirs = self.empty_all_trashdirs
        self.cmd.empty_trashdir = self.empty_trashdir

    def test_default_behaviour_is_emtpy_all_trashdirs(self):
        self.cmd.run('trash-empty')

        assert [call()] == self.empty_all_trashdirs.mock_calls
        assert [] == self.empty_trashdir.mock_calls

    def test(self):
        self.cmd.run('trash-empty', '--trash-dir', 'specific')

        assert [] == self.empty_all_trashdirs.mock_calls
        assert [call('specific')] == self.empty_trashdir.mock_calls
 def setUp(self):
     self.err, self.out = StringIO(), StringIO()
     self.cmd = EmptyCmd(
                    err = self.err,
                    out = self.out,
                    environ = {},
                    list_volumes = no_volumes,
                    now = None,
                    file_reader = FileSystemReader(),
                    getuid = None,
                    file_remover = None,
                    version = None,
                    )
 def setUp(self):
     require_empty_dir('topdir')
     self.empty=EmptyCmd(
             out          = StringIO(),
             err          = StringIO(),
             environ      = {},
             list_volumes = lambda: ['topdir'],
             now          = None,
             file_reader  = FileSystemReader(),
             getuid       = lambda: 123,
             file_remover = FileRemover(),
             version      = None,
     )
class describe_trash_empty_command_line__on_invalid_options():
    def setUp(self):
        self.err, self.out = StringIO(), StringIO()
        self.cmd = EmptyCmd(
                       err = self.err,
                       out = self.out,
                       environ = {},
                       list_volumes = no_volumes,
                       now = None,
                       file_reader = FileSystemReader(),
                       getuid = None,
                       file_remover = None,
                       version = None,
                       )

    def it_should_fail(self):

        self.exit_code = self.cmd.run('trash-empty', '-2')

        exit_code_for_command_line_usage = 64
        assert_equals(exit_code_for_command_line_usage, self.exit_code)

    def it_should_complain_to_the_standard_error(self):

        self.exit_code = self.cmd.run('trash-empty', '-2')

        assert_equals(self.err.getvalue(), dedent("""\
                trash-empty: invalid option -- '2'
                """))

    def test_with_a_different_option(self):

        self.cmd.run('trash-empty', '-3')

        assert_equals(self.err.getvalue(), dedent("""\
                trash-empty: invalid option -- '3'
                """))
class TestTrashEmpty_on_help(unittest.TestCase):
    def setUp(self):
        self.err, self.out = StringIO(), StringIO()
        self.cmd = EmptyCmd(
            err=self.err,
            out=self.out,
            environ={},
            list_volumes=no_volumes,
            now=None,
            file_reader=FileSystemReader(),
            getuid=None,
            file_remover=None,
            version=None,
        )

    def test_help_output(self):

        self.cmd.run('trash-empty', '--help')

        assert self.out.getvalue() == dedent("""\
            Usage: trash-empty [days]

            Purge trashed files.

            Options:
              --version   show program's version number and exit
              -h, --help  show this help message and exit

            Report bugs to https://github.com/andreafrancia/trash-cli/issues
            """)

    def test(self):

        self.cmd.run('trash-empty', '-h')

        six.assertRegex(self, self.out.getvalue(), '^Usage. trash-empty.*')
    def test_help_output(self):
        err, out = StringIO(), StringIO()
        cmd = EmptyCmd(err = err,
                       out = out,
                       environ = {},
                       list_volumes = no_volumes,
                       now = None,
                       file_reader = FileSystemReader(),
                       getuid = None,
                       file_remover = None,
                       version = None,
                       )
        cmd.run('trash-empty', '--help')
        assert_equals(out.getvalue(), dedent("""\
            Usage: trash-empty [days]

            Purge trashed files.

            Options:
              --version   show program's version number and exit
              -h, --help  show this help message and exit

            Report bugs to https://github.com/andreafrancia/trash-cli/issues
            """))
 def setUp(self):
     require_empty_dir('XDG_DATA_HOME')
     self.xdg_data_home   = 'XDG_DATA_HOME'
     self.environ = {'XDG_DATA_HOME':'XDG_DATA_HOME'}
     self.now = MagicMock(side_effect=RuntimeError)
     self.empty_cmd=EmptyCmd(
         out = StringIO(),
         err = StringIO(),
         environ = self.environ,
         list_volumes = no_volumes,
         now = self.now,
         file_reader = FileSystemReader(),
         getuid = None,
         file_remover = FileRemover(),
         version = None,
     )
 def setUp(self):
     require_empty_dir('XDG_DATA_HOME')
     self.info_dir_path   = 'XDG_DATA_HOME/Trash/info'
     self.files_dir_path  = 'XDG_DATA_HOME/Trash/files'
     self.environ = {'XDG_DATA_HOME':'XDG_DATA_HOME'}
     now = MagicMock(side_effect=RuntimeError)
     self.empty_cmd = EmptyCmd(
         out = StringIO(),
         err = StringIO(),
         environ = self.environ,
         list_volumes = no_volumes,
         now = now,
         file_reader = FileSystemReader(),
         getuid = None,
         file_remover = FileRemover(),
         version = None,
     )
class TestEmptyCmdWithMultipleVolumes(unittest.TestCase):
    def setUp(self):
        self.temp_dir = MyPath.make_temp_dir()
        self.top_dir = self.temp_dir / 'topdir'
        self.volumes_listing = Mock(spec=VolumesListing)
        self.volumes_listing.list_volumes.return_value = [self.top_dir]
        require_empty_dir(self.top_dir)
        self.empty = EmptyCmd(
            out=StringIO(),
            err=StringIO(),
            environ={},
            volumes_listing=self.volumes_listing,
            now=None,
            file_reader=FileSystemReader(),
            getuid=lambda: 123,
            file_remover=FileRemover(),
            version=None,
            volume_of=lambda x: "volume_of %s" % x
        )

    def test_it_removes_trashinfos_from_method_1_dir(self):
        self.make_proper_top_trash_dir(self.top_dir / '.Trash')
        make_empty_file(self.top_dir / '.Trash/123/info/foo.trashinfo')

        self.empty.run('trash-empty')

        assert not os.path.exists(
            self.top_dir / '.Trash/123/info/foo.trashinfo')
    def test_it_removes_trashinfos_from_method_2_dir(self):
        make_empty_file(self.top_dir / '.Trash-123/info/foo.trashinfo')

        self.empty.run('trash-empty')

        assert not os.path.exists(
            self.top_dir / '.Trash-123/info/foo.trashinfo')

    def test_it_removes_trashinfo_from_specified_trash_dir(self):
        make_empty_file(self.temp_dir / 'specified/info/foo.trashinfo')

        self.empty.run('trash-empty', '--trash-dir',
                       self.temp_dir / 'specified')

        assert not os.path.exists(
            self.temp_dir / 'specified/info/foo.trashinfo')


    def make_proper_top_trash_dir(self, path):
        make_dirs(path)
        set_sticky_bit(path)

    def tearDown(self):
        self.temp_dir.clean_up()
def empty(argv=sys.argv,
          stdout=sys.stdout,
          stderr=sys.stderr,
          environ=os.environ):
    from trashcli.empty import EmptyCmd
    from trashcli.list_mount_points import mount_points
    from datetime import datetime
    from trashcli.trash import FileSystemReader
    from trashcli.fs import FileRemover
    from trashcli.trash import version
    return EmptyCmd(
        out=stdout,
        err=stderr,
        environ=environ,
        list_volumes=mount_points,
        now=datetime.now,
        file_reader=FileSystemReader(),
        getuid=os.getuid,
        file_remover=FileRemover(),
        version=version,
    ).run(*argv)
class TestEmptyCmdWithMultipleVolumes:
    def setUp(self):
        require_empty_dir('topdir')
        self.empty=EmptyCmd(
                out          = StringIO(),
                err          = StringIO(),
                environ      = {},
                list_volumes = lambda: ['topdir'],
                now          = None,
                file_reader  = FileSystemReader(),
                getuid       = lambda: 123,
                file_remover = FileRemover(),
                version      = None,
        )

    def test_it_removes_trashinfos_from_method_1_dir(self):
        self.make_proper_top_trash_dir('topdir/.Trash')
        having_file('topdir/.Trash/123/info/foo.trashinfo')

        self.empty.run('trash-empty')

        assert not os.path.exists('topdir/.Trash/123/info/foo.trashinfo')
    def test_it_removes_trashinfos_from_method_2_dir(self):
        having_file('topdir/.Trash-123/info/foo.trashinfo')

        self.empty.run('trash-empty')

        assert not os.path.exists('topdir/.Trash-123/info/foo.trashinfo')

    def test_it_removes_trashinfo_from_specified_trash_dir(self):
        having_file('specified/info/foo.trashinfo')

        self.empty.run('trash-empty', '--trash-dir', 'specified')

        assert not os.path.exists('specified/info/foo.trashinfo')


    def make_proper_top_trash_dir(self, path):
        make_dirs(path)
        set_sticky_bit(path)
class TestEmptyCmdWithMultipleVolumes:
    def setUp(self):
        require_empty_dir('topdir')
        self.empty=EmptyCmd(
                out          = StringIO(),
                err          = StringIO(),
                environ      = {},
                list_volumes = lambda: ['topdir'],
                now          = None,
                file_reader  = FileSystemReader(),
                getuid       = lambda: 123,
                file_remover = FileRemover(),
                version      = None,
        )

    def test_it_removes_trashinfos_from_method_1_dir(self):
        self.make_proper_top_trash_dir('topdir/.Trash')
        make_empty_file('topdir/.Trash/123/info/foo.trashinfo')

        self.empty.run('trash-empty')

        assert not os.path.exists('topdir/.Trash/123/info/foo.trashinfo')
    def test_it_removes_trashinfos_from_method_2_dir(self):
        make_empty_file('topdir/.Trash-123/info/foo.trashinfo')

        self.empty.run('trash-empty')

        assert not os.path.exists('topdir/.Trash-123/info/foo.trashinfo')

    def test_it_removes_trashinfo_from_specified_trash_dir(self):
        make_empty_file('specified/info/foo.trashinfo')

        self.empty.run('trash-empty', '--trash-dir', 'specified')

        assert not os.path.exists('specified/info/foo.trashinfo')


    def make_proper_top_trash_dir(self, path):
        make_dirs(path)
        set_sticky_bit(path)
class When_invoked_with_N_days_as_argument:
    def setUp(self):
        require_empty_dir('XDG_DATA_HOME')
        self.xdg_data_home   = 'XDG_DATA_HOME'
        self.environ = {'XDG_DATA_HOME':'XDG_DATA_HOME'}
        self.now = MagicMock(side_effect=RuntimeError)
        self.empty_cmd=EmptyCmd(
            out = StringIO(),
            err = StringIO(),
            environ = self.environ,
            list_volumes = no_volumes,
            now = self.now,
            file_reader = FileSystemReader(),
            getuid = None,
            file_remover = FileRemover(),
            version = None,
        )

    def user_run_trash_empty(self, *args):
        self.empty_cmd.run('trash-empty', *args)

    def set_clock_at(self, yyyy_mm_dd):
        self.now.side_effect = lambda:date(yyyy_mm_dd)

        def date(yyyy_mm_dd):
            from datetime import datetime
            return datetime.strptime(yyyy_mm_dd, '%Y-%m-%d')

    @istest
    def it_should_keep_files_newer_than_N_days(self):
        self.having_a_trashed_file('foo', '2000-01-01')
        self.set_clock_at('2000-01-01')

        self.user_run_trash_empty('2')

        self.file_should_have_been_kept_in_trashcan('foo')

    @istest
    def it_should_remove_files_older_than_N_days(self):
        self.having_a_trashed_file('foo', '1999-01-01')
        self.set_clock_at('2000-01-01')

        self.user_run_trash_empty('2')

        self.file_should_have_been_removed_from_trashcan('foo')

    @istest
    def it_should_kept_files_with_invalid_deletion_date(self):
        self.having_a_trashed_file('foo', 'Invalid Date')
        self.set_clock_at('2000-01-01')

        self.user_run_trash_empty('2')

        self.file_should_have_been_kept_in_trashcan('foo')

    def having_a_trashed_file(self, name, date):
        contents = "DeletionDate=%sT00:00:00\n" % date
        make_file(self.trashinfo(name), contents)

    def trashinfo(self, name):
        return '%(dirname)s/Trash/info/%(name)s.trashinfo' % {
                    'dirname' : self.xdg_data_home,
                    'name'    : name }

    def file_should_have_been_kept_in_trashcan(self, trashinfo_name):
        assert os.path.exists(self.trashinfo(trashinfo_name))
    def file_should_have_been_removed_from_trashcan(self, trashinfo_name):
        assert not os.path.exists(self.trashinfo(trashinfo_name))
class TestWhenCalledWithoutArguments:

    def setUp(self):
        require_empty_dir('XDG_DATA_HOME')
        self.info_dir_path   = 'XDG_DATA_HOME/Trash/info'
        self.files_dir_path  = 'XDG_DATA_HOME/Trash/files'
        self.environ = {'XDG_DATA_HOME':'XDG_DATA_HOME'}
        now = MagicMock(side_effect=RuntimeError)
        self.empty_cmd = EmptyCmd(
            out = StringIO(),
            err = StringIO(),
            environ = self.environ,
            list_volumes = no_volumes,
            now = now,
            file_reader = FileSystemReader(),
            getuid = None,
            file_remover = FileRemover(),
            version = None,
        )

    def user_run_trash_empty(self):
        self.empty_cmd.run('trash-empty')

    def test_it_should_remove_an_info_file(self):
        self.having_a_trashinfo_in_trashcan('foo.trashinfo')

        self.user_run_trash_empty()

        self.assert_dir_empty(self.info_dir_path)

    def test_it_should_remove_all_the_infofiles(self):
        self.having_three_trashinfo_in_trashcan()

        self.user_run_trash_empty()

        self.assert_dir_empty(self.info_dir_path)

    def test_it_should_remove_the_backup_files(self):
        self.having_one_trashed_file()

        self.user_run_trash_empty()

        self.assert_dir_empty(self.files_dir_path)

    def test_it_should_keep_unknown_files_found_in_infodir(self):
        self.having_file_in_info_dir('not-a-trashinfo')

        self.user_run_trash_empty()

        self.assert_dir_contains(self.info_dir_path, 'not-a-trashinfo')

    def test_but_it_should_remove_orphan_files_from_the_files_dir(self):
        self.having_orphan_file_in_files_dir()

        self.user_run_trash_empty()

        self.assert_dir_empty(self.files_dir_path)

    def test_it_should_purge_also_directories(self):
        os.makedirs("XDG_DATA_HOME/Trash/files/a-dir")

        self.user_run_trash_empty()

        self.assert_dir_empty(self.files_dir_path)

    def assert_dir_empty(self, path):
        assert len(os.listdir(path)) == 0

    def assert_dir_contains(self, path, filename):
        assert os.path.exists(os.path.join(path, filename))

    def having_a_trashinfo_in_trashcan(self, basename_of_trashinfo):
        make_empty_file(os.path.join(self.info_dir_path, basename_of_trashinfo))

    def having_three_trashinfo_in_trashcan(self):
        self.having_a_trashinfo_in_trashcan('foo.trashinfo')
        self.having_a_trashinfo_in_trashcan('bar.trashinfo')
        self.having_a_trashinfo_in_trashcan('baz.trashinfo')
        assert_items_equal(['foo.trashinfo',
                            'bar.trashinfo',
                            'baz.trashinfo'], os.listdir(self.info_dir_path))

    def having_one_trashed_file(self):
        self.having_a_trashinfo_in_trashcan('foo.trashinfo')
        make_empty_file(self.files_dir_path + '/foo')
        self.files_dir_should_not_be_empty()

    def files_dir_should_not_be_empty(self):
        assert len(os.listdir(self.files_dir_path)) != 0

    def having_file_in_info_dir(self, filename):
        make_empty_file(os.path.join(self.info_dir_path, filename))

    def having_orphan_file_in_files_dir(self):
        complete_path = os.path.join(self.files_dir_path,
                                     'a-file-without-any-associated-trashinfo')
        make_empty_file(complete_path)
        assert os.path.exists(complete_path)
class When_invoked_with_N_days_as_argument:
    def setUp(self):
        require_empty_dir('XDG_DATA_HOME')
        self.xdg_data_home   = 'XDG_DATA_HOME'
        self.environ = {'XDG_DATA_HOME':'XDG_DATA_HOME'}
        self.now = MagicMock(side_effect=RuntimeError)
        self.empty_cmd=EmptyCmd(
            out = StringIO(),
            err = StringIO(),
            environ = self.environ,
            list_volumes = no_volumes,
            now = self.now,
            file_reader = FileSystemReader(),
            getuid = None,
            file_remover = FileRemover(),
            version = None,
        )

    def user_run_trash_empty(self, *args):
        self.empty_cmd.run('trash-empty', *args)

    def set_clock_at(self, yyyy_mm_dd):
        self.now.side_effect = lambda:date(yyyy_mm_dd)

        def date(yyyy_mm_dd):
            from datetime import datetime
            return datetime.strptime(yyyy_mm_dd, '%Y-%m-%d')

    @istest
    def it_should_keep_files_newer_than_N_days(self):
        self.having_a_trashed_file('foo', '2000-01-01')
        self.set_clock_at('2000-01-01')

        self.user_run_trash_empty('2')

        self.file_should_have_been_kept_in_trashcan('foo')

    @istest
    def it_should_remove_files_older_than_N_days(self):
        self.having_a_trashed_file('foo', '1999-01-01')
        self.set_clock_at('2000-01-01')

        self.user_run_trash_empty('2')

        self.file_should_have_been_removed_from_trashcan('foo')

    @istest
    def it_should_kept_files_with_invalid_deletion_date(self):
        self.having_a_trashed_file('foo', 'Invalid Date')
        self.set_clock_at('2000-01-01')

        self.user_run_trash_empty('2')

        self.file_should_have_been_kept_in_trashcan('foo')

    def having_a_trashed_file(self, name, date):
        contents = "DeletionDate=%sT00:00:00\n" % date
        write_file(self.trashinfo(name), contents)

    def trashinfo(self, name):
        return '%(dirname)s/Trash/info/%(name)s.trashinfo' % {
                    'dirname' : self.xdg_data_home,
                    'name'    : name }

    def file_should_have_been_kept_in_trashcan(self, trashinfo_name):
        assert os.path.exists(self.trashinfo(trashinfo_name))
    def file_should_have_been_removed_from_trashcan(self, trashinfo_name):
        assert not os.path.exists(self.trashinfo(trashinfo_name))
class TestWhenCalledWithoutArguments:

    def setUp(self):
        require_empty_dir('XDG_DATA_HOME')
        self.info_dir_path   = 'XDG_DATA_HOME/Trash/info'
        self.files_dir_path  = 'XDG_DATA_HOME/Trash/files'
        self.environ = {'XDG_DATA_HOME':'XDG_DATA_HOME'}
        now = MagicMock(side_effect=RuntimeError)
        self.empty_cmd = EmptyCmd(
            out = StringIO(),
            err = StringIO(),
            environ = self.environ,
            list_volumes = no_volumes,
            now = now,
            file_reader = FileSystemReader(),
            getuid = None,
            file_remover = FileRemover(),
            version = None,
        )

    def user_run_trash_empty(self):
        self.empty_cmd.run('trash-empty')

    def test_it_should_remove_an_info_file(self):
        self.having_a_trashinfo_in_trashcan('foo.trashinfo')

        self.user_run_trash_empty()

        self.assert_dir_empty(self.info_dir_path)

    def test_it_should_remove_all_the_infofiles(self):
        self.having_three_trashinfo_in_trashcan()

        self.user_run_trash_empty()

        self.assert_dir_empty(self.info_dir_path)

    def test_it_should_remove_the_backup_files(self):
        self.having_one_trashed_file()

        self.user_run_trash_empty()

        self.assert_dir_empty(self.files_dir_path)

    def test_it_should_keep_unknown_files_found_in_infodir(self):
        self.having_file_in_info_dir('not-a-trashinfo')

        self.user_run_trash_empty()

        self.assert_dir_contains(self.info_dir_path, 'not-a-trashinfo')

    def test_but_it_should_remove_orphan_files_from_the_files_dir(self):
        self.having_orphan_file_in_files_dir()

        self.user_run_trash_empty()

        self.assert_dir_empty(self.files_dir_path)

    def test_it_should_purge_also_directories(self):
        os.makedirs("XDG_DATA_HOME/Trash/files/a-dir")

        self.user_run_trash_empty()

        self.assert_dir_empty(self.files_dir_path)

    def assert_dir_empty(self, path):
        assert len(os.listdir(path)) == 0

    def assert_dir_contains(self, path, filename):
        assert os.path.exists(os.path.join(path, filename))

    def having_a_trashinfo_in_trashcan(self, basename_of_trashinfo):
        having_file(os.path.join(self.info_dir_path, basename_of_trashinfo))

    def having_three_trashinfo_in_trashcan(self):
        self.having_a_trashinfo_in_trashcan('foo.trashinfo')
        self.having_a_trashinfo_in_trashcan('bar.trashinfo')
        self.having_a_trashinfo_in_trashcan('baz.trashinfo')
        assert_items_equal(['foo.trashinfo',
                            'bar.trashinfo',
                            'baz.trashinfo'], os.listdir(self.info_dir_path))

    def having_one_trashed_file(self):
        self.having_a_trashinfo_in_trashcan('foo.trashinfo')
        having_file(self.files_dir_path +'/foo')
        self.files_dir_should_not_be_empty()

    def files_dir_should_not_be_empty(self):
        assert len(os.listdir(self.files_dir_path)) != 0

    def having_file_in_info_dir(self, filename):
        having_file(os.path.join(self.info_dir_path, filename))

    def having_orphan_file_in_files_dir(self):
        complete_path = os.path.join(self.files_dir_path,
                                     'a-file-without-any-associated-trashinfo')
        having_file(complete_path)
        assert os.path.exists(complete_path)