Try fast search NHibernate >>>>>>>

2009/11/15

Refactorizing tests

I had read, in some place on the cloud, that SharpTestsEx make the test more verbose even if it is more readable.

In NHibernate.Validator (NHV) we are using #TestsEx. After implements some new features I’m improving some stuff where I’m needing a little breaking change.

This is an existing test using classic NUnit syntax:

[Test]
public void CreditCard()
{
CreditCard card = new CreditCard();
card.number = "1234567890123456";
IClassValidator classValidator = GetClassValidator(typeof(CreditCard));
InvalidValue[] invalidValues = classValidator.GetInvalidValues(card);
Assert.AreEqual(1, invalidValues.Length);
card.number = "541234567890125"; //right CC (luhn compliant)
invalidValues = classValidator.GetInvalidValues(card);
Assert.AreEqual(0, invalidValues.Length);
card.ean = "9782266156066";
invalidValues = classValidator.GetInvalidValues(card);
Assert.AreEqual(0, invalidValues.Length);
card.ean = "9782266156067";
invalidValues = classValidator.GetInvalidValues(card);
Assert.AreEqual(1, invalidValues.Length);
}

The breaking change is about the return value of GetInvalidValues : in NHV1.2.0 the method will return IEnumerable<InvalidValue>.

Refactoring step 1

Same but compileable.

[Test]
public void CreditCard()
{
CreditCard card = new CreditCard();
IClassValidator classValidator = GetClassValidator(typeof(CreditCard));

card.number = "1234567890123456";
Assert.That(classValidator.GetInvalidValues(card), Is.Not.Empty);

card.number = "541234567890125"; //right CC (luhn compliant)
Assert.That(classValidator.GetInvalidValues(card), Is.Empty);

card.ean = "9782266156066";
Assert.That(classValidator.GetInvalidValues(card), Is.Empty);

card.ean = "9782266156067";
Assert.That(classValidator.GetInvalidValues(card), Is.Not.Empty);
}
Refactoring step 2
[Test]
public void CreditCard()
{
CreditCard card = new CreditCard();
var classValidator = GetClassValidator(typeof(CreditCard));

card.number = "1234567890123456";
classValidator.GetInvalidValues(card).Should().Not.Be.Empty();

card.number = "541234567890125"; //right CC (luhn compliant)
classValidator.GetInvalidValues(card).Should().Be.Empty();

card.ean = "9782266156066"; //right EAN
classValidator.GetInvalidValues(card).Should().Be.Empty();

card.ean = "9782266156067"; //wrong EAN
classValidator.GetInvalidValues(card).Should().Not.Be.Empty();
}

Now, using SharpTestsEx, we can run the same test with xUnit, MsTests, MbUnit (if/when we will need/want change the unit test framework) and I can’t see where it is more verbose.

Refactoring step 3
[Test]
public void GivingValidState_NoInvalidValues()
{
var card = new CreditCard {Number = "541234567890125", Ean = "9782266156066"};
var classValidator = GetClassValidator(typeof(CreditCard));

classValidator.GetInvalidValues(card).Should().Be.Empty();
}

[Test]
public void GivingInvalidState_HasInvalidValues()
{
var card = new CreditCard {Number = "1234567890123456", Ean = "9782266156067"};
var classValidator = GetClassValidator(typeof(CreditCard));

classValidator.GetInvalidValues(card).Should().Have.Count.EqualTo(2);
}

Perhaps SharpTestsEx is a little bit more verbose, in some cases, but with your help we can improve it.

2009/11/12

MVP in web-Forms using Ajax

As you probably know I’m not neither an UX nor UI guy and in general, since the last few years, I’m trying to stay far away from something called “view”.

I’m involved in an existing Web-Forms project as consultant and sometimes as developer. The project has some years of active development and, although its success improves day by day, from the point of view of maintenance of some parts we have a problem: too much logic in the code-behind.

Following the rule of the CTO “business’s target at first” we have made a deal: each time we need to “re-touch” a use-case we will re-factorize each part involved.

The team, so far, has no experience with ASP.MVC and considering converting the whole project to ASP.MVC is not an option. As an example of the new work schema we have developed a small part of the application and deployed it in Windows Azure (webForm-MVP + WCF + NHibernate + SQL-Azure), that means, for us: no HttpSession, no VIEWSTATE… but this is another story. You can see the application here.

Our interpretation of MVP

In my opinion, the MVP pattern is one of the least clear of all patterns. This is so true that even the Passive View description has : “WORK-IN-PROGRESS: - this material is still under development”.

Our interpretation, for webForms, is simple: the Presenter is responsible to provide data to the View in the server side. The View know how render itself and what the client-side expect.

With this definition the Presenter, as most, can provide URL as strings but does not know anything about Request/Response, QueryString, Json, jQuery, HTML, javaScript, flash and any other technology involved in the View.

At this point what is the View, and which are its responsibilities, is simple: from the server-side code-behind to the HTML we are in the view and its responsibility is to render its self, to provide input data and, perhaps, to inform the presenter about some events.

