package TestCase::Lib::SPVM::StringBuffer {
use SPVM::StringBuffer;
sub check_fields : int ($buffer : SPVM::StringBuffer, $capacity : int, $length : int) {
# check_fields fields
unless ($buffer->capacity == $capacity && $buffer->length == $length) {
warn("String fields mismatch.\n\t" .
"got: (capacity: " . $buffer->capacity . ", length: " . $buffer->length . ")\n\t" .
"expected: (capacity: " . $capacity . ", length: " . $length . ")");
return 0;
}
return 1;
}
sub test_ctor_default : int () {
unless (check_fields(SPVM::StringBuffer->new, 16, 0)) {
return 0;
}
return 1;
}
sub test_new_opt : int () {
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => 20000);
unless (check_fields(SPVM::StringBuffer->new_opt($opt), 20000, 0)) {
return 0;
}
eval {
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => 0);
SPVM::StringBuffer->new_opt($opt);
};
unless ($@) {
return 0;
}
$@ = undef;
eval {
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => -1);
SPVM::StringBuffer->new_opt($opt);
};
unless ($@) {
return 0;
}
$@ = undef;
return 1;
}
sub test_length : int () {
unless (SPVM::StringBuffer->new->length == 0) {
return 0;
}
my $buffer2 = SPVM::StringBuffer->new;
$buffer2->push("a");
unless ($buffer2->length == 1) {
return 0;
}
return 1;
}
sub test_substr : int () {
my $buffer = SPVM::StringBuffer->new;
$buffer->push("abcd");
unless ($buffer->substr(1, 2) eq "bc") {
return 0;
}
eval {
my $buffer = SPVM::StringBuffer->new;
$buffer->push("a");
$buffer->substr(1, 1);
};
unless ($@) {
return 0;
}
eval {
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => 1);
my $buffer = SPVM::StringBuffer->new_opt($opt);
$buffer->push("a");
$buffer->substr(0, 2);
};
unless ($@) {
return 0;
}
$@ = undef;
return 1;
}
sub test_substr_copy_on_write : int () {
{
my $buffer = SPVM::StringBuffer->new;
$buffer->push("abc");
my $temp = (byte[])$buffer->to_string;
unless (refcnt $temp == 2) { # referenced by field and temp
return 0;
}
}
{
my $buffer = SPVM::StringBuffer->new;
$buffer->push("abc");
$buffer->substr(1, 1);
my $temp = (byte[])$buffer->to_string;
unless (refcnt $temp == 2) {
warn("substr is used. string is referenced by text's field and temp, but refcnt: " . refcnt $temp);
return 0;
}
}
{
my $buffer = SPVM::StringBuffer->new;
$buffer->push("abc");
my $buffer_sub = $buffer->substr(1, 1);
my $temp = (byte[])$buffer_sub;
unless (refcnt $temp == 3) {
warn("substr is used and text_sub is created. string is referenced by text's and text_sub fields and temp, but refcnt: " . refcnt $temp);
return 0;
}
}
return 1;
}
sub test_push : int () {
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => 1);
my $buffer = SPVM::StringBuffer->new_opt($opt);
$buffer->push ("abc");
unless ($buffer->to_string eq "abc" && $buffer->capacity == 3) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
$buffer->push ("de");
unless ($buffer->to_string eq "abcde" && $buffer->capacity == 6) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
$buffer->push ("f");
unless ($buffer->to_string eq "abcdef" && $buffer->capacity == 6) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
return 1;
}
sub test_push_char : int () {
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => 1);
my $buffer = SPVM::StringBuffer->new_opt($opt);
$buffer->push_char('a');
unless ($buffer->to_string eq "a" && $buffer->capacity == 1) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
$buffer->push_char('b');
unless ($buffer->to_string eq "ab" && $buffer->capacity == 2) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
$buffer->push_char('c');
unless ($buffer->to_string eq "abc" && $buffer->capacity == 4) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
return 1;
}
sub test_push_range : int () {
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => 1);
my $buffer = SPVM::StringBuffer->new_opt($opt);
my $string = "abcde";
$buffer->push_range($string, 0, 3);
unless ($buffer->to_string eq "abc" && $buffer->capacity == 3) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
$buffer->push_range($string, 1, 3);
unless ($buffer->to_string eq "abcbcd" && $buffer->capacity == 6) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
$buffer->push_range($string, 2, 3);
unless ($buffer->to_string eq "abcbcdcde" && $buffer->capacity == 12) {
warn("actual string: " . $buffer->to_string . ", capacity: " . $buffer->capacity);
return 0;
}
return 1;
}
sub test_append_copy_on_write : int () {
warn("TODO: append copy-on-write test is not implemented yet");
return 0;
}
sub test_to_string : int () {
{
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => 1);
my $minimal_buf = SPVM::StringBuffer->new_opt($opt);
$minimal_buf->push ("a");
unless ($minimal_buf->to_string eq "a") {
return 0;
}
}
{
my $opt = SPVM::Hash->new;
$opt->set_int(capacity => 1000000);
my $large_buf = SPVM::StringBuffer->new_opt($opt);
$large_buf->push ("b");
unless ($large_buf->to_string eq "b") {
return 0;
}
}
return 1;
}
sub test_index : int () {
my $buf = SPVM::StringBuffer->new;
$buf->push ("hogehogefuga");
unless ($buf->index("hoge", 0) == 0) {
return 0;
}
unless ($buf->index("hoge", 1) == 4) {
return 0;
}
unless ($buf->index("fuga", 0) == 8) {
return 0;
}
unless ($buf->index("foo", 0) == -1) {
return 0;
}
return 1;
}
}