def test_reads_para_para(): raw = "paragraph test\nparagraph 2 test" # [h1, h1] md = markdown.MarkDown() md.reads(raw) assert len(md.nodes) == 1 # expected to be merged into a single Paragraph assert isinstance(md.nodes[0], markdown.Paragraph) assert md.nodes[0].text == raw # should be unchanged
def test_reads_md_single_heading(): raw = "# test h1" md = markdown.MarkDown() md.reads(raw) assert len(md.nodes) == 1 assert isinstance(md.nodes[0], markdown.Heading1) assert md.nodes[0].text == "test h1"
def test_reads_md_h1_h1(): raw = "# test h1\n# test h1.1" # [h1, h1] md = markdown.MarkDown() md.reads(raw) assert len(md.nodes) == 2 assert isinstance(md.nodes[0], markdown.Heading1) assert md.nodes[0].text == "test h1" assert isinstance(md.nodes[1], markdown.Heading1) assert md.nodes[1].text == "test h1.1"
def handle_project(cli): """ Args: cli (Cli) - an object representing execution environment """ server = cli.environment["jira"]["server"] cli.logger.info( "Using JIRA Backend. JIRA Server is %s. Changes will be commited." % server) project = JiraBasedProject(summary=cli.project_conf["project"]["name"], environment=cli.environment, conf=cli.project_conf) project.logger = cli.logger project.schedule = schedule.ProjectSchedule() if "schedule" in project.conf: # relpath has to be handled for non-url entries url = project.conf["schedule"]["calendar_url"] if not (url.startswith("https://") or url.startswith("http://")): url = get_md_abspath(cli.project_path, url) cli.logger.info("Using calendar: %s" % url) project.schedule.from_url(url) project.jira_session_from_env() project.set_action(cli.action) for workflow_section in cli.project_conf.sections( ): # Workflow as in Milestone (e.g Beta) or Epic # these are not milestone sections if workflow_section in ('product', 'ownership'): continue # this can be skipped for handling virtual milestones such as Public Beta, # where the only purpose is to have a separate set of Milestone Tasks # which are named differently if 'markdown_filename' in cli.project_conf[workflow_section]: # section represents e.g. milestone1, order is important due Blocks/Depends On project_relpath = cli.project_conf[workflow_section][ 'markdown_filename'] md_path = get_md_abspath(cli.project_path, project_relpath) cli.logger.debug("Processing %s" % md_path) if not os.path.exists(md_path): cli.logger.error( "Referenced filename doesn't exist! relpath: %s abspath: %s" % (project_relpath, md_path)) sys.exit(3) fd = codecs.open(md_path, encoding='utf-8') md = markdown.MarkDown() md.logger = cli.logger md.read(fd) project.from_markdown(md, override_workflow_name=workflow_section) project.relations_from_conf_section(cli.project_conf, workflow_section) project.publish_task_relations() return True # for testing purposes
def test_reads_md_h1_h2(): raw = "# test h1\n## test h2" # [h1.h2,] md = markdown.MarkDown() md.reads(raw) assert len(md.nodes) == 1 assert isinstance(md.nodes[0], markdown.Heading1) assert md.nodes[0].text == "test h1" assert len(md.nodes[0].nodes) == 1 assert isinstance(md.nodes[0].nodes[0], markdown.Paragraph) assert md.nodes[0].nodes[0].text == "## test h2"
def test_user_group_raw(): raw = "# workflow name\n#### task 1\nResponsible: group_a\ndescription\n#### task 2\nResponsible: group_b\ndescription2" md = markdown.MarkDown() md.reads(raw) environment_config = u""" [TaskRelations] relations = Blocks, Depends On, Implements, Implemented by [jira] relative_link_topurl = http://localhost server = http://localhost project = Test mapping_JiraSubTask = Sub-Task mapping_JiraTask = Task mapping_JiraBasedWorkflow = Epic mapping_EpicName = Epic Name mapping_EpicNameQuery = Epic Link mapping_Assignee = Worker mapping_ProjectName = Product update_states = Open, Backlog """ project_conf = u""" [project] name = Test Product [ownership] markdown_variable = Responsible group_a = foo group_b = bar """ project = jirabackend.JiraBasedProject("Test Product") project.environment.read_string(environment_config) project.conf.read_string(project_conf) project.jira_session = jirabackend.FakeJiraInstance() project.from_markdown(md) project.publish_task_relations() assert project.tasks[0].tasks[0].variables # used for ownership print(project.tasks[0].tasks[0].variables) assert project.tasks[0].tasks[1].variables print(project.tasks[0].tasks[1].variables) assert project.tasks[0].tasks[0].summary == "task 1" assert project.tasks[0].tasks[0].description == "description" assert project.tasks[0].tasks[0].owner == "foo" assert project.tasks[0].tasks[1].summary == "task 2" assert project.tasks[0].tasks[1].description == "description2" assert project.tasks[0].tasks[1].owner == "bar"
def test_process_variable(): """ Check the Markdown tree which contains variable definitions if it matches with expectations """ raw = "# test h1\n#### test task\nvar: value\ndescription\n" md = markdown.MarkDown() md.reads(raw) assert len(md.nodes) == 1 and isinstance(md.nodes[0], markdown.Heading1) assert len(md.nodes[0].nodes) == 1 and isinstance(md.nodes[0].nodes[0], markdown.Heading4) assert len(md.nodes[0].nodes[0].nodes) == 2 assert isinstance(md.nodes[0].nodes[0].nodes[0], markdown.Variable) assert isinstance(md.nodes[0].nodes[0].nodes[1], markdown.Paragraph) assert not md.nodes[0].nodes[0].nodes[0].nodes assert not md.nodes[0].nodes[0].nodes[1].nodes
def handle_csv_export(csv_export_path, opts, logger): """ Args: csv_export_path (str) - path to csv file with dump from redmine opts (OptionParser opts) - dictionary containing passed options Expected CSV format is following ['#', 'Project', 'Tracker', 'Parent task', 'Status', 'Priority', 'Subject', 'Author', 'Assignee', 'Updated', 'Category', 'Target version', 'Start date', 'Due date', 'Estimated time', 'Spent time', '% Done', 'Created', 'Closed', 'Related issues', 'Private', 'Description'] """ # XXX - utf-8 returned # UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb9 in position 3625: invalid start byte # mac_roman seems to pass ... markdown_parser = markdown.MarkDown() with open(csv_export_path, encoding="mac_roman", newline="") as csvfile: csv_reader = csv.reader(csvfile, dialect=csv.Dialect.doublequote) line_no = 0 for row in csv_reader: if line_no == 0: line_no += 1 continue # skip initial heading logger.debug("Line %d %s" % (line_no, str(row))) process_row(row, markdown_parser, opts, logger) line_no += 1 # Solely for debugging of the tree structure logger.debug("Tree summary: %s" % ([str(n) for n in markdown_parser.nodes])) for h1 in markdown_parser.nodes: logger.debug("%s, %s" % (h1, [str(n) for n in h1.nodes])) if not h1.nodes: continue for h4 in h1.nodes: logger.debug("%s, %s" % (h4, [str(n) for n in h4.nodes])) if not h4.nodes: continue for h5 in h4.nodes: logger.debug("%s, %s" % (h5, [str(n) for n in h5.nodes])) # Recursive print out if not opts.no_print: markdown_parser.print_markdown_tree()
def test_process_subtask(): """ Check the Markdown tree if it matches with expectations """ raw = "# test h1\n#### test task\ndescription\n##### test subtask\ndescription\n" md = markdown.MarkDown() md.reads(raw) assert len(md.nodes) == 1 and isinstance(md.nodes[0], markdown.Heading1) assert len(md.nodes[0].nodes) == 1 and isinstance(md.nodes[0].nodes[0], markdown.Heading4) assert len(md.nodes[0].nodes[0].nodes) == 2 # TODO: Better to check whether the order of childs isn't random but this seem to work assert isinstance(md.nodes[0].nodes[0].nodes[0], markdown.Paragraph) assert isinstance(md.nodes[0].nodes[0].nodes[1], markdown.Heading5) assert not md.nodes[0].nodes[0].nodes[0].nodes assert len(md.nodes[0].nodes[0].nodes[1].nodes) == 1 and isinstance( md.nodes[0].nodes[0].nodes[1].nodes[0], markdown.Paragraph) assert not md.nodes[0].nodes[0].nodes[1].nodes[0].nodes
def test_process_variables(): """ Check the Markdown tree which contains multiple variable definitions if it matches with expectations """ raw = "# test h1\n#### test task\nvar: value\nvar2: value\ndescription\n" md = markdown.MarkDown() md.reads(raw) assert len(md.nodes) == 1 and isinstance(md.nodes[0], markdown.Heading1) assert len(md.nodes[0].nodes) == 1 and isinstance(md.nodes[0].nodes[0], markdown.Heading4) assert len(md.nodes[0].nodes[0].nodes) == 3 # TODO: Better to check whether the order of childs isn't random but this seem to work assert isinstance(md.nodes[0].nodes[0].nodes[0], markdown.Variable) assert isinstance(md.nodes[0].nodes[0].nodes[1], markdown.Variable) assert isinstance(md.nodes[0].nodes[0].nodes[2], markdown.Paragraph) assert not md.nodes[0].nodes[0].nodes[0].nodes assert not md.nodes[0].nodes[0].nodes[1].nodes assert not md.nodes[0].nodes[0].nodes[2].nodes
def test_headings1(): content = StringIO( u"""#,Project,Tracker,Parent task,Status,Priority,Subject,Author,Assignee,Updated,Category,Target version,Start date,Due date,Estimated time,Spent time,% Done,Created,Closed,Related issues,Private,Description 1,My Project,action,,Status,Priority,Test task 1,lkocman,lkocman,Updated,Category,Alpha,Start date,Due date,Estimated time,Spent time,% Done,Created,Closed,Related issues,Private,Task 1 Description 2,My Project,action,Test task 1,Status,Priority,Test task 2,lkocman,lkocman,Updated,Category,Alpha,Start date,Due date,Estimated time,Spent time,% Done,Created,Closed,Related issues,Private,Task 2 Description 3,My Project,action,,Status,Priority,Test task 3,lkocman,lkocman,Updated,Category,Beta,Start date,Due date,Estimated time,Spent time,% Done,Created,Closed,Related issues,Private,Task 3 Description 4,My Project,action,Test task 3,Status,Priority,Test task 4,lkocman,lkocman,Updated,Category,Beta,Start date,Due date,Estimated time,Spent time,% Done,Created,Closed,Related issues,Private,Task 4 Description 5,My Project,action,Parent task,Status,Priority,Test task 5,lkocman,lkocman,Updated,Category,RC,Start date,Due date,Estimated time,Spent time,% Done,Created,Closed,Related issues,Private,Task 5 Description""" ) markdown_parser = markdown.MarkDown() target_version = [] # from opts csv_reader = csv.reader(content, dialect=csv.Dialect.doublequote) line_no = 0 for row in csv_reader: if line_no == 0: line_no += 1 continue # skip initial heading redmine_csv.process_row(row, markdown_parser, target_version, logging) assert len(markdown_parser.nodes) == 3 # Alpha, Beta, RC assert str(markdown_parser.nodes[0]) == "Alpha" assert str(markdown_parser.nodes[1]) == "Beta" assert str(markdown_parser.nodes[2]) == "RC" # Alpha assert len(markdown_parser.nodes[0].nodes) == 1 # 1 Epic Task assert len( markdown_parser.nodes[0].nodes[0].nodes ) == 3 # 1 Epic Task -> 1 Subtask (consisting of 3 markdown nodes) ## Heading assert str(markdown_parser.nodes[0].nodes[0]) == "Test task 1" ## Variable assert markdown_parser.nodes[0].nodes[0].nodes[0].name == "Responsible" assert markdown_parser.nodes[0].nodes[0].nodes[0].value == "lkocman" ## Description / Paragraph assert str( markdown_parser.nodes[0].nodes[0].nodes[1]) == "Task 1 Description" ## Subtask heading node (children node) assert str(markdown_parser.nodes[0].nodes[0].nodes[2]) == "Test task 2" ## Subtask Variable assert markdown_parser.nodes[0].nodes[0].nodes[2].nodes[ 0].name == "Responsible" assert markdown_parser.nodes[0].nodes[0].nodes[2].nodes[ 0].value == "lkocman" ## Subtask description / Paragraph assert str(markdown_parser.nodes[0].nodes[0].nodes[2].nodes[1] ) == "Task 2 Description" # Beta assert len(markdown_parser.nodes[1].nodes) == 1 # 1 Epic Task assert len( markdown_parser.nodes[1].nodes[0].nodes ) == 3 # 1 Epic Task -> 1 Ttask (consisting of 3 markdown nodes) ## Heading assert str(markdown_parser.nodes[1].nodes[0]) == "Test task 3" ## Variable assert markdown_parser.nodes[1].nodes[0].nodes[0].name == "Responsible" assert markdown_parser.nodes[1].nodes[0].nodes[0].value == "lkocman" ## Description / Paragraph assert str( markdown_parser.nodes[1].nodes[0].nodes[1]) == "Task 3 Description" ## Subtask heading node (children node) assert str(markdown_parser.nodes[1].nodes[0].nodes[2]) == "Test task 4" ## Subtask Variable assert markdown_parser.nodes[1].nodes[0].nodes[2].nodes[ 0].name == "Responsible" assert markdown_parser.nodes[1].nodes[0].nodes[2].nodes[ 0].value == "lkocman" ## Subtask description / Paragraph assert str(markdown_parser.nodes[1].nodes[0].nodes[2].nodes[1] ) == "Task 4 Description" # RC assert len(markdown_parser.nodes[2].nodes) == 1 # 1 Epic Task assert len(markdown_parser.nodes[2].nodes[0].nodes ) == 2 # Description and Variable assert markdown_parser.nodes[2].nodes[0].nodes[0].name == "Responsible" assert markdown_parser.nodes[2].nodes[0].nodes[0].value == "lkocman" assert str( markdown_parser.nodes[2].nodes[0].nodes[1]) == "Task 5 Description"