The Ajax issue

Probably the most used solution, to resolve Ajax requests, in web-Forms, is through web-services (classic or WCF) or perhaps through some specific IHttpHandler… I worked with the team to accept MVP, and now ? Where is MVP if I have to separate the View’s needs, away from the Presenter ?

The other option is the usage of PageMethod with static methods marked as [WebMethod] and so on… could be usable but with some limitations.

The proof-of-concept

The intention is make the usage of Ajax as light as possible and of course to work with objects.

In the client-side I'll use what is normal today (including jQuery) and jQuery.form (no update-panel, no VIEWSTATE and so on). In the server side Json.NET.

To don’t make the story too much long here, have first a look to the show:

The use-case has two steps (two pages, apparently). There are 3 multiple-select; the first one is filled at page-load and the others are loaded through Ajax. The list of “Equipamiento” is loaded through Ajax. If you try to public (button “Publica”) and something is wrong the list of invalid values is showed (again through Ajax). You can go back and change any value. When you write something in e-mail input, it will check if the user exists and will show its address (“Calle”) through Ajax. Only when everything is OK the info is saved and you are redirected to a list. That’s all.

Instead of the VIEWSTATE I have used the view-state… not clear ? well… try to think about that the page has state in the browser ;-).

Ok… ok… I know… show me the code!!

The code behind

This is the code-behind (I mean the code behind the page in the server side).

public partial class ClasificadoCreate : View, IPublicationView
{
private PublicationPresenter presenter;

protected void Page_Load(object sender, EventArgs e)
{
presenter = new PublicationPresenter(this);
if(Request.IsAjaxRequest())
{
this.ResolveAjaxCallBack();
return;
}
if (!Page.IsPostBack)
{
presenter.InitView(Request.QueryString);
}
}

public void LoadModelos(int marca)
{
JsonResponse(presenter.GetModelos(marca));
}

public void LoadVersiones(int modelo)
{
JsonResponse(presenter.GetVersiones(modelo));
}

public void LoadEquipamiento(int version)
{
JsonResponse(presenter.GetEquipamiento(version));
}

public void LoadUsuario(string email)
{
JsonResponse(presenter.GetUsuario(email));
}

public IEnumerable<NameValueElement> Marcas
{
set
{
rptMarcas.DataSource = value;
rptMarcas.DataBind();
}
}

public void Publica(ClasificadoInfo clasificado)
{
JsonResponse(presenter.Register(clasificado));
}
}

Who calling those methods with parameters ?… especially the last-one where the parameter is the class ClasificadoInfo… and even more interesting if you think that its implementation is this:

public class ClasificadoInfo
{
public int MarcaId { get; set; }
public int ModeloId { get; set; }
public int VersionId { get; set; }
public IEnumerable<int> Equipamiento { get; set; }
public Usuario Usuario { get; set; }

public override string ToString()
{
var sb = new StringBuilder(300);
sb.AppendLine(string.Format("Marca={0},Modelo={1},Version={2}", MarcaId, ModeloId, VersionId));
sb.AppendLine("Equipamiento:");
if (Equipamiento != null)
{
foreach (int e in Equipamiento)
{
sb.Append(e).Append(',');
}
}
sb.AppendLine(string.Format("Usuario={0}", Usuario));
return sb.ToString();
}
}

public class Usuario
{
public string Email { get; set; }
public string Calle { get; set; }
public override string ToString()
{
return string.Format("Email={0},Calle={1}", Email, Calle);
}
}

As you can see that parameter is a class with a collection and a related class.

The code behind in the client side, changing a selected value, is:

<select name="ModeloId" multiple="multiple" id="listamodelos" size="5" onchange="return modelo_onchange()">
function modelo_onchange() {
var b = getFirstSelectedId("listamodelos");
JsonFromServerAction("LoadVersiones", { modelo: b }, function(a) {
replaceNameValueOptionsList("listaversiones", a)
});
replaceCategoriasEquipamiento(null)
}

The important part there is the function JsonFromServerAction whose implementation is:

function JsonFromServerAction(serverAction, params, onsuccess) {
var parameters = { LookupAction: serverAction };
$.getJSON(this.location.href, jQuery.extend(parameters, params), onsuccess);
}

As you can see LoadVersiones is the name of the method in the server-side-code-behind and modelo is the name of its parameter; pretty easy, clear and under convention.

Perhaps you are thinking that the code to post the entirely page inputs, to the server, will look more complicated… no? well… the answer is NO.

The client-side code is:

$(document).ready(function() {
$("#clasificado").ajaxForm({ url: this.location.href + "?LookupAction=Publica", dataType: 'json', success: showResponse })
});

To call the server-side code what you need is only "?LookupAction=Publica". To create the instance of the ClasificadoInfo parameter, of the method Publica, the convention to follow is simple. Each control name should match with a property name so:

