Tuesday, July 28, 2009

Day 44

Yesterday and today were both spent working with my Dad on changing the nature in which FitNesse deals with suites. In the past, FitNesse would save suite pages (a page that runs many test pages) as a massive file with all of the results from each page inside of it, as well display a suite page as a summary of all the test page results and then all the test results below that. So anytime you ran a fairly large suite you would end up with this massive page with tons and tons of results on it. You would also get a history file for just the suite, and it would contain this same huge mass of information.
Now, we have changed FitNesse so that when it saves the suite page's history, it actually saves the history for all the individual test pages and only saves the links to those pages in the suite history file. It also only displays the suite's results as a summary of the individual test page's results, and then links to each of those pages. This strategy makes more sense, and saves memory since the browser no longer needs to save this super huge suite page.

Friday, July 24, 2009

Day 42

Today is the ultimate day. Today is Day 42 of my Object Mentor Appreticeship, and oh what a day it is.

I must say, I have thought I was done with the HistoryComparer time and time again, but I keep needing to improve it. All that work and refactoring that I had done before for the findBestMatch stuff, I deleted all of it... Turns out, it makes more sense to save all of the matches, no matter their score or which tables are matched, then order the matches based on their score (highest to lowest), and then remove any match which use the same table but are of a lower score. This way each table only has 1 match, and it is always matched with its best match. The reason for this change was that we found a bug where if lefthand table6 was matched with righthand table6 with a .8, then lhtable6 was matched with rhtable7 with a .9, and then lhtable7 was matched with rhtable7 with a 1.0, then the only remaining match would be the last one made since each time the new match was added, it had a better score and the previous match was using one of the tables in the new match (and since a table can only have one match, the old match had to be deleted). The new strategy will preserve the lhtable6-rhtable6 match since by the time it compared those matches with the other ones, the lhtable6-rhtable7 match would have been deleted(since it is earlier on the list because it has a higher score, and after the table7-table7 which would delete the table6-table7 because it uses table7).

I also added a few more features, like displaying the score for every match, displaying if the two pages where a complete match, and other things like that.

Wednesday, July 22, 2009

Day 40

I finished the HistoryComparer today, except for maybe a little more refactoring and cleaning. The comparer will now compare every table of one page history, to every table of the other page history search for the most likely matches, and then lining those tables up next to one another in the comparison. This way if an old page history used to have just two testing tables, but the newer page has two new tables, one at the top and one at the bottom, then the comparer will match up the two old tables with the two middle tables of the new page and then leave blank spaces for the other two tables. Its actually pretty cool, because it is now very easy to see the differences between older pages and new ones. And to find which tables were recently added, which ones have been just slightly changed, or even moved around.

To do this I created a rather arbitrary point system that I could use to make a sort of best fit between tables. First, the comparer would compare every cell of the two tables, and give a percentage based off how many of them matched (# of matching cells / average # of cells between the two tables). This was actually done row by row and then column by column, and it would add the percentages from each column and then divide by the total number of columns. Then it would award bonus points if the two tables had the same number of columns and the same number of cells. This way, if two tables were the same, but in one of the histories the table had failed all its tests (leading the cell values to be different) the tables could still be matched together since they had the same number of cell and columns. So the comparer would generate a score for each of the table comparisons, and any score that was over a certain amount would be considered a match.
The next issue was that then I would have situations where one table would match with two or three other tables, and the program would go nuts trying to line them all up. It was actually really funny the first time I saw this because it ended up matching the setup table with the teardown table, and thus added like 30 blank spaces to line them up. Probably had to be there though... :) So to solve this, I made a bestfit checker. For two tables to be matched up they would either have to have no other matches, or the new match would have to have a better score than the last, in which case the old match would be replaced with the new. This turned out to be rather mind bending. If we are comparing table1 and table2, and they have a score of 1.1, but table1 already is matched with table3 with a score of 1.05, then table1 and table2 will be matched, and table3 left unmatched. But if table2 already had a match with table 4 with a score of 1.15, then there couldn't be a new match. Actually when I write it out it seems rather straight forward, and I suppose it was in the end, it just required a lot of tests and postulating to think of all the possible scenarios. The issue with the solution I arrived upon was that I had a ton of if statements, and ifs inside other ifs and so forth. The whole thing just got ugly.

