Skip to content

Commit

Permalink
Merge pull request #60 from Code52/ssboisen-issue_49_math_bot
Browse files Browse the repository at this point in the history
Ssboisen issue 49 math bot
  • Loading branch information
shiftkey-tester committed Jan 15, 2012
2 parents 63628bd + fc0e750 commit d7b24bf
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 0 deletions.
99 changes: 99 additions & 0 deletions Extensions/CalculatorSprocket/CalculatorSprocket.cs
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jabbot.CommandSprockets;
using NCalc;

namespace Jabbot.Extensions
{
public class CalculatorSprocket : CommandSprocket
{
private readonly string _helpInfo;

public CalculatorSprocket()
{
_helpInfo = "Hi {0}," + Environment.NewLine + Environment.NewLine
+ "I accept the following commands:" + Environment.NewLine
+ "info/help:\t" + "this message" + Environment.NewLine
+ "expr/calc:\t" + "accepts a math expression to evaluate and returns the result" + Environment.NewLine + Environment.NewLine
+ "for expression documentation please refer to ncalcs website:" + Environment.NewLine
+ "operators: http://ncalc.codeplex.com/wikipage?title=operators&referringTitle=Home" + Environment.NewLine
+ "values: http://ncalc.codeplex.com/wikipage?title=values&referringTitle=Home" + Environment.NewLine
+ "functions: http://ncalc.codeplex.com/wikipage?title=functions&referringTitle=Home";

}

public override IEnumerable<string> SupportedInitiators
{
get
{
yield return "calc";
yield return "mathbot";
}
}

public override IEnumerable<string> SupportedCommands
{
get
{
yield return "info";
yield return "help";
yield return "expr";
yield return "calc";
}
}

public override bool ExecuteCommand()
{
switch (Command)
{
case "info":
case "help":
return ShowInfo();
case "expr":
case "calc":
return CalculateExpression(GetExpression());
default:
return false;
}
}

private bool CalculateExpression(string mathExpression)
{
var expression = new Expression(mathExpression, EvaluateOptions.IgnoreCase);
object result = null;
try
{
result = expression.Evaluate();
}
catch (Exception ex)
{
if (ex is ArgumentException || ex is EvaluationException)
Bot.Say(string.Format("Sorry {0} - i couldn't evaluate your expression", Message.Sender), Message.Receiver);
}

if (result == null)
return false;

Bot.Say(string.Format("{0} = {1}", mathExpression, result), Message.Receiver);

return true;
}

private string GetExpression()
{
var expression = Message.Content.Substring(Message.Content.LastIndexOf(Command, StringComparison.Ordinal) + Command.Length).Trim();

return expression;
}

private bool ShowInfo()
{
Bot.PrivateReply(Message.Sender, string.Format(_helpInfo, Message.Sender));

return true;

}
}
}
73 changes: 73 additions & 0 deletions Extensions/CalculatorSprocket/CalculatorSprocket.csproj
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{6416F073-97F1-4DBB-B8D6-2011BE448D98}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Jabbot.Extensions</RootNamespace>
<AssemblyName>Jabbot.Extensions.CalculatorSprocket</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\jibbr\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="NCalc">
<HintPath>..\..\packages\ncalc.1.3.8\lib\NCalc.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CalculatorSprocket.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Jabbot.CommandSprockets\Jabbot.CommandSprockets.csproj">
<Project>{FB5CE3F1-1575-440B-A6E9-4E5AFED35D8B}</Project>
<Name>Jabbot.CommandSprockets</Name>
</ProjectReference>
<ProjectReference Include="..\..\Jabbot\Jabbot.csproj">
<Project>{478BFCF7-9397-49A7-AFD4-060B6B749E77}</Project>
<Name>Jabbot</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
36 changes: 36 additions & 0 deletions Extensions/CalculatorSprocket/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CalculatorSprocket")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CalculatorSprocket")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("053807e1-19be-4fa1-94a2-c71615202601")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
4 changes: 4 additions & 0 deletions Extensions/CalculatorSprocket/packages.config
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ncalc" version="1.3.8" />
</packages>
3 changes: 3 additions & 0 deletions Extensions/DisqusAnnouncer/DisqusAnnouncer.csproj
Expand Up @@ -12,6 +12,8 @@
<AssemblyName>DisqusAnnouncer</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\jibbr\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -53,6 +55,7 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
Expand Down
13 changes: 13 additions & 0 deletions Jabbot.sln
Expand Up @@ -62,6 +62,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VolunteerSprocket", "Extens
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeatherSprocket", "Extensions\WeatherSprocket\WeatherSprocket.csproj", "{1BCEA8B3-23C9-4087-9DC1-70EAC94D0787}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalculatorSprocket", "Extensions\CalculatorSprocket\CalculatorSprocket.csproj", "{6416F073-97F1-4DBB-B8D6-2011BE448D98}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -213,6 +215,16 @@ Global
{87E3E12D-F46E-4425-8375-6882A6DF243A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{87E3E12D-F46E-4425-8375-6882A6DF243A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{87E3E12D-F46E-4425-8375-6882A6DF243A}.Release|x86.ActiveCfg = Release|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Debug|x86.ActiveCfg = Debug|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Release|Any CPU.Build.0 = Release|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{6416F073-97F1-4DBB-B8D6-2011BE448D98}.Release|x86.ActiveCfg = Release|Any CPU
{1BCEA8B3-23C9-4087-9DC1-70EAC94D0787}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1BCEA8B3-23C9-4087-9DC1-70EAC94D0787}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BCEA8B3-23C9-4087-9DC1-70EAC94D0787}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
Expand All @@ -235,6 +247,7 @@ Global
{B1E7F2FE-7BC0-409A-9BE5-0A0E03553872} = {7170D00A-149E-427F-A7F9-FBA91CE3F9D7}
{ED3BAD8A-2972-4D52-BE1E-9B73EE43E53C} = {7170D00A-149E-427F-A7F9-FBA91CE3F9D7}
{D05250A1-6F48-49F1-967C-BCB25213EA06} = {7170D00A-149E-427F-A7F9-FBA91CE3F9D7}
{6416F073-97F1-4DBB-B8D6-2011BE448D98} = {7170D00A-149E-427F-A7F9-FBA91CE3F9D7}
{93DB29BE-BC75-4D59-9313-891A1245940D} = {7170D00A-149E-427F-A7F9-FBA91CE3F9D7}
{87E3E12D-F46E-4425-8375-6882A6DF243A} = {7170D00A-149E-427F-A7F9-FBA91CE3F9D7}
{1BCEA8B3-23C9-4087-9DC1-70EAC94D0787} = {7170D00A-149E-427F-A7F9-FBA91CE3F9D7}
Expand Down
81 changes: 81 additions & 0 deletions Tests/ExtensionTests/CalculatorSprocketTest.cs
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jabbot;
using Jabbot.Extensions;
using Jabbot.Models;
using Moq;
using NUnit.Framework;