<select name="VersionId" multiple="multiple" id="listaversiones" size="5" onchange="return version_onchange()">

mean that the selected value will be assigned to the property named VersionId and

e-mail:<input type="text" id="email" name="Usuario.Email" onchange="return usuario_onchange()" /><br />
Calle :<input type="text" id="calle" name="Usuario.Calle" /><br />

mean that the input value of email will be assigned to the property name Usuario.Email.

All the “magic” is done by the classes of HunabKu.Web (and obviously thanks to the others frameworks mentioned above).

If you want play a little bit, the code is available here or down load it.




Conclusion

Considering that we are talking about ~300 code-lines, I know that MonoRails and ASP.MVC are good and Web-Forms is evil… peeeero… la culpa no es siempre, y solo, del chancho.

2009/11/02

Validation Abstraction: Custom

If you have read this post you know I’m having some psychological problem at work: multi-personality.

My dear friend Fabio-NHV said me: hey man! I have a very good OSS validation framework strongly recommended if you are validating entities you are using with NHibernate.

And I said: Cool!! but your framework is only an option for me… soon or later I’ll use something else and, btw, I need to mix the validation done by your framework with my BL and/or UI validation.

The IEntityValidator

The IEntityValidator is part of uNhAddIns because José asked me how I’m abstracting the validation stuff from my application, during the implementation of the ChinookMediamanager example (the same happened with the IGuyWire and, a year ago, with the CpBT and Gustavo).

public interface IEntityValidator
{
bool IsValid(object entityInstance);
IList<IInvalidValueInfo> Validate(object entityInstance);
IList<IInvalidValueInfo> Validate<T, TP>(T entityInstance, Expression<Func<T, TP>> property) where T : class;
IList<IInvalidValueInfo> Validate(object entityInstance, string propertyName);
}
public interface IInvalidValueInfo
{
Type EntityType { get; }
string PropertyName { get; }
string Message { get; }
}

any good validation-framework should give me the way to implement an adapter for, at least, these methods.

The implementation for NHibernate.Validator

We having an implementation of IEntityValidator in uNhAddIns… by the way, in an application in production, I’m using a more simple implementation:

public class NhVEntityValidator : IEntityValidator
{
private readonly ValidatorEngine validatorEngine;

public NhVEntityValidator(ValidatorEngine validatorEngine)
{
this.validatorEngine = validatorEngine;
}

#region Implementation of IEntityValidator

public bool IsValid(object entityInstance)
{
return validatorEngine.IsValid(entityInstance);
}

public IList<IInvalidValueInfo> Validate(object entityInstance)
{
InvalidValue[] iv = validatorEngine.Validate(entityInstance);
return
new
List<IInvalidValueInfo>(
from invalidValue in iv
select (IInvalidValueInfo) new InvalidValueInfo(invalidValue));
}

#endregion
}

public class InvalidValueInfo : IInvalidValueInfo
{
private readonly InvalidValue iv;

public InvalidValueInfo(InvalidValue iv)
{
this.iv = iv;
}

#region Implementation of IInvalidValueInfo

public Type EntityType
{
get { return iv.EntityType; }
}

public string PropertyName
{
get { return iv.PropertyName; }
}

public string Message
{
get { return iv.Message; }
}

#endregion
}

The Usage
As you can imagine the usage is simple. Where you need the IEntityValidator you must inject it:
public UsuarioParticularNuevoService(
    IDaoFactory factory,
IUserSessionContext context,
IMailSender mailSender,
IMailMaker mailMaker,
IEntityValidator entityValidator)

and then simply use it

public IInvalidValueInfo[] Register(UsuarioNuevoInfo usuarioInfo)
{
var usuario = GetUsuario(usuarioInfo);

AddPais(usuario);
AddDireccion(usuario, usuarioInfo);
AddTelefono(usuario, usuarioInfo);
AddNewsletter(usuario, usuarioInfo);
AddNegocio(usuario);

var errors = validator.Validate(usuario);

if (errors != null && errors.Count > 0)
return errors.ToArray();

usuarioDao.SaveOrUpdate(usuario);
mailSender.Send(GetMailMaker(usuarioInfo, usuario).Make());
return new IInvalidValueInfo[0];
}

The chunk, of the IoC’s configuration (in this case Castle.Windsor), in my dear IGuyWire look like:

ValidatorEngine validatorEngine = ConfigureNHibernateValidatorEngine();

container.Register(Component.For<ValidatorEngine>().Instance(validatorEngine));
container.Register(Component.For<ISharedEngineProvider>().ImplementedBy<SharedEngineProvider>());
NHibernate.Validator.Cfg.Environment.SharedEngineProvider =
container.Resolve<ISharedEngineProvider>();
container.Register(Component.For<IEntityValidator>().ImplementedBy<NhVEntityValidator>());

Options

In uNhAddIns you can find two more options, for the IEntityValidator, implemented for ValidationApplicationBlock and for DataAnnotation (thanks to José Romaniello for his implementation).