-
-
-
-
diff --git a/lib/Hitomi.pm b/lib/Hitomi.pm
deleted file mode 100644
index 4ff145d..0000000
--- a/lib/Hitomi.pm
+++ /dev/null
@@ -1,7 +0,0 @@
-use v6;
-
-use Hitomi::XMLParser;
-use Hitomi::Markup;
-
-class Hitomi::DocType::HTML5 {
-}
diff --git a/lib/Hitomi/Attrs.pm b/lib/Hitomi/Attrs.pm
deleted file mode 100644
index 65ccb69..0000000
--- a/lib/Hitomi/Attrs.pm
+++ /dev/null
@@ -1,4 +0,0 @@
-use v6;
-
-class Hitomi::Attrs {
-}
diff --git a/lib/Hitomi/HTMLParser.pm b/lib/Hitomi/HTMLParser.pm
deleted file mode 100644
index f9a7349..0000000
--- a/lib/Hitomi/HTMLParser.pm
+++ /dev/null
@@ -1,9 +0,0 @@
-use v6;
-
-class Hitomi::HTMLParser {
- # RAKUDO: https://trac.parrot.org/parrot/ticket/536 makes the method
- # override the global 'list' sub if we call it 'list'
- method llist() {
- return ();
- }
-}
diff --git a/lib/Hitomi/Input.pm b/lib/Hitomi/Input.pm
deleted file mode 100644
index 2a0c6e3..0000000
--- a/lib/Hitomi/Input.pm
+++ /dev/null
@@ -1,11 +0,0 @@
-use v6;
-
-use Hitomi::Stream;
-use Hitomi::XMLParser;
-
-class ParseError {
-}
-
-sub XML($text) {
- return Hitomi::Stream.new(@(Hitomi::XMLParser.new($text)));
-}
diff --git a/lib/Hitomi/Interpolation.pm b/lib/Hitomi/Interpolation.pm
deleted file mode 100644
index 99f7cb2..0000000
--- a/lib/Hitomi/Interpolation.pm
+++ /dev/null
@@ -1,41 +0,0 @@
-use Hitomi::StreamEventKind;
-
-grammar Hitomi::Interpolation::Grammar {
- regex TOP { ^ * $ }
- regex chunk { || }
-
- regex plain { [ .]+ }
- regex expr { '$' [ | ] }
-
- regex ident { <.alpha> \w* }
- regex identifier { <.ident> [ <.apostrophe> <.ident> ]* }
- token apostrophe { <[ ' \- ]> }
-
- regex block { '{' '}' }
- regex content { <-[{}]>+ }
-}
-
-# Note: It _is_ possible for the above grammar to fail, even though it's
-# probably not very desirable that it can. An example of a failing
-# input is '$'. The way to fix this would likely be (1) see what
-# Genshi does about broken input, (2) write Hitomi tests to do the
-# same, (3) improve the grammar.
-
-sub interpolate($text, $filepath, $lineno = -1, $offset = 0,
- $lookup = 'strict') {
-
- # TODO: Make it impossible to fail here. See the above note.
- return $text
- unless Hitomi::Interpolation::Grammar.parse($text);
-
- return gather for @($ // []) -> $chunk {
- my $pos = [$filepath, $lineno, $offset];
- if $chunk -> $plain {
- take [Hitomi::StreamEventKind::text, ~$plain, $pos];
- }
- elsif $chunk -> $expr {
- my $data = $expr ?? $expr !! $expr;
- take [Hitomi::StreamEventKind::expr, ~$data, $pos];
- }
- }
-}
diff --git a/lib/Hitomi/Markup.pm b/lib/Hitomi/Markup.pm
deleted file mode 100644
index 4031237..0000000
--- a/lib/Hitomi/Markup.pm
+++ /dev/null
@@ -1,122 +0,0 @@
-use Hitomi::Stream;
-use Hitomi::XMLParser;
-use Hitomi::Interpolation;
-
-class Hitomi::Context {
- # I see from the Genshi source that %!vars will eventually be replaced by
- # @!frames. This suffices for now.
- has %!vars;
-
- method new(*%nameds, *@pairs) {
- my %vars = %nameds;
- for @pairs {
- %vars{.key} = .value;
- }
- return self.bless(*, :%vars);
- }
-
- method get($thing is copy) {
- if $thing ~~ /^ '$'/ {
- $thing .= substr(1);
- }
- %!vars{$thing};
- }
-}
-
-class Hitomi::Template {
- has $!source;
- has $!filepath;
- has $!filename;
- has $!loader;
- has $!encoding;
- has $!lookup;
- has $!allow_exec;
- has $!stream;
-
- submethod BUILD(:$source, :$filepath, :$filename, :$loader,
- :$encoding, :$lookup, :$allow_exec) {
-
- $!source = $source;
- $!filepath = $filepath;
- $!filename = $filename;
- $!loader = $loader;
- $!encoding = $encoding;
- $!loader = $loader;
- $!allow_exec = $allow_exec;
-
- $!filepath //= $!filename;
-
- $!stream = self._parse($!source, $!encoding);
- }
-
- method new($source, $filepath?, $filename?, $loader?,
- $encoding?, $lookup = 'strict', $allow_exec = True) {
- self.bless(*,
- :$source, :$filepath, :$filename, :$loader,
- :$encoding, :$lookup, :$allow_exec);
- }
-
- method _parse($source, $encoding) {
- ...
- }
-
- method generate(*%nameds, *@pairs) {
- my $context = Hitomi::Context.new(|%nameds, |@pairs);
- return self._flatten($!stream, $context);
- }
-
- method _flatten($stream, $context) {
- my @newstream = gather for $stream.llist -> $event {
- my ($kind, $data, $pos) = @($event);
- if ($kind ~~ Hitomi::StreamEventKind::expr) {
- take [Hitomi::StreamEventKind::text,
- self._eval($data, $context),
- $pos];
- }
- else {
- take [$kind, $data, $pos];
- }
- };
- return Hitomi::Stream.new(@newstream);
- }
-
- method _eval($data, $context) {
- # Well, this works for expressions which consist of one variable
- # and nothing more. Will expand later.
- $context.get($data);
- }
-}
-
-class Hitomi::MarkupTemplate is Hitomi::Template {
- submethod BUILD(:$!source, :$!filepath, :$!filename, :$!loader,
- :$!encoding, :$!lookup, :$!allow_exec) {
- }
-
- method _parse($source is copy, $encoding) {
- if $source !~~ Hitomi::Stream {
- $source = Hitomi::XMLParser.new($source, $!filename, $encoding);
- }
-
- my @stream;
-
- for $source.llist -> @event {
- my ($kind, $data, $pos) = @event;
-
- if $kind ~~ Hitomi::StreamEventKind::text {
- @stream.push:
- interpolate($data, $!filepath, $pos[1], $pos[2], $!lookup);
- }
- else {
- @stream.push( [$kind, $data, $pos] );
- }
- }
-
- return Hitomi::Stream.new(@stream);
- }
-}
-
-class Hitomi::Markup {
- method new($text) {
- return self.bless(*, :$text);
- }
-}
diff --git a/lib/Hitomi/Output.pm b/lib/Hitomi/Output.pm
deleted file mode 100644
index c794931..0000000
--- a/lib/Hitomi/Output.pm
+++ /dev/null
@@ -1,50 +0,0 @@
-use Hitomi::StreamEventKind;
-
-sub escape($text, :$quotes = True) {
- $text; # TODO
-}
-
-class Hitomi::XMLSerializer {
- has @!filters;
-
- method serialize($stream) {
- return join '', [~] gather for $stream.llist {
- my ($kind, $data, $pos) = @($_);
- if ($kind ~~ Hitomi::StreamEventKind::start
- | Hitomi::StreamEventKind::empty) {
- my ($tag, $attribs) = @($data);
- take '<';
- take $tag;
- for @($attribs) -> $attrib {
- my ($attr, $value) = @($attrib);
- take for ' ', $attr, q[="], escape($value), q["];
- }
- take $kind ~~ Hitomi::StreamEventKind::empty ?? '/>' !! '>';
- }
- elsif ($kind ~~ Hitomi::StreamEventKind::end) {
- take sprintf '%s>', $data;
- }
- else { # TODO More types
- take escape($data, :!quotes);
- }
- }
- }
-}
-
-class Hitomi::XHTMLSerializer is Hitomi::XMLSerializer {
-}
-
-class Hitomi::HTMLSerializer {
-}
-
-class Hitomi::TextSerializer {
-}
-
-sub get_serializer($method, *%_) {
- my $class = ( :xml( Hitomi::XMLSerializer),
- :xhtml( Hitomi::XHTMLSerializer),
- :html( Hitomi::HTMLSerializer),
- :text( Hitomi::TextSerializer) ){$method.lc};
- return $class.new(|%_);
-}
-
diff --git a/lib/Hitomi/Stream.pm b/lib/Hitomi/Stream.pm
deleted file mode 100644
index af15e55..0000000
--- a/lib/Hitomi/Stream.pm
+++ /dev/null
@@ -1,43 +0,0 @@
-use v6;
-use Hitomi::StreamEventKind;
-use Hitomi::Output;
-
-class Hitomi::Stream {
- has @!events;
- has $serializer;
-
- multi method new(@events, $serializer?) {
- return self.new(
- :events(@events),
- :serializer($serializer // Hitomi::XHTMLSerializer.new())
- );
- }
-
- # RAKUDO: We shouldn't have to provide this method. It should be handed
- # to us by C
';
- my @events = (HTMLParser.new($text)).llist;
- my ($kind, $data, $pos) = @events[0];
- is Hitomi::StreamEventKind::start, $kind, 'got a start event';
- $data //= [*, {}];
- is "\x[a0]", $data[1], 'the entity was turned into a character';
- $kind, $data, $pos = @events[1];
- is Hitomi::StreamEventKind::end, $kind, 'got an end event';
-}
-
-{ # test_html_entity_in_text
- my $text = '
';
- my @events = (HTMLParser.new($text)).llist;
- my ($kind, $data, $pos) = @events[1];
- is Hitomi::StreamEventKind::text, $kind, 'got a text event';
- is "\x[a0]", $data, 'the entity was turned into a character';
-}
-
-{ # test_processing_instruction
- my $text = '';
- my @events = (HTMLParser.new($text)).llist;
- my ($kind, $td, $pos) = @events[0];
- my ($target, $data) = $td;
- is Hitomi::StreamEventKind::pi, $kind, 'got a pi event';
- is 'php', $target, 'the target is "php"';
- is 'echo "Foobar"', $data, q[the data is 'echo "Foobar"'];
-}
-
-{ # test_xmldecl
- my $text = '';
- my @events = (HTMLParser.new($text)).llist;
- my ($kind, $data, $pos) = @events[0];
- my ($version, $encoding, $standalone) = $data;
- is Hitomi::StreamEventKind::xml-decl, $kind, 'got an xml-decl event';
- is '1.0', $version, 'the version is 1.0';
- ok !defined $encoding, 'no encoding';
- is -1, $standalone, 'not standalone';
-}
-
-{ # test_xmldecl_encoding
- my $text = '';
- my @events = (HTMLParser.new($text)).llist;
- my ($kind, $data, $pos) = @events[0];
- my ($version, $encoding, $standalone) = $data;
- is Hitomi::StreamEventKind::xml-decl, $kind, 'got an xml-decl event';
- is '1.0', $version, 'the version is 1.0';
- is 'utf-8', $encoding, 'the encoding is "utf-8"';
- is -1, $standalone, 'not standalone';
-}
-
-{ # test_xmldecl_standalone
- my $text = '';
- my @events = (HTMLParser.new($text)).llist;
- my ($kind, $data, $pos) = @events[0];
- my ($version, $encoding, $standalone) = $data;
- is Hitomi::StreamEventKind::xml-decl, $kind, 'got an xml-decl event';
- is '1.0', $version, 'the version is 1.0';
- ok !defined $encoding, 'no encoding';
- is 1, $standalone, 'standalone';
-}
-
-{ # test_processing_instruction_trailing_qmark
- my $text = '';
- my @events = (HTMLParser.new($text)).llist;
- my ($kind, $dt, $pos) = @events[0];
- my ($target, $data) = $dt;
- is Hitomi::StreamEventKind::pi, $kind, 'got a pi event';
- is 'php', $target, 'the target is "php"';
- is 'echo "Foobar" ?', $data, 'the data has one final "?"';
-}
-
-{ # test_out_of_order_tags
- my $text = 'Foobar';
- my @events = (HTMLParser.new($text)).llist;
- is 5, +@events, 'got 5 events';
- @events ||= [] xx 5;
- is [Hitomi::StreamEventKind::start, ['span', []]], @events[0][0,1], 'o1[1]';
- is [Hitomi::StreamEventKind::start, ['b', []]], @events[1][0,1], 'o1[2]';
- is [Hitomi::StreamEventKind::text, ['Foobar' ]], @events[2][0,1], 'o1[3]';
- is [Hitomi::StreamEventKind::end, ['b', ]], @events[3][0,1], 'o1[4]';
- is [Hitomi::StreamEventKind::end, ['span', ]], @events[4][0,1], 'o1[5]';
-}
-
-{ # test_out_of_order_tags2
- my $text = 'Foobar';
- my @events = (HTMLParser.new($text)).llist;
- is 7, +@events, 'got 7 events';
- @events ||= [] xx 7;
- is [Hitomi::StreamEventKind::start, ['span', Attrs.new(:class)]],
- @events[0][0,1], 'o2[1]';
- is [Hitomi::StreamEventKind::start, ['b', []]], @events[1][0,1], 'o2[2]';
- is [Hitomi::StreamEventKind::start, ['i', []]], @events[2][0,1], 'o2[3]';
- is [Hitomi::StreamEventKind::text, ['Foobar' ]], @events[3][0,1], 'o2[4]';
- is [Hitomi::StreamEventKind::end, ['i', ]], @events[4][0,1], 'o2[5]';
- is [Hitomi::StreamEventKind::end, ['b', ]], @events[5][0,1], 'o2[6]';
- is [Hitomi::StreamEventKind::end, ['span', ]], @events[6][0,1], 'o2[7]';
-}
-
-{ # test_out_of_order_tags3
- my $text = 'Foobar';
- my @events = (HTMLParser.new($text)).llist;
- is 5, +@events, 'got 5 events';
- @events ||= [] xx 5;
- is [Hitomi::StreamEventKind::start, ['span', []]], @events[0][0,1], 'o3[1]';
- is [Hitomi::StreamEventKind::start, ['b', []]], @events[1][0,1], 'o3[2]';
- is [Hitomi::StreamEventKind::text, ['Foobar' ]], @events[2][0,1], 'o3[3]';
- is [Hitomi::StreamEventKind::end, ['b', ]], @events[3][0,1], 'o3[4]';
- is [Hitomi::StreamEventKind::end, ['span', ]], @events[4][0,1], 'o3[5]';
-}
-
-{ # test_hex_charref
- my $text = ''';
- my @events = (HTMLParser.new($text)).llist;
- is 3, +@events, 'got 3 events';
- @events ||= [] xx 3;
- is [Hitomi::StreamEventKind::start, ['span', []]], @events[0][0,1], 'hc[1]';
- is [Hitomi::StreamEventKind::text, ["'" ]], @events[1][0,1], 'hc[2]';
- is [Hitomi::StreamEventKind::end, ['span' ]], @events[2][0,1], 'hc[3]';
-}
diff --git a/t/hitomi/06-markup.t b/t/hitomi/06-markup.t
deleted file mode 100644
index 027e887..0000000
--- a/t/hitomi/06-markup.t
+++ /dev/null
@@ -1,252 +0,0 @@
-use v6;
-
-# Copyright (C) 2006 Edgewall Software
-# All rights reserved.
-#
-# This software is licensed as described in the file licences/genshi/COPYING,
-# which you should have received as part of this distribution. The terms
-# are also available at http://genshi.edgewall.org/wiki/License.
-
-use Test;
-plan 22;
-
-use Hitomi::Stream;
-use Hitomi::Markup;
-use Hitomi::Input;
-
-constant Stream = Hitomi::Stream;
-constant MarkupTemplate
- = Hitomi::MarkupTemplate;
-constant Markup = Hitomi::Markup;
-
-## MarkupTemplateTestCase - Tests for markup template processing.
-
-{ # test_parse_string
- my $string = ' ${$var} $var';
- my $tmpl = MarkupTemplate.new($string);
- is ' 42 42',
- ~$tmpl.generate(:var(42)),
- 'markup from a string';
-}
-
-skip(1);
-# skip: unknown error in MarkupTemplate.new($stream)
-##{ # test_parse_stream
-## my Stream $stream = XML(' ${$var} $var');
-## my $tmpl = MarkupTemplate.new($stream);
-## is ' 42 42', ~$tmpl.generate(:var(42)), 'markup from a stream';
-##}
-
-skip(1);
-# skip: unknown error in MarkupTemplate.new($stream)
-##{ # test_pickle
-## # Not sure how we will want to do this.
-## my Stream $stream = XML('$var');
-## my $tmpl = MarkupTemplate.new($stream);
-## my $buf = $tmpl.perl;
-## my $unpickled = eval($buf);
-## is '42', ~$unpickled.?generate(:var(42)),
-## 'template survives pickling';
-##}
-
-{ # test_interpolate_mixed3
- my $tmpl = MarkupTemplate.new(' ${$var} $var');
- is ' 42 42', ~$tmpl.generate(:var(42)), 'mixed interpolation';
-}
-
-todo('not implemented yet', 2);
-{ # test_interpolate_leading_trailing_space
- my $tmpl = MarkupTemplate.new('${ $foo }');
- is 'bar', ~$tmpl.generate(:foo), 'leading/trailing space';
-}
-
-{ # test_interpolate_multiline
- my $tmpl = MarkupTemplate.new(q[${(
- bar => 'baz'
- ).hash{$foo}}]);
- is 'baz', ~$tmpl.generate(:foo), 'interpolate multiline';
-}
-
-skip(1);
-##{ # test_interpolate_non_string_attrs
-## my $tmpl = MarkupTemplate.new('');
-## is '', ~$tmpl.generate(), 'interpolate non-string attrs';
-##}
-
-todo('not implemented', 1);
-{ # test_interpolate_list_result
- my $tmpl = MarkupTemplate.new('@foo');
- is 'buzz', ~$tmpl.generate('@foo' => ['buzz']),
- 'interpolate lists';
-}
-
-skip(1);
-##{ # test_empty_attr
-## my $tmpl = MarkupTemplate.new('');
-## is '', ~$tmpl.generate(), 'empty attribute';
-##}
-
-skip(1);
-##{ # test_empty_attr_interpolated
-## my $tmpl = MarkupTemplate.new('');
-## is '', ~$tmpl.generate(:attr<>), 'empty attr, interpolated';
-##}
-
-todo('not implemented', 3);
-{ # test_bad_directive_error
- my $xml
- = '';
- my $died = True;
- try {
- my $tmpl = MarkupTemplate.new($xml, :filename);
- $died = False;
- }
- # RAKUDO: When we have CATCH, we will want to check the error type here
- ok $died, 'error on bad directive';
- # self.assertEqual('test.html', e.filename)
- # self.assertEqual(1, e.lineno)
-}
-
-{ # test_directive_value_syntax_error
- my $xml = q[];
- my $died = True;
- try {
- my $tmpl = MarkupTemplate.new($xml, :filename).generate();
- $died = False;
- }
- # RAKUDO: When we have CATCH, we will want to check the error type here
- ok $died, 'error on bad directive';
- # self.assertEqual('test.html', e.filename)
- # self.assertEqual(1, e.lineno)
-}
-
-{ # test_expression_syntax_error
- my $xml = q[
- Foo ${bar"}
-
];
- my $died = True;
- try {
- my $tmpl = MarkupTemplate.new($xml, :filename);
- $died = False;
- }
- # RAKUDO: When we have CATCH, we will want to check the error type here
- ok $died, 'template syntax error';
- # self.assertEqual('test.html', e.filename)
- # self.assertEqual(2, e.lineno)
-}
-
-{ # test_expression_syntax_error_multi_line
- my $xml = q[
-
- ${bar"}
-
-
];
- my $died = True;
- try {
- my $tmpl = MarkupTemplate.new($xml, :filename);
- $died = False;
- }
- # RAKUDO: When we have CATCH, we will want to check the error type here
- ok $died, 'template syntax error';
- # self.assertEqual('test.html', e.filename)
- # self.assertEqual(3, e.lineno)
-}
-
-skip(1);
-##{ # test_markup_noescape
-## # Verify that outputting context data that is a `Markup` instance is not
-## # escaped.
-## my $tmpl = MarkupTemplate.new(
-## '
-## $myvar
-##
');
-## is '
-## foo
-##
', ~$tmpl.generate(:myvar(Markup.new('foo'))),
-## 'no escaping of Markup variables';
-##}
-
-skip(1);
-##{ # test_text_noescape_quotes
-## # Verify that outputting context data in text nodes doesn't escape
-## # quotes.
-## my $tmpl = MarkupTemplate.new(
-## '
-## $myvar
-##
');
-## is '
-## "foo"
-##
', ~$tmpl.generate(:myvar<"foo">),
-## 'no escaping of quotes in text';
-##}
-
-skip(1);
-##{ # test_attr_escape_quotes
-## # Verify that outputting context data in attribtes escapes quotes.
-## my $tmpl = MarkupTemplate.new(
-## '
-##
-##
');
-## is '
-##
-##
', ~$tmpl.generate(:myvar<"foo">),
-## 'escaping of quotes in attrs';
-##}
-
-skip(1);
-##{ # test_directive_element
-## my $tmpl = MarkupTemplate.new(
-## '
].encode('UTF-8').decode('iso-8859-1'), :encoding);
-## is qq[\n
-## \xf6
-##
], ~$tmpl.generate(), 'latin1 encoded with xmldecl';
-##}
diff --git a/t/squerl/01-sqlite-write.t b/t/squerl/01-sqlite-write.t
deleted file mode 100644
index 8b2a064..0000000
--- a/t/squerl/01-sqlite-write.t
+++ /dev/null
@@ -1,28 +0,0 @@
-use v6;
-use Test;
-
-use Squerl;
-
-unlink (my $file = 't/squerl/posts.db');
-my $DB = Squerl.sqlite($file);
-
-$DB.create_table: 'posts',
- 'id' => 'primary_key',
- 'user_id' => 'Int',
- 'name' => 'String',
-;
-
-#my $posts = $DB;
-my $posts = $DB.from('posts');
-
-$posts.insert(0, 1, 'Hello Austria!');
-
-ok $file ~~ :e, 'could create the database file';
-
-my $number-of-posts = +$posts.all;
-
-is $number-of-posts, 1, 'could insert and then retrieve a row';
-
-done_testing;
-
-unlink $file;
diff --git a/t/squerl/02-dataset.t b/t/squerl/02-dataset.t
deleted file mode 100644
index eae6091..0000000
--- a/t/squerl/02-dataset.t
+++ /dev/null
@@ -1,327 +0,0 @@
-use v6;
-use Test;
-
-use Squerl;
-
-my $dataset = Squerl::Dataset.new('db');
-
-# RAKUDO: There are plenty of unnecessary semicolons at the end of blocks
-# in this file, due to [perl #69438]
-
-{
- my $db = 'db';
- my %opts = :from;
- my $d = Squerl::Dataset.new($db, |%opts);
- is $d.db, $db, 'attribtue .db was properly set';
- is_deeply $d.opts, %opts, 'attribute .opts was properly set';
-
- $d = Squerl::Dataset.new($db);
- is $d.db, $db, 'attribtue .db was properly set';
- ok $d.opts ~~ Hash, 'attribute .opts is a hash even when not set';
- is_deeply $d.opts, {}, 'attribute .opts is empty';
-};
-
-{
- my $d1 = $dataset.clone( :from( ['test'] ) );
- is $d1.WHAT, $dataset.WHAT, 'clone has the same class as original';
- ok $d1 !=== $dataset, 'clone is distinct from original';
- ok $d1.db === $dataset.db, 'clone has the same .db attribute';
- is_deeply $d1.opts, ['test'],
- 'the attribute passed with the .clone method is there';
- ok !$dataset.opts.exists('from'), 'the original is unchanged';
-
- my $d2 = $d1.clone( :order( ['name'] ) );
- is $d2.WHAT, $dataset.WHAT, 'clone of clone has the class of original';
- ok $d2 !=== $d1, 'clone of clone is distinct from clone';
- ok $d2 !=== $dataset, 'clone of clone is distinct from original';
- ok $d2.db === $dataset.db, 'clone of clone has the same .db attribute';
- is_deeply $d2.opts, ['test'],
- 'the attribute from the first clone is preserved in the second';
- is_deeply $d2.opts, ['name'],
- 'the attribute passed with the .clone method is there';
- ok !$d1.opts.exists('order'), 'the original clone is unchanged';
-};
-
-{
- ok Squerl::Dataset ~~ Positional, 'you can index into Squerl::Dataset';
-};
-
-{
- my $db = Squerl::Database.new( :quote_identifiers );
- ok $db.from('a').quote_identifiers,
- 'should get quote_identifiers default from database I';
- $db = Squerl::Database.new( :!quote_identifiers );
- nok $db.from('a').quote_identifiers,
- 'should get quote_identifiers default from database II';
-};
-
-{
- my $db = Squerl::Database.new( :identifier_input_method );
- ok $db.from('a').identifier_input_method eq 'upcase',
- 'should get identifier_input_method default from database I';
- $db = Squerl::Database.new( :identifier_input_method );
- ok $db.from('a').identifier_input_method eq 'downcase',
- 'should get identifier_input_method default from database II';
-};
-
-{
- my $db = Squerl::Database.new( :identifier_output_method );
- ok $db.from('a').identifier_output_method eq 'upcase',
- 'should get identifier_output_method default from database I';
- $db = Squerl::Database.new( :identifier_output_method );
- ok $db.from('a').identifier_output_method eq 'downcase',
- 'should get identifier_output_method default from database II';
-};
-
-$dataset = Squerl::Dataset.new('db');
-
-{
- $dataset.quote_identifiers = True;
- is $dataset.literal(ident('a')), '"a"',
- 'setting quote_identifiers to True makes .literal quote identifiers';
- $dataset.quote_identifiers = False;
- is $dataset.literal(ident('a')), 'a',
- 'setting quote_identifiers to False makes .literal '
- ~ 'not quote identifiers';
-};
-
-{
- $dataset.identifier_input_method = 'upcase';
- is $dataset.literal(ident('a')), 'A',
- 'identifier_input_method changes literalization of identifiers I';
- $dataset.identifier_input_method = 'downcase';
- is $dataset.literal(ident('A')), 'a',
- 'identifier_input_method changes literalization of identifiers II';
- $dataset.identifier_input_method = 'reverse';
- is $dataset.literal(ident('at_b')), 'b_ta',
- 'identifier_input_method changes literalization of identifiers III';
-
- $dataset.identifier_input_method = 'uc';
- is $dataset.literal(ident('a')), 'A',
- 'identifier_input_method changes literalization of identifiers IV';
- $dataset.identifier_input_method = 'lc';
- is $dataset.literal(ident('A')), 'a',
- 'identifier_input_method changes literalization of identifiers V';
- $dataset.identifier_input_method = 'flip';
- is $dataset.literal(ident('at_b')), 'b_ta',
- 'identifier_input_method changes literalization of identifiers VI';
-};
-
-{
- is $dataset.output_identifier('at_b_C'), 'at_b_C',
- 'identifier_output_method changes identifiers returned from the db I';
-
- $dataset.identifier_output_method = 'upcase';
- is $dataset.output_identifier('at_b_C'), 'AT_B_C',
- 'identifier_output_method changes identifiers returned from the db II';
- $dataset.identifier_output_method = 'downcase';
- is $dataset.output_identifier('at_b_C'), 'at_b_c',
- 'identifier_output_method changes identifiers returned from the db III';
- $dataset.identifier_output_method = 'reverse';
- is $dataset.output_identifier('at_b_C'), 'C_b_ta',
- 'identifier_output_method changes identifiers returned from the db IV';
-
- $dataset.identifier_output_method = 'uc';
- is $dataset.output_identifier('at_b_C'), 'AT_B_C',
- 'identifier_output_method changes identifiers returned from the db V';
- $dataset.identifier_output_method = 'lc';
- is $dataset.output_identifier('at_b_C'), 'at_b_c',
- 'identifier_output_method changes identifiers returned from the db VI';
- $dataset.identifier_output_method = 'flip';
- is $dataset.output_identifier('at_b_C'), 'C_b_ta',
- 'identifier_output_method changes identifiers returned from the db VII';
-};
-
-$dataset = Squerl::Dataset.new(undef).from('items');
-
-{
- $dataset.row_proc = { $^r };
- my $clone = $dataset.clone;
-
- ok $clone !=== $dataset, 'the clone is not the original';
- is $clone.WHAT, $dataset.WHAT, 'clone has the same type as original';
- is_deeply $clone.opts, $dataset.opts, 'opts attributes are equivalent';
- ok $clone.row_proc === $dataset.row_proc, 'row_proc attributes equal';
-};
-
-{
- my $clone = $dataset.clone;
-
- ok $clone.opts !=== $dataset.opts, 'cloning deep-copies .opts';
- $dataset.=filter( 'a' => 'b' );
- ok !$clone.opts.exists('filter'),
- 'changing original.opts leaves clone.opts unchanged';
-};
-
-{
- my $clone = $dataset.clone;
-
- is $clone.WHAT, $dataset.WHAT, 'should return a clone self I';
- is $clone.db, $dataset.db, 'should return a clone self II';
- is_deeply $clone.opts, $dataset.opts, 'should return a clone self III';
-};
-
-$dataset = Squerl::Dataset.new(undef).from('items');
-
-{
- my $clone = $dataset.clone( one => 2 );
-
- is_deeply $clone.opts, { one => 2, from => 'items' },
- 'should merge the specified options';
-};
-
-{
- my $clone = $dataset.clone( :from(['other']) );
-
- is_deeply $clone.opts, { :from(['other']) },
- 'should overwrite existing options';
-};
-
-{
- my $clone = $dataset.clone( :from(['other']) );
-
- is_deeply $dataset.opts, 'items', 'original .opts unharmed';
- is_deeply $clone.opts, ['other'], 'cloned .opts changed'
-};
-
-{
- # TODO: Can't realisticly do this one yet.
-
- # m = Module.new do
- # def __xyz__; "xyz"; end
- # end
- # @dataset.extend(m)
- # @dataset.clone({}).should respond_to(:__xyz__)
-};
-
-$dataset = Squerl::Dataset.new(undef).from('test');
-
-is $dataset.select_sql, 'SELECT * FROM test', 'format a select statement';
-is $dataset.delete_sql, 'DELETE FROM test', 'format a delete statement';
-is $dataset.truncate_sql, 'TRUNCATE TABLE test', 'format a truncate statement';
-is $dataset.insert_sql, 'INSERT INTO test DEFAULT VALUES',
- 'format an insert statement with default values';
-
-{
- my $sql = $dataset.insert_sql(:name, :price(342));
- ok $sql eq q[INSERT INTO test (name, price) VALUES ('wxyz', 342)]
- | q[INSERT INTO test (price, name) VALUES (342, 'wxyz')],
- 'format an insert statement with hash';
- is $dataset.insert_sql({}), 'INSERT INTO test DEFAULT VALUES',
- 'empty hash gives an insert statement with default values';
-};
-
-{
- my $sql = $dataset.insert_sql( 'name' => 'wxyz', 'price' => 342 );
- ok $sql eq q[INSERT INTO test (name, price) VALUES ('wxyz', 342)]
- | q[INSERT INTO test (price, name) VALUES (342, 'wxyz')],
- 'format an insert statement with string keys';
-};
-
-role R1 { method values { 'a' => 1; } }
-role R2 { method values { {} } };
-
-{
- my $v = Object.new but R1;
- is $dataset.insert_sql($v), 'INSERT INTO test (a) VALUES (1)',
- 'format an insert statement with an object that .can("values") I';
-
- $v = Object.new but R2;
- is $dataset.insert_sql($v), 'INSERT INTO test DEFAULT VALUES',
- 'format an insert statement with an object that .can("values") II';
-};
-
-{
- is $dataset.insert_sql(123), 'INSERT INTO test VALUES (123)',
- 'format an insert statement with an arbitrary value';
-};
-
-{
- my $sub = Squerl::Dataset.new('').from('something').filter('x' => 2);
- is $dataset.insert_sql($sub),
- 'INSERT INTO test SELECT * FROM something WHERE (x = 2)',
- 'format an insert statement with sub-query';
-};
-
-{
- is $dataset.insert_sql('a', 2, 6.5),
- q[INSERT INTO test VALUES ('a', 2, 6.5)],
- 'format an insert statement with array';
-};
-
-{
- is $dataset.update_sql('name' => 'abc'),
- q[UPDATE test SET name = 'abc'],
- 'format an update statement';
-};
-
-{
- is $dataset.clone(:sql('xxx yyy zzz')).select_sql(), 'xxx yyy zzz',
- 'return rows for arbitrary SQL';
-};
-
-{
- my $sql = 'X';
- my $ds = Squerl::Dataset.new(undef, :$sql);
- is $ds.select_sql(), $sql, ':sql option works for .select_sql';
- is $ds.insert_sql(), $sql, ':sql option works for .insert_sql';
- is $ds.delete_sql(), $sql, ':sql option works for .delete_sql';
- is $ds.update_sql(), $sql, ':sql option works for .update_sql';
- is $ds.truncate_sql(), $sql, ':sql option works for .truncate_sql';
-};
-
-sub throws_exception(&block, $expected-type, $message = '') {
- try {
- &block();
- }
- if $! {
- my $got-type = ~$!;
- ok $got-type.substr(0, $expected-type.chars) eq $expected-type,
- $message;
- }
- else {
- is 'ran without failure', $expected-type, $message;
- }
-}
-
-$dataset = Squerl::Dataset.new(undef).from('t1', 't2');
-
-todo('not implemented yet', 4);
-{
- throws_exception { $dataset.update_sql( a => 1 ) },
- 'Squerl::InvalidOperation',
- 'multi-table dataset dies on .update_sql';
-
- throws_exception { $dataset.delete_sql() },
- 'Squerl::InvalidOperation',
- 'multi-table dataset dies on .delete_sql';
-
- throws_exception { $dataset.truncate_sql() },
- 'Squerl::InvalidOperation',
- 'multi-table dataset dies on .truncate_sql';
-
- throws_exception { $dataset.insert_sql() },
- 'Squerl::InvalidOperation',
- 'multi-table dataset dies on .insert_sql';
-};
-
-{
- is $dataset.select_sql, 'SELECT * FROM t1, t2',
- 'generate a select query FROM all specified tables';
-}
-
-my $ds1 = Squerl::Dataset.new(undef).from('test');
-# RAKUDO: A bug prevents us from writing this:
-# my $ds2 = $ds1.filter(sql_number('price') < 100);
-# my $ds3 = $ds1.filter(sql_number('price') > 50);
-my $ds2 = $ds1.filter(sql_number('price').lt(100));
-my $ds3 = $ds1.filter(sql_number('price').gt(50));
-
-{
- is $ds1.filter($ds2.exists).sql,
- 'SELECT * FROM test WHERE (EXISTS '
- ~ '(SELECT * FROM test WHERE (price < 100)))',
- 'Dataset#exists works in filters';
-}
-
-done_testing;