namespace ExtensionTests
{
[TestFixture]
public class CalculatorSprocketTest
{
private CalculatorSprocket _calculatorSprocket;
private Mock<IBot> _botMock;
[SetUp]
public void SetUp()
{
_calculatorSprocket = new CalculatorSprocket();
_botMock = new Mock<IBot>();
}

[Test]
public void AcceptsInfoAndHelpCommand()
{
//arrange
var chatMessage = new ChatMessage(string.Format("{0} {1}", "calc", "info"), "Simon", "jibbr");
var chatMessage2 = new ChatMessage(string.Format("{0} {1}", "calc", "help"), "Simon", "jibbr");

//act
_calculatorSprocket.Handle(chatMessage, _botMock.Object);
_calculatorSprocket.Handle(chatMessage2, _botMock.Object);

//assert
_botMock.Verify(b => b.PrivateReply(It.Is<string>(who => who.Contains("Simon")), It.IsAny<string>()), Times.Exactly(2));
}

[Test]
public void CanRequestValidCalculation()
{
//arrange
var expression = "2 * 2";
var chatMessage = new ChatMessage(string.Format("{0} {1} {2}", "calc", "expr", expression), "Simon", "jibbr");

//act
_calculatorSprocket.Handle(chatMessage, _botMock.Object);

//assert
_botMock.Verify(b => b.Say(It.Is<string>(what => what.Equals(string.Format("{0} = {1}", expression, "4"))), It.IsAny<string>()));
}

[Test]
public void CanRequestInValidCalculation()
{
//arrange
var chatMessage = new ChatMessage(string.Format("{0} {1} {2}", "calc", "expr", "2 *"), "Simon", "jibbr");

//act
_calculatorSprocket.Handle(chatMessage, _botMock.Object);

//assert
_botMock.Verify(b => b.Say(It.Is<string>(what => what.Contains("Sorry")), It.IsAny<string>()));
}

[Test]
public void CanCalculateSquareRoot()
{
//arrange
var expression = "sqrt(16)";
var chatMessage = new ChatMessage(string.Format("{0} {1} {2}", "calc", "expr", expression), "Simon", "jibbr");

//act
_calculatorSprocket.Handle(chatMessage, _botMock.Object);

//assert
_botMock.Verify(b => b.Say(It.Is<string>(what => what.Equals(string.Format("{0} = {1}", expression, "4"))), It.IsAny<string>()));
}
}
}
5 changes: 5 additions & 0 deletions Tests/ExtensionTests/ExtensionTests.csproj
Expand Up @@ -54,13 +54,18 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CalculatorSprocketTest.cs" />
<Compile Include="QuizSprocketTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Extensions\CalculatorSprocket\CalculatorSprocket.csproj">
<Project>{6416F073-97F1-4DBB-B8D6-2011BE448D98}</Project>
<Name>CalculatorSprocket</Name>
</ProjectReference>
<ProjectReference Include="..\..\Extensions\QuizSprocket\QuizSprocket.csproj">
<Project>{93DB29BE-BC75-4D59-9313-891A1245940D}</Project>
<Name>QuizSprocket</Name>
Expand Down

0 comments on commit d7b24bf

Please sign in to comment.