from threading import Lock

from unittesting import DeferrableTestCase
from SublimeLinter.tests.mockito import unstub, verify, when

import sublime
from SublimeLinter import sublime_linter
from SublimeLinter.lint import Linter, persist


class TestLinterElection(DeferrableTestCase):
    @classmethod
    def setUpClass(cls):

        # make sure we have a window to work with
        s = sublime.load_settings("Preferences.sublime-settings")
        s.set("close_windows_when_empty", False)

    @classmethod
    def tearDownClass(cls):
        unstub()

    def setUp(self):
        sublime.run_command("new_window")
        self.window = sublime.active_window()

    def tearDown(self):
        self.window.run_command('close_window')
        persist.linter_classes.clear()
        unstub()

    def create_view(self, window):
        view = window.new_file()
        self.addCleanup(self.close_view, view)
        return view

    def close_view(self, view):
        view.set_scratch(True)
        view.close()

    def test_happy_path(self):
        class FakeLinter(Linter):
            defaults = {'selector': ''}
            cmd = 'fake_linter_1'

        when(sublime_linter.backend).lint_view(...).thenReturn(None)

        view = self.create_view(self.window)
        sublime_linter.lint(view, lambda: False, Lock(), 'on_user_request')

        verify(sublime_linter.backend).lint_view(...)

    def test_log_info_if_no_assignable_linter(self):
        class FakeLinter(Linter):
            defaults = {'selector': 'foobar'}
            cmd = 'fake_linter_1'

        when(sublime_linter.logger).info(...).thenReturn(None)

        view = self.create_view(self.window)
        sublime_linter.lint(view, lambda: False, Lock(), 'on_user_request')

        verify(sublime_linter.logger).info(
            "No installed linter matches the view."
        )

    def test_log_if_no_linter_installed(self):
        when(sublime_linter.logger).info(...).thenReturn(None)

        view = self.create_view(self.window)
        sublime_linter.lint(view, lambda: False, Lock(), 'on_user_request')

        verify(sublime_linter.logger).info(
            "No installed linter matches the view."
        )

@@ -229,16 +229,89 @@
 persist%0A
+from SublimeLinter.lint.generic_text_command import replace_view_content%0A
 %0A%0Aclass 
@@ -1469,16 +1469,1231 @@
 w(...)%0A%0A
+    def test_file_only_linter_skip_on_unsaved_file(self):%0A        class FakeLinter(Linter):%0A            defaults = %7B'selector': ''%7D%0A            cmd = 'fake_linter_1'%0A            tempfile_suffix = '-'%0A%0A        when(sublime_linter.backend).lint_view(...).thenReturn(None)%0A%0A        view = self.create_view(self.window)%0A        assert view.file_name() is None%0A        sublime_linter.lint(view, lambda: False, Lock(), 'on_user_request')%0A%0A        verify(sublime_linter.backend, times=0).lint_view(...)%0A%0A    def test_file_only_linter_skip_dirty_file(self):%0A        class FakeLinter(Linter):%0A            defaults = %7B'selector': ''%7D%0A            cmd = 'fake_linter_1'%0A            tempfile_suffix = '-'%0A%0A        when(sublime_linter.backend).lint_view(...).thenReturn(None)%0A%0A        view = self.create_view(self.window)%0A        replace_view_content(view, %22Some text.%22)%0A        assert view.is_dirty()%0A        sublime_linter.lint(view, lambda: False, Lock(), 'on_user_request')%0A%0A        verify(sublime_linter.backend, times=0).lint_view(...)%0A        # Strangely, %60set_scratch(True)%60 is not enough to close the view%0A        # without Sublime wanting to save it.  Empty the view to succeed.%0A        replace_view_content(view, %22%22)%0A%0A
     def 

Add failing test