While trying to refactor this code, I discovered that a huge portion of the code had outstayed its welcome and needed to be moved to a new class. I called this the TableComparer, and it managed all the code having to do with making the matches between the tables. This made it much easier to make the code readable because now I had the group of semi ugly functions all in one class with one goal, so I could pull out a lot of arguments and turn them into fields, thus making it easier to extract new and descriptive methods. The other thing that was great about this refactoring was keeping the tests passing the whole time, and slowly transitioning the code into its new form. I would pull a chunk of code from the HistoryComparer and move it to the TableComparer, get everything to pass, and then remove the code from the HC. As I did this, the tests also informed me that I needed to make a new test file for the new class, and needed to move the appropriate tests into it. It was quite nice.

Tuesday, July 21, 2009

Day 39

Today I enhanced my sorting algorithm which lines up all the tables. First I made the function that compares two tables a little more forgiving. Ultimately I will need to make this comparison a percentage fitting algorithm, so that it will still match tables that are just a tiny bit different. Since FitNesse tests often have collapsible sections, that reveal some test specifics, I also had to make the comparison ignore those collapsed sections.

The biggest task today was to refactor the whole HistoryComparitor class. Most of this I just did myself, extracting method after method, giving names that described to true intent of the code, and abstracting certain repeditive concepts and variables. There was one method I needed help refactoring because it was a bit tricky. This was the same method that had a three level loop, that I described breifly yesterday. The method was actually one algorithm repeated twice for its compliment. Once for the firstTableList and again for the secondTableList. Once we noticed this, we began to implement the Strategy Pattern.
First we created an interface which described what methods we were going to need. Then we implemented that interface in two derivative classes, one for the firstTableList and another for the second.
By extracting the details of the algorithm into two subclasses, we had the power to remove all the duplication and generalize the algorithm such that it worked for both lists. This process made the code much easier to understand and follow, removed duplication and regidity, as well as freed the algorithm to be used elsewhere if needed.

The really cool part was that we kept the tests passing the entire time. At anypoint during our refactoring process we could have released the code and it would have worked. This is an essential skill that I must master. The refactoring was slow and careful, but vastly increased my understanding of both my own code and the power of the tests I wrote. The Strategy Pattern was pretty cool to.

Monday, July 20, 2009

Day 38

Today I worked on improving the historyComparer some more. I needed a way to take two lists of tables, and match them up in length and in value. So if I had a list of 3 tables and a list of four tables, where table 1 of the first list matched table 2 of the second list, I would ten add a blank table before table 1 of the first list. This would line up the matching tables as well as the end of both lists (they would both be 4 tables long). But then I also needed to guarantee that if two tables didn't match eachother, the would not be in the same row/lined up. The process would look something like this:

List1 List 2 ---> List1 List2 -----> List1 List2
_A_ X_____ blank_ X _______blank__ X
_B_ Y_______ A__ Y_________ A__ blank
_C_ B_______ B__ B_______ blank__ Y
_D_ Z_______ C__ Z_________ B___ B
_--_ D_______D__ D_________C__ blank
_________________________blank__ Z
__________________________ D___ D

This way, when comparing the tables of two page's test history, the user would be able to easily see which tables have changed, new tables, deleted tables, and so forth.
The solution was to first, put the tables in lists like above, then to compare the tables, then line them up, then finally add blanks where needed. This sounds simple enough, but what ended up happening was that I had loops inside loops inside of loops.
The process would start by comparing each table to every other table in the other list. Every time the comparison found a match, it would add the index of those two tables to a list of pairs, to keep track of the matches. Once all the matches were found, it would loop through the matches trying to line them up by adding in blank tables. But every time a blank table was added to a one of the lists, the indices of the matches had to be updated, so it would have to loop through the matches again inside the first loop, updating all the indices. After all the matches were lined up, it would loop through the lists adding blank tables anywhere there were two tables in a row that didn't match, and then again update all the match indices. Finally, it would make sure both lists had the same number of tables by adding blanks to the end of either list if needed.
Now I have a lot of refactoring to do to make the code explain itself. This is, I think, the most important part of coding, and its a good thing I have tests.

Friday, July 17, 2009

Day 37

