public string Compose(RequirementSpecification data)
        {
            var markdown = string.Empty;

            markdown += $"# {data.Title}\n";
            foreach (var upperRequirement in data.Requirements)
            {
                markdown += $"\n## [{upperRequirement.ID}]{upperRequirement.Summary}\n";
                markdown += $"\n### 理由\n\n{upperRequirement.Reason}\n";
                markdown += $"\n### 説明\n\n{upperRequirement.Description}\n";
                foreach (var lowerRequirement in upperRequirement.Requirements)
                {
                    markdown += $"\n### [{lowerRequirement.ID}]{lowerRequirement.Summary}\n";
                    markdown += $"\n#### 理由\n\n{lowerRequirement.Reason}\n";
                    markdown += $"\n#### 説明\n\n{lowerRequirement.Description}\n";

                    markdown += "\n#### 仕様\n";
                    foreach (var group in lowerRequirement.SpecificationGroups)
                    {
                        markdown += $"\n<{group.Category}>\n";
                        if (group.Specifications.Any())
                        {
                            markdown += "\n";
                        }
                        foreach (var specification in group.Specifications)
                        {
                            var check = specification.IsImplemented ? "x" : " ";
                            markdown += $"* [{check}] [{specification.ID}]{specification.Description}\n";
                        }
                    }
                }
            }
            return(markdown);
        }
        /// <summary>
        /// Parse a markdown document
        /// </summary>
        /// <param name="content">The markdown text</param>
        /// <returns></returns>
        public RequirementSpecification Parse(string content)
        {
            _document.Parse(content);
            status = UsdmScope.None;

            var data = new RequirementSpecification();

            foreach (var element in _document.Blocks)
            {
                switch (element.Type)
                {
                case MarkdownBlockType.Header:
                    AnalyzeHeader(element, data);
                    break;

                case MarkdownBlockType.Paragraph:
                    AnalyzeParagraph(element, data);
                    break;

                case MarkdownBlockType.List:
                    AnalyzeList(element, data);
                    break;

                default:
                    Console.WriteLine($"Type: {element.Type}");
                    Console.WriteLine(element.ToString());
                    break;
                }
            }
            return(data);
        }
        private void AnalyzeParagraph(MarkdownBlock element, RequirementSpecification data)
        {
            var item = data.Requirements.Last();

            switch (status)
            {
            case UsdmScope.UpperRequiremetReason:
                item.Reason += element.ToString() ?? string.Empty;
                break;

            case UsdmScope.UpperRequiremetDescription:
                item.Description += element.ToString() ?? string.Empty;
                break;

            case UsdmScope.LowerRequiremetReason:
                item.Requirements.Last().Reason += element.ToString() ?? string.Empty;
                break;

            case UsdmScope.LowerRequiremetDescription:
                item.Requirements.Last().Description += element.ToString() ?? string.Empty;
                break;

            case UsdmScope.Specification:
                var rawString = element.ToString();
                if (rawString != null)
                {
                    item.Requirements.Last()
                    .SpecificationGroups.Add(
                        new SpecificationGroup
                    {
                        Category = ParseUtility.ExtractGroupCategory(rawString)
                    }
                        );
                }
                break;

            default:
                Console.WriteLine($"Type: {element.Type}");
                Console.WriteLine(element.ToString());
                break;
            }
        }
        private void AnalyzeList(MarkdownBlock element, RequirementSpecification data)
        {
            switch (status)
            {
            case UsdmScope.UpperRequiremetReason:
                data.Requirements.Last().Reason += "\n" + element.ToString() ?? string.Empty;
                break;

            case UsdmScope.UpperRequiremetDescription:
                data.Requirements.Last().Description += "\n" + element.ToString() ?? string.Empty;
                break;

            case UsdmScope.LowerRequiremetReason:
                data.Requirements.Last().Requirements.Last().Reason += "\n" + element.ToString() ?? string.Empty;
                break;

            case UsdmScope.LowerRequiremetDescription:
                data.Requirements.Last().Requirements.Last().Description += "\n" + element.ToString() ?? string.Empty;
                break;

            case UsdmScope.Specification:
                var listBlock = element as ListBlock;
                if (listBlock != null)
                {
                    data.Requirements.Last()
                    .Requirements.Last()
                    .SpecificationGroups.Last()
                    .Specifications.AddRange(
                        ParseUtility.DecomposeSpecification(listBlock)
                        );
                }
                break;

            default:
                Console.WriteLine($"Type: {element.Type}");
                Console.WriteLine(element.ToString());
                break;
            }
        }
        public void DecomposeHeadingCorrectly()
        {
            var data = new RequirementSpecification
            {
                Title        = "title",
                Requirements = new List <UpperRequirement>()
                {
                    new UpperRequirement
                    {
                        ID           = "REQ01",
                        Summary      = "requirement1",
                        Reason       = "reason1",
                        Description  = "description1",
                        Requirements = new List <LowerRequirement>()
                        {
                            new LowerRequirement
                            {
                                ID                  = "REQ01-01",
                                Summary             = "requirement1-1",
                                Reason              = "reason1-1",
                                Description         = "description1-1",
                                SpecificationGroups = new List <SpecificationGroup>()
                                {
                                    new SpecificationGroup
                                    {
                                        Category       = "group",
                                        Specifications = new List <Specification>()
                                        {
                                            new Specification
                                            {
                                                IsImplemented = false,
                                                ID            = "SPC01-01-01",
                                                Description   = "description1"
                                            },
                                            new Specification
                                            {
                                                IsImplemented = true,
                                                ID            = "SPC01-01-02",
                                                Description   = "description2"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
            };

            var target = new ExcelDecoder();
            var book   = target.Decode(data);

            var sheet = book.GetSheet("title");

            Assert.Equal("要求", sheet.GetRow(0).GetCell(0).StringCellValue);
            Assert.Equal("REQ01", sheet.GetRow(0).GetCell(1).StringCellValue);
            Assert.Equal("requirement1", sheet.GetRow(0).GetCell(2).StringCellValue);
            Assert.Equal("理由", sheet.GetRow(1).GetCell(1).StringCellValue);
            Assert.Equal("reason1", sheet.GetRow(1).GetCell(2).StringCellValue);
            Assert.Equal("説明", sheet.GetRow(2).GetCell(1).StringCellValue);
            Assert.Equal("要求", sheet.GetRow(3).GetCell(1).StringCellValue);
            Assert.Equal("REQ01-01", sheet.GetRow(3).GetCell(2).StringCellValue);
            Assert.Equal("requirement1-1", sheet.GetRow(3).GetCell(3).StringCellValue);
            Assert.Equal("理由", sheet.GetRow(4).GetCell(2).StringCellValue);
            Assert.Equal("reason1-1", sheet.GetRow(4).GetCell(3).StringCellValue);
            Assert.Equal("説明", sheet.GetRow(5).GetCell(2).StringCellValue);
            Assert.Equal("description1-1", sheet.GetRow(5).GetCell(3).StringCellValue);
            Assert.Equal("<group>", sheet.GetRow(6).GetCell(2).StringCellValue);
            Assert.Equal("□", sheet.GetRow(7).GetCell(1).StringCellValue);
            Assert.Equal("SPC01-01-01", sheet.GetRow(7).GetCell(2).StringCellValue);
            Assert.Equal("description1", sheet.GetRow(7).GetCell(3).StringCellValue);
            Assert.Equal("■", sheet.GetRow(8).GetCell(1).StringCellValue);
            Assert.Equal("SPC01-01-02", sheet.GetRow(8).GetCell(2).StringCellValue);
            Assert.Equal("description2", sheet.GetRow(8).GetCell(3).StringCellValue);
        }
        private void AnalyzeHeader(MarkdownBlock element, RequirementSpecification data)
        {
            var header = element as HeaderBlock;

            if (header != null)
            {
                var text = header.ToString().Trim();
                switch (header.HeaderLevel)
                {
                case 1:
                    data.Title = text;
                    break;

                case 2:
                {
                    var info = ParseUtility.DecomposeHeading(header);
                    data.Requirements.Add(
                        new UpperRequirement
                        {
                            ID      = info.id,
                            Summary = info.summary
                        }
                        );
                }
                break;

                case 3:
                    if (text.Equals("理由"))
                    {
                        status = UsdmScope.UpperRequiremetReason;
                    }
                    else if (text.Equals("説明"))
                    {
                        status = UsdmScope.UpperRequiremetDescription;
                    }
                    else
                    {
                        var info = ParseUtility.DecomposeHeading(header);
                        data.Requirements.Last().Requirements.Add(
                            new LowerRequirement
                        {
                            ID      = info.id,
                            Summary = info.summary
                        }
                            );
                    }
                    break;

                case 4:
                    if (text.Equals("理由"))
                    {
                        status = UsdmScope.LowerRequiremetReason;
                    }
                    else if (text.Equals("説明"))
                    {
                        status = UsdmScope.LowerRequiremetDescription;
                    }
                    else if (text.Equals("仕様"))
                    {
                        status = UsdmScope.Specification;
                    }
                    break;

                default:
                    Console.WriteLine($"Text: {text}");
                    Console.WriteLine($"Level: {header.HeaderLevel}");
                    Console.WriteLine(element.ToString());
                    status = UsdmScope.None;
                    break;
                }
            }
        }
        public void ComposeCorrectly()
        {
            var expect = @"# title

## [REQ01]requirement1

### 理由

reason1

### 説明

description1

### [REQ01-01]requirement1-1

#### 理由

reason1-1

#### 説明

description1-1

#### 仕様

<group>

* [ ] [SPC01-01-01]description1
* [x] [SPC01-01-02]description2
";
            var data   = new RequirementSpecification
            {
                Title        = "title",
                Requirements = new List <UpperRequirement>()
                {
                    new UpperRequirement
                    {
                        ID           = "REQ01",
                        Summary      = "requirement1",
                        Reason       = "reason1",
                        Description  = "description1",
                        Requirements = new List <LowerRequirement>()
                        {
                            new LowerRequirement
                            {
                                ID                  = "REQ01-01",
                                Summary             = "requirement1-1",
                                Reason              = "reason1-1",
                                Description         = "description1-1",
                                SpecificationGroups = new List <SpecificationGroup>()
                                {
                                    new SpecificationGroup
                                    {
                                        Category       = "group",
                                        Specifications = new List <Specification>()
                                        {
                                            new Specification
                                            {
                                                IsImplemented = false,
                                                ID            = "SPC01-01-01",
                                                Description   = "description1"
                                            },
                                            new Specification
                                            {
                                                IsImplemented = true,
                                                ID            = "SPC01-01-02",
                                                Description   = "description2"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
            };

            var target = new MarkdownComposer();
            var actual = target.Compose(data);

            Assert.Equal(expect, actual);
        }
        public IWorkbook Decode(RequirementSpecification data)
        {
            var book = new XSSFWorkbook();

            book.CreateSheet(data.Title);

            var font = book.CreateFont();

            font.FontName = "Yu Gothic Medium";

            var headingStyle       = CreateHeadingCellStyle(book, font);
            var upperHeadingStyle  = CreateUpperHeadingCellStyle(book, font);
            var mediumHeadingStyle = CreateMediumHeadingCellStyle(book, font);
            var lowerHeadingStyle  = CreateLowerHeadingCellStyle(book, font);
            var baseStyle          = CreateBasicCellStyle(book, font);
            var itemStyle          = CreateItemCellStyle(book, font);

            var sheet = book.GetSheet(data.Title);

            var rowIndex = 0;

            foreach (var element in data.Requirements)
            {
                // 上位要求の項目の作成
                WriteCell(sheet, 0, rowIndex, "要求");
                WriteCell(sheet, 1, rowIndex, element.ID);
                WriteCell(sheet, 2, rowIndex, element.Summary);
                sheet.AddMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 2, 3));
                WriteStyle(sheet, 0, rowIndex, upperHeadingStyle);
                WriteStyle(sheet, 1, rowIndex, upperHeadingStyle);
                WriteStyle(sheet, 2, rowIndex, headingStyle);
                WriteStyle(sheet, 3, rowIndex, headingStyle);
                rowIndex++;

                // 上位要求の理由の作成
                WriteCell(sheet, 1, rowIndex, "理由");
                WriteCell(sheet, 2, rowIndex, element.Reason);
                sheet.AddMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 2, 3));
                WriteStyle(sheet, 0, rowIndex, mediumHeadingStyle);
                WriteStyle(sheet, 1, rowIndex, itemStyle);
                WriteStyle(sheet, 2, rowIndex, baseStyle);
                WriteStyle(sheet, 3, rowIndex, baseStyle);
                rowIndex++;

                // 上位要求の説明の作成
                WriteCell(sheet, 1, rowIndex, "説明");
                WriteCell(sheet, 2, rowIndex, element.Description);
                sheet.AddMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 2, 3));
                WriteStyle(sheet, 0, rowIndex, lowerHeadingStyle);
                WriteStyle(sheet, 1, rowIndex, itemStyle);
                WriteStyle(sheet, 2, rowIndex, baseStyle);
                WriteStyle(sheet, 3, rowIndex, baseStyle);
                rowIndex++;

                foreach (var item in element.Requirements)
                {
                    // 下位要求の項目の作成
                    WriteCell(sheet, 1, rowIndex, "要求");
                    WriteCell(sheet, 2, rowIndex, item.ID);
                    WriteCell(sheet, 3, rowIndex, item.Summary);
                    WriteStyle(sheet, 1, rowIndex, upperHeadingStyle);
                    WriteStyle(sheet, 2, rowIndex, upperHeadingStyle);
                    WriteStyle(sheet, 3, rowIndex, headingStyle);
                    rowIndex++;

                    // 下位要求の理由の作成
                    WriteCell(sheet, 2, rowIndex, "理由");
                    WriteCell(sheet, 3, rowIndex, item.Reason);
                    WriteStyle(sheet, 1, rowIndex, mediumHeadingStyle);
                    WriteStyle(sheet, 2, rowIndex, itemStyle);
                    WriteStyle(sheet, 3, rowIndex, baseStyle);
                    rowIndex++;

                    // 下位要求の説明の作成
                    WriteCell(sheet, 2, rowIndex, "説明");
                    WriteCell(sheet, 3, rowIndex, item.Description);
                    WriteStyle(sheet, 1, rowIndex, lowerHeadingStyle);
                    WriteStyle(sheet, 2, rowIndex, itemStyle);
                    WriteStyle(sheet, 3, rowIndex, baseStyle);
                    rowIndex++;

                    foreach (var group in item.SpecificationGroups)
                    {
                        // 仕様グループの作成
                        WriteCell(sheet, 2, rowIndex, $"<{group.Category}>");
                        WriteStyle(sheet, 1, rowIndex, baseStyle);
                        WriteStyle(sheet, 2, rowIndex, baseStyle);
                        WriteStyle(sheet, 3, rowIndex, baseStyle);
                        sheet.AddMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 2, 3));

                        rowIndex++;
                        foreach (var spec in group.Specifications)
                        {
                            // 仕様の記述
                            WriteCell(sheet, 1, rowIndex, spec.IsImplemented ? "■" : "□");
                            WriteCell(sheet, 2, rowIndex, spec.ID);
                            WriteCell(sheet, 3, rowIndex, spec.Description);
                            WriteStyle(sheet, 1, rowIndex, baseStyle);
                            WriteStyle(sheet, 2, rowIndex, baseStyle);
                            WriteStyle(sheet, 3, rowIndex, baseStyle);
                            rowIndex++;
                        }
                    }
                }
            }
            sheet.AutoSizeColumn(0);
            sheet.AutoSizeColumn(1);
            sheet.AutoSizeColumn(2);
            sheet.SetColumnWidth(3, 256 * 87 - (
                                     sheet.GetColumnWidth(0) +
                                     sheet.GetColumnWidth(1) +
                                     sheet.GetColumnWidth(2)
                                     ));
            sheet.PrintSetup.PaperSize = 9;
            return(book);
        }
示例#9
0
        public RequirementSpecification Encode(IWorkbook book)
        {
            var result = new RequirementSpecification();

            var sheet = book.GetSheetAt(0);

            result.Title = sheet.SheetName;

            var rowIndex = 0;
            var row      = sheet.GetRow(rowIndex);

            while (row != null)
            {
                var cell = row.GetCell(0);
                if (cell != null)
                {
                    var label = cell.StringCellValue;
                    if (label.Equals("要求"))
                    {
                        var id      = row.GetCell(1).StringCellValue;
                        var summary = row.GetCell(2).StringCellValue;

                        row = sheet.GetRow(++rowIndex);
                        var reason = row.GetCell(2).StringCellValue;

                        row = sheet.GetRow(++rowIndex);
                        var description = row.GetCell(2).StringCellValue;
                        result.Requirements.Add(new UpperRequirement
                        {
                            ID          = id,
                            Summary     = summary,
                            Reason      = reason,
                            Description = description,
                        });
                    }
                    else
                    {
                        throw new UsdmFormatException($"Unknown label: {label}");
                    }
                }
                else
                {
                    cell = row.GetCell(1);
                    if (cell != null)
                    {
                        var label = cell.StringCellValue;
                        if (label.Equals("要求"))
                        {
                            var id      = row.GetCell(2).StringCellValue;
                            var summary = row.GetCell(3).StringCellValue;

                            row = sheet.GetRow(++rowIndex);
                            var reason = row.GetCell(3).StringCellValue;

                            row = sheet.GetRow(++rowIndex);
                            var description = row.GetCell(3).StringCellValue;

                            result.Requirements.Last()
                            .Requirements.Add(new LowerRequirement
                            {
                                ID          = id,
                                Summary     = summary,
                                Reason      = reason,
                                Description = description,
                            });
                        }
                        else if (label.Equals(string.Empty))
                        {
                            var category = row.GetCell(2).StringCellValue;
                            result.Requirements.Last()
                            .Requirements.Last()
                            .SpecificationGroups.Add(
                                new SpecificationGroup
                            {
                                Category = ParseUtility.ExtractGroupCategory(category)
                            }
                                );
                        }
                        else if (label.Equals("■") || label.Equals("□"))
                        {
                            var isImplemented = label.Equals("■");
                            var id            = row.GetCell(2).StringCellValue;
                            var description   = row.GetCell(3).StringCellValue;
                            result.Requirements.Last()
                            .Requirements.Last()
                            .SpecificationGroups.Last()
                            .Specifications.Add(
                                new Specification
                            {
                                IsImplemented = isImplemented,
                                ID            = id,
                                Description   = description
                            }
                                );
                        }
                        else
                        {
                            throw new UsdmFormatException($"Unknown sublabel: {label}");
                        }
                    }
                }
                row = sheet.GetRow(++rowIndex);
            }

            return(result);
        }