pondělí 2. listopadu 2009

Ubuntu 9.10 64bit and custom 32bit JDK and Eclipse 3.5 pwned

In this short HOWTO, I recap installation of 32bit JDK and Eclipse on 64bit linux platform. Nowadays 64bit linux distribution is not something special. Everything works fine, until is we want 32bit JDK on it - for me, I have one linux developer folder spread out to other team members, why force anybody to use 64bit at all.

OK. We have freshy new Ubuntu 9.10 amd64 with custom 32bit JDK downloaded from Sun. Why Ubuntu supports only 32bit JRE and not JDK???

Shorty mentioned, full how-to may be found here

  1. download JDK from java.sun.com
  2. unzip in /usr/lib/jvm
  3. good behaviour is create symlink pointed to /usr/lib/jvm/java -> /usr/lib/jvm/jdk1.6.0_16
  4. create /etc/profile.d/setup-dev-env.sh, which is setted up for every user, for console and graphical work
  5. export JAVA_HOME=/usr/lib/jvm/java 
    export JDK_HOME=$JAVA_HOME
    
  6. optionally, you may re-write custom create-jvm-alternative script, which sets up additional envirnonment variables and fonts, browser plugins (which on 64bit firefox doen't work of course).

    You are familiar with
    update-java-alternatives -l #list of all alternatives
    update-java-alternatives -s jdk1.6.0_16 #sets to particular one
    
    but its not necessary if you change eclipse.ini file to point -vm argument to your java installation.
    -startup
    plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
    --launcher.library
    plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.0.200.v20090520
    -product
    org.eclipse.epp.package.jee.product
    -showsplash
    org.eclipse.platform
    --launcher.XXMaxPermSize
    512m
    -vm
    /usr/lib/jvm/java/bin/java
    -vmargs
    -Dosgi.requiredJavaVersion=1.5
    -XX:MaxPermSize=512m
    -Xms80m
    -Xmx768m
    
OK. We have 32bit JDK installed, 32bit Eclipse installed. On Ubuntu 9.10, there is one problem with GTK2 and workaround for bug "Eclipse buttons in Ubuntu 9.10" is known.

We must create custom eclipse launcher, OK.
#!/bin/sh
export GDK_NATIVE_WINDOWS=1
/optdev/eclipse-3.5/eclipse
Everything works well, except internal SWT browser widget, you may found this exceptions on error console in eclipse or like this in Aptana IDE
(Build 1.5.0.25497) [ERROR] Unable to determine current running state of Aptana Studio
org.eclipse.swt.SWTError: No more handles [MOZILLA_FIVE_HOME='/usr/lib/xulrunner-1.9.1.4'] (java.lang.UnsatisfiedLinkError: no swt-mozilla-gtk-3550 or swt-mozilla-gtk in swt.library.path, java.library.path or the jar file)
    at org.eclipse.swt.SWT.error(SWT.java:3910)
    at org.eclipse.swt.browser.Mozilla.create(Mozilla.java:514)
    at org.eclipse.swt.browser.Browser.(Browser.java:119)
    at com.aptana.ide.documentation.views.TutorialView.createPartControl(TutorialView.java:59)
    at org.eclipse.ui.internal.ViewReference.createPartHelper(ViewReference.java:367)
    at org.eclipse.ui.internal.ViewReference.createPart(ViewReference.java:226)
    at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
    at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:313)
    at org.eclipse.ui.internal.ViewPane.setVisible(ViewPane.java:529)
    at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:180)
    at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:270)
    at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
    at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:473)
    at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1256)
    at org.eclipse.ui.internal.PartStack.setSelection(PartStack.java:1209)
    at org.eclipse.ui.internal.PartStack.showPart(PartStack.java:1608)
    at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:649)
    at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:576)
    at org.eclipse.ui.internal.PartSashContainer.createControl(PartSashContainer.java:568)
    at org.eclipse.ui.internal.PerspectiveHelper.activate(PerspectiveHelper.java:272)
    at org.eclipse.ui.internal.Perspective.onActivate(Perspective.java:981)
    at org.eclipse.ui.internal.WorkbenchPage.onActivate(WorkbenchPage.java:2626)
    at org.eclipse.ui.internal.WorkbenchWindow$27.run(WorkbenchWindow.java:2964)
    at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
    at org.eclipse.ui.internal.WorkbenchWindow.setActivePage(WorkbenchWindow.java:2945)
    at org.eclipse.ui.internal.WorkbenchWindow.busyOpenPage(WorkbenchWindow.java:760)
    at org.eclipse.ui.internal.Workbench$21.runWithException(Workbench.java:1045)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3468)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3115)
    at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
    at org.eclipse.ui.internal.Workbench$28.runWithException(Workbench.java:1384)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3468)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3115)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2316)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
    at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at com.aptana.ide.rcp.IDEApplication.start(IDEApplication.java:121)
    at com.aptana.ide.desktop.integration.Application.start(Application.java:56)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
Caused by: java.lang.UnsatisfiedLinkError: no swt-mozilla-gtk-3550 or swt-mozilla-gtk in swt.library.path, java.library.path or the jar file
    at org.eclipse.swt.internal.Library.loadLibrary(Library.java:254)
    at org.eclipse.swt.internal.Library.loadLibrary(Library.java:159)
    at org.eclipse.swt.browser.Mozilla.create(Mozilla.java:499)
    ... 57 more
What to do to solve this strange problem? And this is thing what this article is about :)
  1. First of all, there is magical script called getlibs on Debian and ubuntu, by which you may download 32bit libraries needed by some executable. Install it, it will be invaluable in next steps.
  2. Cleverer may noticed that /usr/lib/xulrunner-1.9.1.4 is not xulrunner you need.

    Download 32bit one by getlibs and set up environmental variable MOZILLA_FIVE_HOME.

    getlibs -i xulrunner-1.9.1.4
    export MOZILLA_FIVE_HOME=/usr/lib32/xulrunner-1.9.1.4
  3. Unfortunately it's not all, we need swt-mozilla-gtk-3550 in 32bits, older version is in 64bit package libswt-mozilla-gtk-3.4-jni, but there is not something like libswt-mozilla-gtk-3.5-jni in 32 or 64bits. So we must download it manually - all -3550.so files - from eclipse subversion repository to /usr/lib32/jni folder
  4. Next thing I had to made, was looking to org.eclipse.swt.browser.Mozilla source code, what is trying to load. I created sample test class, where I simulated eclipse classloader loading behaviour.

    public class Main {
        private static final String JAVA_LIBRARY_PATH = "java.library.path";
    
        public static void main(String[] args) {
            String property = System.getProperty(JAVA_LIBRARY_PATH);
            System.out.println("Original java.library.path=" + property);
            try {
                System.loadLibrary("swt-mozilla-gtk-3550");
            } catch (UnsatisfiedLinkError e) {
                System.err.println("hacking attempt exception :)");
                e.printStackTrace();
            }
        }
    }
    
  5. Executing this piece of code, I figured this out (each time executed getlibs and created symlink to point somewhere in java.library.path). We must download these 32bit libraries to relieve of dependency hell.
    getlibs -l libxcb-atom.so.1
    getlibs -l libxcb-event.so.1
    getlibs -l libxcb-aux.so.0
    getlibs -l libstartup-notification-1.so.0
    getlibs -l libhunspell-1.2.so.0
    getlibs -l libxpcom.so
    
  6. Last but not least is set up environmental variable LD_LIBRARY_PATH to be pointed to 32bit libs. So final /etc/profile.d/setup-dev-env.sh will be:
    export JAVA_HOME=/usr/lib/jvm/java 
    export JDK_HOME=$JAVA_HOME
    export MOZILLA_FIVE_HOME=/usr/lib32/xulrunner-1.9.1.4/
    
    And final eclipse eclipse executable will be (because of this variables are cleared somehow in ubuntu after executing profile script):
    #!/bin/sh
    export GDK_NATIVE_WINDOWS=1
    export LD_LIBRARY_PATH=/usr/lib32/jni:/usr/lib32
    /optdev/eclipse-3.5/eclipse
    
  7. And vuala. We have working custom Eclipse 32bit installation on 32bit JDK and 64bit linux with 32bit xulrunner and his dependencies. We have working SWT browser widget and eclipse welcome screen (BIRT reports preview, GWT less than 2.0-SNAPSHOT hosted mode and so on...). Well done, dude ;)

středa 17. června 2009

Symbolicky odkaz ve Windows

Malo kdo vi, ze i ve Windows na NTFS filesystemu jde udelat symlink (i hardlink). Kdo nedelal nikdy s UNIXem po tom ani nepatra. Nedalo mi to a nasel jsem reseni. Podle wikipedie k tomu slouzi prikaz mklink.
C:\optdev\Console2>mklink
Vytvorí symbolicky odkaz.
MKLINK [[/D] | [/H] | [/J]] Cíl Odkaz
 /D    Vytvorí symbolicky odkaz na adresár. Vychozí je symbolicky
       odkaz na soubor.
 /H    Vytvorí pevny odkaz namísto symbolického odkazu.
 /J    Vytvorí spojení adresáre.
 Odkaz Urcuje název nového symbolického odkazu.
 Cíl   Urcuje cestu (relativní nebo absolutní), na kterou novy odkaz
       odkazuje.
