import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Scanner; import java.io.PrintStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.File; import java.io.FileNotFoundException; public class EratostheneTest extends junit.framework.TestCase { private static Class aCla = Eratosthene.class; // le nom de la classe doit etre : Eratosthene private static Eratosthene aCrible /*= null*/; private static PrintStream out /*= null*/; private static PrintStream console /*= null*/; private void createCrible( final int pN ) throws Exception { Constructor vCo = aCla.getDeclaredConstructor( new Class[]{int.class} ); aCrible = (Eratosthene)(vCo.newInstance( new Object[]{pN} )); } // createCrible() public void testAttributs() throws Exception { assertNotNull( "Pas d'attribut aMax !?", aCla.getDeclaredField("aMax") ); assertNotNull( "Pas d'attribut aTab !?", aCla.getDeclaredField("aTab") ); assertTrue( "type de aMax ???", hasField( aCla, "p", "int", "aMax" ) ); assertTrue( "type de aTab ???", hasField( aCla, "p", "boolean[]", "aTab" ) ); assertTrue( "attributs non private ???", hasField( aCla, "i", "int", "aMax" ) && hasField( aCla, "i", "boolean[]", "aTab" ) ); } // testAttributs() public void testConstructeur() throws Exception { assertTrue( "Pas de constructeur a un parametre ???", hasConstructor( aCla, "p", 1 ) ); assertTrue( "Le constructeur n'est pas public !?", hasConstructor( aCla, "u", 1 ) ); int vMax = 10; createCrible( vMax ); Field vN = aCla.getDeclaredField("aMax"); vN.setAccessible( true ); assertEquals( "aMax ne vaut pas "+vMax+" !?", new Integer(vMax), (Integer)vN.get( aCrible ) ); Field vT = aCla.getDeclaredField("aTab"); vT.setAccessible( true ); assertNotNull( "aTab est null !?", (boolean[])vT.get( aCrible ) ); assertEquals( "aTab n'a pas "+vMax+" cases !?", vMax+1, ((boolean[])vT.get( aCrible )).length ); } // testConstructeur() public void testInitV() throws Exception { // creation tableau de test final int SUP = 20; createCrible( SUP ); boolean[] vT = new boolean[SUP+1]; // remplacement du tableau du crible par celui du test Field vS = aCrible.getClass().getDeclaredField("aMax"); vS.setAccessible( true ); vS.set( aCrible, SUP ); Field vF = aCrible.getClass().getDeclaredField("aTab"); vF.setAccessible( true ); vF.set( aCrible, vT ); for ( int i=0; i<=SUP; i++ ) vT[i] = false; run( aCrible, "initV" ); // aCrible.initV(); assertFalse( "0 n'est pas premier !", vT[0] ); assertFalse( "1 n'est pas considere comme premier !", vT[1] ); for ( int i=2; i<=SUP; i++ ) assertTrue( "Case "+i+" non initialisée !", vT[i] ); } // testInitV() public void testRaye() throws Exception { // creation tableau de test // 0 1 2 3 4 5 6 7 8 9 boolean[] res = { false, false, true, true, false, true, false, true, false, false, // 10 11 12 13 14 15 16 17 18 19 20 false, true, false, true, false, false, false, true, false, true, false }; final int SUP = res.length-1; createCrible( SUP ); boolean[] vT = new boolean[SUP+1]; // remplacement du tableau du crible par celui du test Field vS = aCrible.getClass().getDeclaredField("aMax"); vS.setAccessible( true ); vS.set( aCrible, SUP ); Field vF = aCrible.getClass().getDeclaredField("aTab"); vF.setAccessible( true ); vF.set( aCrible, vT ); run( aCrible, "initV" ); // aCrible.initV(); run( aCrible, "raye" ); // aCrible.raye(); for ( int i=2; i<=SUP; i++ ) assertEquals( "Rayage incorrect pour "+i+" !", res[i], vT[i] ); } // testRaye() public void testPrepare() throws Exception { // creation tableau de test // 0 1 2 3 4 5 6 7 8 9 boolean[] res = { false, false, true, true, false, true, false, true, false, false, // 10 11 12 13 14 15 16 17 18 19 20 false, true, false, true, false, false, false, true, false, true, false }; final int SUP = res.length-1; createCrible( SUP ); // recuperation du tableau alloue dans le crible Field vF = aCrible.getClass().getDeclaredField("aTab"); vF.setAccessible( true ); boolean[] vT = (boolean[])vF.get( aCrible ); // verification de toutes les cases assertFalse( "Taille insuffisante a cause de la case 0 !", SUP == vT.length ); assertEquals( "Taille du tableau incorrecte !", SUP+1, vT.length ); for ( int i=2; i<=SUP; i++ ) assertEquals( "Preparation incorrecte pour "+i+" !", res[i], vT[i] ); // verification que prepare ne s'execute pas plusieurs fois for ( int i=0; i<=SUP; i++ ) vT[i] = false; run( aCrible, "prepare" ); // aCrible.prepare(); for ( int i=0; i<=SUP; i++ ) assertFalse( "prepare s'execute plusieurs fois ("+i+") !", vT[i] ); for ( int i=0; i<=SUP; i++ ) vT[i] = true; run( aCrible, "prepare" ); // aCrible.prepare(); for ( int i=0; i<=SUP; i++ ) assertTrue( "prepare s'execute plusieurs fois ("+i+") !", vT[i] ); } // testPrepare() public void testEstPremier() throws Exception { // 0 1 2 3 4 5 6 7 8 9 boolean[] res = { false, false, true, true, false, true, false, true, false, false, // 10 11 12 13 14 15 16 17 18 19 20 false, true, false, true, false, false, false, true, false, true, false }; final int SUP = res.length-1; createCrible( SUP ); for ( int i=2; i<=SUP; i++ ) assertEquals( "Résultat incorrect pour "+i+" !", res[i], run( aCrible, "estPremier", i ) ); } // testEstPremier() public void testAffiche() throws Exception { final int SUP = 1000; createCrible( SUP ); if ( ! redirectTerminal() ) fail( "Probleme avec la fenetre Terminal !" ); run( aCrible, "affiche" ); String res = compareTerminal( "eratos.in" ); if ( ! res.equals( "OK" ) ) fail( res ); } // testAffiche() ////////////////////////////////// Methodes utilitaires ///////////////////////////////////////////// protected void setUp() // throws java.lang.Exception { assertTrue( "Pas d'attribut aMax ?", hasField( aCla, "p", "int", "aMax" ) ); assertTrue( "Pas d'attribut aTab ?", hasField( aCla, "p", "[boolean", "aTab" ) ); } protected void tearDown() // throws java.lang.Exception { } private static boolean redirectTerminal() { boolean ok = false; try { console = System.out; out = new PrintStream( new BufferedOutputStream( new FileOutputStream( "test.out" ) )); System.setOut( out ); ok = true; } catch( Exception e ) { e.printStackTrace(); } return ok; } // redirectTerminal() private static String compareTerminal( String refName ) { try { out.flush(); out.close(); Scanner ref = new Scanner( new File( refName ) ); Scanner res = new Scanner( new File( "test.out" ) ); while ( ref.hasNextLine() ) { String liRef = ref.nextLine(); if ( ! res.hasNextLine() ) return "Il manque au moins une ligne d'affichage !" ; String liRes = res.nextLine(); if ( ! liRef.equals( liRes ) ) return "Display expected <" + liRef + "> but was <" + liRes + "> !" ; } // while } catch( FileNotFoundException fnfe ) { return "Fichier " + refName + " introuvable !" ; } catch( Exception e ) { e.printStackTrace(); } finally { System.setOut( console ); } return "OK"; } // compareTerminal(.) private void run( final Eratosthene pCrible, final String pMet ) throws Exception { Method vM = pCrible.getClass().getDeclaredMethod( pMet ); vM.setAccessible( true ); vM.invoke( pCrible ); } // run(..) private boolean run( final Eratosthene pCrible, final String pMet, final int pN ) throws Exception { Method vM = pCrible.getClass().getDeclaredMethod( pMet, new Class[]{int.class} ); vM.setAccessible( true ); return (Boolean)vM.invoke( pCrible, new Object[]{pN} ); } // run(...) private boolean hasField( Class pC, String pL, String pT, String pN ) { // pUblic prOtected pAckage prIvate for ( Field vF : pC.getDeclaredFields() ) { if ( isField( vF, pL, pT, pN ) ) return true; } // for return false; } // hasField() private boolean isField( Field pF, String pL, String pT, String pN ) { // pUblic prOtected pAckage prIvate boolean vR = true; vR = vR && hasModifiers( pF, pL ); Class vC = pF.getType(); if ( pT.charAt(0) == '[' ) { if ( ! vC.isArray() ) return false; vC = vC.getComponentType(); pT = pT.replace( "[", "" ); } // if vR = vR && vC.getSimpleName().equals( pT ); vR = vR && pF.getName().equals( pN ); return vR; } // isField() private boolean hasModifiers( Field pF, String pL ) { // pUblic prOtected pAckage prIvate boolean vR= true; int vM= pF.getModifiers(); if ( !pL.contains( "p" ) ) { if ( Modifier.isPublic( vM ) ) vR= vR && pL.contains( "u" ); if ( Modifier.isProtected( vM ) ) vR= vR && pL.contains( "o" ); if ( Modifier.isPrivate( vM ) ) vR= vR && pL.contains( "i" ); if ( !Modifier.isPublic( vM ) && !Modifier.isProtected( vM ) && !Modifier.isPrivate( vM ) ) vR= vR && pL.contains( "a" ); } //if if ( pL.contains( "f" ) ) vR= vR && Modifier.isFinal( vM ); if ( pL.contains( "s" ) ) vR= vR && Modifier.isStatic( vM ); return vR; } // hasModifiers() private static boolean hasConstructor( Class pC, String pL, int pN ) { // pUblic prOtected pAckage prIvate ou anyProtection for ( Constructor vC : pC.getDeclaredConstructors() ) { if ( isConstructor( vC, pL, pN ) ) return true; } // for return false; } // hasConstructor() private static boolean isConstructor( Constructor pC, String pL, int pN ) { // pUblic prOtected pAckage prIvate ou anyProtection return hasModifiers( pC, pL ) && pC.getParameterTypes().length == pN; } // isConstructor() private static boolean hasModifiers( Constructor pC, String pL ) { // pUblic prOtected pAckage prIvate ou anyProtection boolean vR= true; int vM= pC.getModifiers(); if ( !pL.contains( "p" ) ) { if ( Modifier.isPublic( vM ) ) vR= vR && pL.contains( "u" ); if ( Modifier.isProtected( vM ) ) vR= vR && pL.contains( "o" ); if ( Modifier.isPrivate( vM ) ) vR= vR && pL.contains( "i" ); if ( !Modifier.isPublic( vM ) && !Modifier.isProtected( vM ) && !Modifier.isPrivate( vM ) ) vR= vR && pL.contains( "a" ); } //if return vR; } // hasModifiers() } // EratostheneTest