Skip to content

Commit d2ca700

Browse files
committed
Added the command controller
does complex things like saving w/o blocking the UI thread
1 parent c4782af commit d2ca700

File tree

7 files changed

+150
-21
lines changed

7 files changed

+150
-21
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Threading;
2+
using Moq;
3+
using Xunit;
4+
5+
namespace Jump.Location.Specs
6+
{
7+
public class CommandControllerSpec
8+
{
9+
public class DescribeUpdateTimes
10+
{
11+
private readonly Mock<IDatabase> dbMock;
12+
private readonly Mock<IFileStoreProvider> fsMock;
13+
private readonly CommandController controller;
14+
15+
public DescribeUpdateTimes()
16+
{
17+
dbMock = new Mock<IDatabase>();
18+
fsMock = new Mock<IFileStoreProvider>();
19+
controller = new CommandController(dbMock.Object, fsMock.Object);
20+
}
21+
22+
[Fact]
23+
public void It_saves_eventually()
24+
{
25+
controller.UpdateLocation("foo");
26+
Thread.Sleep(30);
27+
fsMock.Verify(x => x.Save(dbMock.Object));
28+
}
29+
}
30+
}
31+
}

Jump.Location.Specs/DatabaseSpec.cs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,59 @@ namespace Jump.Location.Specs
77
{
88
public class DatabaseSpec
99
{
10-
[Fact]
11-
public void It_adds_a_new_record_by_path()
10+
public class DescribeAdding
1211
{
13-
var db = new Database();
14-
db.Add("full::path");
15-
db.Records.Count().ShouldEqual(1);
12+
[Fact]
13+
public void It_adds_a_new_record_by_path()
14+
{
15+
var db = new Database();
16+
db.Add("full::path");
17+
db.Records.Count().ShouldEqual(1);
18+
}
19+
20+
[Fact]
21+
public void It_adds_a_new_record_by_object()
22+
{
23+
var db = new Database();
24+
db.Add(Mock.Of<IRecord>());
25+
db.Records.Count().ShouldEqual(1);
26+
}
1627
}
1728

18-
[Fact]
19-
public void It_adds_a_new_record_by_object()
29+
public class DescribeFindingByFullName
2030
{
21-
var db = new Database();
22-
db.Add(Mock.Of<IRecord>());
23-
db.Records.Count().ShouldEqual(1);
31+
[Fact]
32+
public void It_returns_the_matching_record()
33+
{
34+
var db = new Database();
35+
db.Add(Mock.Of<IRecord>(x => x.FullName == "foo"));
36+
db.Add(Mock.Of<IRecord>(x => x.FullName == "bar"));
37+
38+
db.GetByFullName("bar").ShouldNotBeNull();
39+
}
40+
41+
[Fact]
42+
public void It_creates_a_record_when_missing()
43+
{
44+
var db = new Database();
45+
db.Add(Mock.Of<IRecord>(x => x.FullName == "foo"));
46+
db.Add(Mock.Of<IRecord>(x => x.FullName == "bar"));
47+
48+
var baz = db.GetByFullName("foo::bar");
49+
baz.ShouldNotBeNull();
50+
baz.ShouldBeType<Record>();
51+
}
52+
53+
[Fact]
54+
public void It_adds_the_missing_record_to_its_list()
55+
{
56+
var db = new Database();
57+
db.Add(Mock.Of<IRecord>(x => x.FullName == "foo"));
58+
db.Add(Mock.Of<IRecord>(x => x.FullName == "bar"));
59+
60+
db.GetByFullName("foo::bar");
61+
db.Records.Count().ShouldEqual(3);
62+
}
2463
}
2564
}
2665
}

Jump.Location.Specs/Jump.Location.Specs.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
</Reference>
5555
</ItemGroup>
5656
<ItemGroup>
57+
<Compile Include="CommandControllerSpec.cs" />
5758
<Compile Include="DatabaseSpec.cs" />
5859
<Compile Include="DirectoryWaitPeriodSpec.cs" />
5960
<Compile Include="FileStoreProviderSpec.cs" />

