Skip to content

Instantly share code, notes, and snippets.

@nbarbettini
Created September 30, 2017 17:01
Show Gist options
  • Save nbarbettini/24c0edc7108d5c27e67e3dfb6df7a6c0 to your computer and use it in GitHub Desktop.
Save nbarbettini/24c0edc7108d5c27e67e3dfb6df7a6c0 to your computer and use it in GitHub Desktop.
URI template parser kata
using System;
using System.Collections.Generic;
using System.Linq;
namespace UriTemplateTestKata
{
public class UriTemplate
{
public string Template { get; }
public UriTemplate(string template)
{
if (string.IsNullOrEmpty(template))
throw new ArgumentNullException(nameof(template));
Template = template;
}
public IReadOnlyDictionary<string, string> GetTokensFromUri(string uri)
{
if (string.IsNullOrEmpty(uri))
throw new ArgumentNullException(nameof(uri));
var templateTokens = Template.TrimEnd('/').Split('/');
var uriTokens = uri.TrimEnd('/').Split('/');
if (templateTokens.Length != uriTokens.Length)
throw new ArgumentException("URI does not match template");
return templateTokens
.Select((template, index) => (token: template, value: uriTokens[index]))
.Where(pair => pair.token.StartsWith('{') && pair.token.EndsWith('}'))
.ToDictionary(pair => pair.token.TrimStart('{').TrimEnd('}'), pair => pair.value);
}
}
}
using System;
using System.Collections.Generic;
using FluentAssertions;
using Xunit;
namespace UriTemplateTestKata
{
public class UriTemplateShould
{
[Fact]
public void ThrowIfUriDoesNotMatchTemplate()
{
var template = new UriTemplate("/api/{stuff}/{more}");
template.Invoking(x => x.GetTokensFromUri("/api/1")).ShouldThrow<ArgumentException>();
}
[Fact]
public void GetTokensFromUri()
{
var template = new UriTemplate("/api/v1/users/{userId}/factors/{factorId}");
var result = template.GetTokensFromUri("/api/v1/users/my-userId/factors/my-factorId") as IDictionary<string, string>;
result.Count.Should().Be(2);
result.Should().Contain("userId", "my-userId");
result.Should().Contain("factorId", "my-factorId");
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="4.19.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment