vendredi 24 juillet 2015

Test unitaire Javascript : QUnit

Tests Javascript

Les testes unitaires sont devenues une nécessité dans nos projets de développement. Aujourd'hui, j'ai pris un peu de temps pour apprendre à tester du code Javascript. Il existe pléthore de framework javascript de test. J'ai choisi d'apprendre QUnit qui est le framework de test utilisé par JQuery et JQuery UI. Il permet essentiellement de faire des testes unitaires, et non pas des testes d'intégrations comme pourrait le faire Mocha, Jasmine, Karma, Protractor.

Exemples QUnit

Exemple d'un test unitaire avec QUnit :


QUnit.test( "hello test", function( assert ) {
  assert.ok( 1 == "1", "Passed!" );
});


Exemple d'un test unitaire checkbox de JQuery UI :

test("checkbox", function( assert ) {
  expect( 4 );
  
  var input = $("#check"),
  label = $("label[for=check]");
  ok( input.is(":visible") );
  ok( label.is(":not(.ui-button)") );
  input.button();
  assert.hasClasses( input, "ui-helper-hidden-accessible" );
  assert.hasClasses( label, "ui-button" );

});


Pour tester entièrement du code Javascript, il est indispensable de pouvoir simuler des évènements Javascript. jquery-simulate permet de simuler ces évènements du navigateur. Elle est utilisé dans les tests unitaires de JQuery UI :

Exemple de test unitaire avec jquery-simulate :


QUnit.test('s', function(assert) {
  expect(5);
 
 var target = $("#resizable1").resizable({
  handles: "all"
 });

 var handle = $("#resizable1").find(".ui-resizable-s");

 handle.simulate("mouseover").simulate('drag', { dx: 0, dy: 20, moves: 1});
 equal( target.height(), 120, "compare height" );

 handle.simulate("mouseover").simulate('drag', { dx: 0, dy: -50, moves: 2});
 equal( target.height(), 70, "compare height2" );

 equal( target[0].style.top, "", "top should not be modified" );
 equal( target[0].style.left, "", "left should not be modified" );
 equal( target[0].style.width, "", "width should not be modified" );

});



Liens :

Framework javascript de test
QUnit
jquery-simulate
Unit test de JQuery
Fichier complet de test

jeudi 3 juillet 2014

Un projet, combien ça vaut ?

Une idée ça vaut
Une bonne idée ça vaut
Une réalisation ça vaut
Une bonne réalisation ça vaut 6

Si on prend l'équation une idée * (une réalisation-1) = valeur de mon projet 

Une idée seule =
Une bonne idée seule =
Une idée réalisée =
Une idée bien réalisée = 5
Une bonne idée réalisée = 6
Une bonne idée bien réalisée = 10

Et vous, combien vaut votre projet ?

jeudi 26 juin 2014

JqueryUI - popup chargement ajax

Réaliser un message de chargement à la "google" en haut de page à chaque appel ajax :


 <fmt:message key="flux.view.title" />
 
 
 
 
 
 
 



 

Chargement en cours …

lundi 21 mai 2012

Le coin de l'architecte logiciel: Hibernate: flush et dirty checking

Comprendre le "dirty check" d'hibernate : ou pourquoi lors d'un select, hibernate fait parfois des update !

Le coin de l'architecte logiciel: Hibernate: flush et dirty checking: Avec Hibernate, lorsqu'une entité (attachée) est manipulée, toute modification qui lui est apportée est supposée être reportée dans la base ...

mercredi 16 mai 2012

Java Geeks: jQuery FlexGrid & Spring MVC 3

Java Geeks: jQuery FlexGrid & Spring MVC 3: Recently I have been working on Spring MVC 3. There is inbuilt support for returning JSON data using @ResponseBody annotation. Just make su...

I have worked on the same idea, but instead using spring MVC 3, I used Jersey.
But the result is pretty the same.

samedi 3 mars 2012

Spring3 et WADL generation

Il n'existe pas à ce jour de génération de wadl pour Spring.
Spring MVC de part sa structure supporte l'architecture de type REST. Il n'utilise cependant pas le standard JSR-311. Il existe plusieurs implémentations de ce standard comme Jersey, Restlet, Apache CXF, et la plupart fournissent une génération automatique de wadl.

Je me suis donc motivé pour générer cette wadl avec un simple Controller spring.
Pour cela, je me suis fortement basé sur l'article suivant :
http://nurkiewicz.blogspot.com/2012/02/automatically-generating-wadl-in-spring.html

Source du controlleur :


package org.dyndns.tuxgalaxy.springrestwadl.controllers;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import net.java.dev.wadl._2009._02.WadlApplication;
import net.java.dev.wadl._2009._02.WadlDoc;
import net.java.dev.wadl._2009._02.WadlMethod;
import net.java.dev.wadl._2009._02.WadlParam;
import net.java.dev.wadl._2009._02.WadlParamStyle;
import net.java.dev.wadl._2009._02.WadlRepresentation;
import net.java.dev.wadl._2009._02.WadlRequest;
import net.java.dev.wadl._2009._02.WadlResource;
import net.java.dev.wadl._2009._02.WadlResources;
import net.java.dev.wadl._2009._02.WadlResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Controller
@RequestMapping("/application.wadl")
public class WadlController {
 
 @Autowired
 private RequestMappingHandlerMapping handlerMapping;
 
    @RequestMapping(method=RequestMethod.GET, produces={"application/xml"} ) 
    public @ResponseBody WadlApplication generateWadl(HttpServletRequest request) {
     WadlApplication result = new WadlApplication();
     WadlDoc doc = new WadlDoc();
     doc.setTitle("REST Service WADL");
     result.getDoc().add(doc);
     WadlResources wadResources = new WadlResources();
  wadResources.setBase(getBaseUrl(request));
  
     Map handletMethods = handlerMapping.getHandlerMethods();
     for (Map.Entry entry : handletMethods.entrySet()) {
      WadlResource wadlResource = new WadlResource();
      
      HandlerMethod handlerMethod = entry.getValue();
      RequestMappingInfo mappingInfo = entry.getKey();
      
      Set pattern =  mappingInfo.getPatternsCondition().getPatterns();
      Set httpMethods =  mappingInfo.getMethodsCondition().getMethods();
      ProducesRequestCondition producesRequestCondition = mappingInfo.getProducesCondition();
      Set mediaTypes = producesRequestCondition.getProducibleMediaTypes();
      
      for (RequestMethod httpMethod : httpMethods) {
       WadlMethod wadlMethod = new WadlMethod();
       
       for (String uri : pattern) {
        wadlResource.setPath(uri);  
    }
       
       wadlMethod.setName(httpMethod.name());
       Method javaMethod = handlerMethod.getMethod();
       wadlMethod.setId(javaMethod.getName());
       WadlDoc wadlDocMethod = new WadlDoc();
       wadlDocMethod.setTitle(javaMethod.getDeclaringClass().getName()+"."+javaMethod.getName());
       wadlMethod.getDoc().add(wadlDocMethod);
       
       // Request
       WadlRequest wadlRequest = new WadlRequest();
       
       Annotation[][] annotations = javaMethod.getParameterAnnotations();
       for (Annotation[] annotation : annotations) {
        for (Annotation annotation2 : annotation) {
         if (annotation2 instanceof RequestParam ) {
          RequestParam param2 = (RequestParam)annotation2;
          WadlParam waldParam = new WadlParam();
                waldParam.setName(param2.value());
                waldParam.setStyle(WadlParamStyle.QUERY);
                waldParam.setRequired(param2.required());
                String defaultValue = cleanDefault(param2.defaultValue());
                if ( !defaultValue.equals("") ) {
                 waldParam.setDefault(defaultValue);
                }
                wadlRequest.getParam().add(waldParam);
         } else if ( annotation2 instanceof PathVariable ) {
          PathVariable param2 = (PathVariable)annotation2;
          WadlParam waldParam = new WadlParam();
                waldParam.setName(param2.value());
                waldParam.setStyle(WadlParamStyle.TEMPLATE);
                waldParam.setRequired(true);
                wadlRequest.getParam().add(waldParam);
         }
     }
    }
       if ( ! wadlRequest.getParam().isEmpty() ) {
        wadlMethod.setRequest(wadlRequest);
       }
       
       // Response
       if ( !mediaTypes.isEmpty() ) {
        WadlResponse wadlResponse = new WadlResponse();
     wadlResponse.getStatus().add(200l);
        for (MediaType mediaType : mediaTypes) {
         WadlRepresentation wadlRepresentation = new WadlRepresentation();
         wadlRepresentation.setMediaType(mediaType.toString());
         wadlResponse.getRepresentation().add(wadlRepresentation);
     }
        wadlMethod.getResponse().add(wadlResponse);
       }
       
       wadlResource.getMethodOrResource().add(wadlMethod);
       
   }
      
      wadResources.getResource().add(wadlResource);
      
  }
     result.getResources().add(wadResources);
     
     return result;
    }
    
    
    private String getBaseUrl (HttpServletRequest request) {
     String requestUri = request.getRequestURI();
  return request.getScheme()+"://"+ request.getServerName()+":"+ request.getServerPort() + requestUri;
 }
    
    private String cleanDefault(String value) {
     value = value.replaceAll("\t", "");
     value = value.replaceAll("\n", "");
     value = value.replaceAll("", "");
     value = value.replaceAll("", "");
     value = value.replaceAll("", "");
     return value;
    }
 
}


Example de wadl généré





 
 
  
   
    
    
     
    
   
  
  
   
    
    
     
    
     
     
    
   
  
  
   
    
    
     
   
  
 



Example


Un example de code se trouve sur google code ( projet : SpringRestWadl )


Importer le projet dans eclipse puis accéder à l'url :

http://localhost:8080/SpringRestWadl/rest/application.wadl