Jump.Location/CommandController.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace Jump.Location
6+
{
7+
class CommandController
8+
{
9+
private readonly IDatabase database;
10+
private readonly IFileStoreProvider fileStore;
11+
private bool needsToSave;
12+
13+
public CommandController(IDatabase database, IFileStoreProvider fileStore)
14+
{
15+
this.database = database;
16+
this.fileStore = fileStore;
17+
Task.Factory.StartNew(SaveLoop);
18+
}
19+
20+
public CommandController(string path)
21+
:this(new Database(), new FileStoreProvider(path))
22+
{
23+
}
24+
25+
public void UpdateLocation(string fullName)
26+
{
27+
var record = database.GetByFullName(fullName);
28+
needsToSave = true;
29+
}
30+
31+
private void SaveLoop()
32+
{
33+
while(true)
34+
{
35+
if (needsToSave)
36+
{
37+
try
38+
{
39+
needsToSave = false;
40+
fileStore.Save(database);
41+
}
42+
catch(Exception e)
43+
{
44+
Console.Error.WriteLine("Jump-Location received {0}: {1}", e.GetType().Name, e.Message);
45+
}
46+
}
47+
else Thread.Sleep(0);
48+
}
49+
}
50+
}
51+
}

Jump.Location/Database.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Linq;
23

34
namespace Jump.Location
45
{
@@ -7,6 +8,7 @@ public interface IDatabase
78
IEnumerable<IRecord> Records { get; }
89
void Add(string fullPath);
910
void Add(IRecord record);
11+
IRecord GetByFullName(string fullName);
1012
}
1113

1214
class Database : IDatabase
@@ -24,5 +26,18 @@ public void Add(IRecord record)
2426
{
2527
records.Add(record);
2628
}
29+
30+
public IRecord GetByFullName(string fullName)
31+
{
32+
var record = records.FirstOrDefault(x => x.FullName == fullName);
33+
34+
if (record == null)
35+
{
36+
record = new Record(fullName);
37+
Add(record);
38+
}
39+
40+
return record;
41+
}
2742
}
2843
}

Jump.Location/Jump.Location.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
<Reference Include="System.Xml" />
5959
</ItemGroup>
6060
<ItemGroup>
61+
<Compile Include="CommandController.cs" />
6162
<Compile Include="Database.cs" />
6263
<Compile Include="DirectoryWaitPeriod.cs" />
6364
<Compile Include="FileStoreProvider.cs" />

Jump.Location/JumpLocationCommand.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
using System;
22
using System.Linq;
33
using System.Management.Automation;
4-
using System.Management.Automation.Runspaces;
5-
using Microsoft.PowerShell.Commands;
64

75
namespace Jump.Location
86
{
97
[Cmdlet("Jump", "Location")]
108
public class JumpLocationCommand : PSCmdlet
119
{
1210
private static bool _hasRegisteredDirectoryHook;
13-
private Container container;
11+
private static readonly CommandController Controller = new CommandController(@"C:\jump-location.db");
1412

1513
/*
1614
* 1. Figure out how long they stay in the directory
@@ -22,21 +20,14 @@ public class JumpLocationCommand : PSCmdlet
2220
[Parameter(Position = 0)]
2321
public string Directory { get; set; }
2422

25-
class Container
26-
{
27-
public string Last { get; set; }
28-
}
29-
30-
private static int counter = 0;
3123
public static void UpdateTime(string location)
3224
{
33-
Console.WriteLine(location);
25+
Controller.UpdateLocation(location);
3426
}
3527

3628
protected override void BeginProcessing()
3729
{
3830
base.BeginProcessing();
39-
container = container ?? new Container();
4031

4132
if (_hasRegisteredDirectoryHook) return;
4233

0 commit comments

Comments
 (0)