Nez neco bastlit v konzoli, bude lepsi pouzit pripravene reseni Link Shell Extension, ktere dointegruje do pruzkumnika dialogy povesene na prave tlacitko mysi. Konecne :)

úterý 16. června 2009

Killerapp for today - downloading stuff from Rapidshare with FreeRapid downloader

There are plenty of so called downloaders from web hostings like rapishare.com, so competition is huge. College from CTU University wrote this FreeRapid downloader as his diploma thesis, it's entirely in pure Java language and it's open source (it's first usable tool for linux at all)


Today, it supports many of sites (50+), each "site extractor" is implemented as plugin to FreeRapid. Each plugin uses Apache Commons HTTPClient and java.util.regex package to communicate throw AJAX and to parse needed things.

Author made a sample screencast how to write plugin on your own.

Next stage of development will be probably feature of automatical CAPTCHA recognition (which USDownloader handles). Wanna participate? Go to project homepage http://wordrider.net/freerapid/

středa 3. června 2009

FatJar s maven assembly pro Spring aplikaci

Jar file v Jave je dobra vec na delivery jednoducheho programu, ktery nezavisi na zadnych knihovnach. Jakmile pouzijeme vic knihoven, musime uvest do parametru --classpath vsechny jary, na kterych projekt zavisi. Pro jednou se to da zkousnout, ale resit to pokazde ? :) Nastesti existuje reseni - jmenuje se Fat Jar. Ten jde vytvorit napr. z Eclipsu pomoci tohoto pluginu. Je tu nekdo, kdo jeste pouziva ant? Tomu nasledujici clanek moc neprinese. Pro ty z Vas, kdo pouzivaji pro build a dependency managment maven, mam ukazku trochu slozitejsiho nastaveni maven assembly pluginu. Jedna se o plugin, ktery dokaze vzit zdrojovy kod a ve fazi buildeni (presneji v package goalu) rozjede vytvareni distribuce pro aplikaci. Je to takova nadstavba nad maven-jar/war/... pluginem. Tady ukazu, jak jsem vybuildil Java SE aplikaci se Springem (Hibernatem atd.). Vyskytli se 2 problemy.
  1. Je potreba pouzit posledni verzi (tj. 2.2-beta-3). Predchozi verze mela bug, ze misto toho, aby se pouzil jen jeden soubor stejneho jmena v classpath se konkatenovaly soubory do sebe.
  2. Unable to locate Spring NamespaceHandler for XML schema namespace, s posledni verzi pluginu proces reseni duplicit funguje tak, ze vyhraje prvni (resp. ta z projektu, ktery buildime). Spring potrebuje v META-INF mit soubory spring.handlers a spring-schemas. Je treba projit obsah vsech spring-* zavislosti a rucne konkatenovat obsah do sveho souboru v META-INF buildeneho projektu.
edit: Unable to locate schema namespace resi lepe maven shade plugin, viz http://maestro-lab.blogspot.com/2010/06/upgrading-to-spring-3-unable-to-locate.html Co je potreba tedy nastavit? V prvni rade pom.xml!
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <build>
     <plugins>
         <plugin>
             <artifactid>
                 maven-assembly-plugin
             </artifactid>
             <!-- verze je tu nutna, 2.2-beta-2 ma bug, kde se misto prepsani konkatenuji soubory se stejnym jmenem -->
             <version>
                 2.2-beta-3
             </version>
             <executions>
                 <execution>
                     <id>
                         make-assembly
                     </id>
                     <phase>
                         package
                     </phase>
                     <goals>
                         <goal>
                             assembly
                         </goal>
                     </goals>
                     <configuration>
                         <appendassemblyid>
                             false
                         </appendassemblyid>
                         <!-- ve vetsine pripadu staci uvest
    <descriptorrefs>
     <descriptorref>jar-with-dependencies</descriptorref>
    </descriptorrefs>
   -->
                         <descriptors>
                             <descriptor>
                                 ${basedir}/src/assemble/fatJar.xml
                             </descriptor>
                         </descriptors>
                         <archive>
                             <manifest>
                                 <mainclass>
                                     your.package.name.Main
                                 </mainclass>
                             </manifest>
                         </archive>
                     </configuration>
                 </execution>
             </executions>
         </plugin>
     </plugins>
     <!-- potrebujeme spojit spring.handlers a spring.schemas -->
     <resources>
         <resource>
             <directory>
                 src/main/META-INF
             </directory>
             <targetpath>
                 META-INF
             </targetpath>
         </resource>
     </resources>
 </build>
