mercoledì 8 agosto 2012
giovedì 8 marzo 2012
venerdì 11 novembre 2011
Tomcat Debug Mode [ENG]
Just a quick note. To start Tomcat in debug mode:
%java_bin%\bin\java.exe -Xms48m -Xmx384m -Xdebug -Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=n -jar -Duser.dir="%catalina_home%" "%catalina_home%\bin\bootstrap.jar" start
In Eclipse create a new Debug Configuration/Remote Java App, Standard (Socket Attach) with the actual Host and Port (1044 in my example)
mercoledì 21 settembre 2011
Extremely Simple PHP Unit Test Framework/3 [ENG]
We've seen the test suite, the test, the test runner (the contraption required to get the test to run). The last thing is the test base class which implements the assertions.
class Test
{
function assertEquals($expected, $got)
{
if ($expected!=$got)
{
trigger_error("Expected '" .$expected. "' but got '" .$got. "'", E_USER_ERROR);
}
}
function assertContains($haystack, $needle)
{
if (strpos($haystack, $needle)<0)
{
trigger_error("String '" .$needle. "' is not contained in '" .$haystack. "'", E_USER_ERROR);
}
}
function assertNotNull($object)
{
if ($object==NULL)
{
trigger_error("assertNotNull failure", E_USER_ERROR);
}
}
function assertTrue($condition)
{
if (!$condition)
{
trigger_error("assertTrue failed", E_USER_ERROR);
}
}
}
As you can see I kept that really really simple.
Extremely Simple PHP Unit Test Framework/2 [ENG]
How does ESP-UTF (see part 1) run the single test?
function doTest($testClassName, $testMethodName)
{
global $testFailed;
global $testFailedCause;
$testFailedCause = "";
$testFailed = false;
$object = new $testClassName();
$object->$testMethodName();
$result = new TestResult($testClassName, $testMethodName, !$testFailed, $testFailedCause);
return $result;
}
Things to note here:
- the test result is held by a pair of global variables (lines 3 and 4); that's how I handled the errors; more on that later
- strings can be used as class and methods names without further ado (lines 8 and 9)
- the result is returned as a TestResult object
I did not know how to trap errors (did I already say that I'm stuck with PHP4 and no exception handling?) other than by setting an error handler:
set_error_handler ('errorHandler');
function errorHandler($errno, $errstr, $errfile, $errline)
{
global $testFailed;
global $testFailedCause;
$testFailedCause = "\nError: " . $errno . ", file: " . $errfile . "; line: " . $errline . "; error: ". $errstr . "";
$testFailed = true;
return true;
}
There's catch of course: if an assertion fails the execution of the method does not get stopped, it just goes on through to the end because that's how the error handler's supposed to work. Since I consider that a minor annoyance I did not waste further effort trying to mend that.
Here's the TestResult class:
class TestResult
{
var $testClassName;
var $testMethodName;
var $testBooleanResult;
var $testMessageResult;
function TestResult($className, $methodName, $booleanResult, $messageResult)
{
$this->testClassName = $className;
$this->testMethodName = $methodName;
$this->testBooleanResult = $booleanResult;
$this->testMessageResult = $messageResult;
}
function x()
{
return $this->testClassName . "." . $this->testClassMethod . "='" . $this->testMessageResult . "'";
}
}
Nothing fancy, in fact.
In the next episode the Test class
lunedì 19 settembre 2011
Extremely Simple PHP Unit Test Framework [ENG]
Ok, I know. There is PHPUnit, already, and enough good books to get you started if you want to go down that path (that is the sensible thing to do, by the way).
Since I had to play with PHP for a pet project, got stuck with PHP4, was not able to set up PHPUnit and lost my patience, I decided to whip up something on my own. ESP-UTF is just an experiment: I wanted to peek behind the curtains to see how a unit test framework is made. Hope you may find something interesting among this crap.
First of all I only knew how to send the output of PHP scripts to a web page, so that's how I thought to show the test outcome.
How will the test cases look like? Well something like this:
class TestLanguage extends Test
{
function testLanguageUK()
{
$pLang = new phpI18N('en');
$testResult = $pLang->getPhrase('register', 'first_name');
$this->assertEquals('First Name', $testResult);
}
}
As in JUnit 3 I need to extend a basic Test class, and the test method has to be called testName. Since that's exactly what you have to do in Groovy I can live with that.
Now, how do I create a test runner? I did not want to do anything complicated, just a simple report. And I wanted my framework to handle test suites. Here's how I did that:
$testSuite = array( "TestDAOArticoli", "TestDAOUtente", "TestDAOCategoria", "TestLanguage", "TestCart" ); $testResults = doTestSuite($testSuite); render($testResults);
Could there be anything simpler? How do I load the test methods from each class?
function doTestSuite($testSuite)
{
$testResults = array();
foreach($testSuite as $testClass)
{
$testResults = array_merge($testResults, doTests($testClass));
}
return $testResults;
}
I collect the test results in an array. The render function will display that in a fancy style. Here's the doTests() method (more interesting):
function doTests($testClassName)
{
$testResults = array();
$class_methods = get_class_methods($testClassName);
foreach ($class_methods as $method_name)
{
if (preg_match("/^test/", $method_name))
{
$testResults[] = doTest($testClassName, $method_name);
}
}
return $testResults;
}
No rocket science, so far, right? In the next episode: how to do the test?
venerdì 8 luglio 2011
Greasemonkey e Il Post [ITA]
Il sito Il Post pubblica alcune news in formato "Post-it", vale a dire che riporta solo il link all'articolo originale. Chi segue il sito tramite feed RSS deve quindi fare due clic per raggiungere il contenuto.
Oppure usare questo script Greasemonkey:
// ==UserScript==
// @name Il Post - Post-it
// @namespace personal
// @description Inoltra da post-it a destinazione finale
// @include http://www.ilpost.it/*
// ==/UserScript==
var h1 = document.getElementsByTagName("h1")[0];
var h1_a_href = h1.childNodes[1].getAttribute("href");
var isPostIt = document.body.innerHTML.indexOf("categoria Post-it");
if (isPostIt>=0)
{
document.location.href = h1_a_href;
}
venerdì 14 gennaio 2011
Ruby: flatten directory [ENG]
We've organized files in subdirectories according to tags and according to creation date. What if you would like to flatten a tree, moving all files from the sub-directories into a single directory?
"Move all the files from the tree starting at source_dir"
"into dest_dir out of the tree"
def flatten(source_dir, dest_dir)
Dir.foreach(source_dir) do |filename|
# exclude current dir and parent dir
if (!filename.eql?(".") and !filename.eql?(".."))
if File.directory?(filename) # subdirectory
flatten(filename, dest_dir) # recursively flatten subdir
else #file
dirname = File.dirname(filename)
filenameonly = filename[(dirname.length-1)..-1]
old_name = source_dir + "/" + filename
new_name = dest_dir + "/" + filenameonly
puts("moving '#{old_name}' to '#{new_name}'")
File.rename(old_name, new_name)
end
end
end
end
# read line parameters
source_dir = ARGV.shift
# default source dir is current dir
if (source_dir == nil)
source_dir = "."
end
dest_dir = ARGV.shift
# default destination dir current dir
if (dest_dir == nil)
dest_dir = "."
end
flatten(source_dir, dest_dir)
martedì 11 gennaio 2011
Java: Reflect on this [ENG]
Reflection in Java is a powerful tool, expecially useful when your code must get in touch with the outer world (configuration files, database, http protocol...). Here's an example, a simple parser for a CSV string where every value has a tag:
id=1112396889697; t=22740834120; x=184549969; y=8389273; f=89; q0=0.18810; q1=0.07500; q2=-0.23573; q3=0.96616
What I would like to do here is parsing the data into an object with (a subset of) the fields in each line. The solution is overly simplified, but it just works:
import java.lang.reflect.Field;
public class Sample
{
class SampleData
{
public Long t = new Long(0);
public Long x = new Long(0);
public Long y = new Long(0);
public Long f = new Long(0);
public Double q0 = new Double(0);
public Double q1 = new Double(0);
public Double q2 = new Double(0);
public Double q3 = new Double(0);
}
private SampleData data = new SampleData();
public Sample(String taggedCsv)
{
if (taggedCsv != null && !"".equals(taggedCsv))
{
String[] chunks = taggedCsv.split(";");
for (String chunk : chunks)
{
chunk = chunk.trim();
String[] parts = chunk.split("=");
String tag = parts[0].trim();
String value = parts[1].trim();
try
{
Class<? extends SampleData> class1 = data.getClass();
Field f = class1.getField(tag);
if (f!=null)
{
if (f.getType().equals(java.lang.Double.class))
{
f.set(data, new Double(value));
}
else
if (f.getType().equals(java.lang.Long.class))
{
f.set(data, new Long(value));
}
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
}
public long getT()
{
return data.t.longValue();
}
public double getX()
{
return data.x.longValue();
}
public double getY()
{
return data.y.longValue();
}
public double getF()
{
return data.f.longValue();
}
public double getQ0()
{
return data.q0.doubleValue();
}
public double getQ1()
{
return data.q1.doubleValue();
}
public double getQ2()
{
return data.q2.doubleValue();
}
public double getQ3()
{
return data.q3.doubleValue();
}
}
It seems like it's doing its job just fine:
@Test
public void firstTest()
{
Sample a = new Sample(
"id=1112396889697; t=22740834120; " +
"x=184549969; y=8389273; f=89; " +
"q0=0.18810; q1=0.07500; q2=-0.23573; q3=0.96616");
assertTrue(22740834120L==a.getT());
assertTrue(184549969L==a.getX());
assertTrue(8389273L==a.getY());
}
NOTE: there is an awkward thing in the code up there. To obtain encapsulation I had to use a PRIVATE class (DataSample) with PUBLIC fields because getField() can not access PRIVATE fields. There are other ways round, but they are not as lean. Still don't like it, though.
lunedì 18 ottobre 2010
Oracle 10g: ODBC on a 64 bit machine [ENG]
After installing Oracle 10g 32 Bit Client on a Windows 2K8 64 bit machine ODBC drivers were nowhere to be found.
The trick is (apparently) of abysmal stupidity: you have to launch an EXE (C:\WINDOWS\SysWOW64\odbcad32.exe) to make them show up in Administrative Tools / ODBC Data Sources.
Thanks to Nicolas Gerard for saving my bacon with his precious hint.
More about this here (thanks to Paolo C. for the link).