This week my Dad taught a four day class to a couple of students, including myself, which was focused on the Agile Principles, Patterns, and Practices. The first day was a very quick run through on TDD so that the students would have the context under which all agile practices are performed. The most important information from that first day was the three rules of TDD: You may not write any production code until you have a test for it. You can only right as much of a test as is needed to fail, including compiler errors. You can only right as much production code as it takes the make the test pass. If you are using these three rules you are practicing TDD, and will experience the wealth of benefits that come along with extensive testing. What is interesting is how just following those three rules may actually lead you to many of the other agile practices like the Open/Closed Principle. A plethora of tests will force you to keep your code very flexible, because the act of writing a test forces you to access you production code from a separate path, often decoupling tight and nasty bonds.

The three days following were all about the agile PPP. The five PPP are:
Single Responsibility Principle
Open/Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle

SOLID

The SRP says that a class or a method can only have one reason to change. Every class needs to be based around one idea, and one idea only. Every method of that class should be geared to accomplish, manage, or add behavior to that one idea. A class named House should not, for example, have a method that tells the user what other houses or condos the owner of the house has. A method named makeGoldenFish should not set the fishing boat's x and y location. By using this principle we can avoid unexpected changes or failures when we create a certain class or use a certain method. It also makes sure that if we just so happened wanted to change the type of fishing boat, we wouldn't have to go into the makeGoldenFish method and change the boat type in there. It guarentees a certain degree of flexibilty in your code, as well as helping another coder understand what your code's intentions are.

The OCP says that classes or components should be open for extension but closed for modification. It should be easy to add new features to an existing framework, and you shouldn't have to change any of the existing code to do it. Making changes should be a low cost and low risk opperation. Adding new code is cheaper than changing old code, and by following the OCP you guarentee that adding new features is cheap, or at least cheaper than it would have been otherwise. Part of the process of writing good code is forgeting that details exist and writing very general solutions to problems, and then adding the details later. The OCP encourages you to write very abstract classes, methods, and solutions so that details can be added, interchanged, or removed without having to change much code at all. An example would be if I had some pets that I wanted to be able to command to move. I have a dog that runs, and fish that swims, and a bird that flies. A poor way to write the code to do this would be to have one Pet class, with some switch statement or if -else chain that checked what type of pet it was then said dog.run or bird.fly. This would violate the OCP because to add a new type of pet, like a sloth that can only walk, I would have to add another ifelse or case statement in every spot I wished to tell this pet to move. Thats a lot of changes, and very expensive, just to add a new pet. A better way to do this would be to use the Template Pattern. I would create an interface named Pet, and have a Dog, a Bird, and a Fish class which were derivatives of the Pet interface. I would then have a method in pet, which each derivative would implement, called move(). This way I could avoid all if and switch statements, and replace them all with pet.move(), and at runtime the appropriate pet would get the correct move call. This makes my code far more dynamic and flexible. To add a new pet, I would merely create a new derivative to Pet. Thats all. If the pet happened to be a sloth, then pet.move() would call the sloth's move function. This is cheap to add features too.

The LSP says that a derivative must be a sutable substitution for the base class. If I have a base class Hero with a method saveLife(Person) then my derivative Batman must have a saveLife(Person) method that will sufice in a situation that a user might call Hero.saveLife(Person). One must be careful with this however, for the IS-A relationship may apply for the real situation, but not the coded representation. The coded representation might not always match the reality. Some symptoms of the LSP are when low level details are forced to become visible, when bases know of their derivatives, when not all abstract methods are implemented in derivatives. A violation of the LSP often is a, or leads to a, violation of the OCP. An example is lets say you have a Driver base class and a Vehicle base class. Their derivatives are CabDriver ,Pilot and Car, Jet respectively. When driver.operate(vehicle) is called, you may have a CabDriver trying to operate a Jet, which simply wont work, and thus you have violated the LSP. To solve this you might use the Intelligent Children Pattern, which is useful when you have a dual higherarchy (such as the current example), and you don't want to have to use ifs or downcast your types. You can have the children, or the derivatives, hold the types of their respective needs. So the CabDriver would know his vehicle is a Car. This adds a dependancy, but there is a trade off either way.

