Created
December 1, 2009 04:32
-
-
Save tj/246057 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <time.h> | |
#include "yamp.h" | |
#include "cspec.h" | |
#define fixture(N) \ | |
if (!(fd = fopen("spec/fixtures/" N, "r"))) \ | |
fprintf(stderr, "failed to open fixture `%s'\n", N), exit(1); | |
#define parse \ | |
root = Yamp_parse(fd); | |
#define parse_fixture(N) \ | |
fixture(N ".html"); parse; | |
#define parse_xml_fixture(N) \ | |
fixture(N ".xml"); parse; | |
#define match_have_name(A, E) \ | |
(strcmp(((Element *) A)->name, E) == 0) | |
#define match_have_parent(A, E) \ | |
(A->parent == E) | |
#define match_have_n_children(A, E) \ | |
(A->nchildren == E) | |
#define match_have_n_attrs(A, E) \ | |
(children_of_type(A, tAttr) == E) | |
#define match_have_text(A, E) \ | |
(strcmp(((Text *) A)->val, E) == 0) | |
#define match_be_type(A, E) \ | |
(A->type == E) | |
#define match_include_text(A, E) \ | |
strstr(((Text *) A)->val, E) | |
#define at(I) \ | |
(node ? node->children[I] : root->children[I]) | |
#define bm_start \ | |
clock_t start = clock(); | |
#define bm_stop \ | |
printf("\n duration: %0.6f ms\n", (float) (clock() - start) / CLOCKS_PER_SEC); | |
static int | |
children_of_type(Node *self, NodeType type) { | |
int c = 0; | |
for (int i = 0; i < self->nchildren; ++i) | |
if (self->children[i]->type == type) | |
++c; | |
return c; | |
} | |
static FILE *fd; | |
static Node *root = NULL; | |
static Node *node = NULL; | |
describe "Yamp_parse()" | |
it "should return the root element" | |
parse_fixture("nested.ws"); | |
root should have_name "html"; | |
root should have_parent NULL; | |
end | |
it "should parse elements with child elements" | |
parse_fixture("nested"); | |
root should have_n_children 1; | |
at(0) should have_name "body"; | |
end | |
it "should parse elements with child elements disregarding whitespace" | |
parse_fixture("nested.ws"); | |
root should have_n_children 1; | |
at(0) should have_name "body"; | |
end | |
it "should parse reset parent elements" | |
parse_fixture("nested"); | |
node = at(0); | |
node should have_n_children 2; | |
at(0) should have_name "h1"; | |
at(1) should have_name "p"; | |
end | |
it "should parse reset parent elements disregarding whitespace" | |
parse_fixture("nested.ws"); | |
node = at(0); | |
node should have_n_children 2; | |
at(0) should have_name "h1"; | |
at(1) should have_name "p"; | |
end | |
it "should parse self-closing elements" | |
parse_fixture("self-closing"); | |
root should have_n_children 4; | |
at(0) should have_name "input"; | |
at(1) should have_name "link"; | |
at(2) should have_name "br"; | |
at(3) should have_name "a"; | |
end | |
it "should parse attributes" | |
parse_fixture("attrs"); | |
root should have_n_attrs 2; | |
node = root->children[0]; | |
at(0) should have_text "lang"; | |
at(1) should have_text "en"; | |
node = root->children[1]; | |
at(0) should have_text "class"; | |
at(1) should have_text "im some classes"; | |
end | |
it "should parse attributes with whitespace before / after keys and values" | |
parse_fixture("attrs.ws"); | |
root should have_n_attrs 2; | |
node = root->children[0]; | |
at(0) should have_text "lang"; | |
at(1) should have_text "en"; | |
node = root->children[1]; | |
at(0) should have_text "class"; | |
at(1) should have_text "im some classes"; | |
end | |
it "should parse single-quoted attributes" | |
parse_fixture("attrs.single"); | |
root should have_n_attrs 1; | |
node = at(0); | |
at(0) should have_text "lang"; | |
at(1) should have_text "en"; | |
end | |
it "should parse empty attributes but not push as a node" | |
parse_fixture("attrs.empty"); | |
root should have_n_children 0; | |
end | |
it "should parse empty attributes but not push as a node when whitespace is present" | |
parse_fixture("attrs.empty.ws"); | |
root should have_n_children 0; | |
end | |
it "should parse text" | |
parse_fixture("text"); | |
at(0) should have_text "foo bar"; | |
end | |
it "should ignore processing instructions" | |
parse_xml_fixture("po"); | |
end | |
it "should parse mixed element and text nodes" | |
parse_fixture("text.mixed"); | |
node = root->children[0]; | |
node should have_text "foo"; | |
node = root->children[1]; | |
node should have_name "h1"; | |
at(0) should have_text "bar"; | |
node = root->children[2]; | |
node should have_text "baz"; | |
node = root->children[3]; | |
node should have_name "h2"; | |
at(0) should have_text "that"; | |
node = root->children[4]; | |
node should have_text "is dope"; | |
end | |
it "should ignore comments" | |
parse_fixture("comments"); | |
at(0) should have_text "foo"; | |
end | |
it "should ignore comments when mixed with elements" | |
parse_fixture("comments.mixed"); | |
root should have_n_children 2; | |
node = root->children[0]; | |
node should have_name "p"; | |
at(0) should have_text "foo"; | |
node = root->children[1]; | |
node should have_name "p"; | |
at(0) should have_text "bar"; | |
end | |
it "should parse CDATA sections" | |
parse_fixture("cdata"); | |
node = root; | |
node should have_name "code"; | |
node = at(0); | |
node should be_type tCDATA; | |
node = at(0); | |
node should include_text "(function(){"; | |
node should include_text "})()"; | |
end | |
it "should parse script retaining its contents" | |
parse_fixture("script"); | |
node = root; | |
node should have_name "script"; | |
node = at(0); | |
node should include_text "(function(){"; | |
node should include_text "})()"; | |
end | |
it "should parse style retaining its contents" | |
parse_fixture("style"); | |
node = root; | |
node should have_name "style"; | |
node = at(0); | |
node should include_text "body {"; | |
node should include_text "background: url"; | |
node should include_text "}"; | |
end | |
it "should ignore doctypes" | |
parse_fixture("doctype"); | |
root should have_name "html"; | |
end | |
it "benchmark 200,000 elements" | |
bm_start; | |
parse_fixture("huge"); | |
bm_stop; | |
end | |
it "benchmark 1000 elements with many text nodes" | |
bm_start; | |
parse_fixture("huge.text"); | |
bm_stop; | |
end | |
it "benchmark 600 deep nested elements" | |
bm_start; | |
parse_fixture("huge.nested"); | |
bm_stop; | |
end | |
it "benchmark 1000 elements with lots of attributes" | |
bm_start; | |
parse_fixture("huge.attrs"); | |
bm_stop; | |
end | |
after_each | |
node = NULL; | |
if (fclose(fd) < 0) | |
perror("failed to close fixture file"); | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment