27 lipca 2013

Firefox - plugin na bazie FireBreath

Szukam sposobu, na podpięcie się do przeglądarki i dobranie się do źródła wyświetlanej strony - co w konsekwencji jeszcze nie całkiem mi się nie udało. Padło na stworzenie rozszerzenia do przeglądarki. Firefox oferuje interfejs NPAPI (http://en.wikipedia.org/wiki/NPAPI) do takie celów. Projekt FireBreath, umożliwia tworzenie rozszerzeń na różne przeglądarki pod różne systemy. Instalacja frameworka jest bardzo przyjemna.
#wymagana jest wcześniejsza instalacja libgtk
sudo apt-get install libgtk2.0-dev

git clone git://github.com/firebreath/FireBreath.git -b firebreath-1.7 firebreath-1.7
cd firebreath-1.7
# zaciągane są potrzebne biblioteki np. boost
git submodule update --recursive --init

# budowanie przykładów dostarczonych z projektem
./prepmake.sh examples
cd buildex/
make
Autorzy dostarczają także kilka wideo tutoriali, który szybciej pozwalają zapoznać się z architekturą całego projektu.
Mamy też do dyspozycji odpowiednie skrypty, umożliwiające stworzenie szkieletu pod nasz projekt. Autor nawet zaleca, by nie by tworzyć go zupełnie na zewnątrz, a firebreath podpiąć jako submoduł.
cd firebreath-1.7
./fbgen.py
# Plugin Name []: BeruPlugin
# Plugin Identifier [BeruPlugin]: 
# Plugin Prefix [BPL]: 
# Plugin MIME type [application/x-beruplugin]: 
# Plugin Description []: Beru Testing Plugin
# Plugin has no UI [false]: 
# Company Name []: NiegodziwyBeru
# Company Identifier [NiegodziwyBeru]: 
# Company Domain [niegodziwyberu.com]: nberu.blogspot.com         

# Dobrą praktyk jest rozpoczęcie pracy od stworzenia repozytorium
mv projects/BeruPlugin/ ../
cd ../BeruPlugin/
git init .
git add .
git commit -m"Beru Plugin first commit"

# ustawiamy firebreath jako submodułu
git submodule add git://github.com/firebreath/FireBreath.git firebreath
git submodule update --init --recursive
git commit -m"Added firebreath as submodule"

# Budowanie
./firebreath/prepmake.sh . build/
cd build
make

# Kopiowanie naszego rozszerzenie stamtąd zostanie 
# automatycznie zaczytany przez Firefoxa
cp bin/BeruPlugin/npBeruPlugin.so ~/.mozilla/plugins/
Wciąż nie wiem, czy możliwe jest dobranie się całego źródła strony. Poniżej mały eksperyment pokazujący możliwości rozszerzenia , czyli pobranie adresu strony, z której został zawołany (http://www.firebreath.org/display/documentation/Tips+and+Tricks#TipsandTricks-GettingtheURLofthecurrentpage).
void BeruPlugin::onPluginReady()
{
    // When this is called, the BrowserHost is attached, the JSAPI object is
    // created, and we are ready to interact with the page and such.  The
    // PluginWindow may or may not have already fire the AttachedEvent at
    // this point.
    const std::string current_url = m_host->getDOMWindow()->getLocation();
    const std::string page_html = m_host->getDOMElement()->getInnerHTML();

    std::ofstream f;
    f.open("/home/beru/BeruPluginLog.txt", std::ios_base::out | std::ios_base::app);
    f << current_url << std::endl;
    if (page_html.empty())
        f << "Empty content " << std::endl;
    else
        f << "Content: " << page_html << std::endl;
    f << "-------------------------" << std::endl;
    f.close();
}
Ładowania rozszerzenia.
<html>
<head>
<title>Test page for object beruplugin</title>
</head>
<object id="player" type="application/x-beruplugin" width="300" height="200">
aaa<i>iii</i></object>
<br/>
<b>Hello world application/x-beruplugin</b>
</html>
I wynik działania:
file:///home/beru/test.html
Content: aaa<i>iii</i>
-------------------------

22 lipca 2013

Trochę o Unit Testach

Zbiorczy zestaw linków, traktujących o testach jednostkowych i trochę moich notatek.

http://www.youtube.com/watch?v=RlfLCWKxHJ0
    Zastosowanie dependeny injection oraz prawo Demeter w testowaniu.

http://www.youtube.com/watch?v=wEhu57pih5w
    Testy jednostkowy pozwalają nam wykryć błędy w działaniu małych komponentów. Dają przewagę nad testami systemowymi, pozwalając szybko zorientować się gdzie leży przyczyna błędu. Całościowe test, też mogą to wykazać, ale znacznie trudniej jest ustalić, gdzie leży usterka, albo co jest jej przyczyną.
    Mieszanie mechanizmu tworzenie obiektów z business logic sprawia, że bardzo trudno napisać dobry test. Nie można tworzyć obiektów w izolacji. Jedyne co można tworzyć to cały łańcuch zależnych od siebie obiektów. Nie mamy wtedy już do czynienia z testami jednostkowymi (np. test silnika), tylko z testami systemowymi (test działania całego samochodu).

http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/
    Tutaj autor, przestawia TDD jako proces projektowania (i nie jest procesem testowania). TDD i testy jednostkowe pomagają dostarczyć komponenty oprogramowania, które indywidualnie zachowują się zgodnie z założeniami projektowymi. Jedynym odstępstwem, w którym testy jednostkowe naprawdę potrafią wykryć błędy jest proces refactoringu. Trochę inna wizja niż ta prezentowana na Google Talks.

Ciekawy pattern do nazywania testów np. ProductPurchaseAction_IfStockIsZero_RendersOutOfStockView()
  • Subject
  • Scenario
  • Result

http://www.exubero.com/junit/antipatterns.html
    Mowa o antywzorcach, jakie najczęściej pojawiają się podczas tworzenia testów jednostkowych. "Unit testing is the first of a long series of steps to verify that the code works correctly."