The ISP says that an interface must be cohesive to the classes that implement them. When an interface begins to acquire more and more methods, and the classes that implement the interface don't use all of the methods, than the interface has gotten too fat. An interface should be specific to a general idea, and the classes that implement that interface should all fit into that idea. The example in Agile Software Development is a Door class, which is abstract, and has Door derivatives like a TimedDoor (a door that can only be open for a certain period of time). This TimedDoor uses the methods of a Door, but also inherets from a Timer class, to get the functionality it needs to know when it has been open too long. The example than explains a solution to this problem that demonstrates how an interface could be made for a TimerClient, which Door and then Timed Door would then implement. But why should Door implement a TimerClient? It shouldn't. A general Door has nothing to do with the timer, but in that solution it would implement the TimerClient just to get the timer functionality. This demonstrates at least part of the ISP. The ISP also outlines a strategy to write maintainable code. If you have some base class with a TON of methods, that a whole bunch of other classes use by extending the base class, then everytime you make a change to that base class you will need to recompile all of those children classes as well (even if they only use one of the base class methods). To solve this, you can stick an interface in between the base class and some of the child classes, so that the child classes will call the methods on the interface, and the base class will inherit the methods from the interface. This way you can free up some dependencies and only have to recompile small chunks of code if you make a change to the super base class.

Friday, July 10, 2009

Day 32

Yesterday turned out pretty excellent I thought. We got the new FitNesse release out! And now, its so cool, all you need to do to update is download and run the .jar file and FitNesse will do the rest! I spent most of the morning working on adding a button and some user friendly tools to the compareHistory function. I had a long debate with myself on how to actually accomplish making it user friendly. In the end I decided to use check boxes next to the test history files, and the user would select two and click the compare button I added. For awhile I was considering both doing the check boxes in Java Script, which I don't know much of and porbably would have taken me a day to learn the basics well enough to get the functionality done, or I would have made two parrallel option circle things thus making sure the user could only select two. Instead I just send an error page if the user attempts to compare history with any number of boxes checked other than just two. I am starting to get the hang out making new features, and finally I have a decent idea of how FitNesse works.
My next task has already been given to me, and that is to improve the compare history feature. Right now it merely displays the two pages side by side, and shows whether or not they match. Now I need to make this comparison table by table, showing which tables match and which don't. Even more than that, and this will be the challenging part, if a old page had lets say 1 more table than the new one, then of course all the tables wont line up right. So I need to make the comparison just a little smarter so that it will actually look for matching tables and line those ones up and just attach any extra ones to the end.

Wednesday, July 8, 2009

Day 31

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.

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 :/

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

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.

Monday, June 29, 2009

Day 24

I have been quite inconsistent with this blog, and I believe this is a mistake. Thus I will remedy this mistake by trying to blog after each day... something I should have done from the start. The blog for me will be an excellent reference to what I have learned, what I need to learn, and what I have accomplished. It will also solidify, each day, what I have learned.

The last weekish has been mostly focused on the lighthouse task #123, changing the manner in which FitNesse updates. It turned out to be a rather larger task than first anticipated, but at long last it has been resolved. Just today we went back and refactored the code we used to implement it. FitNesse can now be updated from a single jar file, whereas it used to require a zip file containing many bits and pieces, and some of the files would even have to be changed manually.

Much of today was actually spent on getting our iPhones to work!

I have also been able to make more progress on my major summer project, the issue is that I was planning on building this project upon my FitNesse Side Bar project that I completed earlier, but now that code is overextending it intended boundaries and thus is getting a bit messy. I have been constantly refactoring, but I fear I might just have to scrap it and start from ground zero. The biggest problem I am having is that I have started passing page information through Limelight props... it might not be terrible yet, but the idea of passing the program's data through the GUI is rather disconcerting.

Monday, June 22, 2009

Day 15 & 16

I was able to finish the Lighthouse task #127 which was the purge history task. I added three buttons to the test history page, Purge > 30days Purge >7days Purge all. As proof that they all work, I no longer have any history! Since a user can also just type in the command URL?purgeHistory&days=?? where they can choose the number of days, I also had to add many checks to make sure the input is valid. A note on tests that test text outputs, they are overwhelmingly sensitive! After I was done making my changes I ran all the tests, making sure everything still worked, and I got one failure. Somehow something got changed in one of the template, though I didn't even know I changed it, and a test was failing because the text it got wasn't what it expected. So I looked at the output and what was expected and they looked the same, except finally I saw one case where there happened to be a newline out of no where. Long story short, I spent a very long time hunting through the code to find this line, and it ended up being in one of the html (velocity) templates. Maybe I hit the reformat command while in that file, and my IDE added a new line. I don't know, but it was very frustrating.

