I finished the task! To be honest, and it was a bit frustrating, the hardest part about this task was actually testing it. It was good though because I learned a lot about Mockito, which by the way is awesome, as well has some other neat little testing tricks. For example, if you have a method that you want to test, but it calls another method that you don't want to test, you can just override that method in your test by saying something like :
Object object = new Object() {
public void methodIDontWantToTest(){...}
}
I prefer using Mockito, but there are certain cases when mockito wouldn't fit and I had to override. Good to know though.
The biggest issue I encountered actually came about because of some naming conventions, where I thought a Table was one thing, but really and super secretly, it was the same thing?!? Except meant for a different purpose and spot, and it tripped me up. I hate super secret, but extremely obvious code.
Wednesday, July 8, 2009
Tuesday, July 7, 2009
Day 30
Work continued on Lighthouse task #117. Today I was able to make the responder which would call the comparer class to compare two files. The responder looks for, in the url request, the tag ?compareHistory followed by two file names, which are then extended based off the current page name, and extended once again to include the root directory. After a little fiddling around I got this to work, but then it would just display a ton of html and ugly tables in the result page. So then I made a velocity template which would accept three things, a boolean of whether the files matched or not, the first file, and the second file. This was a little better, but the files contain more information than is needed, so next I will have to somehow extract only the important information from the files, and then stick that into the velocity template.
Day 29
Yesterday I was given a new task, Lighthouse #117, which is to add a feature that will allow the user to compare a page's test histories. It is supposed to take two page histories, find any differences, and then display those differences to the user. Since the page histories are stored as Xml, my first plan was going to be to scan through the code using regular expressions, and try to compare certain expressions which store whether a page passed or failed. The issue with this was that it would be very difficult to line those expressions up to one another in order to compare one page to another. Also, if a page was different at the times in which the histories were saved, then the comparison would be extremely difficult. Then I found out that there is a nice html parser that would break down the page into more manigable chunks, which I could then compare one section at a time. Even though I found out there was a better way of solving this task, the research I did on regexes will still be useful at some point. They are very very powerful, letting you find in one search that which would have taken 5, 6 , 7 or just a ton of searches in a text editor or a regular text search. And the syntax is pretty easy once you know the 11 metacharacters. But ok, so once I found the html parser, I was able to break a page down into tables, then rows and collumns, and then just the cells which I could then compare to see how similar two pages are. To display the differences of the pages, I started making a result page that would just store all the differences and display them one by one, but now I think I am going to line them up and display the two pages side by side and have some scheme to highlight differences.
Friday, July 3, 2009
Day 28
A large portion of today was spent on trying to get the new version of jruby, getting it to work with IntelliJ, and getting IntelliJ to require that same limelight gem. The trouble at the moment is that IntelliJ says it can't find the test/unit/autorunner in the $LOAD_PATH. Rather than getting nothing done today while trying to fix this issue, I just began writing the program that will use these players. My biggest challenge will be to find a way to avoid the problem I started having with my sidebar program. I need to create a good way to keep the information out of the limelight props and in the actual program even when it would be terribly convinient or clever to stick a little something something in a prop.
Thursday, July 2, 2009
Day 27
Today I another Lighthouse task, #131, which was to add a xml format feature to a few of the responders. Normally the responders, testHistory and pageHistory, would send back a FitNesse page with all the pretty pictures and dodads and such, but this nifty feature lets you see all the important information in some xml. This would also make it easier to have a program sift through the information. To accomplish this goal, I had to create two new velocity templates, one for testHistory and one for pageHistory. Each of them would layout all the data in a simple xml form. I came across an issue while trying to display the link to another page though. The link would be something like ...SomePage.ChildPage?testHistory&format=xml and then the browser would complain about the '=' sign. No matter how I changed the manner in which the '=' was displayed, it complained. Then I discovered it wasn't actually the '=' sign, but I needed to escape the '&'. This was done by just replacing the '&' with '&' followed with a amp; (hahaha, it wouldn't actually let me type the & amp; together in this blog) and this fixed the issue. I also had to write a few tests for each responder, and a little snippet to catch if the &format=xml was included in the request. Then just load the xml content rather than html, and mark a flag saying it was to be left as xml.
A note for anyone using IntelliJ to work on some ruby project, there used to be an issue with opening the project structure, but they just released a new update for the ruby plugin which fixed the issue.
I am still finding it difficult to test the Limelight players for my project, mostly because I need to require the Limelight gem, and it simply refuses! I am trying to get the newest version of jruby, which might fix the issue, but I had done this in a previous project last year and it worked fine :/
A note for anyone using IntelliJ to work on some ruby project, there used to be an issue with opening the project structure, but they just released a new update for the ruby plugin which fixed the issue.
I am still finding it difficult to test the Limelight players for my project, mostly because I need to require the Limelight gem, and it simply refuses! I am trying to get the newest version of jruby, which might fix the issue, but I had done this in a previous project last year and it worked fine :/
Day 26
Yesterday I got started on my summer project, but I had some trouble when I began trying to test my Limelight Players. I can look at the Limelight source code, and there are a few player tests that are an interesting reference, but it is still a bit confusing.
Most of Yesterday was spent learning about a new language called Clojure. It is a sort of hybrid between Java and Lisp. Lisp being a purely constant language, although there are cute ways to cheat, and then you can also make calls to Java methods. As a whole the language seems quite powerful and able to accomplish large amounts with just a few lines. The annoying part is the parentheses. Lisp has been called Lots of insignificant parentheses simply because at the end of even a small program you will get this chain of maybe 12 closing parens. Its kinda ridiculous.
I also did some investigating into Json objects, their format, and their nature. Like that a Json object can actually be executed in Java Script
Most of Yesterday was spent learning about a new language called Clojure. It is a sort of hybrid between Java and Lisp. Lisp being a purely constant language, although there are cute ways to cheat, and then you can also make calls to Java methods. As a whole the language seems quite powerful and able to accomplish large amounts with just a few lines. The annoying part is the parentheses. Lisp has been called Lots of insignificant parentheses simply because at the end of even a small program you will get this chain of maybe 12 closing parens. Its kinda ridiculous.
I also did some investigating into Json objects, their format, and their nature. Like that a Json object can actually be executed in Java Script
Tuesday, June 30, 2009
Day 25
Today I was able to start planning my new Limelight FitNesse program, since there is just no way I can expand the sidebar project. I figure I will have a load of players, one for each widget, but they will all be rather uniquely defined. Since the range of widgets is vast, like from an image to making text bold, I think it will be hard to try and follow one format. I am also going to have to do a series of conversions to interpret the Json object that FitNesse will send me, containing the widgets. At the moment, I am think this will be the chain of conversions: Json-> someList -> a widgetInterpreter -> a widget ordering process -> Players -> props and then onto the scene.
While doing some more refactoring today, I learned a lot about the nature of exceptions. When an exception is thrown, the current process will be stopped (although process might not be the right word) and Java will crawl back up the stack until there is a catch block. From there it will continue on. So in memory, a chunk of space is left open in the stack for this catch block (which I believe comes right after the function parameters), and anything below this block will be removed from the stack. An interesting question would be, if we make a thread, and in this thread we throw an exception with no catch block, where will the exception be caught? Will it rise to the top of the thread and just die? I would like to believe Java has some last resort catch so that this thread will still print the exception, and then maybe die right after that, but I am not sure. Also, if you wish to pass a certain type exception even higher, but you need to catch other exceptions at a lower level, then you can first catch the specific exception, and throw it again, then catch all others.
try{
...
} catch (SocketException se){
throw(se)
}
catch(Exception e)
{...}
this way you can migrate all exceptions to where you want them.
On another note:
Liskov Substitution Principle: Subtypes must be substitutable for their base types.
An example of this from Agile Software Development is: "Presume that we have a function f that takes, as its argument, a pointer or reference to some base class B. Presume also that there is some derivative D of B which, when passed to f in the guise of B, causes f to misbehave. Then D violate the LSP."
We came across an example of this today when trying to create a List from an array. There is a method in the Arrays class called .asList(Array array), which as you might guess, apprears to do what we wished; however, when we then tried to remove an item from the list we just made, we got an error that indicated a remove was not possible. Apparently, and correct me if I am wrong, this asList function returned an object masquerading as a List, while really having the array data structure. This was a violation of the LSP.
Reading further into this, another excellent example would be a Square extending a Rectangle. Given that a square need only have 1 side set, and the rectangle requires 2, it is possible to forsee certain errors and fragilities that might arrise.
While doing some more refactoring today, I learned a lot about the nature of exceptions. When an exception is thrown, the current process will be stopped (although process might not be the right word) and Java will crawl back up the stack until there is a catch block. From there it will continue on. So in memory, a chunk of space is left open in the stack for this catch block (which I believe comes right after the function parameters), and anything below this block will be removed from the stack. An interesting question would be, if we make a thread, and in this thread we throw an exception with no catch block, where will the exception be caught? Will it rise to the top of the thread and just die? I would like to believe Java has some last resort catch so that this thread will still print the exception, and then maybe die right after that, but I am not sure. Also, if you wish to pass a certain type exception even higher, but you need to catch other exceptions at a lower level, then you can first catch the specific exception, and throw it again, then catch all others.
try{
...
} catch (SocketException se){
throw(se)
}
catch(Exception e)
{...}
this way you can migrate all exceptions to where you want them.
On another note:
Liskov Substitution Principle: Subtypes must be substitutable for their base types.
An example of this from Agile Software Development is: "Presume that we have a function f that takes, as its argument, a pointer or reference to some base class B. Presume also that there is some derivative D of B which, when passed to f in the guise of B, causes f to misbehave. Then D violate the LSP."
We came across an example of this today when trying to create a List from an array. There is a method in the Arrays class called .asList(Array array), which as you might guess, apprears to do what we wished; however, when we then tried to remove an item from the list we just made, we got an error that indicated a remove was not possible. Apparently, and correct me if I am wrong, this asList function returned an object masquerading as a List, while really having the array data structure. This was a violation of the LSP.
Reading further into this, another excellent example would be a Square extending a Rectangle. Given that a square need only have 1 side set, and the rectangle requires 2, it is possible to forsee certain errors and fragilities that might arrise.
Subscribe to:
Posts (Atom)
