Unit testing lists with CollectionAssert.AreEquivalent() - c#

First, I would like to let you know that this is part of a homework exercise over Unit Testing.
What I need the test to do: I need to test that the list "actual" is equivalent to the list "expected".
This test fails and I receive this message:
CreatePurchasableList_IncludesExpectedItems
Source: GrandTotal.UnitTests.cs line 13
Duration: 30 ms
Message:
CollectionAssert.AreEquivalent failed. The expected collection contains 1 occurrence(s) of <GrandTotal_exercise.Appointment>. The actual collection contains 0 occurrence(s).
Stack Trace:
ProgramTests.CreatePurchasableList_IncludesExpectedItems() line 51
The method we want to test...
public static List<IPurchasable> CreatePurchasableList()
{
var appointment = new Appointment()
{
Name = "James",
StartDateTime = DateTime.Now.AddHours(1),
EndDateTime = DateTime.Now.AddHours(2),
Price = 100D
};
var book = new Book()
{
Title = "Welcome to Advanced C#",
Price = 50D,
TaxRate = 0.0825D,
ShippingRate = 5D
};
var snack = new Snack()
{
Price = 2D
};
var tshirt = new TShirt()
{
Size = "2X",
Price = 25D,
TaxRate = 0.0625D,
ShippingRate = 2
};
var items = new List<IPurchasable>();
items.Add(appointment);
items.Add(book);
items.Add(snack);
items.Add(tshirt);
return items;
}
TestMethod...
[TestMethod]
public void CreatePurchasableList_IncludesExpectedItems()
{
//Arrange
var appointment = new Appointment()
{
Name = "James",
StartDateTime = DateTime.Now.AddHours(1),
EndDateTime = DateTime.Now.AddHours(2),
Price = 100D
};
var book = new Book()
{
Title = "Welcome to Advanced C#",
Price = 50D,
TaxRate = 0.0825D,
ShippingRate = 5D
};
var snack = new Snack()
{
Price = 2D
};
var tshirt = new TShirt()
{
Size = "2X",
Price = 25D,
TaxRate = 0.0625D,
ShippingRate = 2
};
var expectedList = new List<IPurchasable>();
var purchasableListActual = Program.CreatePurchasableList();
//Act
expectedList.Add(appointment);
expectedList.Add(book);
expectedList.Add(snack);
expectedList.Add(tshirt);
//Assert
CollectionAssert.AreEquivalent(expectedList, purchasableListActual);
}
To be more clear I want to ensure that both tests include "appointment", "book", "snack", and "t-shirt".
I do not care what is inside of these objects or the order that they are in.

Related

Grouping and summing by Linq

I would like to get the total order amount for each customer with Linq, I know I need to group and sum I have only succeeded to group without summing the whole amount for each order.
var OrderByCustumer = new[] {
new { name = "cust1", order = 400 },
new { name = "cust1", order = 250 },
new { name = "cust1", order = 130 },
new { name = "cust2", order = 30 },
new { name = "cust3", order = 205}
};
var res= OrderByCustumer.GroupBy(x=>x.name).Select((x,y)=>new{
a=x.Key
});
foreach(var a in res){
Console.WriteLine(a);
}
.**
OutPut
a = cust1
a = cust2
a = cust3
**
Try this
var res = OrderByCustumer.GroupBy(x => x.name).Select(x => new {
a = x.Key,
sum = x.Sum(c => c.order)
});
foreach (var item in res)
{
Console.WriteLine($"{ item.a} - Sum = {item.sum}");
}

"select" query using "PetaPoco" ORM

I tried something like the following, but it didn't work.
var _records = new string[] {"SqlServer", "IIS" };
var result = db.Fetch<EntityRecords>(#" select * from tblRecords where RecordName IN rs", new { rs = _records });
and also i have tried another way like the following, but same problem
var _records = new string[] {"SqlServer", "IIS" };
var query = PetaPoco.Sql.Builder.Select("*").From("tblRecords").Where("RecordName IN (#rs)",new { rs = _records });
var result = db.Query<EntityRecords>(query);
The first one should be
var result = db.Fetch<EntityRecords>(#" select * from tblRecords where RecordName IN (#rs)", new { rs = _records });
or
var result = db.Fetch<EntityRecords>(#" select * from tblRecords where RecordName IN (#0)", _records);
The second one I'm not too sure about because the following tests pass
[Fact]
public void Append_GivenArrayAndValue_ShouldBeValid()
{
// Simple collection parameter expansion
_sql = Sql.Builder.Append("#0 IN (#1) #2", 20, new int[] { 1, 2, 3 }, 30);
_sql.SQL.ShouldBe("#0 IN (#1,#2,#3) #4");
_sql.Arguments.Length.ShouldBe(5);
_sql.Arguments[0].ShouldBe(20);
_sql.Arguments[1].ShouldBe(1);
_sql.Arguments[2].ShouldBe(2);
_sql.Arguments[3].ShouldBe(3);
_sql.Arguments[4].ShouldBe(30);
}
[Fact]
public void Append_GivenArrayAndNamedValue_ShouldBeValid1()
{
// Simple collection parameter expansion
_sql = Sql.Builder.Append("#p1 IN (#p2) #p3", new { p1 = 20 }, new { p2 = new int[] { 1, 2, 3 }}, new { p3 = 30 });
_sql.SQL.ShouldBe("#0 IN (#1,#2,#3) #4");
_sql.Arguments.Length.ShouldBe(5);
_sql.Arguments[0].ShouldBe(20);
_sql.Arguments[1].ShouldBe(1);
_sql.Arguments[2].ShouldBe(2);
_sql.Arguments[3].ShouldBe(3);
_sql.Arguments[4].ShouldBe(30);
}

c# Linq List add entry

I have this C# LINQ
List<RateRecord> ls = occupancyList.Where(s => s.publish_flag.Contains("0020")).Select(x => new RateRecord()
{
RATECODE = x.rate_code.Trim(),
Occ = new List<RateRecordDtl>()
{
new RateRecordDtl { date = dateFromShort, pricing = new List<Pricing>() {new Pricing {adults = 2, price = x.rate }}
}
}
).ToList();
I want to add to the List a second Pricing object {adults = 1, price = x.rate }
How can I achieve that?
Add a comma and another Pricing object:
List<RateRecord> ls = occupancyList.Where(s => s.publish_flag.Contains("0020")).Select(x => new RateRecord()
{
RATECODE = x.rate_code.Trim(),
Occ = new List<RateRecordDtl>()
{
new RateRecordDtl { date = dateFromShort, pricing = new List<Pricing>() {
new Pricing {adults = 2, price = x.rate },
new Pricing {adults = 1, price = x.rate }}
}
}
).ToList();

C# Dynamic array

I want an array to contain strings, floats and ints that can be accessed via an index key.
I have an example in Lua how you would do but I don't know how you do it in C#
bookArray = [];
bookArray[1] =
{
Name = "Book 1";
Price = 50;
WPP = 374;
Pages = 42;
}
You may create a class and use List<MyClass>
class MyClass
{
public string Name {get;set;}
public double Price {get;set;}
public int Pages {get;set;}
}
Here is the list:
List<MyClass> values = new List<MyClass>();
Adding item
values.Add(new MyClass(){Name = "Book 1", Pages = 42, Price=50.0});
Insert at specific index:
values.Insert(0,new MyClass(){Name = "Book 2", Pages = 432, Price=10.0});
Retrieve at specific index:
MyClass theClass = values[1];
If you are ok with your inner type being immutable, you could do this:
var ar = new[] {
new { Name = "Book 1", Price = 50, WPP = 374, Pages = 42 },
new { Name = "Book 2", Price = 55, WPP = 220, Pages = 129 }
};
Which is about as close as you can come to the Lua definition

Populating a highchart graph from a linq query

I am trying to populate a chart with data from my database. I'm using Entity framework and fairly new to asp.net.
What I'm trying to do is populate the chart from my linq query.
var totals = from s in db.ClassInstanceDetails.Include("ClassInstance")
where s.ClassInstance.ClassID == 2
group s by s.ClassInstance.Date into grouped
select new
{
CIDate = grouped.Key,
TotalStudentsInClass = grouped.Count(s => s.Attendance)
};
The linq query works fine, it counts all the students in a classinstance, groups them and counts them. My problem is how do extract the data and put it into the chart. When I debug I can see that the totals variable is
{System.Data.Objects.ObjectQuery<<>f__AnonymousType0<System.DateTime,int>>}
and I can see the results view held by totals as :
{CIDate = {04/09/2012}, TotalStudentsInClass = 5}
{CIDate = {05/09/2012}, TotalStudentsInClass = 7}
{CIDate = {06/09/2012}, TotalStudentsInClass = 14}
Which is great as the query works, it finds how many pupils attended a particular class instance. I'm trying to put this data into a line graph using highcharts. I've tried to separate the linq results into 2 arrays one array containing the dates and another array containing the TotalStudentsInClass value but having no luck as the types are different??? Is this even the right way to do this?
The example I found online pulls from an array I think
.SetSeries(new[]
{
new Series { Name = "Tokyo", Data = new Data(ChartsData.TokioData) },
new Series { Name = "New York", Data = new Data(ChartsData.NewYorkData) },
new Series { Name = "Berlin", Data = new Data(ChartsData.BerlinData) },
new Series { Name = "London", Data = new Data(ChartsData.LondonData) }
}
with the data coming from an object,
public static object[] TokioData = new object[] { 7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6 };
I've tried to run my linq query into an object but that throws me more errors than I know what to do with!!
Any help would be GREATLY appreciated!!
Chart
public static Highcharts TimeSeriesZoomable(Series[] Series, Number MinRange, Number PointInterval, DateTime PointStartDate, AxisTypes XAxisType = AxisTypes.Datetime, string Title = "", string SubTitle = "", string XAxisTitle = "", string YAxisTitle = "", string ToolTipFormat = "", string YAxisLabel = "")
{
Highcharts chart = new Highcharts("chart")
.SetOptions(new GlobalOptions { Global = new Global { UseUTC = false } })
.InitChart(new Chart { ZoomType = ZoomTypes.X, SpacingRight = 20, DefaultSeriesType = ChartTypes.Area, Height = 300, BorderRadius = 0 })
.SetTitle(new Title { Text = Title })
.SetSubtitle(new Subtitle { Text = SubTitle })
.SetXAxis(new XAxis
{
Type = XAxisType,
MinRange = MinRange,
Title = new XAxisTitle { Text = XAxisTitle }
})
.SetYAxis(new YAxis
{
Title = new YAxisTitle { Text = YAxisTitle },
Min = 0.6,
StartOnTick = false,
EndOnTick = false,
Labels = new YAxisLabels
{
Formatter = #"function() { return this.value +' " + YAxisLabel + "';}"
}
})
.SetTooltip(new Tooltip { Shared = true/*, Formatter = #"function() { return ''+ this.x +' - '+ this.y +' " + ToolTipFormat + "'; }" */})
.SetLegend(new Legend { Enabled = true, VerticalAlign = VerticalAligns.Top })
.SetPlotOptions(new PlotOptions
{
Line = new PlotOptionsLine
{
LineWidth = 3,
Marker = new PlotOptionsLineMarker
{
Enabled = false,
States = new PlotOptionsLineMarkerStates
{
Hover = new PlotOptionsLineMarkerStatesHover
{
Enabled = true,
Radius = 5
}
}
},
Shadow = false,
States = new PlotOptionsLineStates { Hover = new PlotOptionsLineStatesHover { LineWidth = 3 } },
PointInterval = PointInterval,
PointStart = new PointStart(PointStartDate)
},
Spline = new PlotOptionsSpline
{
LineWidth = 3,
Marker = new PlotOptionsSplineMarker
{
Enabled = false,
States = new PlotOptionsSplineMarkerStates
{
Hover = new PlotOptionsSplineMarkerStatesHover
{
Enabled = true,
Radius = 5
}
}
},
Shadow = false,
States = new PlotOptionsSplineStates { Hover = new PlotOptionsSplineStatesHover { LineWidth = 3 } },
PointInterval = PointInterval,
PointStart = new PointStart(PointStartDate)
},
Area = new PlotOptionsArea
{
//FillColor = new BackColorOrGradient(new Gradient
//{
// LinearGradient = new[] { 0, 0, 0, 300 },
// Stops = new object[,] { { 0, "rgb(116, 116, 116)" }, { 1, Color.Gold } }
//}),
LineWidth = 1,
Marker = new PlotOptionsAreaMarker
{
Enabled = false,
States = new PlotOptionsAreaMarkerStates
{
Hover = new PlotOptionsAreaMarkerStatesHover
{
Enabled = true,
Radius = 5
}
}
},
Shadow = false,
States = new PlotOptionsAreaStates { Hover = new PlotOptionsAreaStatesHover { LineWidth = 1 } },
PointInterval = PointInterval,
PointStart = new PointStart(PointStartDate)
}
})
.SetSeries(Series);
return chart;
}
Chart Data
public static Series GetTimeSeriesData(IQueryable<YourModel> model, ChartTypes ChartType)
{
List<Series> Series = new List<Series>();
var chartSeries = model.GroupBy(x => x.Name)
.Select(g => new
{
Name = g.Key,
Data = g.Select(x => x.Value).ToArray()
}).ToArray();
foreach (var item in chartSeries)
{
object[] data = item.Data.Cast<object>().ToArray();
Series localSeries = new Series { Name = item.Name, Data = new Data(data), Type = ChartType };
Series.Add(localSeries);
}
return Series;
}
Usage
IQueryable<YourModel> model;
ChartData chartData = new ChartData();
Highcharts chart = new HighChart("chart_time_series");
try
{
model = db.ClassInstanceDetails.AsQueryable();
chartData = GetTimeSeriesData(model, ChartTypes.Line);
chart = TimeSeriesZoomable(chartData.ToArray(), another_options);
}
catch (Exception e)
{
}
And full examples of charts : http://dotnethighcharts.codeplex.com/releases/view/85324
Are you using Highcharts.Net? If so, I'm not sure how much help I can be (I have only done it manually, creating my own objects and converting to JSON etc, which I found to give me complete control, albeit with more effort)
Anyway, this usually largely depends on how your X-axis needs to behave... it appears like it would just be discrete datetime values, (not automatically sequential), and so your object array probably needs to be composed of X- and Y-values, rather than just the Y-values, as it appears you have there.
This next part really depends on how your implementation works, so please excuse the pseudo-pseudo-code...
You either need a 2D array:
eg: data = [[1,1], [2,5], [3,4]...]
or something more concrete: I use a class which has an X and a Y property (amongst other things), but you could try anonymous types perhaps?
eg [{x=1, y=1}, {x=2, y=5}, {x=3, y=4}...] etc
Does this help at all?
Note: you will probably want to read up a bit on how to convert your datetime values for your x-axis - I had to calculate ticks from Epoch etc

Categories