Skip to content

Commit

Permalink
Added first unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jgehring committed Nov 4, 2011
1 parent 57cdedd commit cf7d667
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -1,4 +1,7 @@
*.[oa]
*.gcda
*.gcno
*.gcov
.*.swp
examples/select
src/lexer.h
7 changes: 5 additions & 2 deletions Makefile
Expand Up @@ -2,16 +2,19 @@
# hcxselect - A CSS selector engine for htmlcxx
#

SUBDIRS = src examples
SUBDIRS = src examples test
.PHONY: all $(SUBDIRS)

all: examples
all: examples test

src:
@$(MAKE) -wC src $(MFAGS)

examples: src
@$(MAKE) -wC examples $(MFLAGS)

test: src
@$(MAKE) -wC test $(MFLAGS)

clean:
for d in $(SUBDIRS); do ($(MAKE) -wC $$d clean ); done
20 changes: 20 additions & 0 deletions test/Makefile
@@ -0,0 +1,20 @@
#
# hcxselect - A CSS selector engine for htmlcxx
#

CXXFLAGS += -Wall -g
CXXFLAGS += $(shell pkg-config --cflags htmlcxx)
INCLUDES += -I../src
LIBS += -L../src -lhcxselect
LIBS += $(shell pkg-config --libs htmlcxx)

all: test

.cpp.o:
$(CXX) $(CXXFLAGS) $(INCLUDES) $(DEFINES) -c -o $@ $<

test: test.o ../src/libhcxselect.a
$(CXX) $(LDFLAGS) test.o $(LIBS) -o $@

clean:
$(RM) *.o
151 changes: 151 additions & 0 deletions test/test.cpp
@@ -0,0 +1,151 @@
/*
* hcxselect - A CSS selector engine for htmlcxx
* Copyright (C) 2011 Jonas Gehring
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holders nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


#include <iostream>
#include <istream>
#include <sstream>
#include <string>

#include <htmlcxx/html/ParserDom.h>

#include <hcxselect.h>

using namespace std;


const char *rawsource = \
"<html>"
" <ul>"
" <li>A list element</li>"
" <li>Another one</li>"
" </ul>"
" <p id=\"foobar\">This is a paragraph</p>"
" <nonsense id=\"id1\">This is not real</nonsense>"
" <p title=\"title\">"
" A paragraph with a title"
" <span class=\"class1\" lang=\"en-fr\">A span</span>"
" </p>"
" <p title=\"t2\" lang=\"en-gb\">Another one</p>"
" <span class=\"a bb c\">Multi-class span</span>"
"</html>"
;

struct tvec {
const char *s;
size_t n;
const char *t;
} vectors[] = {
{"li,nonsense", 3, "<li>Another one</li><li>A list element</li><nonsense id=\"id1\">This is not real</nonsense>"},
{"nonsense", 1, "<nonsense id=\"id1\">This is not real</nonsense>"},
{"*", 1, rawsource},
{"*.class1", 1, "<span class=\"class1\" lang=\"en-fr\">A span</span>"},
{"#foobar", 1, "<p id=\"foobar\">This is a paragraph</p>"},
{"p[title]", 2, "<p title=\"t2\" lang=\"en-gb\">Another one</p><p title=\"title\"> A paragraph with a title <span class=\"class1\" lang=\"en-fr\">A span</span> </p>"},
{"p[title=\"t2\"]", 1, "<p title=\"t2\" lang=\"en-gb\">Another one</p>"},
{"p[title='t2']", 1, "<p title=\"t2\" lang=\"en-gb\">Another one</p>"},
{"span[class~=\"c\"]", 1, "<span class=\"a bb c\">Multi-class span</span>"},
{"span[class~=\"b\"]", 0, ""},
{"span[class~=\"a bb\"]", 0, ""},
{"p[lang|=\"en\"]", 1, "<p title=\"t2\" lang=\"en-gb\">Another one</p>"},
{"p[lang|=\"fr\"]", 0, ""},
{"p[title^='ti']", 1, "<p title=\"title\"> A paragraph with a title <span class=\"class1\" lang=\"en-fr\">A span</span> </p>"},
{"span[class~=\"c\"]", 1, "<span class=\"a bb c\">Multi-class span</span>"},
{"span[class~=\"b\"]", 0, ""},
{"span[class~=\"a bb\"]", 0, ""},
{"p[lang|=\"en\"]", 1, "<p title=\"t2\" lang=\"en-gb\">Another one</p>"},
{"p[lang|=\"fr\"]", 0, ""},
{"p[id^=\"foo\"]", 1, "<p id=\"foobar\">This is a paragraph</p>"},
{"p[id$=\"bar\"]", 1, "<p id=\"foobar\">This is a paragraph</p>"},
{"p[id*=\"oob\"]", 1, "<p id=\"foobar\">This is a paragraph</p>"},
{".class1", 1, "<span class=\"class1\" lang=\"en-fr\">A span</span>"},
{".cl", 0, ""},
{".cl.ass1", 0, ""},
{".a", 1, "<span class=\"a bb c\">Multi-class span</span>"},
{".a.a", 1, "<span class=\"a bb c\">Multi-class span</span>"},
{".a:not(.bb)", 0, ""},
{":not(.a).bb", 0, ""},
{"span.bb:not(.a):not(.a)", 0, ""},
{"#foo", 0, ""},
{"#foo#id1", 0, ""},
{"#id1#id1", 1, "<nonsense id=\"id1\">This is not real</nonsense>"},
};


// Program entry point
int main(int argc, char **argv)
{
// Parse HTML tree
string source(rawsource);
htmlcxx::HTML::ParserDom parser;
tree<htmlcxx::HTML::Node> dom = parser.parseTree(source);

for (size_t i = 0; i < sizeof(vectors) / sizeof(tvec); i++) {
hcxselect::Selector s(dom);
try {
s = s.select(vectors[i].s);
} catch (hcxselect::ParseException &ex) {
cerr << "Parse error: '" << vectors[i].s << "': " << ex.what() << endl;
cerr << " ";
for (int i = 1; i < ex.position(); i++) {
cerr << " ";
}
cerr << "^" << endl;
return 1;
} catch (...) {
cerr << "Error parsing '" << vectors[i].s << "'" << endl;
return 1;
}

stringstream ss;
for (size_t j = 0; j < s.size(); j++) {
ss << source.substr(s[j]->data.offset(), s[j]->data.length());
}

if (s.size() != vectors[i].n) {
cerr << endl;
cerr << i << " (" << vectors[i].s << ") failed: " <<
"Expected " << vectors[i].n << " results, got " <<
s.size() << ":" << endl << ss.str() << endl;
return 1;
}

if (ss.str() != vectors[i].t) {
cerr << endl;
cerr << i << " (" << vectors[i].s << ") failed: " <<
"Expected " << vectors[i].t << ", got " << ss.str() << endl;
return 1;
}

cout << i << (i > 0 && i % 20 == 0 ? "\n" : " ");
}
cout << endl;

return 0;
}

0 comments on commit cf7d667

Please sign in to comment.