</project>

Pokud nepotrebujeme nic excludovat, includovat, staci pouzit zmineny descriptor jar-with-dependencies. Pokud ano, je treba jej poupravit a vytvorit spec. assembly skript. V tomto pripade /src/assembly/fatJar.xml.
<assembly schemalocation="http://maven.apache.org/xsd/assembly-1.0.0.xsd" xsi="http://www.w3.org/2001/XMLSchema-instance">
 <id>
     fatJar
 </id>
 <formats>
     <format>
         jar
     </format>
 </formats>
 <includebasedirectory>
     false
 </includebasedirectory>
 <dependencysets>
     <dependencyset>
         <outputdirectory>
         </outputdirectory>
         <outputfilenamemapping>
         </outputfilenamemapping>
         <unpack>
             true
         </unpack>
         <scope>
             runtime
         </scope>
     </dependencyset>
 </dependencysets>
 <filesets>
     <fileset>
         <directory>
             target/classes
         </directory>
         <outputdirectory>
         </outputdirectory>
         <!-- must exclude by hand content of src/main/release, there is no anything like fileSet priority -->
         <excludes>
             <exclude>
                 database.properties
             </exclude>
             <exclude>
                 log4j.xml
             </exclude>
         </excludes>
     </fileset>
     <fileset>
         <directory>
             src/main/release
         </directory>
         <outputdirectory>
         </outputdirectory>
     </fileset>
 </filesets>
</assembly>

Pro ty kdo budete chtit vybuildit Spring aplikaci, pridavam jeste workaround pro pred chvili zminene soubory umistene v src/main/META-INF. spring.handlers
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler

http\://www.springframework.org/schema/security=org.springframework.security.config.SecurityNamespaceHandler

http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler

http\://www.springframework.org/schema/webflow-config=org.springframework.webflow.config.WebFlowConfigNamespaceHandler
a spring.schemas
http\://www.springframework.org/schema/context/spring-context-2.5.xsd=org/springframework/context/config/spring-context-2.5.xsd
http\://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context-2.5.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.0.xsd=org/springframework/ejb/config/spring-jee-2.0.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.5.xsd=org/springframework/ejb/config/spring-jee-2.5.xsd
http\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-2.5.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.0.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.5.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd
http\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd

http\://www.springframework.org/schema/security/spring-security.xsd=org/springframework/security/config/spring-security-2.0.4.xsd
http\://www.springframework.org/schema/security/spring-security-2.0.xsd=org/springframework/security/config/spring-security-2.0.xsd
http\://www.springframework.org/schema/security/spring-security-2.0.1.xsd=org/springframework/security/config/spring-security-2.0.1.xsd
http\://www.springframework.org/schema/security/spring-security-2.0.2.xsd=org/springframework/security/config/spring-security-2.0.2.xsd
http\://www.springframework.org/schema/security/spring-security-2.0.4.xsd=org/springframework/security/config/spring-security-2.0.4.xsd

http\://www.springframework.org/schema/tx/spring-tx-2.0.xsd=org/springframework/transaction/config/spring-tx-2.0.xsd
http\://www.springframework.org/schema/tx/spring-tx-2.5.xsd=org/springframework/transaction/config/spring-tx-2.5.xsd
http\://www.springframework.org/schema/tx/spring-tx.xsd=org/springframework/transaction/config/spring-tx-2.5.xsd

http\://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd=org/springframework/webflow/config/spring-webflow-config-1.0.xsd

http\://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd=org/springframework/webflow/config/spring-webflow-config-2.0.xsd
A fat jar je na svete :) :D

neděle 8. března 2009

Smalltalk's Pier Persistent Store

I want to trot out by my school project. In smalltalk (first even looked at the code) with other fellows from CEE in Prague, we will implement small work with Seaside, Pier and Magritte frameworks - simple file based persistency for Pier. You can use this project from souce code repository located at http://www.squeaksource.com/PierPersistentStore.html. It's based on Magritte meta-description framework and it's not so collest lib, but we learned much about Smalltalk and it's programming, so maybe there is some possibillity to extend it in the spirit of open source. We don't put any licence, so it's public domain. Posible commitee may contact us...

