def test(c): def objcstr(value): value = ak.NSString.alloc().initWithString_(value) isinstance(value, objc.pyobjc_unicode), (type(value), value) return value def check(flag, key, serial, value=None): if flag: assert key in serial, (key, serial) if value is not None: eq_(serial[key], value) else: assert key not in serial, key proj = Project(None) recent = [objcstr("/file.txt"), objcstr("/doc.xml")] if c.recent: proj.recent.extend(Recent(p) for p in recent) if c.name: proj.name = objcstr("<name>") if c.docs: proj.editors = [MockDoc(1)] proj.expanded = c.expn serial = proj.serialize() check(False, "path", serial, proj.path) check(c.name, "name", serial, proj.name) check(c.docs, "documents", serial) check(True, "expanded", serial, c.expn) check(c.recent, "recent", serial, recent) dump_yaml(serial) # verify that it does not crash
def test_create_editor_with_state(): with test_app() as app: window = TestConfig(app=app) project = Project(window) state = {"path": "Untitled"} result = project.create_editor_with_state(state) eq_(result.project, project) assert result in project.editors, project.editors
def iter_dropped_paths(self, pasteboard): from editxt.document import TextDocument if not pasteboard.types().containsObject_(ak.NSFilenamesPboardType): raise StopIteration() for path in pasteboard.propertyListForType_(ak.NSFilenamesPboardType): if Project.is_project_path(path): proj = self.app.find_project_with_path(path) if proj is None: proj = Project.create_with_path(path) yield proj else: yield TextDocument.get_with_path(path)
def test_set_main_view_of_window(): window = TestConfig(command="<command>") project = Project(window) eq_(project.main_view, None) m = Mocker() view = m.mock() view.bounds() >> "<frame>" win = m.mock() with m: project.set_main_view_of_window(view, win) assert project.main_view is not None eq_(project.command_view.editor, project) eq_(project.command_view.command, "<command>")
def test_close(): m = Mocker() window = m.mock(name="window") proj = Project(window) proj.editors = docs = [] for i in range(2): dv = m.mock(Editor) docs.append(dv) dv.close() with m: proj.close() eq_(proj.proxy, None) eq_(proj.window, None) eq_(proj.editors, None)
def test(serial): m = Mocker() proj = Project.create() log = m.replace("editxt.project.log", passthrough=False) nsdat = m.replace(NSData, passthrough=False) nspls = m.replace(NSPropertyListSerialization, passthrough=False) create_document_view_with_state = m.method(Project.create_document_view_with_state) create_document_view = m.method(Project.create_document_view) proj._documents = docs = m.mock(KVOList) if "path" in serial: data = nsdat.dataWithContentsOfFile_(serial["path"]) >> m.mock() serial_, format, error = nspls. \ propertyListFromData_mutabilityOption_format_errorDescription_( \ data, NSPropertyListImmutable, None, None) >> ({}, m.mock(), None) else: serial_ = serial docs_ = serial_.get("documents", []) for item in docs_: create_document_view_with_state(item) if item == "doc_not_found": m.throw(Exception("document not found")) log.warn("cannot open document: %r" % item) #proj._is_dirty = True bool(docs); m.result(bool(docs_)) if not docs_: create_document_view() #proj._is_dirty = True with m: proj.deserialize(serial) if "path" in serial: eq_(proj.path, serial["path"]) assert "name" not in serial else: eq_(proj.name, serial.get("name", const.UNTITLED_PROJECT_NAME)) eq_(proj.expanded, serial.get("expanded", True))
def test_set_main_view_of_window(): proj = Project.create() m = Mocker() view = m.mock(ak.NSView) win = m.mock(ak.NSWindow) with m: proj.set_main_view_of_window(view, win) # for now this does nothing
def test_displayName(): proj = Project.create() eq_(proj.displayName(), const.UNTITLED_PROJECT_NAME) proj.setDisplayName_("name") eq_(proj.displayName(), "name") proj.path = path = "/tmp/test.edxt" eq_(proj.displayName(), "test")
def test_set_main_view_of_window(): proj = Project.create() m = Mocker() view = m.mock(NSView) win = m.mock(NSWindow) with m: proj.set_main_view_of_window(view, win) # for now this does nothing
def test(c): proj = Project.create() m = Mocker() dsd_class = m.replace("editxt.application.DocumentSavingDelegate") app = m.replace("editxt.app", type=Application) ed = m.mock(Editor) app.find_editors_with_project(proj) >> [ed for x in xrange(c.num_eds)] if c.num_eds == 1: docs = [m.mock(TextDocumentView)] doc = docs[0].document >> m.mock(TextDocument) app.iter_editors_with_view_of_document(doc) >> \ (ed for x in xrange(c.num_doc_views)) dirty_documents = m.method(proj.dirty_documents) dirty_documents() >> docs def check_docs(_docs): d = docs if c.num_doc_views == 1 else [] eq_(list(_docs), d + [proj]) return True callback = [] def get_callback(func): callback.append(func) return True def do_callback(): callback[0](c.should_close) saver = m.mock(DocumentSavingDelegate) dsd_class.alloc() >> saver saver.init_callback_(MATCH(check_docs), MATCH(get_callback)) >> saver expect(saver.save_next_document()).call(do_callback) if c.should_close: ed.discard_and_focus_recent(proj) else: ed.discard_and_focus_recent(proj) with m: proj.perform_close(ed)
def test_append_document_view_already_in_project(): class Fake(object): pass proj = Project.create() dv = Fake() proj.append_document_view(dv) proj.append_document_view(dv) assert len(proj.documents()) == 2, proj.documents()
def test_create_with_path(): path = "/temp/non-existent/project.edxt" assert not os.path.exists(path) result = Project.create_with_path(path) try: eq_(result.path, path) finally: result.close()
def test_append_document_view(): proj = Project.create() #assert not proj.is_dirty m = Mocker() doc = m.mock(TextDocumentView) doc.project = proj with m: proj.append_document_view(doc) assert doc in proj.documents()
def test(config): found = [] proj = Project(None) proj.editors = docs = [] m = Mocker() doc = m.mock(TextDocument) for item in config: editor = m.mock(Editor) docs.append(editor) editor.name >> item adoc = m.mock(TextDocument) editor.document >> (doc if item is DOC else adoc) if item is DOC: found.append(editor) with m: eq_(config, [editor.name for editor in docs]) result = list(proj.iter_editors_of_document(doc)) eq_(result, found)
def do_save_project(path): proj = Project.create() m = Mocker() doc = m.mock(TextDocumentView) doc.edit_state >> {"path": "xyz"} doc.project = proj with m: proj.append_document_view(doc) proj.save_with_path(path) assert os.path.exists(path), "project not saved: %s" % path
def test_create_with_serial(): m = Mocker() serial = {"path": "/temp/non-existent/project.edxt"} assert not os.path.exists(serial["path"]) with m: result = Project.create_with_serial(serial) try: eq_(result.path, serial["path"]) finally: result.close()
def test_init_with_serial(): m = Mocker() kvo_class = m.replace(mod, 'KVOList') deserialize = m.method(Project.deserialize) reset_cache = m.method(Project.reset_serial_cache) docs = kvo_class.alloc().init() >> [] deserialize("<serial>") reset_cache(); m.count(2) with m: proj = Project.alloc().init_with_serial("<serial>")
def test_close(): from editxt.util import KVOList proj = Project.create() m = Mocker() proj._documents = docs = [] for i in range(2): dv = m.mock(TextDocumentView) docs.append(dv) dv.close() with m: proj.close()
def do_test(template): proj = Project(None) temp_docs = proj.editors try: m = Mocker() all_docs = [] dirty_docs = [] for item in template: doc = m.mock(Editor) all_docs.append(doc) doc.is_dirty >> (item == "d") if item == "d": dirty_docs.append(doc) proj.editors = all_docs with m: result = list(proj.dirty_editors()) assert len(dirty_docs) == template.count("d") assert dirty_docs == result, "%r != %r" % (dirty_docs, result) finally: proj.editors = temp_docs
def is_project_drag(self, info): """Return True if only projects are being dropped else False""" pb = info.draggingPasteboard() t = pb.availableTypeFromArray_(self.supported_drag_types) if t == const.DOC_ID_LIST_PBOARD_TYPE: items = self.iter_dropped_id_list(pb) return all(isinstance(item, Project) for item in items) elif t == ak.NSFilenamesPboardType: paths = pb.propertyListForType_(ak.NSFilenamesPboardType) return all(Project.is_project_path(path) for path in paths) return False
def test_init_with_serial(): m = Mocker() kvo_class = m.replace(mod, 'KVOList') deserialize = m.method(Project.deserialize) reset_cache = m.method(Project.reset_serial_cache) docs = kvo_class.alloc().init() >> [] deserialize("<serial>") reset_cache() m.count(2) with m: proj = Project.alloc().init_with_serial("<serial>")
def test_create_document_view_with_state(): proj = Project.create() m = Mocker() state = m.mock() dv_class = m.replace("editxt.document.TextDocumentView") dv = m.mock(TextDocumentView) dv_class.create_with_state(state) >> dv dv.project = proj with m: result = proj.create_document_view_with_state(state) eq_(result, dv) assert dv in proj.documents()
def do_load_project(path): import editxt.project as mod m = Mocker() create_document_view_with_state = m.method(Project.create_document_view_with_state) create_document_view_with_state(ANY) with m: proj = Project.create_with_path(path) try: assert proj.path == path assert len(proj.documents()) == 1 finally: proj.close()
def test_create_document_view_with_state(): proj = Project.create() m = Mocker() state = m.mock() dv_class = m.replace(mod, 'TextDocumentView') dv = m.mock(TextDocumentView) dv_class.create_with_state(state) >> dv dv.project = proj with m: result = proj.create_document_view_with_state(state) eq_(result, dv) assert dv in proj.documents()
def get_current_project(self, create=False): docs_controller = self.wc.docsController if docs_controller is not None: path = docs_controller.selectionIndexPath() if path is not None: index = path.indexAtPosition_(0) path2 = fn.NSIndexPath.indexPathWithIndex_(index) return docs_controller.objectAtArrangedIndexPath_(path2) if create: proj = Project.create() self.projects.append(proj) return proj return None
def test_remove_document_view(): class MockView(object): project = None project = Project.create() doc = MockView() project.insert_document_view(0, doc) assert doc in project.documents() eq_(doc.project, project) #project.is_dirty = False project.remove_document_view(doc) #assert project.is_dirty assert doc not in project.documents() eq_(doc.project, None)
def do_load_project(path): import editxt.project as mod m = Mocker() create_document_view_with_state = m.method( Project.create_document_view_with_state) create_document_view_with_state(ANY) with m: proj = Project.create_with_path(path) try: assert proj.path == path assert len(proj.documents()) == 1 finally: proj.close()
def deserialize(self, data): if data: for serial in data.get("project_serials", []): proj = Project.create_with_serial(serial) self.projects.append(proj) for proj_index, doc_index in data.get("recent_items", []): if proj_index < len(self.projects): proj = self.projects[proj_index] if doc_index == "<project>": self.recent.push(proj.id) elif doc_index < len(proj.documents()): doc = proj.documents()[doc_index] self.recent.push(doc.id) self.discard_and_focus_recent(None)
def test_close(): from editxt.util import KVOList proj = Project.create() m = Mocker() proj._documents = m.mock(KVOList) docs = [] for i in xrange(2): dv = m.mock(TextDocumentView) docs.append(dv) dv.close() iter(proj._documents); m.generate(docs) #proj._documents.__length_hint__ >> len(docs) #proj._documents.setItems_([]) with m: proj.close()
def test_save_with_path_when_project_has_a_path(): m = Mocker() path = "<path>" nsdict = m.replace(NSMutableDictionary, passthrough=False) proj = Project.create() proj.name = "<name>" serial = proj.serialize() assert serial, "serial should not be empty: %r" % (serial,) serial["path"] = path proj.path = path data = nsdict.alloc().init() >> m.mock(dict) data.update(serial) data.writeToFile_atomically_(path, True); m.nospec() with m: proj.save_with_path(path)
def test_setDisplayName_(): proj = Project.create() assert proj.path is None #assert not proj.is_dirty eq_(proj.displayName(), const.UNTITLED_PROJECT_NAME) proj.setDisplayName_("name") #assert proj.is_dirty eq_(proj.displayName(), "name") #proj.is_dirty = False proj.path = path = "/tmp/test.edxt" eq_(proj.displayName(), "test") #assert not proj.is_dirty proj.setDisplayName_("name") #assert not proj.is_dirty eq_(proj.displayName(), "test")
def test_save_with_path_when_project_has_a_path(): m = Mocker() path = "<path>" nsdict = m.replace(fn, 'NSMutableDictionary') proj = Project.create() proj.name = "<name>" serial = proj.serialize() assert serial, "serial should not be empty: %r" % (serial, ) serial["path"] = path proj.path = path data = nsdict.alloc().init() >> m.mock(dict) data.update(serial) data.writeToFile_atomically_(path, True) m.nospec() with m: proj.save_with_path(path)
def _setstate(self, state): if state: for serial in state.get("project_serials", []): proj = Project.create_with_serial(serial) self.projects.append(proj) for proj_index, doc_index in state.get("recent_items", []): if proj_index < len(self.projects): proj = self.projects[proj_index] if doc_index == "<project>": self.recent.push(proj.id) elif doc_index < len(proj.documents()): doc = proj.documents()[doc_index] self.recent.push(doc.id) if 'window_settings' in state: self.window_settings = state['window_settings'] self.discard_and_focus_recent(None)
def test_create_document_view(): proj = Project.create() m = Mocker() nsdc = m.replace("AppKit.NSDocumentController") append_document_view = m.method(proj.append_document_view) dc = m.mock(NSDocumentController) doc = m.mock(TextDocument) dv_class = m.replace("editxt.document.TextDocumentView") dv = m.mock(TextDocumentView) nsdc.sharedDocumentController() >> dc dc.makeUntitledDocumentOfType_error_(const.TEXT_DOCUMENT, None) >> (doc, None) dc.addDocument_(doc) dv_class.create_with_document(doc) >> dv append_document_view(dv) >> dv with m: result = proj.create_document_view() eq_(result, dv)
def test_create_document_view(): proj = Project.create() m = Mocker() nsdc = m.replace(ak, 'NSDocumentController') append_document_view = m.method(proj.append_document_view) dc = m.mock(ak.NSDocumentController) doc = m.mock(TextDocument) dv_class = m.replace(mod, 'TextDocumentView') dv = m.mock(TextDocumentView) nsdc.sharedDocumentController() >> dc dc.makeUntitledDocumentOfType_error_(const.TEXT_DOCUMENT, None) >> (doc, None) dc.addDocument_(doc) dv_class.create_with_document(doc) >> dv append_document_view(dv) >> dv with m: result = proj.create_document_view() eq_(result, dv)
def test(path_is_none): proj = Project.create() m = Mocker() if path_is_none: assert proj.path is None doc_states = [] for x in range(3): doc = MockDoc(x) doc_states.append(doc.edit_state) proj.append_document_view(doc) testkey = dict(documents=doc_states, expanded=True) if proj.name != const.UNTITLED_PROJECT_NAME: testkey["name"] = proj.name else: proj.path = "<path>" testkey = {"path": proj.path} with m: result = proj.serialize() eq_(result, testkey)
def test(proj_has_path, is_changed): m = Mocker() proj = Project.create() app = m.replace(mod, 'app') save_with_path = m.method(proj.save_with_path) reset_cache = m.method(proj.reset_serial_cache) m.method(proj.serialize_full)() >> "<serial>" if proj_has_path: proj.path = "test/proj.tmp" if is_changed: proj.serial_cache = "<invalid-cache>" if proj_has_path: save_with_path(proj.path) app.save_editor_states() reset_cache() else: proj.serial_cache = "<serial>" with m: proj.save()
def test(path_is_none): proj = Project.create() m = Mocker() if path_is_none: assert proj.path is None doc_states = [] for x in xrange(3): doc = MockDoc(x) doc_states.append(doc.edit_state) proj.append_document_view(doc) testkey = dict(documents=doc_states, expanded=True) if proj.name != const.UNTITLED_PROJECT_NAME: testkey["name"] = proj.name else: proj.path = "<path>" testkey = {"path": proj.path} with m: result = proj.serialize() eq_(result, testkey)
def do_test(template): proj = Project.create() temp_docs = proj._documents try: m = Mocker() all_docs = [] dirty_docs = [] for item in template: doc = m.mock(TextDocumentView) all_docs.append(doc) doc.is_dirty >> (item == "d") if item == "d": dirty_docs.append(doc) proj._documents = all_docs with m: result = list(proj.dirty_documents()) assert len(dirty_docs) == template.count("d") assert dirty_docs == result, "%r != %r" % (dirty_docs, result) finally: proj._documents = temp_docs
def test(config): theview = None proj = Project.create() proj._documents = docs = [] m = Mocker() doc = m.mock(TextDocument) found = False for item in config: view = m.mock(TextDocumentView) docs.append(view) view.name >> item if not found: adoc = m.mock(TextDocument) view.document >> (doc if item is DOC else adoc) if item is DOC: theview = view found = True with m: eq_(config, [view.name for view in docs]) result = proj.find_view_with_document(doc) eq_(result, theview)
def test(c): proj = Project.create() m = Mocker() dsd_class = m.replace(xtapp, 'DocumentSavingDelegate') app = m.replace(mod, 'app') ed = m.mock(Editor) app.find_editors_with_project(proj) >> [ed for x in range(c.num_eds)] if c.num_eds == 1: docs = [m.mock(TextDocumentView)] doc = docs[0].document >> m.mock(TextDocument) app.iter_editors_with_view_of_document(doc) >> \ (ed for x in range(c.num_doc_views)) dirty_documents = m.method(proj.dirty_documents) dirty_documents() >> docs def check_docs(_docs): d = docs if c.num_doc_views == 1 else [] eq_(list(_docs), d + [proj]) return True callback = [] def get_callback(func): callback.append(func) return True def do_callback(): callback[0](c.should_close) saver = m.mock(xtapp.DocumentSavingDelegate) dsd_class.alloc() >> saver saver.init_callback_(MATCH(check_docs), MATCH(get_callback)) >> saver expect(saver.save_next_document()).call(do_callback) if c.should_close: ed.discard_and_focus_recent(proj) else: ed.discard_and_focus_recent(proj) with m: proj.perform_close(ed)
def test(serial): m = Mocker() proj = Project.create() log = m.replace(mod, 'log') nsdat = m.replace(fn, 'NSData') nspls = m.replace(fn, 'NSPropertyListSerialization') create_document_view_with_state = m.method( Project.create_document_view_with_state) create_document_view = m.method(Project.create_document_view) proj._documents = docs = m.mock(KVOList) if "path" in serial: data = nsdat.dataWithContentsOfFile_(serial["path"]) >> m.mock() serial_, format, error = nspls. \ propertyListFromData_mutabilityOption_format_errorDescription_( \ data, NSPropertyListImmutable, None, None) >> ({}, m.mock(), None) else: serial_ = serial docs_ = serial_.get("documents", []) for item in docs_: create_document_view_with_state(item) if item == "doc_not_found": m.throw(Exception("document not found")) log.warn("cannot open document: %r" % item) #proj._is_dirty = True bool(docs) m.result(bool(docs_)) if not docs_: create_document_view() #proj._is_dirty = True with m: proj.deserialize(serial) if "path" in serial: eq_(proj.path, serial["path"]) assert "name" not in serial else: eq_(proj.name, serial.get("name", const.UNTITLED_PROJECT_NAME)) eq_(proj.expanded, serial.get("expanded", True))
def test(c): def check(flag, key, serial, value=None): if flag: assert key in serial, key if value is not None: eq_(serial[key], value) else: assert key not in serial, key proj = Project.create() if c.path: proj.path = "<path>" if c.name: proj.name = ak.NSString.alloc().initWithString_("<name>") assert isinstance(proj.name, objc.pyobjc_unicode), type(proj.name) if c.docs: proj._documents = [MockDoc(1)] proj.expanded = c.expn serial = proj.serialize_full() check(c.path, "path", serial, proj.path) check(c.name, "name", serial, proj.name) check(c.docs, "documents", serial) check(True, "expanded", serial, c.expn) dump_yaml(serial) # verify that it does not crash
def accept_dropped_items(self, items, project, index, action): """Insert dropped items into the document tree :param items: A sequence of dropped projects and/or documents. :param project: The parent project into which items are being dropped. :param index: The index in the outline view or parent project at which the drop occurred. :param action: The type of drop: None (unspecified), MOVE, or COPY. :returns: True if the items were accepted, otherwise False. """ if project is None: # a new project will be created if/when needed if index < 0: proj_index = 0 else: proj_index = index index = 0 else: proj_index = len(self.projects) # insert projects at end of list assert isinstance(project, Project), project if index < 0: index = len(project.documents()) accepted = False focus = None is_move = action is not const.COPY self.suspend_recent_updates() try: for item in items: accepted = True if isinstance(item, Project): if not is_move: raise NotImplementedError('cannot copy project yet') editors = self.app.find_editors_with_project(item) assert len(editors) < 2, editors if item in self.projects: editor = self pindex = self.projects.index(item) if pindex == proj_index: continue if pindex - proj_index <= 0: proj_index -= 1 else: editor = editors[0] # BEGIN HACK crash on remove project with documents pdocs = item.documents() docs, pdocs[:] = list(pdocs), [] editor.projects.remove(item) # this line should be all that's necessary pdocs.extend(docs) # END HACK self.projects.insert(proj_index, item) proj_index += 1 focus = item continue if project is None: if isinstance(item, TextDocumentView) and is_move: view = item item.project.remove_document_view(view) else: view = TextDocumentView.create_with_document(item) project = Project.create() self.projects.insert(proj_index, project) proj_index += 1 index = 0 else: if isinstance(item, TextDocumentView): view, item = item, item.document else: view = project.document_view_for_document(item) if is_move and view is not None: if view.project == project: vindex = project.documents().index(view) if vindex in [index - 1, index]: continue if vindex - index <= 0: index -= 1 view.project.remove_document_view(view) else: view = TextDocumentView.create_with_document(item) project.insert_document_view(index, view) focus = view index += 1 finally: self.resume_recent_updates() if focus is not None: self.current_view = focus return accepted
def new_project(self): project = Project.create() view = project.create_document_view() self.projects.append(project) self.current_view = view return project
def test_create_and_init(): proj = Project.create() assert proj.path is None eq_(len(proj.documents()), 0) eq_(proj.serial_cache, proj.serialize())
def test(path, expected): result = Project.is_project_path(path) eq_( result, expected, "Project.is_project_path(%r) returned wrong value: %s" % (path, result))