A very unfortunate thing occured on thursday. I lost all of my work for the Lighthouse task #123 because I am a newb at github. I thought that if you had a branch, everything in that branch is protected once you switch to a new branch, and thus you don't always have to commit. So to work on my other task I created a new branch and did a reset --hard to get a earlier version of the code. As it turns out, this deleted everyone of my changes on the other branch since I was a fool and didn't commit... At least now I know how to do it all, so the process of making up all my work should be rather painless, but it still sucks and now I know to always commit!

Tuesday, June 16, 2009

Day 13 & 14

I have been having a fair amount of trouble with my most recent task. Lighthouse task #123 which is to alter the manner in which FitNesse updates itself when it is first run in a new environment. There is a list of files that need to be copied over into the FitNesseRoot every time an update is done. Currently this list of files is in the updater code itself, but my task is to move that list of files. I need to create an ant task in the build.xml file that will call a java program which searches through the FitNesseRoot and finds all the files that need to be copied over in an update. This program must then create a new file with the names of all those files which need to be copied over, and a file of the files which shouldn't be copied, and then put those into the .jar file that is created when the ant build is performed. Then, once FitNesse is started for the first time, the updater must reach into the .jar file and pull out the updateFileList, read the list, and grab all the needed files and place them into the FitNesseRoot.
I have had to learn a lot about ant. How to create a new ant task. How to have that ant task called. How to have that ant task call a java program which creates a file. Currently I am trying to figure out how to pull the needed files out of the .jar file. Micah told me a command jar-x < fitnesse.jar which would pull out all the files in the jar, and then I could search through those to find what I need, but I believe FitNesse already has a way to extract the files I need. I just need to find this method.
I have also been given the new task Lighthouse #127, which is to create a way to delete the test history for a page up to a certain given date. This should be a fairly simple matter... but then again Murphey will probably strike me down for being so foolish as to think a task could be completed in any reasonable amount of time. I believe I will need to either add a new responder all together called the PurgeTestHistoryResponder, or add a feature to the current TestHistoryResponder which looks for a delete command and an input date. The task says to create 3 buttons, Purge >30 Days, Purge >7 Days, Purge all, all which would invoke the responder with a date.

I have also put some more work into my ultimate task for this summer. I believe I am going to create a LimeLight player for each of the WikiWidgets, so that when I recieve the JSON object from FitNesse, I can render the data into my own data structure of Players. This in theory could then be placed directly on the screen without too much extra effort.

Friday, June 5, 2009

MyUltimateTaskForTheSummer

So I need to find a way to bring FitNesse into Limelight. This will have to be done by taking all of the rendered information of a FitNesse page, wrapping it up in a nice bundle, sending it to Limelight, and then finally interpreting that information to reconstruct the page.

FitNesse pages are made up of a large string of WikiText (and some xml for some of the page properties, like if its a test page or a suite). When a page is rendered to be displayed, all of that WikiText is broken down into a massive tree structure of WikiWidgets. The WikiWidgets are objects that represent a wide range of functions or qualities. There is a WikiWidget for making text bold, for putting the date on the page, for making comments, or for inserting images. Each widget has a pattern of WikiText that it looks for, to know if it should be that sort of Widget. The widgets also have a parent widget and child widgets (with the ultimate parent being the WikiWidget Root). The bold WikiWidget is referenced with a ''' text to be made bold '''. When the page is rendered, the chunk of text with the ''' some text ''' would be turned into a bold widget, and the text inside those quotes (some text) would be made into a text widget, and as a child of the bold widget.

The process of breaking down the text into widgets is quite interesting. When it begins, a WidgetData object is created, and is loaded with every WikiWidget class (except literals, which is a different story). Then a builder object is created, which contains the WidgetData as well as the WikiText from the page to be rendered. Next, it will add a child widget to the WikiWidget Root by looping through every widget in the WidgetData and trying to find the first match of that widget's pattern to the WikiText. If it finds a match, it saves where the match is in the WikiText , and then keeps checking the other widget patterns to see if they come any earlier in the text. Once it finds the first match, it creates a WikiWidget object of that match, saves that object as a child of its parent (for the first match the parent is the WikiWidget Root), searches the text inside that widget for more matches (to become children of the just created widget), and searches the remainder of the WikiText for the next first match. This cycles recurssively until the entirety of the WikiText has been turned into a massive tree of WikiWidgets.

This tree of WikiWidgets would then be parsed into html and put on the page, but for my task I want to stop right here. I would then take this tree and probably turn it into a JSON object (a fairly simple data structure) and then ship it over to Limelight. Finally I would have to create some sort of translator which will turn this tree of widgets, in the JSON object, into Limelight props to be displayed.

