Skip to content

Commit

Permalink
#27: Synergy.Documentation: Added description of using Comments As Co…
Browse files Browse the repository at this point in the history
…de into README.md
  • Loading branch information
MarcinCelej committed Jan 13, 2024
1 parent 303645b commit f5b8076
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 27 deletions.
76 changes: 73 additions & 3 deletions Documentation/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Synergy.Documentation nuget package

Here is the documentation of the Synergy.Documentation and Synergy.Documentation.Annotations nuget packages.
They were created to help developers to document their code in a simple way.
It is based on the idea of [Docs as Code](https://www.writethedocs.org/guide/docs-as-code/).

## Enlisting Public API

To enlist public API, we use the following tool:
Expand Down Expand Up @@ -110,11 +114,77 @@ When all tech debt for the project is materialized in single file - we can start
It also helps to keep track of all tech debt in the project.
Moreover, it is much easier to spot new technical debt during the code review.

## Comments in code
## Comments as code

TBC
You probably wonder why we use this approach instead of using standard comments.
For sure you heard that comments in code are bad because nobody reads them.
Actually they are invisible for developer.

To make them visible, we need to convert them into code.
To use comments as code approach, we use the following tool:

```csharp
using Synergy.Catalogue;
using Synergy.Documentation.Annotations;

namespace Synergy.Documentation.Tests.Comments;

[CodeFilePath]
public class NoteTests
{
[Fact]
public void ShowOff()
{
this.Comment("Here you have full sample of comments as code")
.Because("I want to show you how to use them")
.DoNothing("because this is just a comment")
.Because("I want to show you how to use them")
.DoNotThrowException("because this is just a comment")
.Because("I want to show you how to use them")
.Then("I want to show you how to use them")
.But("I want to show you how to use them")
.Therefore("I want to show you how to use them")
.Otherwise("I want to show you how to use them")
.Moreover("I want to show you how to use them");
}

[Fact]
public void CommentsTests()
{
try
{
var list = new List<string>(10.Because("we do not waste memory when we know exact size of the list"));

if (list.IsEmpty())
this.DoNothing("because we do not have any items in the list");
}
catch
{
this.DoNotThrowException("when something bad happens here")
.Because("this code should always work")
.Therefore("we should log the exception at least");
}
}
}
```

For sample code, please check: [NoteTests.cs](Synergy.Documentation.Tests/Comments/NoteTests.cs)

**Notes:**

- Do not use this approach to comment something obvious. Do not use ANY comment in such case.
- Use this approach to comment something that is important and you want to explain it to the reader.

[//]: # (TODO Write the documentation of Note class usage)
To learn more how to write good comments, please check: [Best practices for writing code comments](https://stackoverflow.blog/2021/12/23/best-practices-for-writing-code-comments/):
> - Rule 1: Comments should not duplicate the code.
> - Rule 2: Good comments do not excuse unclear code.
> - Rule 3: If you can't write a clear comment, there may be a problem with the code.
> - Rule 4: Comments should dispel confusion, not cause it.
> - Rule 5: Explain unidiomatic code in comments.
> - Rule 6: Provide links to the original source of copied code.
> - Rule 7: Include links to external references where they will be most helpful.
> - Rule 8: Add comments when fixing bugs.
> - Rule 9: Use comments to mark incomplete implementations.
## Generating markdown files from code - Docs as Code

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Technical Debt for Synergy.Documentation

Total: 5

## [NoteTests.cs](../../Comments/NoteTests.cs)
- TODO: Marcin Celej [from: Marcin Celej on: 08-01-2024]: Add tests for Note class
Total: 4

## [README.Generate.cs](../../Docs/README.Generate.cs)
- TODO: Marcin Celej [from: Marcin Celej on: 09-01-2024]: Extract this to a separate project Synergy.Documentation.Docs with all needed samples inside
Expand Down
40 changes: 38 additions & 2 deletions Documentation/Synergy.Documentation.Tests/Comments/NoteTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
namespace Synergy.Documentation.Tests.Comments;
using Synergy.Catalogue;
using Synergy.Documentation.Annotations;

namespace Synergy.Documentation.Tests.Comments;

[CodeFilePath]
public class NoteTests
{
// TODO: Marcin Celej [from: Marcin Celej on: 08-01-2024]: Add tests for Note class
[Fact]
public void ShowOff()
{
this.Comment("Here you have full sample of comments as code")
.Because("I want to show you how to use them")
.DoNothing("because this is just a comment")
.Because("I want to show you how to use them")
.DoNotThrowException("because this is just a comment")
.Because("I want to show you how to use them")
.Then("I want to show you how to use them")
.But("I want to show you how to use them")
.Therefore("I want to show you how to use them")
.Otherwise("I want to show you how to use them")
.Moreover("I want to show you how to use them");
}

[Fact]
public void CommentsTests()
{
try
{
var list = new List<string>(10.Because("we do not waste memory when we know exact size of the list"));

if (list.IsEmpty())
this.DoNothing("because we do not have any items in the list");
}
catch
{
this.DoNotThrowException("when something bad happens here")
.Because("this code should always work")
.Therefore("we should log the exception at least");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Synergy.Documentation.Markup;
using Synergy.Documentation.Tests.Architecture.Dependencies;
using Synergy.Documentation.Tests.Architecture.Public;
using Synergy.Documentation.Tests.Comments;

namespace Synergy.Documentation.Tests.Docs;

Expand Down Expand Up @@ -32,6 +33,9 @@ partial class README
private CodeFile RelationsOfMarkdown => this.RelationsFile.Folder.File("Relations.of.Markdown.verified.md");
private Markdown.Link RelationsOfMarkdownLink => Markdown.Link.To(this.RelationsOfMarkdown).RelativeFrom(README.readmeFile);

private CodeFile NoteTestsFile => CodeFile.For<NoteTests>();
private Markdown.Link NoteTestsLink => Markdown.Link.To(this.NoteTestsFile).RelativeFrom(README.readmeFile);

[Fact]
public void Generate()
{
Expand Down
40 changes: 27 additions & 13 deletions Documentation/Synergy.Documentation.Tests/Docs/README.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,84 +25,98 @@ public partial class README : READMEBase
/// </summary>
public virtual string TransformText()
{
this.Write("# Synergy.Documentation nuget package\r\n\r\n## Enlisting Public API\r\n\r\nTo enlist public API, we use the following tool:\r\n\r\n```csharp\r\n");
this.Write("# Synergy.Documentation nuget package\r\n\r\nHere is the documentation of the Synergy.Documentation and Synergy.Documentation.Annotations nuget packages.\r\nThey were created to help developers to document their code in a simple way.\r\nIt is based on the idea of [Docs as Code](https://www.writethedocs.org/guide/docs-as-code/).\r\n\r\n## Enlisting Public API\r\n\r\nTo enlist public API, we use the following tool:\r\n\r\n```csharp\r\n");

#line 10 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 14 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.ApiFile.ReadAllText()));

#line default
#line hidden
this.Write("\r\n```\r\n\r\nFor sample code, please check: ");

#line 13 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 17 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.ApiLink));

#line default
#line hidden
this.Write("\r\n\r\nTo see the results, please check: ");

#line 15 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 19 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.ApiForSynergyDocsLink));

#line default
#line hidden
this.Write("\r\n\r\n**Note:**\r\n\r\nWhen you expose your public API, you should be aware how it looks like from the outside - ");

#line 19 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 23 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.ApiLink));

#line default
#line hidden
this.Write(".\r\n\r\nWhen you consume some external library - you can enlist its public API and see how it looks like - ");

#line 21 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 25 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.PackageLink));

#line default
#line hidden
this.Write(".\r\n\r\n## Enlisting dependencies of a class\r\n\r\nTo document dependencies of a specific class, we use the following tool:\r\n\r\n```csharp\r\n");

#line 28 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 32 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.RelationsFile.ReadAllText()));

#line default
#line hidden
this.Write("\r\n```\r\n\r\nFor sample code, please check: ");

#line 31 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 35 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.RelationsLink));

#line default
#line hidden
this.Write("\r\n\r\nTo see the results, please check: ");

#line 33 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 37 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.RelationsOfMarkdownLink));

#line default
#line hidden
this.Write("\r\n\r\n## Managing technical debt\r\n\r\nTo manage technical debt, we use the following tool:\r\n\r\n```csharp\r\n");

#line 40 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 44 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.TodosFile.ReadAllText()));

#line default
#line hidden
this.Write("\r\n```\r\n\r\nFor sample code, please check: ");

#line 43 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 47 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.TodosLink));

#line default
#line hidden
this.Write("\r\n\r\nTo see the results, please check: ");

#line 45 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
#line 49 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.TodosDebtLink));

#line default
#line hidden
this.Write("\r\n\r\n**Note:** \r\n\r\nBasic idea of using this test is to have a list of all technical debt in the project.\r\nEach time developer adds a new technical debt, he should re-run this test otherwise it will fail on the CI.\r\nWhen all tech debt for the project is materialized in single file - we can start working on it.\r\nIt also helps to keep track of all tech debt in the project.\r\nMoreover, it is much easier to spot new technical debt during the code review.\r\n\r\n## Comments in code\r\n\r\nTBC\r\n\r\n[//]: # (TODO Write the documentation of Note class usage)\r\n\r\n## Generating markdown files from code - Docs as Code\r\n\r\nTBC\r\n\r\n[//]: # (TODO Write the documentation of Markdown class usage)\r\n\r\n");
this.Write("\r\n\r\n**Note:** \r\n\r\nBasic idea of using this test is to have a list of all technical debt in the project.\r\nEach time developer adds a new technical debt, he should re-run this test otherwise it will fail on the CI.\r\nWhen all tech debt for the project is materialized in single file - we can start working on it.\r\nIt also helps to keep track of all tech debt in the project.\r\nMoreover, it is much easier to spot new technical debt during the code review.\r\n\r\n## Comments as code\r\n\r\nYou probably wonder why we use this approach instead of using standard comments.\r\nFor sure you heard that comments in code are bad because nobody reads them.\r\nActually they are invisible for developer.\r\n\r\nTo make them visible, we need to convert them into code.\r\nTo use comments as code approach, we use the following tool:\r\n\r\n```csharp\r\n");

#line 69 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.NoteTestsFile.ReadAllText()));

#line default
#line hidden
this.Write("\r\n```\r\n\r\nFor sample code, please check: ");

#line 72 "C:\Projects\Synergy\framework\src\Documentation\Synergy.Documentation.Tests\Docs\README.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(this.NoteTestsLink));

#line default
#line hidden
this.Write("\r\n\r\n**Notes:** \r\n\r\n- Do not use this approach to comment something obvious. Do not use ANY comment in such case.\r\n- Use this approach to comment something that is important and you want to explain it to the reader.\r\n\r\nTo learn more how to write good comments, please check: [Best practices for writing code comments](https://stackoverflow.blog/2021/12/23/best-practices-for-writing-code-comments/):\r\n> - Rule 1: Comments should not duplicate the code.\r\n> - Rule 2: Good comments do not excuse unclear code.\r\n> - Rule 3: If you can't write a clear comment, there may be a problem with the code.\r\n> - Rule 4: Comments should dispel confusion, not cause it.\r\n> - Rule 5: Explain unidiomatic code in comments.\r\n> - Rule 6: Provide links to the original source of copied code.\r\n> - Rule 7: Include links to external references where they will be most helpful.\r\n> - Rule 8: Add comments when fixing bugs.\r\n> - Rule 9: Use comments to mark incomplete implementations.\r\n\r\n## Generating markdown files from code - Docs as Code\r\n\r\nTBC\r\n\r\n[//]: # (TODO Write the documentation of Markdown class usage)\r\n\r\n");
return this.GenerationEnvironment.ToString();
}
}
Expand Down
35 changes: 32 additions & 3 deletions Documentation/Synergy.Documentation.Tests/Docs/README.tt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<#@output extension=".md"#>
# Synergy.Documentation nuget package

Here is the documentation of the Synergy.Documentation and Synergy.Documentation.Annotations nuget packages.
They were created to help developers to document their code in a simple way.
It is based on the idea of [Docs as Code](https://www.writethedocs.org/guide/docs-as-code/).

## Enlisting Public API

To enlist public API, we use the following tool:
Expand Down Expand Up @@ -52,11 +56,36 @@ When all tech debt for the project is materialized in single file - we can start
It also helps to keep track of all tech debt in the project.
Moreover, it is much easier to spot new technical debt during the code review.

## Comments in code
## Comments as code

TBC
You probably wonder why we use this approach instead of using standard comments.
For sure you heard that comments in code are bad because nobody reads them.
Actually they are invisible for developer.

To make them visible, we need to convert them into code.
To use comments as code approach, we use the following tool:

```csharp
<#= this.NoteTestsFile.ReadAllText() #>
```

For sample code, please check: <#= this.NoteTestsLink #>

**Notes:**

- Do not use this approach to comment something obvious. Do not use ANY comment in such case.
- Use this approach to comment something that is important and you want to explain it to the reader.

[//]: # (TODO Write the documentation of Note class usage)
To learn more how to write good comments, please check: [Best practices for writing code comments](https://stackoverflow.blog/2021/12/23/best-practices-for-writing-code-comments/):
> - Rule 1: Comments should not duplicate the code.
> - Rule 2: Good comments do not excuse unclear code.
> - Rule 3: If you can't write a clear comment, there may be a problem with the code.
> - Rule 4: Comments should dispel confusion, not cause it.
> - Rule 5: Explain unidiomatic code in comments.
> - Rule 6: Provide links to the original source of copied code.
> - Rule 7: Include links to external references where they will be most helpful.
> - Rule 8: Add comments when fixing bugs.
> - Rule 9: Use comments to mark incomplete implementations.

## Generating markdown files from code - Docs as Code

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
<Compile Update="Docs\README.Generate.cs">
<DependentUpon>README.tt</DependentUpon>
</Compile>
<Compile Include="..\..\Synergy.Catalogue\Extensions\EnumerableExtensions.cs">
<Link>Extensions\EnumerableExtensions.cs</Link>
</Compile>
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions Synergy.Catalogue/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ namespace Synergy.Catalogue
#endif
static class EnumerableExtensions
{
public static bool IsEmpty<T>(IEnumerable<T> collection)
public static bool IsEmpty<T>(this IEnumerable<T> collection)
=> collection.Any() == false;

public static bool IsNotEmpty<T>(IEnumerable<T> collection)
public static bool IsNotEmpty<T>(this IEnumerable<T> collection)
=> collection.Any();

public static bool In<T>(this T value, params T[] values)
Expand Down

0 comments on commit f5b8076

Please sign in to comment.