Commit c6bf372
Changed files (7)
src
src/domain/GasPlant.cs
@@ -8,6 +8,7 @@ namespace domain
public interface IFacility
{
void AcceptFlowFrom(IWell well);
+ IQuantity AvailableCapacityFor(Month month);
}
public class GasPlant : IFacility
@@ -36,6 +37,10 @@ namespace domain
return MonthsOverAvailableCapacity(Month.Now().UpTo(new Month(2099, 12)));
}
+ public virtual IQuantity AvailableCapacityFor(Month month){
+ throw new System.NotImplementedException();
+ }
+
public IEnumerable<Month> MonthsOverAvailableCapacity(IRange<Month> months)
{
var results = new List<Month>();
src/domain/Production.cs
@@ -18,6 +18,16 @@ namespace domain
return month.Equals(otherMonth);
}
+ public virtual bool OccursDuring(IRange<Month> period)
+ {
+ return period.Contains(this.month);
+ }
+
+ public virtual bool IsGreaterThanAvailableAt(IFacility facility)
+ {
+ return facility.AvailableCapacityFor(this.month).IsGreaterThan(produced);
+ }
+
public IQuantity ProductionOf<T>() where T : ICommodity, new()
{
return split.PercentageOf<T>(produced);
src/domain/Range.cs
@@ -13,6 +13,7 @@ namespace domain
public interface IRange<T> where T : IComparable<T>
{
void Accept(Action<T> action);
+ bool Contains(T item);
}
public class Range<T> : IRange<T> where T : IComparable<T>, IIncrementable<T>
@@ -36,6 +37,11 @@ namespace domain
next = next.Next();
}
}
+
+ public bool Contains(T item)
+ {
+ return start.CompareTo(item) <= 0 && end.CompareTo(item) > 0;
+ }
}
public interface IIncrementable<T>
src/domain/TypeCurve.cs
@@ -1,5 +1,6 @@
namespace domain
{
+ using System;
using System.Linq;
using System.Collections.Generic;
@@ -18,5 +19,9 @@ namespace domain
{
return production.Single(x => x.IsFor(month)).ProductionOf<Commodity>();
}
+
+ public virtual void Accept(Action<Production> visitor)
+ {
+ }
}
}
src/domain/Well.cs
@@ -32,8 +32,22 @@ namespace domain
public void FlowInto(IFacility facility)
{
ensure_that_this_well_is_not_already_flowing_into_a_plant();
- this.facility = facility;
+ ensure_that_this_well_does_not_overflow_the_plant(facility);
facility.AcceptFlowFrom(this);
+ this.facility = facility;
+ }
+
+ void ensure_that_this_well_does_not_overflow_the_plant(IFacility facility)
+ {
+ var period = initialProductionMonth.UpTo(new Month(2099, 12));
+ this.curve.Accept( production =>
+ {
+ if( production.OccursDuring(period)){
+ if(production.IsGreaterThanAvailableAt(facility)){
+ throw new Exception();
+ }
+ }
+ });
}
void ensure_that_this_well_is_not_already_flowing_into_a_plant()
src/test/RangeSpecs.cs
@@ -23,12 +23,40 @@ namespace test
Because of = () =>
{
sut.Accept(x =>
- {
- results.Add(x);
- });
+ {
+ results.Add(x);
+ });
};
static IList<Month> results = new List<Month>();
}
+ public class when_a_range_contains_an_item
+ {
+ It should_return_true=()=>
+ {
+ result.ShouldBeTrue();
+ };
+
+ Because of = ()=>
+ {
+ result = sut.Contains(new Month(2012, 02));
+ };
+
+ static bool result;
+ }
+ public class when_an_item_is_before_the_range{
+ It should_return_false=()=>
+ {
+ var result = sut.Contains(new Month(2011, 12));
+ result.ShouldBeFalse();
+ };
+ }
+ public class when_an_item_is_after_the_range{
+ It should_return_false=()=>
+ {
+ var result = sut.Contains(new Month(2012, 04));
+ result.ShouldBeFalse();
+ };
+ }
}
}
src/test/WellSpecs.cs
@@ -3,15 +3,17 @@ namespace test
using Machine.Specifications;
using domain;
using System;
+ using Rhino.Mocks;
public class WellSpecs
{
Establish context = () =>
{
- var typeCurve = Mock.An<TypeCurve>();
+ typeCurve = Mock.An<TypeCurve>();
sut = new Well(Month.Now(), 100m.Percent(), typeCurve );
};
static IWell sut;
+ static TypeCurve typeCurve;
public class when_flowing_a_gas_well_into_a_gas_plant
{
@@ -35,6 +37,39 @@ namespace test
};
}
+ public class when_the_plant_would_overflow_if_it_accepted_flow_from_this_well
+ {
+ It should_not_let_you_flow_this_well_into_the_facility=()=>
+ {
+ exception.ShouldNotBeNull();
+ };
+
+ Establish context = ()=>
+ {
+ var jan2013 = 2013.January();
+ var feb2013 = 2013.February();
+ typeCurve
+ .Stub(x => x.Accept( Arg<Action<Production>>.Is.Anything ))
+ .WhenCalled(x =>
+ {
+ var splits = new CommoditySplits();
+ splits.SplitFor<Gas>(100m.Percent());
+ var action = x.Arguments[0] as Action<Production>;
+ action(new Production(jan2013,100m.BOED(),splits ));
+ action(new Production(feb2013, 91m.BOED(), splits));
+ });
+ gasPlant.Stub(x => x.AvailableCapacityFor(jan2013)).Return(100m.BOED());
+ gasPlant.Stub(x => x.AvailableCapacityFor(feb2013)).Return(90m.BOED());
+ };
+
+ Because of = ()=>
+ {
+ exception = Catch.Exception(()=> sut.FlowInto(gasPlant));
+ };
+
+ static Exception exception;
+ }
+
public class when_a_well_is_already_flowing_into_a_facility
{
It should_not_allow_you_to_flow_into_another_plant=()=>