def test_heading_parsing_with_date_and_body(self): """"" 'text' contains valid dates (in the body). """ # orgdatetime text = [ "* TODO This is a test <2011-08-25 Thu 10:10> :hallo:", "some body text", "some body text" ] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertTrue(isinstance(h.active_date, OrgDateTime)) self.assertEqual("<2011-08-25 Thu 10:10>", str(h.active_date)) text = [ "* TODO This is a test :hallo:", "some body text", "some body text<2011-08-25 Thu 10:10>" ] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertTrue(isinstance(h.active_date, OrgDateTime)) self.assertEqual("<2011-08-25 Thu 10:10>", str(h.active_date)) text = [ "* TODO This is a test :hallo:", "some body text <2011-08-24 Wed>", "some body text<2011-08-25 Thu 10:10>" ] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) odate = OrgDate(True, 2011, 8, 24) self.assertEqual(odate, h.active_date)
def test_filter_items(self): # only headings with date and todo should be returned tmpdate = date.today() odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day) tmp_head = Heading(title=u'Refactor the code', todo=u'TODO', active_date=odate) headings = [tmp_head] filtered = filter_items(headings, [contains_active_date, contains_active_todo]) self.assertEqual(len(filtered), 1) self.assertEqual(filtered, headings) # try a longer list headings = headings * 3 filtered = filter_items(headings, [contains_active_date, contains_active_todo]) self.assertEqual(len(filtered), 3) self.assertEqual(filtered, headings) # date does not contain all needed fields thus gets ignored tmpdate = date.today() odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day) tmp_head = Heading(title=u'Refactor the code', active_date=odate) headings = [tmp_head] filtered = filter_items(headings, [contains_active_date, contains_active_todo]) self.assertEqual([], filtered)
def test_heading_parsing_with_date_and_body(self): """"" 'text' contains valid dates (in the body). """ # orgdatetime text = ["* TODO This is a test <2011-08-25 Thu 10:10> :hallo:", "some body text", "some body text"] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertTrue(isinstance(h.active_date, OrgDateTime)) self.assertEqual("<2011-08-25 Thu 10:10>", str(h.active_date)) text = ["* TODO This is a test :hallo:", "some body text", "some body text<2011-08-25 Thu 10:10>"] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertTrue(isinstance(h.active_date, OrgDateTime)) self.assertEqual("<2011-08-25 Thu 10:10>", str(h.active_date)) text = ["* TODO This is a test :hallo:", "some body text <2011-08-24 Wed>", "some body text<2011-08-25 Thu 10:10>"] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) odate = OrgDate(True, 2011, 8, 24) self.assertEqual(odate, h.active_date)
def test_contains_active_date(self): heading = Heading(title=u'Refactor the code', active_date=None) self.assertFalse(contains_active_date(heading)) odate = OrgDate(True, 2011, 11, 1) heading = Heading(title=u'Refactor the code', active_date=odate) self.assertTrue(contains_active_date(heading))
def test_contains_active_todo(self): heading = Heading(title=u'Refactor the code', todo='TODO') self.assertTrue(contains_active_todo(heading)) heading = Heading(title=u'Refactor the code', todo='DONE') self.assertFalse(contains_active_todo(heading)) heading = Heading(title=u'Refactor the code', todo=None) self.assertFalse(contains_active_todo(heading))
def test_heading_parsing_with_date(self): """"" 'text' does contain valid dates. """ # orgdate text = ["* TODO This is a test <2011-08-24 Wed> :hallo:"] odate = OrgDate(True, 2011, 8, 24) h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertEqual(odate, h.active_date) # orgdatetime text = ["* TODO This is a test <2011-08-25 Thu 10:10> :hallo:"] odate = OrgDateTime(True, 2011, 8, 25, 10, 10) h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertEqual(odate, h.active_date)
def test_is_within_week_with_orgdatetime(self): # to far in the future tmp = date.today() + timedelta(days=1000) odate = OrgDateTime(True, tmp.year, tmp.month, tmp.day, 10, 10) heading = Heading(title=u'Refactor the code', active_date=odate) self.assertFalse(is_within_week(heading)) # within a week tmpdate = date.today() + timedelta(days=5) odate = OrgDateTime(True, tmpdate.year, tmpdate.month, tmpdate.day, 1, 0) heading = Heading(title=u'Refactor the code', active_date=odate) self.assertTrue(is_within_week(heading)) # in the past tmpdate = date.today() - timedelta(days=5) odate = OrgDateTime(True, tmpdate.year, tmpdate.month, tmpdate.day, 1, 0) heading = Heading(title=u'Refactor the code', active_date=odate) self.assertTrue(is_within_week(heading))
def setUp(self): self.allowed_todo_states = ["TODO"] tmp = ["* This heading is earlier <2011-08-24 Wed>"] self.h1 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states) tmp = ["* This heading is later <2011-08-25 Thu>"] self.h2 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states) tmp = ["* This heading is later <2011-08-25 Thu 10:20>"] self.h2_datetime = Heading.parse_heading_from_data(tmp, self.allowed_todo_states) tmp = ["* This heading is later <2011-08-26 Fri 10:20>"] self.h3 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states) tmp = ["* This heading has no date and should be later than the rest"] self.h_no_date = Heading.parse_heading_from_data(tmp, self.allowed_todo_states)
def test_heading_parsing_no_date(self): """"" 'text' doesn't contain any valid date. """ text = ["* TODO This is a test :hallo:"] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertEqual(None, h.active_date) text = ["* TODO This is a test <2011-08-25>"] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertEqual(None, h.active_date) text = ["* TODO This is a test <2011-08-25 Wednesday>"] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertEqual(None, h.active_date) text = ["* TODO This is a test <20110825>"] h = Heading.parse_heading_from_data(text, self.allowed_todo_states) self.assertEqual(None, h.active_date)
def test_filter_items_with_some_todos_and_dates(self): u""" Only the headings with todo and dates should be retunrned. """ tmp = [u"* TODO OrgMode Demo und Tests" u"<2011-08-22 Mon>"] headings = [Heading.parse_heading_from_data(tmp, [u'TODO'])] filtered = list(filter_items(headings, [is_within_week_and_active_todo])) self.assertEqual(len(filtered), 1) self.assertEqual(headings, filtered) tmp = [Heading.parse_heading_from_data([u"** DONE something <2011-08-10 Wed>"], [u'TODO']), Heading.parse_heading_from_data([u"*** TODO rsitenaoritns more <2011-08-25 Thu>"], [u'TODO']), Heading.parse_heading_from_data([u"*** DONE some more <2011-08-25 Thu>"], [u'TODO']), Heading.parse_heading_from_data([u"*** TODO some more <2011-08-25 Thu>"], [u'TODO']), Heading.parse_heading_from_data([u"** DONE something2 <2011-08-10 Wed>"], [u'TODO']) ] for h in tmp: headings.append(h) filtered = list(filter_items(headings, [is_within_week_and_active_todo])) self.assertEqual(len(filtered), 3) self.assertEqual(filtered, [headings[0], headings[2], headings[4]])
def test_filter_items_with_some_todos_and_dates(self): u""" Only the headings with todo and dates should be retunrned. """ tmp = [u"* TODO OrgMode Demo und Tests" u"<2011-08-22 Mon>"] headings = [Heading.parse_heading_from_data(tmp, [u'TODO'])] filtered = list( filter_items(headings, [is_within_week_and_active_todo])) self.assertEqual(len(filtered), 1) self.assertEqual(headings, filtered) tmp = [ Heading.parse_heading_from_data( [u"** DONE something <2011-08-10 Wed>"], [u'TODO']), Heading.parse_heading_from_data( [u"*** TODO rsitenaoritns more <2011-08-25 Thu>"], [u'TODO']), Heading.parse_heading_from_data( [u"*** DONE some more <2011-08-25 Thu>"], [u'TODO']), Heading.parse_heading_from_data( [u"*** TODO some more <2011-08-25 Thu>"], [u'TODO']), Heading.parse_heading_from_data( [u"** DONE something2 <2011-08-10 Wed>"], [u'TODO']) ] for h in tmp: headings.append(h) filtered = list( filter_items(headings, [is_within_week_and_active_todo])) self.assertEqual(len(filtered), 3) self.assertEqual(filtered, [headings[0], headings[2], headings[4]])
def test_filter_items(self): # only headings with date and todo should be returned vim.command( u_encode( u"let g:org_todo_keywords = ['TODO', 'STARTED', '|', 'DONE']")) tmpdate = date.today() odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day) tmp_head = Heading(title=u'Refactor the code', todo=u'TODO', active_date=odate) tmp_head_01 = Heading(title=u'Refactor the code', todo=u'STARTED', active_date=odate) headings = [tmp_head, tmp_head_01] filtered = list( filter_items(headings, [contains_active_date, contains_active_todo])) self.assertEqual(len(filtered), 2) self.assertEqual(filtered, headings) # try a longer list headings = headings * 3 filtered = list( filter_items(headings, [contains_active_date, contains_active_todo])) self.assertEqual(len(filtered), 6) self.assertEqual(filtered, headings) # date does not contain all needed fields thus gets ignored tmpdate = date.today() odate = OrgDate(True, tmpdate.year, tmpdate.month, tmpdate.day) tmp_head = Heading(title=u'Refactor the code', active_date=odate) headings = [tmp_head] filtered = list( filter_items(headings, [contains_active_date, contains_active_todo])) self.assertEqual([], filtered)
def setUp(self): self.allowed_todo_states = ["TODO"] tmp = ["* This heading is earlier <2011-08-24 Wed>"] self.h1 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states) tmp = ["* This heading is later <2011-08-25 Thu>"] self.h2 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states) tmp = ["* This heading is later <2011-08-25 Thu 10:20>"] self.h2_datetime = Heading.parse_heading_from_data( tmp, self.allowed_todo_states) tmp = ["* This heading is later <2011-08-26 Fri 10:20>"] self.h3 = Heading.parse_heading_from_data(tmp, self.allowed_todo_states) tmp = ["* This heading has no date and should be later than the rest"] self.h_no_date = Heading.parse_heading_from_data( tmp, self.allowed_todo_states)
def new_heading(cls, below=None, insert_mode=False, end_of_last_child=False): u""" :below: True, insert heading below current heading, False, insert heading above current heading, None, special behavior for insert mode, use the current text as heading :insert_mode: True, if action is performed in insert mode :end_of_last_child: True, insert heading at the end of last child, otherwise the newly created heading will "take over" the current heading's children """ d = ORGMODE.get_document() current_heading = d.current_heading() cursor = vim.current.window.cursor[:] if not current_heading: # the user is in meta data region pos = cursor[0] - 1 heading = Heading(title=d.meta_information[pos], body=d.meta_information[pos + 1:]) d.headings.insert(0, heading) del d.meta_information[pos:] d.write() vim.command( u_encode(u'exe "normal %dgg"|startinsert!' % (heading.start_vim, ))) return heading # check for plain list(checkbox) current_heading.init_checkboxes() c = current_heading.current_checkbox() if c is not None: ORGMODE.plugins[u"EditCheckbox"].new_checkbox(below, not c.status) return heading = Heading(level=current_heading.level) # it's weird but this is the behavior of original orgmode if below is None: below = cursor[1] != 0 or end_of_last_child # insert newly created heading l = current_heading.get_parent_list() idx = current_heading.get_index_in_parent_list() if l is not None and idx is not None: l.insert(idx + (1 if below else 0), heading) else: raise HeadingDomError( u'Current heading is not properly linked in DOM') if below and not end_of_last_child: # append heading at the end of current heading and also take # over the children of current heading for child in current_heading.children: heading.children.append(child, taint=False) current_heading.children.remove_slice( 0, len(current_heading.children), taint=False) # if cursor is currently on a heading, insert parts of it into the # newly created heading if insert_mode and cursor[1] != 0 and cursor[ 0] == current_heading.start_vim: offset = cursor[1] - current_heading.level - 1 - ( len(current_heading.todo) + 1 if current_heading.todo else 0) if offset < 0: offset = 0 if int(settings.get(u'org_improve_split_heading', u'1')) and \ offset > 0 and len(current_heading.title) == offset + 1 \ and current_heading.title[offset - 1] not in (u' ', u'\t'): offset += 1 heading.title = current_heading.title[offset:] current_heading.title = current_heading.title[:offset] heading.body = current_heading.body[:] current_heading.body = [] d.write() # do not start insert upon adding new headings, unless already in insert mode. Issue #211 if int(settings.get(u'org_prefer_insert_mode', u'1')) or insert_mode: vim.command( u_encode(u'exe "normal %dgg"|startinsert!' % (heading.start_vim, ))) else: vim.command(u_encode(u'exe "normal %dgg$"' % (heading.start_vim, ))) # return newly created heading return heading
def new_heading(cls, below=None, insert_mode=False, end_of_last_child=False): u""" :below: True, insert heading below current heading, False, insert heading above current heading, None, special behavior for insert mode, use the current text as heading :insert_mode: True, if action is performed in insert mode :end_of_last_child: True, insert heading at the end of last child, otherwise the newly created heading will "take over" the current heading's children """ d = ORGMODE.get_document() current_heading = d.current_heading() cursor = vim.current.window.cursor[:] if not current_heading: # the user is in meta data region pos = cursor[0] - 1 heading = Heading(title=d.meta_information[pos], body=d.meta_information[pos + 1:]) d.headings.insert(0, heading) del d.meta_information[pos:] d.write() vim.command(u_encode(u'exe "normal %dgg"|startinsert!' % (heading.start_vim, ))) return heading # check for plain list(checkbox) current_heading.init_checkboxes() c = current_heading.current_checkbox() if c is not None: ORGMODE.plugins[u"EditCheckbox"].new_checkbox(below, not c.status) return heading = Heading(level=current_heading.level) # it's weird but this is the behavior of original orgmode if below is None: below = cursor[1] != 0 or end_of_last_child # insert newly created heading l = current_heading.get_parent_list() idx = current_heading.get_index_in_parent_list() if l is not None and idx is not None: l.insert(idx + (1 if below else 0), heading) else: raise HeadingDomError(u'Current heading is not properly linked in DOM') if below and not end_of_last_child: # append heading at the end of current heading and also take # over the children of current heading for child in current_heading.children: heading.children.append(child, taint=False) current_heading.children.remove_slice( 0, len(current_heading.children), taint=False) # if cursor is currently on a heading, insert parts of it into the # newly created heading if insert_mode and cursor[1] != 0 and cursor[0] == current_heading.start_vim: offset = cursor[1] - current_heading.level - 1 - ( len(current_heading.todo) + 1 if current_heading.todo else 0) if offset < 0: offset = 0 if int(settings.get(u'org_improve_split_heading', u'1')) and \ offset > 0 and len(current_heading.title) == offset + 1 \ and current_heading.title[offset - 1] not in (u' ', u'\t'): offset += 1 heading.title = current_heading.title[offset:] current_heading.title = current_heading.title[:offset] heading.body = current_heading.body[:] current_heading.body = [] d.write() # do not start insert upon adding new headings, unless already in insert mode. Issue #211 if int(settings.get(u'org_prefer_insert_mode', u'1')) or insert_mode: vim.command(u_encode(u'exe "normal %dgg"|startinsert!' % (heading.start_vim, ))) else: vim.command(u_encode(u'exe "normal %dgg$"' % (heading.start_vim, ))) # return newly created heading return heading
def new_heading(cls, below=None, insert_mode=False, end_of_last_child=False): u""" :below: True, insert heading below current heading, False, insert heading above current heading, None, special behavior for insert mode, use the current text as heading :insert_mode: True, if action is performed in insert mode :end_of_last_child: True, insert heading at the end of last child, otherwise the newly created heading will "take over" the current heading's children """ d = ORGMODE.get_document() current_heading = d.current_heading() cursor = vim.current.window.cursor[:] if not current_heading: # the user is in meta data region pos = cursor[0] - 1 heading = Heading(title=d.meta_information[pos], body=d.meta_information[pos + 1:]) d.headings.insert(0, heading) del d.meta_information[pos:] d.write() vim.command((u'exe "normal %dgg"|startinsert!' % (heading.start_vim, )).encode(u'utf-8')) return heading heading = Heading(level=current_heading.level) # it's weird but this is the behavior of original orgmode if below is None: below = cursor[1] != 0 or end_of_last_child heading_insert_position = 0 if below: heading_insert_position = 1 if not end_of_last_child: # append heading at the end of current heading but also take # over the children of current heading heading.children = [h.copy() for h in current_heading.children] del current_heading.children # if cursor is currently on a heading, insert parts of it into the # newly created heading if insert_mode and cursor[1] != 0 and cursor[0] == current_heading.start_vim: offset = cursor[1] - current_heading.level - 1 - (len(current_heading.todo) \ + 1 if current_heading.todo else 0) if offset < 0: offset = 0 if int(settings.get(u'org_improve_split_heading', u'1')) and \ offset > 0 and len(current_heading.title) == offset + 1 \ and current_heading.title[offset - 1] not in (u' ', u'\t'): offset += 1 heading.title = current_heading.title[offset:] current_heading.title = current_heading.title[:offset] heading.body = current_heading.body[:] current_heading.body = [] # insert newly created heading l = current_heading.get_parent_list() idx = current_heading.get_index_in_parent_list() if l is not None and idx is not None: l.insert(idx + heading_insert_position, heading) else: raise HeadingDomError(u'Current heading is not properly linked in DOM') d.write() vim.command((u'exe "normal %dgg"|startinsert!' % (heading.start_vim, )).encode(u'utf-8')) # return newly created heading return heading