This should be fun.

Day 11 & 12

On Thursday, and part of today, I worked on LightHouse task #126. In FitNesse are these things called scenarios. The scenarios are tables that the user can make which tie the test tables in the acceptance tests to the functions, like fixtures, that will allow FitNesse to test the production code. Whenever an acceptance test is run, FitNesse will grab all the text on the test page and render that text table by table. The test pages will also include Scenario Libraries, and thus when a test page is run, FitNesse also grabs the Scenario Libraries to be rendered. An issue occured recently (when FitNesse was changed from rendering a test page all at once to rendering a test page table by table) where FitNesse would silently crash while running tests if a scenario was ever defined twice. FitNesse would crash because when rendering the page (into html) table by table FitNesse needed a method to find exactly where in the String of text, of the page, a table resided. Knowing where a table resides is important when trying to generate the html after a table has been rendered (the rows of the table have been turned red or green and such). To find that location, FitNesse would search the whole String for the string of characters which make up the table. The issue is that if there are two scenarios (and actually the same problem would occur with two tests that are exactly alike) that are exactly alike, then that search through the String would find only the location of the first scenario, and not the second. Thus, when FitNesse attempted to render the second copy of that table, it would assume the location of the first copy, and an exception would be thrown.
In the end, the solution was fairly simple. All that needed to be done was guarentee that all tables were unique, so I just made a quick little method that added table number attribute to all tables, and generated a random number for each table. In this way, it would be dreadfully unlikely that two tables would even be exactly alike.
Today I was told what my ultimate task for this summer would be. I must find a way to bring FitNesse into Limelight.

Thursday, June 4, 2009

Day 9 & 10

On Tuesday I resolved the LightHouse task #125. FiteNesse keeps track of all the test history in a bunch of directories named after that test page. Inside those directories with the a strictly formatted name which includes things like the date and the number of passing and failing tests, and so forth. The issue was that if someone tried to access the history through FitNesse, FitNesse would toss up an error if it found any files that didn't follow its strict format. So I just made FitNesse a little more forgiving with those history files by ignoring any file that appeared corrupt, and then sending a message if someone inquired further.
On Wednesday I did a little more refactoring on my Limelight sidebar app for FitNesse. I made a video with my dad, demonstating a software kata. This is some small program which you practice writing again and again using TDD. We did created a prime number generator. What is interesting about the process of creating the PNG was that the tests would step by step lead us to a 3 line algorithm which would have been terribly difficult to come up with on the spot. I also created a quicksort algorithm using the same sort of step by step testing process in order to see if the testing process would lead to the bubble sort algorithm or if I could have arrived at the quicksort algorithm. What I discovered was that there was a leap that had to be made when testing a list of 3 unordered elements. At this leap, there were several simple solutions to make the test pass, but each solution would wind up with disparate algorithms in the long run. The diference between quicksort and bubblesort at that point in the testing was a matter of adding 1 extra variable named pivotpoint (which would eventually lead to the pivot which defines quicksort). It was pretty damn interesting.

Monday, June 1, 2009

Day 8

Today we refactored the rest of the code I wrote for the AddChildPageResponder. We also wrote all the FitNesse acceptance tests for that responder. I am now far more familiar with the FitNesse style acceptance tests and how to make the necessary fixtures to make the tests work. I also looked at the next LightHouse task #125 which has to do with the TestPageHistory files that FitNesse maintains, and making the algorithm, which uses these files, a little more forgiving towards the file names.

Friday, May 29, 2009

Day 6 & 7

I was able to complete my Limelight app for FitNesse, which displays the hierarchy of pages in an agreeable manner. A few issues came up, such as whether I should load all the pages at once (which I tried at first, but it would take about 10 seconds to load!) or only load the current level pages, and then load a page's children when the user expands that page (by clicking on the plus sign which then becomes a minus sign, this is hopefully a familiar structure). For the most part it all went smoothely, and my code is, I believe, 100 % tested (except for my GUI code, which I wasn't sure how to test but Micah says there is a way to do it). I also added a new small little FitNesse feature, that made life easier for my limelight app.
Much of today has been spent working with my dad on refactoring my tests and code for the AddChildResponder for FitNesse. Its funny, when I look at the code and think it looks pretty readable and well abstracted, my dad will see it and say "But oh, look at this, these 3 lines show up here, here and here... Lets extract that into a new method. Ahh, thats better," then low and behold it becomes even more clear what my intentions were when I was writing the code... even if I hadn't known those were my intentions. Its a pretty awesome skill that I hope to acquire in time.

