Skip to content

Commit 3eab868

Browse files
authored
Merge pull request #82 from Jcparkyn/dev
Update to v1.1.0
2 parents 7899d72 + 778e490 commit 3eab868

32 files changed

+314
-183
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,4 +337,7 @@ ASALocalRun/
337337
.localhistory/
338338

339339
# BeatPulse healthcheck temp database
340-
healthchecksdb
340+
healthchecksdb
341+
342+
# Auto-generated xml documentation file
343+
Nodexr/Nodexr.xml

Nodexr.Tests/RegexParserTests/RegexParserTests.cs

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,13 @@ namespace Nodexr.Tests.RegexParserTests
1313
{
1414
class RegexParserTests
1515
{
16-
17-
18-
/* [TestCase(@"a", @"a")]
19-
public void TextNode_BasicString_ReturnsContents(string input, string expectedContents)
20-
{
21-
var result = TextParser.ParseTextWithOptionalQuantifier.ParseOrThrow(input);
22-
Assert.AreEqual(expectedContents, result.Input.Contents);
23-
}
24-
25-
[TestCase(@"a")]
26-
[TestCase(@"abc")]
27-
[TestCase(@"ab\tc")]
28-
[TestCase(@"ab\\c")]
29-
[TestCase(@"ab\\\c")]
30-
[TestCase(@"\\\*c", Ignore = "Low priority, will fix later")]
31-
public void TextNode_ValidStrings_OutputsSame(string input)
32-
{
33-
var result = RegexParser.ParseTextNode.ParseOrThrow(input);
34-
Assert.AreEqual(input, result.CachedOutput);
35-
}
36-
37-
[TestCase(@"\")]
38-
[TestCase(@"\\\")]
39-
[TestCase(@"*")]
40-
public void TextNode_InvalidStrings_Fails(string input)
41-
{
42-
TestDelegate getResult = () => RegexParser.ParseTextNode.ParseOrThrow(input);
43-
Assert.Throws<ParseException>(getResult);
44-
}*/
45-
4616
[TestCase(@"abc")]
4717
[TestCase(@"abc[abc]")]
4818
[TestCase(@"[abc]+")]
4919
[TestCase(@"(a[bc])+")]
5020
[TestCase(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$")] //Email address
5121
[TestCase(@"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$")] //Floating point
22+
[TestCase(@"^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$")] //IPv4. Contains empty group option.
5223
public void ParseRegex_OutputIsSameAsInput(string input)
5324
{
5425
var outputNode = RegexParser.ParseRegex.ParseOrThrow(input);

Nodexr/Nodexr.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0" PrivateAssets="all" />
2929
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
3030
<PackageReference Include="Pidgin" Version="2.4.0" />
31+
<PackageReference Include="Roslynator.Analyzers" Version="2.3.0">
32+
<PrivateAssets>all</PrivateAssets>
33+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
34+
</PackageReference>
3135
<PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
3236

3337
</ItemGroup>

Nodexr/Nodexr.xml

Lines changed: 59 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Nodexr/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@
1717

1818
namespace Nodexr
1919
{
20-
public class Program
20+
public static class Program
2121
{
2222
public static async Task Main(string[] args)
2323
{
2424
var builder = WebAssemblyHostBuilder.CreateDefault(args);
2525
builder.RootComponents.Add<App>("app");
2626

2727
builder.Services.AddBlazoredToast();
28-
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
28+
builder.Services.AddTransient(_ => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
2929
builder.Services.AddScoped<INodeDragService, NodeDragService>();
3030
builder.Services.AddScoped<INoodleDragService, NoodleDragService>();
3131
builder.Services.AddScoped<INodeHandler, NodeHandler>();
3232
builder.Services.AddScoped<RegexReplaceHandler>();
3333
builder.Services.AddBlazoredModal();
3434

35-
await builder.Build().RunAsync();
35+
await builder.Build().RunAsync().ConfigureAwait(false);
3636
}
3737
}
3838
}

Nodexr/Shared/Components/NoodleCollection.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
@foreach (var node in Nodes)
99
{
10-
var inputsWithNoodles = node.GetInputsRecursive()
10+
var inputsWithNoodles = node.GetAllInputs()
1111
.OfType<InputProcedural>()
1212
.Where(input => input.ConnectedNode != null);
1313

Nodexr/Shared/Components/OutputDisplay.razor

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
@inject IModalService ModalService
44
@inject NavigationManager NavManager
55
@inject IToastService ToastService
6+
@inject RegexReplaceHandler RegexReplaceHandler
67
@using Microsoft.AspNetCore.WebUtilities
78

89
<h3 style="margin:6px 10px 7px 7px; display:inline-block;">Output:</h3>
910

1011
<div class="output-regex-container">
1112
<div class="output-regex">@foreach (var segment in @NodeHandler.CachedOutput)
12-
{<OutputDisplaySegment Segment="segment" />}</div>
13+
{<OutputDisplaySegment Segment="segment" />@*This must not be surrounded by whitespace*@}</div>
1314

1415
<button title="Copy to clipboard" class="output-regex output-regex-button" @onclick="CopyTextToClipboard"><i class="far fa-clipboard"></i></button>
1516
<button title="Edit" class="output-regex output-regex-button" @onclick="OnEditButtonClick"><i class="fas fa-pencil-alt"></i></button>
@@ -44,7 +45,22 @@
4445

4546
private async Task OnCreateLinkButtonClick()
4647
{
47-
string url = QueryHelpers.AddQueryString(NavManager.BaseUri, "parse", NodeHandler.CachedOutput.Expression);
48+
var urlParams = new Dictionary<string, string>
49+
{
50+
{ "parse", NodeHandler.CachedOutput.Expression }
51+
};
52+
53+
if (RegexReplaceHandler.SearchText != RegexReplaceHandler.DefaultSearchText)
54+
{
55+
urlParams.Add("search", RegexReplaceHandler.SearchText);
56+
}
57+
58+
if (RegexReplaceHandler.ReplacementRegex != RegexReplaceHandler.DefaultReplacementRegex)
59+
{
60+
urlParams.Add("replace", RegexReplaceHandler.ReplacementRegex);
61+
}
62+
63+
string url = QueryHelpers.AddQueryString(NavManager.BaseUri, urlParams);
4864
await JSRuntime.InvokeVoidAsync("clipboardCopy.copyText", url, "");
4965
ToastService.ShowInfo("", "Link copied to clipboard");
5066
}

Nodexr/Shared/NodeInputs/InputCheckbox.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public bool IsChecked
1414
}
1515
}
1616

17-
public override int Height => 19;
17+
public override int Height => 23;
1818

1919
public InputCheckbox(bool isChecked = false)
2020
{

Nodexr/Shared/NodeInputs/InputCollection.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using Nodexr.Shared.Nodes;
2+
using System;
23
using System.Collections.Generic;
34
using System.Linq;
45

@@ -28,9 +29,10 @@ private void OnInputPositionsChanged()
2829
InputPositionsChanged?.Invoke(this, EventArgs.Empty);
2930
}
3031

31-
public void AddItem()
32+
public void AddItem(INodeOutput node = null)
3233
{
3334
var newInput = new InputProcedural() { Title = this.Title };
35+
newInput.ConnectedNode = node;
3436
newInput.ValueChanged += OnValueChanged;
3537
inputs.Add(newInput);
3638
OnInputPositionsChanged();

Nodexr/Shared/NodeInputs/InputProcedural.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Nodexr.Shared.NodeInputs
77
public class InputProcedural : NodeInput, INoodleData
88
{
99
private INodeOutput connectedNode;
10+
1011
public INodeOutput ConnectedNode
1112
{
1213
get => connectedNode;

Nodexr/Shared/NodeTypes/AnchorNode.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Nodexr.Shared.NodeTypes
99
public class AnchorNode : Node
1010
{
1111
public override string Title => "Anchor";
12+
1213
public override string NodeInfo => "Inserts a start-of-line or end-of-line character. " +
1314
"Useful for ensuring that your regex only matches if it's at a specific position in a line." +
1415
"\nNote: The \"Start/End of string\" options will match the starts and ends of individual lines when in Multiline mode.";

Nodexr/Shared/NodeTypes/CharSetNode.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Nodexr.Shared.NodeTypes
99
public class CharSetNode : Node, IQuantifiableNode
1010
{
1111
public override string Title => "Character Set";
12+
1213
public override string NodeInfo => "Inserts a character class containing the characters you specify. "
1314
+ "You can enter these the same way you would in a normal regex, including ranges (e.g. A-Z).\n"
1415
+ "The 'Invert' option creates a negated class by adding a ^ character at the start.";
@@ -33,7 +34,7 @@ public CharSetNode()
3334
SetupInputEnables();
3435
}
3536

36-
void SetupInputEnables()
37+
private void SetupInputEnables()
3738
{
3839
InputNumber.IsEnabled = () => InputCount.Value == Reps.Number;
3940
InputMin.IsEnabled = () => InputCount.Value == Reps.Range;
@@ -42,7 +43,6 @@ void SetupInputEnables()
4243

4344
protected override NodeResultBuilder GetValue()
4445
{
45-
4646
string charSet = InputCharacters.GetValue();
4747

4848
string prefix = InputDoInvert.IsChecked ? "^" : "";

Nodexr/Shared/NodeTypes/IfElseNode.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ public class IfElseNode : Node
1111
public override string NodeInfo => "Matches either of two expressions, depending on whether the 'Condition' expression has matched. " +
1212
"\nIf the name or number of a captured group is used as the 'Condition' expression, it will be considered to have matched if the group it references was matched.";
1313

14-
1514
[NodeInput]
1615
public InputString InputCondition { get; } = new InputString("") { Title = "Condition:" };
1716

@@ -21,7 +20,6 @@ public class IfElseNode : Node
2120
[NodeInput]
2221
public InputProcedural InputElse { get; set; } = new InputProcedural() { Title = "Match if false" };
2322

24-
2523
protected override NodeResultBuilder GetValue()
2624
{
2725
//return null;

Nodexr/Shared/NodeTypes/OrNode.cs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,56 @@ namespace Nodexr.Shared.NodeTypes
99
public class OrNode : Node, INode
1010
{
1111
public override string Title => "Or";
12+
1213
public override string NodeInfo => "Outputs a Regex that will accept any of the given inputs.";
1314

1415
[NodeInput]
15-
public InputCollection Inputs { get; } = new InputCollection("Option", 2);
16+
public InputCheckbox InputCapture { get; } = new InputCheckbox(false) { Title = "Capture" };
17+
18+
[NodeInput]
19+
public InputCollection Inputs { get; } = new InputCollection("Option");
20+
21+
public OrNode()
22+
{
23+
Inputs.AddItem();
24+
Inputs.AddItem();
25+
}
26+
27+
/// <summary>
28+
/// Creates an OrNode with the given nodes as inputs.
29+
/// </summary>
30+
public OrNode(IEnumerable<INodeOutput> inputs)
31+
{
32+
foreach (var input in inputs)
33+
{
34+
Inputs.AddItem(input);
35+
}
36+
}
37+
38+
/// <summary>
39+
/// Creates an OrNode with the given nodes as inputs.
40+
/// This overload is to allow easy instantiation with params.
41+
/// </summary>
42+
public OrNode(params INodeOutput[] inputs) : this(inputs as IEnumerable<INodeOutput>) { }
1643

1744
protected override NodeResultBuilder GetValue()
1845
{
1946
var builder = new NodeResultBuilder();
20-
var inputs = Inputs.Inputs.Where(input => input.IsConnected);
21-
builder.Append(@"(?:", this);
47+
var inputs = Inputs.Inputs;
48+
string prefix = InputCapture.IsChecked ? "(" : "(?:";
49+
builder.Append(prefix, this);
2250

23-
if (inputs.Any())
51+
if (inputs.Count > 0)
2452
{
2553
builder.Append(inputs.First().Value);
2654
foreach (var input in inputs.Skip(1))
2755
{
2856
builder.Append("|", this);
2957
builder.Append(input.Value);
30-
}
58+
}
3159
}
32-
builder.Append(")", this);
3360

61+
builder.Append(")", this);
3462
return builder;
3563
}
3664
}

0 commit comments

Comments
 (0)