Skip to content

Commit

Permalink
Fix #9
Browse files Browse the repository at this point in the history
  • Loading branch information
Keuvain committed Aug 7, 2016
1 parent fcff846 commit 0efc969
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,4 @@ paket-files/
.idea/
*.sln.iml
tools/
_site/
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Strinken

**Warning:** Documentation is for version 2.0.0 and is not up to date with the current state of the repo as
some things are being rewritten.

---

[![NuGet](https://img.shields.io/nuget/v/Strinken.svg)](https://www.nuget.org/packages/Strinken/)
[![GitHub release](https://img.shields.io/github/release/k94ll13nn3/Strinken.svg)](https://github.com/k94ll13nn3/Strinken/releases/latest)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/k94ll13nn3/Strinken/master/LICENSE)
Expand Down
16 changes: 16 additions & 0 deletions src/Strinken/Common/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// stylecop.header
namespace Strinken.Common
{
/// <summary>
/// Collection of common extensions methods.
/// </summary>
internal static class Extensions
{
/// <summary>
/// Tests if a <see cref="char"/> is a valid token name character : a-z, A-Z, 0-9, - and _
/// </summary>
/// <param name="c">The <see cref="char"/> to test.</param>
/// <returns>A value indicating whether the <see cref="char"/> is a valid token name character</returns>
public static bool IsValidTokenNameCharacter(this char c) => !char.IsLetter(c) && c != '-' && c != '_';
}
}
3 changes: 2 additions & 1 deletion src/Strinken/Engine/StrinkenEngine.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// stylecop.header
using System;
using System.Text;
using Strinken.Common;
using Strinken.Machine;

namespace Strinken.Engine
Expand Down Expand Up @@ -438,7 +439,7 @@ private static State ProcessOutsideToken(Cursor cursor, StringBuilder result)
private static void ThrowIfInvalidCharacter(Cursor cursor)
{
var value = (char)cursor.Value;
if (!char.IsLetter(value) && cursor.Value != '-' && cursor.Value != '_')
if (value.IsValidTokenNameCharacter())
{
throw new FormatException($"Illegal '{(char)cursor.Value}' at position {cursor.Position}");
}
Expand Down
29 changes: 21 additions & 8 deletions src/Strinken/Parser/Parser`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Strinken.Common;
using Strinken.Engine;
using Strinken.Filters;

Expand Down Expand Up @@ -132,11 +133,7 @@ public void AddFilter(IFilter filter)
throw new ArgumentException($"{filter.Name} was already registered in the filter list.");
}

if (string.IsNullOrWhiteSpace(filter.Name))
{
throw new ArgumentException("A filter cannot have an empty name.");
}

ThrowIfInvalidName(filter.Name);
this.filters.Add(filter.Name, filter);
}

Expand All @@ -151,12 +148,28 @@ public void AddTag(ITag<T> tag)
throw new ArgumentException($"{tag.Name} was already registered in the tag list.");
}

if (string.IsNullOrWhiteSpace(tag.Name))
ThrowIfInvalidName(tag.Name);
this.tags.Add(tag.Name, tag);
}

/// <summary>
/// Validates a name and throws a <see cref="ArgumentException"/> if the name is invalid.
/// </summary>
/// <param name="name">The name to validate.</param>
private static void ThrowIfInvalidName(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("A tag cannot have an empty name.");
throw new ArgumentException("A name cannot be empty.");
}

this.tags.Add(tag.Name, tag);
for (int i = 0; i < name.Length; i++)
{
if (name[i].IsValidTokenNameCharacter())
{
throw new ArgumentException($"{name[i]} is an invalid character for a name.");
}
}
}
}
}
25 changes: 22 additions & 3 deletions test/Strinken.Tests/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,37 @@ public void Constructor_TagWithEmptyName_ThrowsArgumentException()
{
Assert.That(
() => new Parser<string>().WithTag("", "", s => s),
Throws.ArgumentException.With.Message.EqualTo("A tag cannot have an empty name."));
Throws.ArgumentException.With.Message.EqualTo("A name cannot be empty."));
Assert.That(
() => new Parser<string>().WithTag(new EmptyNameTag()),
Throws.ArgumentException.With.Message.EqualTo("A tag cannot have an empty name."));
Throws.ArgumentException.With.Message.EqualTo("A name cannot be empty."));
}

[Test]
public void Constructor_FilterWithEmptyName_ThrowsArgumentException()
{
Assert.That(
() => new Parser<string>().WithTag("tag", "tag", s => s).WithFilter(new EmptyNameFilter()),
Throws.ArgumentException.With.Message.EqualTo("A filter cannot have an empty name."));
Throws.ArgumentException.With.Message.EqualTo("A name cannot be empty."));
}

[Test]
public void Constructor_TagWithInvalidName_ThrowsArgumentException()
{
Assert.That(
() => new Parser<string>().WithTag("st*r", "", s => s),
Throws.ArgumentException.With.Message.EqualTo("* is an invalid character for a name."));
Assert.That(
() => new Parser<string>().WithTag(new InvalidNameTag()),
Throws.ArgumentException.With.Message.EqualTo("$ is an invalid character for a name."));
}

[Test]
public void Constructor_FilterWithInvalidName_ThrowsArgumentException()
{
Assert.That(
() => new Parser<string>().WithTag("tag", "tag", s => s).WithFilter(new InvalidNameFilter()),
Throws.ArgumentException.With.Message.EqualTo("! is an invalid character for a name."));
}

[Test]
Expand Down
15 changes: 15 additions & 0 deletions test/Strinken.Tests/TestsClasses/InvalidNameFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Strinken.Parser;

namespace Strinken.Tests.TestsClasses
{
public class InvalidNameFilter : IFilter
{
public string Description => string.Empty;
public string Name => "name!";
public string Usage => string.Empty;

public string Resolve(string value, string[] arguments) => value;

public bool Validate(string[] arguments) => true;
}
}
12 changes: 12 additions & 0 deletions test/Strinken.Tests/TestsClasses/InvalidNameTag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Strinken.Parser;

namespace Strinken.Tests.TestsClasses
{
public class InvalidNameTag : ITag<string>
{
public string Description => string.Empty;
public string Name => "dollar$";

public string Resolve(string value) => value;
}
}

0 comments on commit 0efc969

Please sign in to comment.