Commit 75e59c1

mo k <mo@mokhan.ca>
2012-04-26 19:08:15
create a Collect extension method to collect results from IVisitable's
1 parent 8dc4088
src/domain/utility/IVisitor.cs
@@ -1,5 +1,8 @@
 namespace utility
 {
+  using System;
+  using System.Collections.Generic;
+
   public interface IVisitor<T>
   {
     void Visit(T item);
@@ -9,10 +12,12 @@ namespace utility
   {
     void Accept(IVisitor<T> visitor);
   }
+
   public interface IValueReturningVisitor<T, TResult> : IVisitor<T>
   {
     TResult Result();
   }
+
   public static class Visiting
   {
     public static TResult AcceptAndReturnResultFrom<T, TResult>(this IVisitable<T> visitable, IValueReturningVisitor<T, TResult> visitor)
@@ -20,5 +25,30 @@ namespace utility
       visitable.Accept(visitor);
       return visitor.Result();
     }
+
+    public static IEnumerable<T> Collect<T>( this IVisitable<T> visitable, Func<T, bool> predicate)
+    {
+      var results = new List<T>();
+      visitable.Accept(new AnonymousVisitor<T>(item =>
+      {
+        if(predicate(item)) results.Add(item);
+      }));
+      return results;
+    }
+  }
+
+  public class AnonymousVisitor<T> : IVisitor<T>
+  {
+    Action<T> visitor;
+
+    public AnonymousVisitor(Action<T> visitor) 
+    {
+      this.visitor = visitor;
+    }
+
+    public void Visit(T item)
+    {
+      visitor(item);
+    }
   }
 }
src/domain/EstimatedNetProductionFor.cs
@@ -2,7 +2,7 @@ namespace domain
 {
   using utility;
 
-  public class EstimatedNetProductionFor<T> : IValueReturningVisitor<IWell, IQuantity> where T : ICommodity, new()
+  public class EstimatedNetProductionFor<Commodity> : IValueReturningVisitor<IWell, IQuantity> where Commodity : ICommodity, new()
   {
     Month month;
     IQuantity result;
@@ -15,7 +15,7 @@ namespace domain
 
     public void Visit(IWell well)
     {
-      result = result.Plus(well.NetProductionFor<T>(month));
+      result = result.Plus(well.NetProductionFor<Commodity>(month));
     }
 
     public IQuantity Result()
src/domain/GasPlant.cs
@@ -34,27 +34,25 @@ namespace domain
 
     public IEnumerable<Month> MonthsOverAvailableCapacity()
     {
-      return MonthsOverAvailableCapacity(Month.Now().UpTo(new Month(2099, 12)));
+      return MonthsOverAvailableCapacity(Month.Now().UpTo(Month.Infinity));
     }
 
-    public virtual IQuantity AvailableCapacityFor(Month month){
-      throw new System.NotImplementedException();
+    public virtual IQuantity AvailableCapacityFor(Month month)
+    {
+      return capacity.AvailableFor(month);
     }
 
     public IEnumerable<Month> MonthsOverAvailableCapacity(IRange<Month> months)
     {
-      var results = new List<Month>();
-      months.Accept(month =>
+      return months.Collect( month =>
       {
-        if(IsOverCapacity(month))
-          results.Add(month);
+        return IsOverCapacity(month);
       });
-      return results;
     }
 
     bool IsOverCapacity(Month month)
     {
-      return capacity.AvailableFor(month).IsGreaterThan(TotalProductionFor(month));
+      return AvailableCapacityFor(month).IsGreaterThan(TotalProductionFor(month));
     }
 
     IQuantity TotalProductionFor(Month month)
src/domain/Range.cs
@@ -1,6 +1,7 @@
 namespace domain
 {
   using System;
+  using utility;
 
   public static class Ranges
   {
@@ -10,7 +11,7 @@ namespace domain
     }
   }
 
-  public interface IRange<T> where T : IComparable<T>
+  public interface IRange<T> : IVisitable<T> where T : IComparable<T>
   {
     void Accept(Action<T> action);
     bool Contains(T item);
@@ -27,6 +28,11 @@ namespace domain
       this.end = end;
     }
 
+    public void Accept(IVisitor<T> visitor) 
+    {
+      Accept(visitor.Visit);
+    }
+
     public void Accept(Action<T> visitor)
     {
       var next = this.start;
src/test/GasPlantSpecs.cs
@@ -44,5 +44,20 @@ namespace test
       static IWell firstWell;
       static IWell secondWell;
     }
+    public class when_retrieving_the_available_capacity_for_a_month
+    {
+      It should_return_the_correct_amount = () =>
+      {
+        result.ShouldEqual(30m.MCF());
+      };
+
+      Because of = () =>
+      {
+        sut.IncreaseCapacityTo(30m.MCF(),Month.Now());
+        result = sut.AvailableCapacityFor(Month.Now());
+      };
+
+      static IQuantity result;
+    }
   }
 }