Skip to content

Commit

Permalink
+ Support for "Given I did" clause
Browse files Browse the repository at this point in the history
* Complete refactoring of the Account example
  • Loading branch information
Tom Janssens authored and Tom Janssens committed Nov 13, 2009
1 parent cd187e0 commit 65cad7f
Show file tree
Hide file tree
Showing 18 changed files with 289 additions and 154 deletions.
@@ -1,8 +1,8 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<StartArguments>-html website\stories\*.txt</StartArguments>
<StartArguments>accounts\stories\*.txt</StartArguments>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<StartArguments>-html website\stories\*.txt</StartArguments>
<StartArguments>accounts\stories\*.txt</StartArguments>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion Be.Corebvba.Aubergine.ConsoleRunner/Program.cs
Expand Up @@ -83,7 +83,7 @@ static int Main(string[] args)
static void PrettyPrint(IElement v, int depth,string header,string fmt,string footer)
{
var whitespace = "".PadLeft(depth * 4);
Console.WriteLine(whitespace+fmt.FormatWith(v));
Console.WriteLine(whitespace+fmt.FormatWith(v).Replace("GivenIdid","Given I did"));
if (!string.IsNullOrEmpty(header))
Console.WriteLine(whitespace+header);
foreach (var c in v.Children)
Expand Down
72 changes: 39 additions & 33 deletions Be.Corebvba.Aubergine.Examples/Accounts/Contexts/AccountContext.cs
Expand Up @@ -4,72 +4,78 @@
using System.Text;
using Be.Corebvba.Aubergine.Model;
using Be.Corebvba.Aubergine.Extensions;
using Be.Corebvba.Aubergine.Examples.Accounts.SoftwareToTest;
using Be.Corebvba.Aubergine.Examples.Accounts.SoftwareToTest.Model;
using Be.Corebvba.Aubergine.Examples.Accounts.SoftwareToTest.Services;

namespace Be.Corebvba.Aubergine.Examples.Accounts.Contexts
{
internal class AccountContext
{
public User currentUser = new User();
public Account AccountA = new Account();
public Account AccountB = new Account();
public Exception WhenException;
public AccountService AccountService = new AccountService();
public ProcessStatus LastStatus;

#region Given

[DSL(@"(?<account>Account[AB]) has (?<amount>.+)")]
void accountX_has_Ym(Account account, decimal amount)
[DSL(@"the (?<member>.+) of (?<instance>.+) is (?<value>.+)")]
void assignfield(object instance,string member,object value)
{
account.Balance = amount * 1m;
instance.Set(member, value);
}

[DSL(@"the current user is authenticated for (?<account>Account[AB])")]
void authenticate_for_account_x(Account account)
[DSL(@"the (?<member>.+) of (?<instance>.+) should be (?<value>.*)")]
bool shouldbefield(object instance, string member, object value)
{
account.IsAuthenticated = true;
var obj = instance.Get<object>(member);
return Convert.ChangeType(value, obj.GetType()).Equals(obj);
}

#endregion


#region When

[DSL(@"transfering (?<amount>.+) from (?<from>Account[AB]) to (?<to>Account[AB])")]
void transfering_xm_from_a_to_b(decimal amount, Account from, Account to)
[DSL(@"I request authentication for (?<user>.+)")]
void authenticate_for_account_x(User user)
{
from.Transfer(amount * 1m, to);
LastStatus = AccountService.AuthenticateUser(user);
}
#endregion

#region Then

[DSL(@"it should have (?<amount>.+) on (?<account>Account[AB])")]
bool should_have_Xm_on_AccountY(Account account, decimal amount)
[DSL(@"I request authentication for (?<account>.+) with (?<user>.+)")]
void authenticate_for_account_x(User user, Account account)
{
LastStatus = AccountService.AuthenticateUserForAccount(account,user);
}

[DSL(@"I transfer (?<amount>.+) from (?<from>.+) to (?<to>.+) with (?<user>.+)")]
void transfering_xm_from_a_to_b(decimal amount, Account from, Account to,User user)
{
return account.Balance == amount * 1m;
LastStatus = AccountService.Transfer(user,amount, from,to);
}

[DSL]
bool it_should_fail_with_error()
bool The_process_should_fail()
{
return WhenException != null;
return LastStatus.Success == false;
}

#endregion

#region Recursive DSL
[DSL]
bool The_process_should_succeed()
{
return LastStatus.Success == true;
}

[DSL("(?<name>Account[AB])")]
Account getaccountAB(string name)
{
return this.Get<Account>(name);
}

[DSL(@"(?<amount>\d+)m")]
decimal getmillion(decimal amount)
[DSL(@"(?<amount>\d+)(?<ismillion>m?)")]
decimal getmillion(decimal amount,string ismillon)
{
return amount * 1m;
return amount*(ismillon=="m"?1m:1);
}

#endregion
[DSL]
User the_current_user()
{
return currentUser;
}
}
}
34 changes: 0 additions & 34 deletions Be.Corebvba.Aubergine.Examples/Accounts/SoftwareToTest/Account.cs

This file was deleted.

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Be.Corebvba.Aubergine.Examples.Accounts.SoftwareToTest.Model
{
public class Account
{
public Account()
{
Balance = 0;
}

public User Owner { get; set; }

public Decimal Balance { get; set; }

}
}
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Be.Corebvba.Aubergine.Examples.Accounts.SoftwareToTest.Model
{
public class ProcessStatus
{
public bool Success { get; set; }
public string Message { get; set; }
}
}
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Be.Corebvba.Aubergine.Examples.Accounts.SoftwareToTest.Model
{
public class User
{
public string Name { get; set; }
public string Password { get; set; }
}
}
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Be.Corebvba.Aubergine.Examples.Accounts.SoftwareToTest.Model;

namespace Be.Corebvba.Aubergine.Examples.Accounts.SoftwareToTest.Services
{
public class AccountService
{
public ProcessStatus AuthenticateUser(User user)
{
if (user.Name == "Neo" && user.Password == "Red pill")
return new ProcessStatus() { Message = "Welcome " + user.Name, Success = true };
else
return new ProcessStatus() { Message = "Wrong username or password", Success = false };

}

public ProcessStatus AuthenticateUserForAccount(Account a, User u)
{
var x = AuthenticateUser(u);
if (!x.Success) return x;
if (a.Owner == u)
return new ProcessStatus() { Success = true };
else
return new ProcessStatus() { Message ="Access to this account is not allowed", Success = false };

}


public ProcessStatus Transfer(User u,decimal amount, Account From,Account ToAccount)
{
var x = AuthenticateUserForAccount(From,u);
if (!x.Success) return x;

if (From.Balance < amount)
return new ProcessStatus() { Message = "There is not enough money available on the account", Success = false };

From.Balance -= amount;
ToAccount.Balance += amount;

return new ProcessStatus() { Message = amount.ToString() + " was transferred",Success = true };
}
}
}
Expand Up @@ -9,37 +9,54 @@ Story Transfer money between accounts
I want to transfer money between accounts
So that I can have real use for my money

Given AccountA has 3m
Given AccountB has 2m
Given the balance of AccountA is 3m
Given the balance of AccountB is 2m
Given the owner of AccountA is the current user

Scenario Authenticate the current user as a 'valid or invalid' user
Given the name of the current user is 'username'
And the password of the current user is 'password'
When I request authentication for the current user
Then the process should 'fail or succeed'

Example
+--------------------+------------+------------+------------------+
| 'valid or invalid' | 'username' | 'password' | 'fail or succeed'|
+--------------------+------------+------------+------------------+
| valid | Neo | Red pill | succeed |
| invalid | Neo | Blue pill | fail |
+--------------------+------------+------------+------------------+

Scenario Authenticate the current user for 'an account'
Given I did authenticate the current user as a valid user
When I request authentication for 'an account' with the current user
Then the process should 'fail or succeed'

Example accounts :
+--------------+-------------------+
| 'an account' | 'fail or succeed' |
+--------------+-------------------+
| AccountA | succeed |
| AccountB | fail |
+--------------+-------------------+


Scenario Transfer AAm between 2 accounts

Given the current user is authenticated for AccountA
When transfering AAm from AccountA to AccountB
Then it should have BBm on AccountA
Then it should have CCm on AccountB
Given I did authenticate the current user for AccountA
When I transfer AAm from AccountA to AccountB with the current user
Then the balance of AccountA should be BBm
Then the balance of AccountB should be CCm
Then the process should 'fail or succeed'

Example for the transfer

+----+----+----+
| AA | BB | CC |
+----+----+----+
| 1 | 2 | 3 |
| 2 | 1 | 4 |
| 3 | 0 | 5 |
+----+----+----+
+----+----+----+-------------------+
| AA | BB | CC | 'fail or succeed' |
+----+----+----+-------------------+
| 1 | 2 | 3 | succeed |
| 2 | 1 | 4 | succeed |
| 3 | 0 | 5 | succeed |
| 4 | 3 | 2 | fail |
+----+----+----+-------------------+

Scenario Transfer too much

Given the current user is authenticated for AccountA
When transfering 4m from AccountA to AccountB
Then it should have 3m on AccountA
Then it should have 2m on AccountB
Then it should fail with error

Scenario Not authorized for transfer

When transfering 1m from AccountB to AccountA
Then it should have 3m on AccountA
Then it should have 2m on AccountB
Then it should fail with error
Expand Up @@ -50,7 +50,10 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Accounts\Contexts\AccountContext.cs" />
<Compile Include="Accounts\SoftwareToTest\Account.cs" />
<Compile Include="Accounts\SoftwareToTest\Model\Account.cs" />
<Compile Include="Accounts\SoftwareToTest\Services\AccountService.cs" />
<Compile Include="Accounts\SoftwareToTest\Model\Transaction.cs" />
<Compile Include="Accounts\SoftwareToTest\Model\User.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Website\Contexts\BrowserContext.cs" />
<Content Include="Website\Stories\Make_sure_my_Website_gets_enough_traffic.txt">
Expand Down
Binary file modified Be.Corebvba.Aubergine.Examples/Lib/Be.Corebvba.Aubergine.dll
Binary file not shown.
Binary file modified Be.Corebvba.Aubergine.Examples/Lib/ConsoleRunner.exe
Binary file not shown.
Expand Up @@ -6,19 +6,19 @@ Story Make sure my website gets enough visibility
I want to make sure that I get enough visibility
So that I can get enough traffic

Scenario Search results for 'keywords' on searchengine should contain 'my url'
Scenario Search results for 'keywords' on searchengine should contain 'www.corebvba.be'
Given the current url is 'search url'
When searching for 'keywords'
Then the result should contain 'my url'
Then the result should contain 'www.corebvba.be'
Example
+--------------+--------------------------------+------------------+-----------------+
| searchengine | search url | keywords | my url |
+--------------+--------------------------------+------------------+-----------------+
| google | http://www.google.be/search?q= | BDD .Net | www.corebvba.be |
| bing | http://www.bing.com/search?q= | core bvba tom | www.corebvba.be |
| bing | http://www.bing.com/search?q= | Quantum physics | www.corebvba.be |
| faulty link | http://www.googleaaa | core bvba tom | www.corebvba.be |
+--------------+--------------------------------+------------------+-----------------+
+--------------+--------------------------------+------------------+
| searchengine | search url | keywords |
+--------------+--------------------------------+------------------+
| google | http://www.google.be/search?q= | BDD .Net |
| bing | http://www.bing.com/search?q= | core bvba tom |
| bing | http://www.bing.com/search?q= | Quantum physics |
| faulty link | http://www.googleaaa | core bvba tom |
+--------------+--------------------------------+------------------+

Scenario Search results on google for keywords should contain 'www.corebvba.be'
Given the current url is 'http://www.google.be/search?q='
Expand Down
Binary file modified Be.Corebvba.Aubergine.suo
Binary file not shown.

0 comments on commit 65cad7f

Please sign in to comment.