Wednesday, May 27, 2009

Day 4 & 5

So I have been given a project in my mentors absence. I must create a tree structure for the names of all the Fitnesse pages in limelight, such that all the pages will be displayed in an expandable list. I will first need to create a limelight app that can display the list correctly. Then I need to get the names of the pages from Fitnesse, and use my Limelight app to display that list of all the names. Finally I believe I will need to use the names in the list as links that will open a browser to that Fitnesse page. Yesterday I re-familiarized myself with Ruby and Limelight, finally got Rspec to work in text-mate after working for about two hours to get it to work in Intellij, only to find that Intellij has a bug that prevents you from opening project structures in certain cases. I also got a start on the gui aspect of this project. Today I got a large amount of the list and tree node code all done, as well as finished the skeleton of what the Limelight app should look like. Now I must find a way to pull the names from Fitnesse into my app, and then implement the list structure once I have the names. Finally I will need to make those names links.
I also got a few more of the Craftsmanship articles done, and am about 100 pages into Clean Code (its a very dense book, and takes awhile to recognize the important details in the code).

Thursday, May 21, 2009

Day 3

Today we got done LightHouse task #23, the add child button for any wiki page. I did the AddChildPageResponder which would handle the command to create a child, passing the correct response to the browser as well as generating a new page with a given name, content, and page attributes. I also made a fairly decent dent in Clean Code! SMALL FUNCTIONS! ok i get it, 1 goal per function. Also got done a few more of the Craftsmanship article, I will add summaries tomorrow. We still need to write acceptance tests for Lighthouse #23 though

Wednesday, May 20, 2009

Day 2

Today we got to work on fitnesse. We solved Lighthouse request #121 where we made scenario libraries add themselves automatically for all slim test pages using the uncle hierarchy. Wrote lots of tests, did almost no debugging :)
Finished at least 5 more Craftsmanship articles, though I am a little uncertain about the meaning behind #22 and #23.

Tuesday, May 19, 2009

Craftsmanship Article Notes

These are my notes on the craftsmanship articles. If you find any flaws, mistakes, or perhaps something else that should be included in my notes then please inform me because I would like to understand principles in the articles as best I can.

Notes from Craftsman 1-5:

-A function can have only one purpose
-Meaningful names
-Don't get attached to your code, deleting it can help sometimes
-Write the simplest test that will fail, then solve it in the simplest more generalizing manner

Craftsman 6:
race condition: when two threads are running at the same time, and something in one thread must finish before something in the other thread finishes
-When dealing with threads, make a habit of running tests several times, checking for race conditions

Craftsman 7:
Mock Object: an interface in the testing unit that allows you to create a mock user of your code. It helps keep the testing code in the test unit and out of the real code.

Craftsman 8:
Tests are useful even if they don't add to your functionality. They are a form of documentation for your code. They demonstrate to your user, or another craftsman, the purpose and the function of your code.

Craftsman 9:
reentrant: when a function is entered more than once before it exits. This can be done by accessing the function through two separate threads, and ending the first one after the second. Run the tests a few times, the threads may interfere with one another.

Craftsman 10:
Its important to make sure you maintain the way threads are running at all times. When using lists, be sure not to leave an iterator open for long when other threads might by modifying the list.
Read about Design Patterns. Decorator pattern (synchronizedList)
Decorator - An object which defers to the object it inherits from in order to work around a dependency.

Craftsman 11:
The design for your code should be in the tests. Who ever writes the test, dictates the design and manner of your code. Start your program by writing the tests, not the main function. For a well written batch of code, your main really isn't very important and can be written close to the end of design.

Craftsman 12:
It is possible to make stubs for testing. Stubs are the outline of a class or function that do no work, but allow you to make the function calls.
Always be certain to extract duplicated code as soon as you find it.
Make small incremental changes.

Craftsman 13:
Thinking abstractly about code is essential. If you can abstract a group of variables into an object instead, you have generally made the code simpler and easier to change and read.
To "Micah" someone is to find a simpler way (or simpler abstraction) to solve a problem and to make aspects of their code, that they anticipated would be needed, obsolete.