Dependencies

  • Seaside
  • Pier
  • Magritte

Build instructions

Example code ready to run

"This will change persistency of the kernel to PRXmlPersistency and store everything from the kernel on your disk. If needed, change the first line to reflect your setup."

kernel := PRKernel allInstances first.
PRPierPersistentStoreConnector storeEverythingFrom: kernel.

Another killer app - Subdownloader

Today, I downloaded new episode of Battle Star Galactica - it is no important :) but I had to say - and on the whole internet, there were no Czech subtitles nor English ones. So I spoke to myself, try Subdownloader app. This is simple GUI client for downloading/uploading subtitles to opensubtitles.org. That's not so amazing after all. But what you can do is to download subtitle by movie file, you simple choose to which file you want to find subtitles and if you have a luck, you will find some. On proper forum, there wasn't any and I tryied to find any subtitles by file... and found even Czech ones. I gone to the forum, click refresh on the browser and voiala, there it was - same subtitles. Why I am writting this piece of crap? It is very GOOD to see, that a comunity is using opensubtitles.org even before that they are uploading subz to proper web forum. Another thing... this killerapp appliction, by which is downloading subtitles simplest thing ever :)

sobota 31. ledna 2009

Google muze poskodit vas pocitac!

Je videt, ze regrese se dostane vsude, neco na prislovi "2x mer, jednou res" preci jen bude :)

středa 21. ledna 2009

Google Web Toolkit prezentace

Dalsi prezentace do skoly, tentokrat na GWT.
Gwt Prezentace
View more presentations or upload your own. (tags: web gwt)

Internetove technologie na platforme Java

Rozhodl jsem se, ze dam svoji bakalarskou praci pro FEL CVUT na slideshare. Obsahuje resersi weboveho developmentu v Jave, respektive frameworky Spring 2.0, Hibernate3, jUnit, JMock, Spring Web Flow, Spring Web MVC a dalsi. V druhe casti je popsany vyvoj software pomoci eXtremniho programovani a popsane nektere implementacni detaily. Super cteni pro uplne zacatecniky (pry) :)

úterý 20. ledna 2009

Jednoduchý Unit framework pro C/C++

Máte rádi Test Driven Development jako já? Používáte v Javě JUnit a chcete něco podobného v C? Dal jsem si ten čas a projel všechny frameworky, které mi google nabídnul. Na první pohled jsem si oblíbil následující 2:

Pro začátek nemusíme definovat, TestRunner, tj. říci které všechny testy se mají spustit. U simplectests je toto implementováno pomocí header files a preprocesoru, kdy za makro definující testovací metodu dosazují main(). Jednoduché a účinné :) Simplectest mi přijde nejminimalističtější řešení jaké si dokážu představit, naproti tomu Easyunit toho umí víc, je psaný v C++ a to čitelně pro javistu.

Hello world v simplectests

/*
* This demonstrates the simplest way to do some tests using simplectest.
* See "readme.txt" for more information, or the website at
* http://simplectest.sf.net/.
*
* Jevon Wright 2004-05
*/
#include "tests.h"

// Start the overall test suite
START_TESTS()

// A new group of tests, with an identifier
START_TEST("simple")
  // We then write the tests we want to check
  ASSERT(1 == 1);
  ASSERT_EQUALS_FLOAT(1, 1);
END_TEST()

START_TEST("fail")
  // These tests will fail, and we will get output.
  ASSERT(1 == 0);
  ASSERT_EQUALS_FLOAT(1, 0);

  // Lets give a description of the test, before it
  // fails - this will be printed out instead.
  TEST("we expect this test to fail. (3==2)");
  ASSERT(3 == 2);
END_TEST()

// End the overall test suite
END_TESTS()

Hello world v Easyunit

stacktest.cpp

#include "easyunit\test.h"
#include "stack.h"

using namespace easyunit;

TEST(Stack,Constructor)
{
  Stack s;
  ASSERT_TRUE(s.size() == 0);
  ASSERT_TRUE(s.pull() == 0);
}

TEST(Stack, PushTop)
{
  Stack s;
  s.push(1);
  ASSERT_TRUE(s.top() == 1);
  s.push(2);
  s.push(3);
  ASSERT_TRUE(s.top() == 3);
} 

main.cpp

#include "easyunit\testharness.h"

using namespace easyunit;

int main()
{
  TestRegistry::runAndPrint();
}