def test_closeAllDocumentsWithDelegate_didCloseAllSelector_contextInfo_(): import editxt.util as util context = 42 dc = ak.NSDocumentController.sharedDocumentController() m = Mocker() app = m.replace(editxt, 'app') def perf_sel(delegate, selector, *args): should_term(*args) dsd_class = m.replace(mod, 'DocumentSavingDelegate', spec=False) docs = m.mock() app.iter_dirty_documents() >> docs selector = "_docController:shouldTerminate:context:" delegate = m.mock() def test_callback(callback): callback("<result>") return True should_term = delegate._docController_shouldTerminate_context_ should_term(dc, "<result>", context) saver = m.mock(DocumentSavingDelegate) dsd_class.alloc() >> saver saver.init_callback_(docs, MATCH(test_callback)) >> saver saver.save_next_document() with replattr(mod, 'perform_selector', perf_sel), m: dc.closeAllDocumentsWithDelegate_didCloseAllSelector_contextInfo_( delegate, selector, context)
def test_reload_config(): from editxt import app from editxt.config import Config m = Mocker() config = m.mock(Config) config.reload() tv = m.mock(ak.NSTextView) with m, replattr(app, "config", config): mod.reload_config(tv, "<sender>", None)
def test_BaseCommandController_options(): with replattr(BaseCommandController, "OPTIONS_CLASS", FakeOptions): ctl = BaseCommandController.create() #assert isinstance(ctl.opts, FakeOptions), ctl.opts eq_(type(ctl.opts).__name__, "FakeOptions_KVOProxy") assert ctl.opts is ctl.options() obj = object() ctl.setOptions_(obj) eq_(ctl.options(), obj)
def test(c): m = Mocker() fc = FindController.shared_controller() if c.tag in fc.action_registry: tv = (m.mock(TextView) if c.has_target else None) m.method(fc.find_target)() >> tv if c.has_target: if c.tag in mod.SELECTION_REQUIRED_ACTIONS: tv.selectedRange().length >> c.sel with m, replattr(fc, 'options', FindOptions()): result = fc.validate_action(c.tag) eq_(result, c.result)
def test_application_init(): from editxt.util import ContextMap from editxt.errorlog import ErrorLog m = Mocker() reg_vtrans = [] def vtrans(): reg_vtrans.append(1) with replattr(mod, 'register_value_transformers', vtrans), m: app = Application() eq_(app.editors, []) assert isinstance(app.context, ContextMap) assert reg_vtrans
def test(c): with test_app() as app: m = Mocker() fc = FindController(app) if c.tag in fc.action_registry: editor = (m.mock(Editor) if c.has_target else None) m.method(fc.get_editor)() >> editor if c.has_target: if c.tag in mod.SELECTION_REQUIRED_ACTIONS: editor.selection >> (0, c.sel) with m, replattr(fc, 'options', FindOptions()): result = fc.validate_action(c.tag) eq_(result, c.result)
def test(original, config="editor"): diffed = [] text_name = "file.txt" rm = [] def diff_stub(path1, path2, diff_program, remove=None): for path in remove: os.remove(path) eq_(path1, path_1) eq_(path2, path_2) eq_(diff_program, "opendiff") diffed.append(1) with tempdir() as tmp, test_app(config) as app, \ replattr(mod, "external_diff", diff_stub): window = app.windows[0] editor = text_editor = window.projects[0].editors[0] if config == "editor": path = editor.file_path = join(tmp, "file.txt") with open(path, mode="w", encoding="utf8") as fh: fh.write("abc") m = Mocker() text_view = editor.text_view = m.mock(TextView) path_1 = editor.file_path if original: make_dirty(editor.document) name_ext = splitext(test_app(app).name(editor)) path_2 = Regex(r"/file-.*\.txt$") args = None text_view.string() >> "def" elif len(window.selected_items) == 2: editor2 = window.selected_items[1] editor2.text_view = m.mock(TextView) name_ext = splitext(test_app(app).name(editor)[7:-1]) path_1 = Regex(r"/{}-.*{}$".format(*name_ext)) name_ext = splitext(test_app(app).name(editor2)[7:-1]) path_2 = Regex(r"/{}-.*{}$".format(*name_ext)) args = None text_view.string() >> "def" editor2.text_view.string() >> "ghi" else: path_1 = join(tmp, "other.txt") path_2 = editor.file_path with open(path_1, mode="w", encoding="utf8") as fh: fh.write("other") assert " " not in path_1, path_1 args = mod.diff.arg_parser.parse(path_1) with m: mod.diff(editor, args) assert diffed
def test_external_diff(): popen_called = [] def popen(command, **kw): popen_called.append(True) print(command) eq_(sum(1 for c in command if c == ";"), 1, command) args = shlex.split(command.split(";")[0]) print(args) eq_(args, ["true", "--arg", path, path]) check_call(command, **kw) assert not exists(path), "test file not removed: {}".format(path) with tempdir() as tmp, replattr(mod, "Popen", popen): path = join(tmp, "file.txt") with open(path, mode="w") as fh: fh.write("abc") mod.external_diff(path, path, "true --arg", [path]) assert popen_called, "diff command was not executed"
def test(c): with test_app(c.app) as app: m = Mocker() teardown_main_view = m.replace(mod, 'teardown_main_view') window = app.windows[0] editor = window.projects[0].editors[0] make_dirty(editor.document) assert window.is_dirty editor.text_view = None if c.tv_is_none else m.mock(ak.NSTextView) doc = editor.document undo = editor.undo_manager if c.ts_is_none: doc.text_storage = None else: with replattr(doc, 'reset_text_attributes', lambda *a: None, sigcheck=False): text_storage = doc.text_storage #text_storage.setDelegate_(doc) remove_layout = m.method(text_storage.removeLayoutManager_) if not (c.tv_is_none or c.ts_is_none): lm = editor.text_view.layoutManager() >> m.mock(ak.NSLayoutManager) remove_layout(lm) if c.main_is_none: editor.main_view = None else: editor.main_view = m.mock() teardown_main_view(editor.main_view) assert editor.on_dirty_status_changed in undo.callbacks.items with m: editor.close() if next(window.iter_editors_of_document(doc), None) is not None: assert window.is_dirty else: assert not window.is_dirty eq_(editor.command_view, None) eq_(editor.scroll_view, None) eq_(editor.text_view, None) eq_(editor.document, None) eq_(editor.proxy, None) assert editor.on_dirty_status_changed not in undo.callbacks.items if c.close_doc: eq_(doc.text_storage, None) #if not c.ts_is_none: #eq_(text_storage.delegate(), None) else: assert doc.text_storage is not None eq_(test_app(app).state, c.end)
def test(with_id=True, fail=False): with tempdir() as tmp: state_path = os.path.join(tmp, const.STATE_DIR) editor = TestConfig(state=[42], id=9) args = (editor.id,) if with_id else () app = Application(tmp) state_name = app.save_editor_state(editor, *args) if fail: editor = editor(state="should not be written") def dump_fail(state, fh=None): if fh is not None: fh.write("should not be seen") raise Exception("dump fail!") with replattr(mod, "dump_yaml", dump_fail, sigcheck=False): state_name = app.save_editor_state(editor, *args) assert os.path.isdir(state_path), state_path with open(os.path.join(state_path, state_name)) as f: eq_(load_yaml(f), [42])
def test(c): m = Mocker() app = Application() exists = lambda path: True alog = m.replace(mod, 'log') ed = m.mock(Editor) dv_class = m.replace(edoc, 'TextDocumentView') m.method(app.current_editor)() >> (ed if c.has_editor else None) if not c.has_editor: m.method(app.create_editor)() >> ed focus = None for p in c.paths: exists(p.path) >> p.exists dv = dv_class.create_with_path(p.path) >> m.mock(TextDocumentView) focus = ed.add_document_view(dv) >> dv if focus is not None: ed.current_view = dv with replattr(os.path, 'isfile', exists), m: app.open_documents_with_paths([p.path for p in c.paths])
def test(with_id=True, fail=False): with tempdir() as tmp: state_path = os.path.join(tmp, const.STATE_DIR) editor = TestConfig(state=[42], id=9) args = (editor.id, ) if with_id else () app = Application(tmp) state_name = app.save_editor_state(editor, *args) if fail: editor = editor(state="should not be written") def dump_fail(state, fh=None): if fh is not None: fh.write("should not be seen") raise Exception("dump fail!") with replattr(mod, "dump_yaml", dump_fail, sigcheck=False): state_name = app.save_editor_state(editor, *args) assert os.path.isdir(state_path), state_path with open(os.path.join(state_path, state_name)) as f: eq_(load_yaml(f), [42])
def test(lang, string, expect, edit=None): theme.reset() if isinstance(lang, Highlighter): hl = lang else: hl = Highlighter(theme) hl.syntaxdef = get_syntax_definition(lang) text = string if isinstance(string, Text) else Text(dedent(string)) get_color = lambda value: value with replattr(editxt.theme, "get_color", get_color, sigcheck=False), CaptureLogging(mod) as log: if edit: start, length, insert = edit text[(start, length)] = Text(insert) hl.color_text(text, (start, len(insert))) else: hl.color_text(text) errors = log.data.get("error") assert not errors, "Errors logged:\n" + "\n---\n\n".join(errors) a = list(chain.from_iterable(x.split("\n") for x in text.colors(hl))) b = dedent(expect).strip().split("\n") if expect else [] assert a == b, "\n" + "\n".join(unified_diff(b, a, "expected", "actual", lineterm=""))
def test(name, color): with replattr(mod, "get_color", get_color, sigcheck=False): eq_(theme.get_syntax_color(name), color)
def __call__(self, command): with replattr(ak, "NSBeep", lambda: None): # HACK self.bar.execute(command)
def __call__(self, command): with replattr(ak, "NSBeep", lambda:None): # HACK self.bar.execute(command)
def replay(self): self.ctx = replattr(*self.replargs, **self.replkw) self.ctx.__enter__()
def test(input, output, *args): if input.startswith("/"): input = tmp + "/" with replattr(os.path, "expanduser", expanduser): check(input, output, *args)
def test(input, output): if input.startswith("/"): input = tmp + "/" with replattr(os.path, "expanduser", expanduser): arg = mod.Arg(field, input, 0, None) eq_(field.get_completions(arg), output)
def test_File(): from editxt.test.util import test_app field = File('path') eq_(str(field), 'path') eq_(repr(field), "File('path')") with test_app("project(/dir) editor") as app: tmp = test_app(app).tmp os.mkdir(join(tmp, "dir")) os.mkdir(join(tmp, "space dir")) for path in [ "dir/a.txt", "dir/b.txt", "dir/B file", ".hidden", "file.txt", "file.doc", "space dir/file", #"x y", ]: assert not isabs(path), path with open(join(tmp, path), "w") as fh: pass test = make_consume_checker(field) yield test, "relative.txt", 0, Error("cannot make absolute path (no context): relative.txt") test = make_completions_checker(field) yield test, "", [] editor = app.windows[0].projects[0].editors[0] field = field.with_context(editor) test = make_completions_checker(field) yield test, ".../", ["a.txt", "B file", "b.txt"], 4 with replattr(editor.project, "path", editor.project.path + "/"): yield test, ".../", ["a.txt", "B file", "b.txt"], 4 yield test, "...//", ["a.txt", "B file", "b.txt"], 5 test = make_arg_string_checker(field) yield test, "/str", "/str" yield test, "/a b", '"/a b"', 6 yield test, os.path.expanduser("~/a b"), '"~/a b"', 7 yield test, join(tmp, "dir/file"), "file" yield test, join(tmp, "dir/a b"), '"a b"', 5 yield test, join(tmp, "file"), join(tmp, "file") yield test, "arg/", Error("not a file: path='arg/'") test = make_consume_checker(field) yield test, '', 0, (None, 0) yield test, 'a', 0, (join(tmp, 'dir/a'), 2) yield test, 'abc', 0, (join(tmp, 'dir/abc'), 4) yield test, 'abc ', 0, (join(tmp, 'dir/abc'), 4) yield test, 'file.txt', 0, (join(tmp, 'dir/file.txt'), 9) yield test, '../file.txt', 0, (join(tmp, 'dir/../file.txt'), 12) yield test, '/file.txt', 0, ('/file.txt', 10) yield test, '~/file.txt', 0, (os.path.expanduser('~/file.txt'), 11) yield test, '...', 0, (join(tmp, 'dir'), 4) yield test, '.../file.txt', 0, (join(tmp, 'dir/file.txt'), 13) yield test, '"ab c"', 0, (join(tmp, 'dir/ab c'), 6) yield test, "'ab c'", 0, (join(tmp, 'dir/ab c'), 6) yield test, "'ab c/'", 0, (join(tmp, 'dir/ab c/'), 7) # completions def expanduser(path): if path.startswith("~"): if len(path) == 1: return tmp assert path.startswith("~/"), path return tmp + path[1:] return path def test(input, output): if input.startswith("/"): input = tmp + "/" with replattr(os.path, "expanduser", expanduser): arg = mod.Arg(field, input, 0, None) eq_(field.get_completions(arg), output) yield test, "", ["a.txt", "B file", "b.txt"] yield test, "a", ["a.txt"] yield test, "a.txt", ["a.txt"] yield test, "b", ["B file", "b.txt"] yield test, "B", ["B file"] yield test, "..", ["../"] yield test, "../", ["dir", "file.doc", "file.txt", "space dir"] yield test, "../.", [".hidden"] yield test, "...", [".../"] yield test, ".../", ["a.txt", "B file", "b.txt"] yield test, "../dir", ["dir/"] yield test, "../dir/", ["a.txt", "B file", "b.txt"] yield test, "../sp", ["space dir"] yield test, "../space\\ d", ["space dir"] yield test, "../space\\ dir", ["space dir/"] yield test, "../space\\ dir/", ["file"] yield test, "val", [] yield test, "/", ["dir", "file.doc", "file.txt", "space dir"] yield test, "~", ["~/"] yield test, "~/", ["dir", "file.doc", "file.txt", "space dir"] # delimiter completion def test(input, output, start=0): arg = mod.Arg(field, input, 0, None) words = field.get_completions(arg) assert all(isinstance(w, CompleteWord) for w in words), \ repr([w for w in words if not isinstance(w, CompleteWord)]) eq_([w.complete() for w in words], output) eq_([w.start for w in words], [start] * len(words), words) yield test, "", ["a.txt ", "B\\ file ", "b.txt "] yield test, "x", [] yield test, "..", ["../"] yield test, "../", ["dir/", "file.doc ", "file.txt ", "space\\ dir/"], 3 yield test, "../dir", ["dir/"], 3 yield test, "../di", ["dir/"], 3 yield test, "../sp", ["space\\ dir/"], 3 yield test, "../space\\ d", ["space\\ dir/"], 3 yield test, "../space\\ dir", ["space\\ dir/"], 3 yield test, ".../", ["a.txt ", "B\\ file ", "b.txt "], 4 yield test, "../space\\ dir/", ["file "], 14 yield test, "~", ["~/"], None field = File('dir', directory=True) eq_(str(field), 'dir') eq_(repr(field), "File('dir', directory=True)") field = field.with_context(editor) test = make_consume_checker(field) yield test, '', 0, (None, 0) yield test, 'a', 0, (join(tmp, 'dir/a'), 2) yield test, 'abc', 0, (join(tmp, 'dir/abc'), 4) yield test, 'abc ', 0, (join(tmp, 'dir/abc'), 4) yield test, 'abc/', 0, (join(tmp, 'dir/abc/'), 5) yield test, '...', 0, (join(tmp, 'dir'), 4) yield test, '.../abc/', 0, (join(tmp, 'dir/abc/'), 9) test = make_completions_checker(field) yield test, "", [], 0 yield test, "a", [], 0 yield test, "..", ["../"], 0 yield test, "../", ["dir", "space dir"], 3 field = File('dir', default="~/dir") check = make_completions_checker(field) def test(input, output, *args): if input.startswith("/"): input = tmp + "/" with replattr(os.path, "expanduser", expanduser): check(input, output, *args) yield test, "", [], 0 project = app.windows[0].projects[0] check = make_completions_checker(field.with_context(project)) yield test, "", ["a.txt", "B file", "b.txt"], 0 yield test, "./", ["a.txt", "B file", "b.txt"], 2 with replattr(project, "path", project.path + "/"): check = make_completions_checker(field.with_context(project)) yield test, "", ["a.txt", "B file", "b.txt"], 0 yield test, "./", ["a.txt", "B file", "b.txt"], 2
def end(): # this allows us to return early (reducing nested if's) with replattr(mod, 'filestat', filestat), m: eq_(doc._filestat, c.prestat) doc.check_for_external_changes(win) eq_(doc._filestat, (c.prestat if not c.extmod or c.win_is_none else c.modstat))
def replace_history(): with tempdir() as tmp: history = CommandHistory(tmp) with replattr(editxt.app.text_commander, "history", history): yield history