Craftsman 14:
Write purposeful tests. Tests that test functionality that is not a requirement aren't very useful.

Craftsman 15:
Single Responsibility Principle: "A class should have one and only one reason to change. All the functions and variables of that class should work for a single goal. A class should have only one goal."

Craftsman 16:
Template Method pattern: To eliminate duplication, where the duplicated code would be similar but with different parameters you can create an abstract class with different functions to establish the different parameters. You make an abstract method for a higher level class, then extend that class and have the methods in the lower level class define the abstract method.
abstract public class Sorter {
public Sort();
abstract public compare();
}
public class IntegerSorter extends Sorter {
public compare() //and this would define compare for integers

Study those patterns!

Craftsman 17:
Rather than using a chain of if statements, it is often better to use Guard statements. This is where you flip the if from: if (this) {do} else {don't} to: if(!this){return} {do}
Take note of single/entry single/exit

Craftsman 18:
Another good reason for writing tests and code is because its like writing everything twice, and perhaps a typo in one place will be caught because you didn't make the same typo in the other. Known as dual entry bookkeeping
There should be no rushing your work. Always make clean code over a lot of ugly code that works. Lots of ugly code will always slow you down in the long run.

Craftsman 19:
If you write slowly, clearly, and thoughtfully you can end up getting a lot more done than if you rush. You will spend far less time debugging.

Craftsman 20:
Its possible you will get a batch of ideas and want to code them out before you can think of tests for them. Then it is possible the batch of code will do something that looks like it works, but without tests, you might not really understand what is happening. Tests give you a foundation of understanding. Its like measuring out and cutting each piece of wood for a house to exact specifications and knowing for certain that every piece will fit, rather than lining up a bunch of wood and cutting through them all at once with a giant machete and hoping everything will stand the way you pictured it working out in your mind.

Craftsman 21:
A note on deleting directories, it might be a good idea to check for subdirectories and files in those subdirectories before you delete the primary directory.
Make sure your tests clean up after themselves.

Craftsman 22:
A foreshadow to a grave mistake that I believe Alphonse and Avery are making. To add just a bit of functionality that made a wide range of changes to the code all over the place. All these changes were done without writing new tests and as a chain of changes trying to make the last test work without rethinking their strategy. Although I felt uneasy about this, no note of a mistake was mentioned in the following articles... I am uncertain of the intended message.

Craftsman 23:
An example of pair programming, write the test then have your pair make it pass. StarCraft > LandCraft

Craftsman 24:
A sort of interlude to the next section. Also acceptances tests can help organize the structure of your code.

Craftsman 25:
An explanation of acceptance tests, their purpose as the requirements, and the idea that they can be written by the project managers, and the craftsman make them pass.

Craftsman 26:
Introduction to fitnesse. Writing acceptance tests.

Craftsman 27:
Some what deeper explanation of writting acceptance tests, and a Fitnesse.
A reminder of the need for not only unit tests, but acceptance tests as well, and the importance of the tests having the ability to test the code.

Craftsman 28:
Public vs private fields in classes. Much of OOP is centered around encapsulating variables, data, and ideas, and thus it is often appropriate to use getter and setter methods; however, for data structures that are mostly used to transfer data, getters and setters would be a waste and thus public fields are advisable. With objects, you mostly want private variables, with data structures (such as Fitnesse Fixtures) you can have public variables.

Craftsman 29:
Tests aren't a waste of time.
Another common trend that is being displayed, and easily observed in the real world is a stubbornness to do things the way you have always done them. The wise man isn't the smartest, or the one who always knows what to do, but the one whom corrects his mistakes the moment he sees he was wrong.

Craftsman 30:
Hooking up Fitnesse to the application via fixtures.

Craftsman 31:
For acceptance tests you don't do the simplest thing to make it pass, thats for unit tests. For acceptance tests you need to really make them work, and use unit tests to get you to that point. If you are tempted to use a simple method to solve the acceptance tests, chances are you need more unit tests (unless the solution is actually simple of course).
To deal with a database, without specifically writing functions in the database itself, you can use a gateway/interface. This is an object that knows how to handle the data. Push off decisions about the database for as long as possible.

Day 1

Got intelliJ up and running with my fitnesse project
Beat the crap out of ResponseExaminer, and made first Fitnesse Commit on github
Finished some of the craftsmanship articles, currently at #20
Learn about Template Method Pattern and Decorator Pattern
Established this blog account