def test(eds_config): app = Application() m = Mocker() create_window = m.method(app.create_window) open_error_log = m.method(app.open_error_log) nsapp = m.mock(ak.NSApplication) ud_class = m.replace(fn, 'NSUserDefaults') m.method(app.iter_saved_window_states)() >> iter(eds_config) tc = m.replace(app, 'text_commander', spec=CommandManager) dc = m.mock(DocumentController) tc.load_commands(dc.textMenu >> m.mock(ak.NSMenu)) tc.load_shortcuts(dc.shortcutsMenu >> m.mock(ak.NSMenu)) if eds_config: error = False for ed_config in eds_config: if isinstance(ed_config, mod.StateLoadFailure): error = True else: create_window(ed_config) if error: open_error_log(set_current=False) else: create_window() with m: app.application_will_finish_launching(nsapp, dc) eq_(app.text_commander, tc)
def __enter__(self): from editxt.application import Application self.tempdir = tempdir() self.tmp = os.path.realpath(self.tempdir.__enter__()) profile_path = os.path.join(self.tmp, ".profile") app = Application(profile_path) app.syntax_factory = {} if self.config is not None: def update(data, key, value): if "." in key: base, sub = key.split(".", 1) if base not in data: data[base] = {} update(data[base], sub, value) else: data[key] = value for key, value in self.config.items(): assert isinstance(key, str), key update(app.config.data, key, value) self.items = {} self.news = 0 self.app = app self._setup(app) app.__test_app = self return app
def test_save_window_settings_with_unknown_editor(): ac = Application() m = Mocker() df_class = m.replace("editxt.application.NSUserDefaults") ed = m.mock(Editor) with m: ac.save_window_settings(ed)
def test(c): m = Mocker() ac = Application() ac.windows = eds = [] found_item = None for w in c.eds: ed = m.mock(Window) eds.append(ed) projs = (ed.projects >> []) for p in w.projs: proj = m.mock(Project) docs = [] projs.append(proj) if found_item is None: proj.id >> p.id if p.id == c.id: found_item = proj else: proj.editors >> docs for d in p.docs: doc = m.mock(Editor) docs.append(doc) if found_item is None: doc.id >> d.id if d.id == c.id: found_item = doc with m: result = ac.find_item_with_id(c.id) eq_(result, found_item) if c.found: assert result is not None else: assert result is None
def do_test(windows_template): app = Application() m = Mocker() seen = set() dirty_docs = [] eds = [] for ecfg in windows_template: projects = [] for pcfg in ecfg: proj = m.mock(Project) projects.append(proj) editors = [] has_dirty = False for doc_id in pcfg: editor = m.mock(Editor) editors.append(editor) (editor.document.id << doc_id).count(1, 2) if doc_id not in seen: seen.add(doc_id) dirty_docs.append(editor) has_dirty = True proj.dirty_editors() >> editors if has_dirty: dirty_docs.append(proj) ed = m.mock(Window) ed.projects >> projects eds.append(ed) m.method(app.iter_windows)() >> eds with m: result = list(app.iter_dirty_editors()) eq_(result, dirty_docs)
def test(ed_config): ac = Application() m = Mocker() df_class = m.replace("editxt.application.NSUserDefaults") iter_editors = m.method(ac.iter_editors) save_open_projects = m.method(ac.save_open_projects) discard_editor = m.method(ac.discard_editor) nsapp = m.mock() ac.editors = eds = [] all_settings = [] for i in ed_config: ed = m.mock(Editor) eds.append(ed) ed.window_settings_loaded >> (i != 2) if i != 2: settings = "<settings %s>" % i all_settings.append(settings) ed.window_settings >> settings iter_editors(nsapp) >> reversed(eds) defaults = df_class.standardUserDefaults() >> MockUserDefaults() save_open_projects(defaults) with m: ac.app_will_terminate(nsapp) result = defaults.arrayForKey_(const.WINDOW_SETTINGS_DEFAULTS_KEY) eq_(result, all_settings) assert defaults.synced
def test_setup_profile_at_file(): with tempdir() as tmp: path = os.path.join(tmp, 'profile') with open(path, 'w') as fh: pass app = Application(path) eq_(app.setup_profile(), False) assert os.path.isfile(path), path
def test(config): ac = Application() m = Mocker() ac.iter_windows = iwc = m.method(ac.iter_windows) iwc() >> iter(config) with m: result = ac.current_window() eq_(result, (config[0] if config else None))
def test_add_editor(): ac = Application() m = Mocker() ed = m.mock(Editor) assert not ac.editors with m: ac.add_editor(ed) assert ed in ac.editors
def test_add_window(): ac = Application() m = Mocker() ed = m.mock(Window) assert not ac.windows with m: ac.add_window(ed) assert ed in ac.windows
def test_set_current_document_view(): ac = Application() m = Mocker() dv = m.mock(TextDocumentView) ac.find_editor_with_document_view = m.method(ac.find_editor_with_document_view) ed = ac.find_editor_with_document_view(dv) >> m.mock(Editor) ed.current_view = dv with m: ac.set_current_document_view(dv)
def test_set_current_editor(): ac = Application() m = Mocker() editor = m.mock(Editor) ac.find_window_with_editor = m.method(ac.find_window_with_editor) ed = ac.find_window_with_editor(editor) >> m.mock(Window) ed.current_editor = editor with m: ac.set_current_editor(editor)
def test_Application_logger(): root = logging.getLogger() app = Application() handler = app.errlog_handler assert hasattr(app, "errlog"), app.errlog assert handler not in root.handlers, root.handlers with app.logger() as errlog: handler = app.errlog_handler assert handler in root.handlers, root.handlers assert handler not in root.handlers, root.handlers
def test(c): m = Mocker() app = Application() ed = m.mock(Editor) if c.ed_in_eds: app.editors.append(ed) def verify(): assert ed not in app.editors, "ed cannot be in app.editors at this point" expect(ed.close()).call(verify) with m: app.discard_editor(ed)
def test(c): m = Mocker() app = Application() ctype = 0 item = m.mock(TextDocument if c.item_type == "d" else Project) for e in range(c.eds): ed = m.mock(Editor) ed.item_changed(item, ctype) app.add_editor(ed) with m: app.item_changed(item, ctype)
def test(c): m = Mocker() app = Application() create_window = m.method(app.create_window) window = m.mock(Window) m.method(app.current_window)() >> (window if c.has_window else None) if not c.has_window: create_window() >> window items = window.open_paths("<paths>") >> m.mock() with m: app.open_documents_with_paths("<paths>")
def test(file_exists=True): m = Mocker() app = Application() view = m.mock(TextDocumentView) m.method(app.open_documents_with_paths)([app.config.path]) >> [view] default_config = m.property(app.config, "default_config") m.replace("os.path.exists")(app.config.path) >> file_exists if not file_exists: default_config.value >> "# config" view.document.text = "# config" with m: app.open_config_file()
def test(c): app = Application() m = Mocker() window = m.mock(Window) if c.has_window else None m.method(app.current_window)() >> window if c.has_window: editor = m.mock(Editor) if c.has_editor else None window.current_editor >> editor if c.has_editor: window.close_item(editor) with m: app.close_current_document()
def test(c): app = Application() m = Mocker() ed = m.mock(Editor) if c.has_editor else None m.method(app.current_editor)() >> ed if c.has_editor: view = m.mock(TextDocumentView) if c.has_view else None ed.current_view >> view if c.has_view: view.perform_close(ed) with m: app.close_current_document()
def test_init_syntax_definitions(): import editxt.syntax as syntax m = Mocker() app = Application(profile='/editxtdev') rsrc_path = m.method(app.resource_path)() >> "/tmp/resources" SyntaxFactory = m.replace(syntax, 'SyntaxFactory', spec=False) sf = SyntaxFactory() >> m.mock(syntax.SyntaxFactory) app_log = m.replace("editxt.application.log") for path, info in [(rsrc_path, False), ('/editxtdev', True)]: sf.load_definitions(os.path.join(path, const.SYNTAX_DEFS_DIR), info) sf.index_definitions() with m: app.init_syntax_definitions()
def test(ed_count, all_settings, result, add_eds=True): ac = Application() m = Mocker() defaults = m.mock(NSUserDefaults) df_class = m.replace("editxt.application.NSUserDefaults") eds = [m.mock(Editor) for x in xrange(ed_count)] if add_eds: df_class.standardUserDefaults() >> defaults defaults.arrayForKey_(const.WINDOW_SETTINGS_DEFAULTS_KEY) >> all_settings ac.editors = eds with m: window_settings = ac.load_window_settings(eds[-1]) eq_(window_settings, result)
def test_init_syntax_definitions(): import editxt.syntax as syntax m = Mocker() app = Application(profile='/editxtdev') rsrc_path = m.method(app.resource_path)() >> "/tmp/resources" SyntaxFactory = m.replace(syntax, 'SyntaxFactory', spec=False) sf = SyntaxFactory() >> m.mock(syntax.SyntaxFactory) app_log = m.replace("editxt.application.log") for path, info in [(rsrc_path, False), ('/editxtdev', True)]: sf.load_definitions(join(path, const.SYNTAX_DEFS_DIR), info) sf.index_definitions() with m: app.init_syntax_definitions()
def test(c): m = Mocker() app = Application() doc = m.mock(TextDocument) m.method(app.open_documents_with_paths)([app.config.path]) >> [doc] (doc.file_path << app.config.path).count(1, None) default_config = m.property(app.config, "default_config") m.replace("os.path.exists")(app.config.path) >> c.exists if not c.exists: doc.document.text >> c.text if not c.text: doc.document.text = default_config.value >> "# config" with m: app.open_config_file()
def do_save_window_settings(ed_count, close_ed, wsets, default_settings, all_settings): m = Mocker() ac = Application() df_class = m.replace("editxt.application.NSUserDefaults") defaults = MockUserDefaults() defaults.setObject_forKey_(default_settings, const.WINDOW_SETTINGS_DEFAULTS_KEY) ac.editors = eds = [m.mock(Editor) for x in xrange(ed_count)] if close_ed < 6: df_class.standardUserDefaults() >> defaults eds[close_ed-1].window_settings >> wsets with m: ac.save_window_settings(eds[close_ed-1]) saved = defaults.arrayForKey_(const.WINDOW_SETTINGS_DEFAULTS_KEY) eq_(saved, all_settings)
def test(c): app = Application() m = Mocker() opc_class = m.replace(mod, 'OpenPathController') opc = m.mock(mod.OpenPathController) m.property(app, "path_opener").value >> (opc if c.exists else None) if c.exists: app.path_opener.window().makeKeyAndOrderFront_(app) else: opc_class(app) >> opc app.path_opener = opc opc.showWindow_(app) app.path_opener.populateWithClipboard() with m: app.open_path_dialog()
def test(c): app = Application() m = Mocker() opc_class = m.replace(OpenPathController, passthrough=False) opc = m.mock(OpenPathController) m.property(app, "path_opener").value >> (opc if c.exists else None) if c.exists: app.path_opener.window().makeKeyAndOrderFront_(app) else: (opc_class.alloc() >> opc).initWithWindowNibName_("OpenPath") >> opc app.path_opener = opc opc.showWindow_(app) app.path_opener.populateWithClipboard() with m: app.open_path_dialog()
def main(argv=list(sys.argv)): try: if "--test" in argv or "--pdb" in argv: DEFAULT_LOGGING_CONFIG['handlers']['console']['level'] = 'DEBUG' use_pdb = "--pdb" in argv if use_pdb: argv.remove("--pdb") objc.setVerbose(1) # make PyObjC use our exception handler Debugging.installExceptionHandler = install_exception_handler if "--test" in argv: from editxt.test.runner import TestApplication app = TestApplication(argv) else: logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) from editxt.application import Application argv = argv[1:] # drop program name doc = __doc__.replace('Profile directory.', 'Profile directory [default: {}].' .format(Application.default_profile())) opts = docopt.docopt(doc, argv, version=editxt.__version__) app = Application(opts.get('--profile')) editxt.app = app run(app, argv, use_pdb) except Exception as err: if len(logging.root.handlers) == 0: logging.config.dictConfig(DEFAULT_LOGGING_CONFIG) log.error('unhandled error', exc_info=True) sys.exit(1)
def test_init_syntax_definitions(): from editxt.syntax import SyntaxFactory m = Mocker() app = Application() sf_class = m.replace(SyntaxFactory, spec=False, passthrough=False) app_log = m.replace("editxt.application.log", passthrough=False) nsb = m.replace(NSBundle) app_support_path = m.method(Application.app_support_path) sf = sf_class() >> m.mock(SyntaxFactory) rsrc_path = nsb.mainBundle().resourcePath() >> "/resources/syntax" asup_path = app_support_path() >> "/app_support/syntax" for path in [rsrc_path, asup_path]: sf.load_definitions(os.path.join(path, const.SYNTAX_DEFS_DIR)) sf.index_definitions() with m: app.init_syntax_definitions()
def test(c): app = Application() m = Mocker() opc_class = m.replace(mod, 'OpenPathController') opc = m.mock(mod.OpenPathController) m.property(app, "path_opener").value >> (opc if c.exists else None) if c.exists: app.path_opener.window().makeKeyAndOrderFront_(app) else: (opc_class.alloc() >> opc).initWithWindowNibName_("OpenPath") >> opc app.path_opener = opc opc.showWindow_(app) app.path_opener.populateWithClipboard() with m: app.open_path_dialog()
def test_syntaxdefs(): from editxt.syntax import SyntaxFactory m = Mocker() app = Application() sf = app.syntax_factory = m.mock(SyntaxFactory) sf.definitions >> "<definitions>" with m: eq_(app.syntaxdefs, "<definitions>")
def test(states): with tempdir() as tmp: state_path = os.path.join(tmp, const.STATE_DIR) if states: # setup previous state m = Mocker() app = Application(tmp) def iter_editors(): for ident in states: yield TestConfig(state=[ident]) m.method(app.iter_editors)() >> iter_editors() with m: app.save_editor_states() assert os.listdir(state_path), state_path app = Application(tmp) result = list(app.iter_saved_editor_states()) eq_(result, [[id] for id in states])
def test_profile_path(): def test(profile, profile_path): app = Application(profile) eq_(app.profile_path, profile_path) appname = Application.name().lower() yield test, None, os.path.expanduser('~/.' + appname) yield test, '~/.editxt', os.path.expanduser('~/.editxt') yield test, '/xt-profile', '/xt-profile'
def test(args): ac = Application() m = Mocker() ed_class = m.replace(editor, 'Editor') wc_class = m.replace(editor, 'EditorWindowController') wc = wc_class.alloc() >> m.mock(editor.EditorWindowController) wc.initWithWindowNibName_("EditorWindow") >> wc ed = ed_class(ac, wc, args[0] if args else None) >> m.mock(editor.Editor) wc.editor = ed #ed = wc.controller >> m.mock(Editor) #wc_class.create_with_serial_data(args[0] if args else None) >> wc with m.order(): ac.editors.append(ed) wc.showWindow_(ac) with m: result = ac.create_editor(*args) eq_(result, ed)
def test(args): ac = Application() m = Mocker() ed_class = m.replace(editor, 'Editor') wc_class = m.replace(editor, 'EditorWindowController') wc = wc_class.alloc() >> m.mock(editor.EditorWindowController) wc.initWithWindowNibName_("EditorWindow") >> wc ed = ed_class(ac, wc, args[0] if args else None) >> m.mock( editor.Editor) wc.editor = ed #ed = wc.controller >> m.mock(Editor) #wc_class.create_with_serial_data(args[0] if args else None) >> wc with m.order(): ac.editors.append(ed) wc.showWindow_(ac) with m: result = ac.create_editor(*args) eq_(result, ed)
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(config, unordered=0): """ config - represents a list of window controllers in on-screen z-order with the front-most window controller first. Key: None - generic NSWindowController (not EditorWindowController) <int> - Editor index in ac.editors unordered - (optional, default 0) number of editors in ac.editors that are not in the on-screen z-order window list. """ ac = Application() m = Mocker() app_class = m.replace(ak, 'NSApp') app = app_class() eds = {} unordered_eds = [] z_windows = [] for item in config: if item is None: wc = m.mock(ak.NSWindowController) else: wc = m.mock(EditorWindowController) ed = m.mock(Editor) print(ed, item) if item != 7: (wc.editor << ed).count(3) unordered_eds.append(ed) else: wc.editor >> ed eds[item] = ed win = m.mock(ak.NSWindow) win.windowController() >> wc z_windows.append(win) for x in range(unordered): unordered_eds.append(m.mock(Editor)) ac.editors = unordered_eds # + [v for k, v in sorted(eds.items())] app.orderedWindows() >> z_windows sorted_eds = [eds[i] for i in config if i not in (None, 7)] sorted_eds.extend(ed for ed in unordered_eds if ed not in sorted_eds) with m: result = list(ac.iter_editors()) eq_(result, sorted_eds)
def test(c): result = None ac = Application() m = Mocker() doc = m.mock(TextDocument) found = [] eds = m.method(ac.iter_editors)() >> [] for e in c.eds: ed = m.mock(Editor) eds.append(ed) if e.has_view: views = [m.mock(TextDocumentView)] found.append(ed) else: views = [] ed.iter_views_of_document(doc) >> iter(views) with m: result = list(ac.iter_editors_with_view_of_document(doc)) eq_(result, found) eq_(len(result), c.count)
def test(config): ac = Application() m = Mocker() doc = m.mock(TextDocument) views = [] total_views = 0 #ac.editors = eds = [] eds = [] for view_count in config: ed = m.mock(Editor) eds.append(ed) total_views += view_count vws = [m.mock(TextDocumentView) for i in range(view_count)] ed.iter_views_of_document(doc) >> vws views.extend(vws) m.method(ac.iter_editors)() >> eds with m: result = list(ac.iter_views_of_document(doc)) eq_(result, views) eq_(len(result), total_views)
def test(eds_config): app = Application() m = Mocker() create_editor = m.method(app.create_editor) nsapp = m.mock(ak.NSApplication) ud_class = m.replace(fn, 'NSUserDefaults') m.method(app.iter_saved_editor_states)() >> iter(eds_config) tc = m.replace(app, 'text_commander', spec=TextCommandController) dc = m.mock(DocumentController) menu = dc.textMenu >> m.mock(ak.NSMenu) m.method(app.init_syntax_definitions)() tc.load_commands(menu) if eds_config: for ed_config in eds_config: create_editor(ed_config) else: create_editor() with m: app.application_will_finish_launching(nsapp, dc) eq_(app.text_commander, tc)
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() ac = Application() ac.editors = eds = [] found_proj = None for it in c.eds: ed = m.mock(Editor) eds.append(ed) if found_proj is None: proj = m.mock(Project) if it.has_path else None ed.find_project_with_path(c.path) >> proj if it.has_path: found_proj = proj with m: result = ac.find_project_with_path(c.path) eq_(result, found_proj) if c.found: assert result is not None else: assert result is None
def test(c): m = Mocker() ed = m.mock(Editor) dv = m.mock(TextDocumentView) dv_class = m.replace(edoc, 'TextDocumentView') app = Application() err = m.property(mod.errlog, "document").value >> m.mock(TextDocument) if c.is_open: idocs = iter([dv]) m.method(app.set_current_document_view)(dv) else: idocs = iter([]) m.method(app.current_editor)() >> (ed if c.has_editor else None) if not c.has_editor: m.method(app.create_editor)() >> ed dv_class.create_with_document(err) >> dv ed.add_document_view(dv) ed.current_view = dv m.method(app.iter_views_of_document)(err) >> idocs with m: app.open_error_log()
def test(config): """Test argument structure: [ # collection of window controllers [ # window controller / collection of projects ["doc1", "doc2", "doc3", ...], # project / collection of documents ... ] ... ] """ result = None ac = Application() m = Mocker() dv = m.mock(TextDocumentView) # this is the view we're looking for document = m.mock(TextDocument) (dv.document << document).count(0, None) ac.iter_editors = m.method(ac.iter_editors) eds = ac.iter_editors() >> [] for ed_projects in config: ed = m.mock(Editor) eds.append(ed) projects = [] ed.projects >> projects found = False for project_documents in ed_projects: project = m.mock(Project) projects.append(project) documents = [] if not found: project.documents() >> documents for doc_name in project_documents: if doc_name == DOC: documents.append(dv) result = ed found = True else: documents.append(m.mock(TextDocumentView)) with m: ed = ac.find_editor_with_document_view(dv) eq_(ed, 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(has_current): m = Mocker() ac = Application() ac.current_editor = m.method(ac.current_editor) if has_current: ed = m.mock(Editor) proj = (ac.current_editor() >> ed).new_project() >> m.mock(Project) else: ac.current_editor() >> None proj = None with m: result = ac.new_project() eq_(result, proj)
def test(eds_config, num_eds): eds_found = [] ac = Application() m = Mocker() proj = m.mock(Project) ac.editors = eds = [] for i, ed_config in enumerate(eds_config): ed = m.mock(Editor) eds.append(ed) projects = [] ed.projects >> projects found = False for item in ed_config: if item is PROJ and not found: eds_found.append(ed) project = proj found = True else: project = m.mock(Project) projects.append(project) with m: eq_(len(eds_found), num_eds) result = ac.find_editors_with_project(proj) eq_(result, eds_found)
def test_set_current_document_view(): ac = Application() m = Mocker() dv = m.mock(TextDocumentView) ac.find_editor_with_document_view = m.method( ac.find_editor_with_document_view) ed = ac.find_editor_with_document_view(dv) >> m.mock(Editor) ed.current_view = dv with m: ac.set_current_document_view(dv)
def test(c): with tempdir() as tmp: state_path = os.path.join(tmp, const.STATE_DIR) if c.previous: # setup previous state m = Mocker() app = Application(tmp) mock_editors(m.method(app.iter_editors), c.previous) with m: app.save_editor_states() assert os.listdir(state_path), state_path m = Mocker() app = Application(tmp) mock_editors(m.method(app.iter_editors), c.editors) with m: app.save_editor_states() assert os.path.isdir(state_path), state_path states = sorted(os.listdir(state_path)) eq_(len(states), len(c.editors), states) for ident, state in zip(c.editors, states): with open(os.path.join(state_path, state)) as f: eq_(load_yaml(f), [ident])
def test(profile, profile_path): app = Application(profile) eq_(app.profile_path, profile_path)
def test_setup_profile_exists(): with tempdir() as tmp: app = Application(tmp) eq_(app.setup_profile(), True)
def test(ed_config): app = Application() m = Mocker() m.method(app.save_editor_states)() >> None with m: ap.app_will_terminate(None)
def test_Application_config(): app = Application("~/.editxt") eq_(app.config.path, os.path.expanduser("~/.editxt/config.yaml"))
def test_setup_profile_parent_exists(): with tempdir() as tmp: path = os.path.join(tmp, 'profile') app = Application(path) eq_(app.setup_profile(), True) assert os.path.exists(path), path
def test_setup_profile_parent_missing(): with tempdir() as tmp: path = os.path.join(tmp, 'missing', 'profile') app = Application(path) eq_(app.setup_profile(), False) assert not os.path.exists(path), path