You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by cu...@apache.org on 2010/08/30 18:50:41 UTC

svn commit: r990860 [3/3] - in /avro/trunk: ./ lang/php/ lang/php/examples/ lang/php/lib/ lang/php/lib/avro/ lang/php/test/

Added: avro/trunk/lang/php/test/LongEncodingTest.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/test/LongEncodingTest.php?rev=990860&view=auto
==============================================================================
--- avro/trunk/lang/php/test/LongEncodingTest.php (added)
+++ avro/trunk/lang/php/test/LongEncodingTest.php Mon Aug 30 16:50:40 2010
@@ -0,0 +1,315 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+require_once('test_helper.php');
+
+class LongEncodingTest extends PHPUnit_Framework_TestCase
+{
+
+  function setUp()
+  {
+    Avro::check_platform();
+  }
+
+  static function is_64_bit() { return (PHP_INT_SIZE == 8); }
+  function skip_64_bit_test_on_32_bit()
+  {
+    if (!self::is_64_bit())
+      $this->markTestSkipped('Requires 64-bit platform');
+  }
+
+  function skip_if_no_gmp()
+  {
+    if (!extension_loaded('gmp'))
+      $this->markTestSkipped('Requires GMP PHP Extension.');
+  }
+
+  function assert_bit_shift($expected, $actual, $shift_type,
+                            $expected_binary, $actual_binary)
+  {
+    $this->assertEquals(
+      $expected, $actual,
+      sprintf("%s\nexpected: %d\n  actual: %d\nexpected b: %s\n  actual b: %s",
+              $shift_type, $expected, $actual,
+              $expected_binary, $actual_binary));
+  }
+
+  /**
+   * @dataProvider bit_shift_provider
+   */
+  function test_bit_shift($val, $shift, $expected_lval, $expected_rval, $lbin, $rbin)
+  {
+
+    $this->skip_64_bit_test_on_32_bit();
+
+    $lval = (int) ((int) $val << $shift);
+    $this->assert_bit_shift($expected_lval, strval($lval),
+                            'lshift', $lbin, decbin($lval));
+    $rval = ((int) $val >> $shift);
+    $this->assert_bit_shift($expected_rval, strval($rval),
+                            'rshift', $rbin, decbin($rval));
+  }
+
+  /**
+   * @dataProvider bit_shift_provider
+   */
+  function test_left_shift_gmp($val, $shift,
+                               $expected_lval, $expected_rval,
+                               $lbin, $rbin)
+  {
+    $this->skip_if_no_gmp();
+    $lval = gmp_strval(AvroGMP::shift_left($val, $shift));
+    $this->assert_bit_shift($expected_lval, $lval, 'gmp left shift',
+                            $lbin, decbin((int) $lval));
+  }
+
+  /**
+   * @dataProvider bit_shift_provider
+   */
+  function test_right_shift_gmp($val, $shift, $expected_lval, $expected_rval,
+                                $lbin, $rbin)
+  {
+    $this->skip_if_no_gmp();
+    $rval = gmp_strval(AvroGMP::shift_right($val, $shift));
+    $this->assert_bit_shift($expected_rval, $rval, 'gmp right shift',
+                            $rbin, decbin((int) $rval));
+  }
+
+  /**
+   * @dataProvider long_provider
+   */
+  function test_encode_long($val, $expected_bytes)
+  {
+    $this->skip_64_bit_test_on_32_bit();
+    $bytes = AvroIOBinaryEncoder::encode_long($val);
+    $this->assertEquals($expected_bytes, $bytes);
+  }
+
+  /**
+   * @dataProvider long_provider
+   */
+  function test_gmp_encode_long($val, $expected_bytes)
+  {
+    $this->skip_if_no_gmp();
+    $bytes = AvroGMP::encode_long($val);
+    $this->assertEquals($expected_bytes, $bytes);
+  }
+
+  /**
+   * @dataProvider long_provider
+   */
+  function test_decode_long_from_array($expected_val, $bytes)
+  {
+    $this->skip_64_bit_test_on_32_bit();
+    $ary = array_map('ord', str_split($bytes));
+    $val = AvroIOBinaryDecoder::decode_long_from_array($ary);
+    $this->assertEquals($expected_val, $val);
+  }
+
+  /**
+   * @dataProvider long_provider
+   */
+  function test_gmp_decode_long_from_array($expected_val, $bytes)
+  {
+    $this->skip_if_no_gmp();
+    $ary = array_map('ord', str_split($bytes));
+    $val = AvroGMP::decode_long_from_array($ary);
+    $this->assertEquals($expected_val, $val);
+  }
+
+  function long_provider()
+  {
+    return array(array('0', "\x0"),
+                 array('1', "\x2"),
+                 array('7', "\xe"),
+                 array('10000', "\xa0\x9c\x1"),
+                 array('2147483647', "\xfe\xff\xff\xff\xf"),
+                 array('98765432109', "\xda\x94\x87\xee\xdf\x5"),
+                 array('-1', "\x1"),
+                 array('-7', "\xd"),
+                 array('-10000', "\x9f\x9c\x1"),
+                 array('-2147483648', "\xff\xff\xff\xff\xf"),
+                 array('-98765432109', "\xd9\x94\x87\xee\xdf\x5")
+      );
+
+  }
+
+  function bit_shift_provider()
+  {
+                      // val shift lval rval
+    return array(
+      array('0', 0, '0', '0',
+            '0',
+            '0'),
+      array('0', 1, '0', '0',
+            '0',
+            '0'),
+      array('0', 7, '0', '0',
+            '0',
+            '0'),
+      array('0', 63, '0', '0',
+            '0',
+            '0'),
+      array('1', 0, '1', '1',
+            '1',
+            '1'),
+      array('1', 1, '2', '0',
+            '10',
+            '0'),
+      array('1', 7, '128', '0',
+            '10000000',
+            '0'),
+      array('1', 63, '-9223372036854775808', '0',
+            '1000000000000000000000000000000000000000000000000000000000000000',
+            '0'),
+      array('100', 0, '100', '100',
+            '1100100',
+            '1100100'),
+      array('100', 1, '200', '50',
+            '11001000',
+            '110010'),
+      array('100', 7, '12800', '0',
+            '11001000000000',
+            '0'),
+      array('100', 63, '0', '0',
+            '0',
+            '0'),
+      array('1000000', 0, '1000000', '1000000',
+            '11110100001001000000',
+            '11110100001001000000'),
+      array('1000000', 1, '2000000', '500000',
+            '111101000010010000000',
+            '1111010000100100000'),
+      array('1000000', 7, '128000000', '7812',
+            '111101000010010000000000000',
+            '1111010000100'),
+      array('1000000', 63, '0', '0',
+            '0',
+            '0'),
+      array('2147483647', 0, '2147483647', '2147483647',
+            '1111111111111111111111111111111',
+            '1111111111111111111111111111111'),
+      array('2147483647', 1, '4294967294', '1073741823',
+            '11111111111111111111111111111110',
+            '111111111111111111111111111111'),
+      array('2147483647', 7, '274877906816', '16777215',
+            '11111111111111111111111111111110000000',
+            '111111111111111111111111'),
+      array('2147483647', 63, '-9223372036854775808', '0',
+            '1000000000000000000000000000000000000000000000000000000000000000',
+            '0'),
+      array('10000000000', 0, '10000000000', '10000000000',
+            '1001010100000010111110010000000000',
+            '1001010100000010111110010000000000'),
+      array('10000000000', 1, '20000000000', '5000000000',
+            '10010101000000101111100100000000000',
+            '100101010000001011111001000000000'),
+      array('10000000000', 7, '1280000000000', '78125000',
+            '10010101000000101111100100000000000000000',
+            '100101010000001011111001000'),
+      array('10000000000', 63, '0', '0',
+            '0',
+            '0'),
+      array('9223372036854775807', 0, '9223372036854775807', '9223372036854775807',
+            '111111111111111111111111111111111111111111111111111111111111111',
+            '111111111111111111111111111111111111111111111111111111111111111'),
+      array('9223372036854775807', 1, '-2', '4611686018427387903',
+            '1111111111111111111111111111111111111111111111111111111111111110',
+            '11111111111111111111111111111111111111111111111111111111111111'),
+      array('9223372036854775807', 7, '-128', '72057594037927935',
+            '1111111111111111111111111111111111111111111111111111111110000000',
+            '11111111111111111111111111111111111111111111111111111111'),
+      array('9223372036854775807', 63, '-9223372036854775808', '0',
+            '1000000000000000000000000000000000000000000000000000000000000000',
+            '0'),
+      array('-1', 0, '-1', '-1',
+            '1111111111111111111111111111111111111111111111111111111111111111',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-1', 1, '-2', '-1',
+            '1111111111111111111111111111111111111111111111111111111111111110',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-1', 7, '-128', '-1',
+            '1111111111111111111111111111111111111111111111111111111110000000',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-1', 63, '-9223372036854775808', '-1',
+            '1000000000000000000000000000000000000000000000000000000000000000',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-100', 0, '-100', '-100',
+            '1111111111111111111111111111111111111111111111111111111110011100',
+            '1111111111111111111111111111111111111111111111111111111110011100'),
+      array('-100', 1, '-200', '-50',
+            '1111111111111111111111111111111111111111111111111111111100111000',
+            '1111111111111111111111111111111111111111111111111111111111001110'),
+      array('-100', 7, '-12800', '-1',
+            '1111111111111111111111111111111111111111111111111100111000000000',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-100', 63, '0', '-1',
+            '0',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-1000000', 0, '-1000000', '-1000000',
+            '1111111111111111111111111111111111111111111100001011110111000000',
+            '1111111111111111111111111111111111111111111100001011110111000000'),
+      array('-1000000', 1, '-2000000', '-500000',
+            '1111111111111111111111111111111111111111111000010111101110000000',
+            '1111111111111111111111111111111111111111111110000101111011100000'),
+      array('-1000000', 7, '-128000000', '-7813',
+            '1111111111111111111111111111111111111000010111101110000000000000',
+            '1111111111111111111111111111111111111111111111111110000101111011'),
+      array('-1000000', 63, '0', '-1',
+            '0',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-2147483648', 0, '-2147483648', '-2147483648',
+            '1111111111111111111111111111111110000000000000000000000000000000',
+            '1111111111111111111111111111111110000000000000000000000000000000'),
+      array('-2147483648', 1, '-4294967296', '-1073741824',
+            '1111111111111111111111111111111100000000000000000000000000000000',
+            '1111111111111111111111111111111111000000000000000000000000000000'),
+      array('-2147483648', 7, '-274877906944', '-16777216',
+            '1111111111111111111111111100000000000000000000000000000000000000',
+            '1111111111111111111111111111111111111111000000000000000000000000'),
+      array('-2147483648', 63, '0', '-1',
+            '0',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-10000000000', 0, '-10000000000', '-10000000000',
+            '1111111111111111111111111111110110101011111101000001110000000000',
+            '1111111111111111111111111111110110101011111101000001110000000000'),
+      array('-10000000000', 1, '-20000000000', '-5000000000',
+            '1111111111111111111111111111101101010111111010000011100000000000',
+            '1111111111111111111111111111111011010101111110100000111000000000'),
+      array('-10000000000', 7, '-1280000000000', '-78125000',
+            '1111111111111111111111101101010111111010000011100000000000000000',
+            '1111111111111111111111111111111111111011010101111110100000111000'),
+      array('-10000000000', 63, '0', '-1',
+            '0',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      array('-9223372036854775808', 0, '-9223372036854775808', '-9223372036854775808',
+            '1000000000000000000000000000000000000000000000000000000000000000',
+            '1000000000000000000000000000000000000000000000000000000000000000'),
+      array('-9223372036854775808', 1, '0', '-4611686018427387904',
+            '0',
+            '1100000000000000000000000000000000000000000000000000000000000000'),
+      array('-9223372036854775808', 7, '0', '-72057594037927936',
+            '0',
+            '1111111100000000000000000000000000000000000000000000000000000000'),
+      array('-9223372036854775808', 63, '0', '-1',
+            '0',
+            '1111111111111111111111111111111111111111111111111111111111111111'),
+      );
+  }
+
+}

Added: avro/trunk/lang/php/test/NameTest.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/test/NameTest.php?rev=990860&view=auto
==============================================================================
--- avro/trunk/lang/php/test/NameTest.php (added)
+++ avro/trunk/lang/php/test/NameTest.php Mon Aug 30 16:50:40 2010
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+require_once('test_helper.php');
+
+class NameExample
+{
+  var $is_valid;
+  var $name;
+  var $namespace;
+  var $default_namespace;
+  var $expected_fullname;
+  function __construct($name, $namespace, $default_namespace, $is_valid,
+                       $expected_fullname=null)
+  {
+    $this->name = $name;
+    $this->namespace = $namespace;
+    $this->default_namespace = $default_namespace;
+    $this->is_valid = $is_valid;
+    $this->expected_fullname = $expected_fullname;
+  }
+
+  function __toString()
+  {
+    return var_export($this, true);
+  }
+}
+
+class NameTest extends PHPUnit_Framework_TestCase
+{
+
+  function fullname_provider()
+  {
+    $examples = array(new NameExample('foo', null, null, true, 'foo'),
+                      new NameExample('foo', 'bar', null, true, 'bar.foo'),
+                      new NameExample('bar.foo', 'baz', null, true, 'bar.foo'),
+                      new NameExample('_bar.foo', 'baz', null, true, '_bar.foo'),
+                      new NameExample('bar._foo', 'baz', null, true, 'bar._foo'),
+                      new NameExample('3bar.foo', 'baz', null, false),
+                      new NameExample('bar.3foo', 'baz', null, false),
+                      new NameExample('b4r.foo', 'baz', null, true, 'b4r.foo'),
+                      new NameExample('bar.f0o', 'baz', null, true, 'bar.f0o'),
+                      new NameExample(' .foo', 'baz', null, false),
+                      new NameExample('bar. foo', 'baz', null, false),
+                      new NameExample('bar. ', 'baz', null, false)
+                      );
+    $exes = array();
+    foreach ($examples as $ex)
+      $exes []= array($ex);
+    return $exes;
+  }
+
+  /**
+   * @dataProvider fullname_provider
+   */
+  function test_fullname($ex)
+  {
+    try
+    {
+      $name = new AvroName($ex->name, $ex->namespace, $ex->default_namespace);
+      $this->assertTrue($ex->is_valid);
+      $this->assertEquals($ex->expected_fullname, $name->fullname());
+    }
+    catch (AvroSchemaParseException $e)
+    {
+      $this->assertFalse($ex->is_valid, sprintf("%s:\n%s",
+                                                $ex,
+                                                $e->getMessage()));
+    }
+  }
+
+  function name_provider()
+  {
+    return array(array('a', true),
+                 array('_', true),
+                 array('1a', false),
+                 array('', false),
+                 array(null, false),
+                 array(' ', false),
+                 array('Cons', true));
+  }
+
+  /**
+   * @dataProvider name_provider
+   */
+  function test_name($name, $is_well_formed)
+  {
+    $this->assertEquals(AvroName::is_well_formed_name($name), $is_well_formed, $name);
+  }
+}

Added: avro/trunk/lang/php/test/SchemaTest.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/test/SchemaTest.php?rev=990860&view=auto
==============================================================================
--- avro/trunk/lang/php/test/SchemaTest.php (added)
+++ avro/trunk/lang/php/test/SchemaTest.php Mon Aug 30 16:50:40 2010
@@ -0,0 +1,463 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+require_once('test_helper.php');
+
+class SchemaExample
+{
+  var $schema_string;
+  var $is_valid;
+  var $name;
+  var $comment;
+  var $normalized_schema_string;
+  function __construct($schema_string, $is_valid, $normalized_schema_string=null,
+                       $name=null, $comment=null)
+  {
+    $this->schema_string = $schema_string;
+    $this->is_valid = $is_valid;
+    $this->name = $name ? $name : $schema_string;
+    $this->normalized_schema_string = $normalized_schema_string
+      ? $normalized_schema_string : json_encode(json_decode($schema_string, true));
+    $this->comment = $comment;
+  }
+}
+
+class SchemaTest extends PHPUnit_Framework_TestCase
+{
+  static $examples = array();
+  static $valid_examples = array();
+
+  protected static function make_primitive_examples()
+  {
+    $examples = array();
+    foreach (array('null', 'boolean',
+                   'int', 'long',
+                   'float', 'double',
+                   'bytes', 'string')
+             as $type)
+    {
+      $examples []= new SchemaExample(sprintf('"%s"', $type), true);
+      $examples []= new SchemaExample(sprintf('{"type": "%s"}', $type), true, sprintf('"%s"', $type));
+    }
+    return $examples;
+  }
+
+  protected static function make_examples()
+  {
+    $primitive_examples = array_merge(array(new SchemaExample('"True"', false),
+                                            new SchemaExample('{"no_type": "test"}', false),
+                                            new SchemaExample('{"type": "panther"}', false)),
+                                        self::make_primitive_examples());
+
+    $array_examples = array(
+      new SchemaExample('{"type": "array", "items": "long"}', true),
+      new SchemaExample('
+    {"type": "array",
+     "items": {"type": "enum", "name": "Test", "symbols": ["A", "B"]}}
+    ', true));
+
+    $map_examples = array(
+      new SchemaExample('{"type": "map", "values": "long"}', true),
+      new SchemaExample('
+    {"type": "map",
+     "values": {"type": "enum", "name": "Test", "symbols": ["A", "B"]}}
+    ', true));
+
+    $union_examples = array(
+      new SchemaExample('["string", "null", "long"]', true),
+      new SchemaExample('["null", "null"]', false),
+      new SchemaExample('["long", "long"]', false),
+      new SchemaExample('
+    [{"type": "array", "items": "long"}
+     {"type": "array", "items": "string"}]
+    ', false),
+      new SchemaExample('["long",
+                          {"type": "long"},
+                          "int"]', false),
+      new SchemaExample('["long",
+                          {"type": "array", "items": "long"},
+                          {"type": "map", "values": "long"},
+                          "int"]', true),
+      new SchemaExample('["long",
+                          ["string", "null"],
+                          "int"]', false),
+      new SchemaExample('["long",
+                          ["string", "null"],
+                          "int"]', false),
+      new SchemaExample('["null", "boolean", "int", "long", "float", "double",
+                          "string", "bytes",
+                          {"type": "array", "items":"int"},
+                          {"type": "map", "values":"int"},
+                          {"name": "bar", "type":"record",
+                           "fields":[{"name":"label", "type":"string"}]},
+                          {"name": "foo", "type":"fixed",
+                           "size":16},
+                          {"name": "baz", "type":"enum", "symbols":["A", "B", "C"]}
+                         ]', true, '["null","boolean","int","long","float","double","string","bytes",{"type":"array","items":"int"},{"type":"map","values":"int"},{"type":"record","name":"bar","fields":[{"name":"label","type":"string"}]},{"type":"fixed","name":"foo","size":16},{"type":"enum","name":"baz","symbols":["A","B","C"]}]'),
+      new SchemaExample('
+    [{"name":"subtract", "namespace":"com.example",
+      "type":"record",
+      "fields":[{"name":"minuend", "type":"int"},
+                {"name":"subtrahend", "type":"int"}]},
+      {"name": "divide", "namespace":"com.example",
+      "type":"record",
+      "fields":[{"name":"quotient", "type":"int"},
+                {"name":"dividend", "type":"int"}]},
+      {"type": "array", "items": "string"}]
+    ', true, '[{"type":"record","name":"subtract","namespace":"com.example","fields":[{"name":"minuend","type":"int"},{"name":"subtrahend","type":"int"}]},{"type":"record","name":"divide","namespace":"com.example","fields":[{"name":"quotient","type":"int"},{"name":"dividend","type":"int"}]},{"type":"array","items":"string"}]'),
+      );
+
+    $fixed_examples = array(
+      new SchemaExample('{"type": "fixed", "name": "Test", "size": 1}', true),
+      new SchemaExample('
+    {"type": "fixed",
+     "name": "MyFixed",
+     "namespace": "org.apache.hadoop.avro",
+     "size": 1}
+    ', true),
+      new SchemaExample('
+    {"type": "fixed",
+     "name": "Missing size"}
+    ', false),
+      new SchemaExample('
+    {"type": "fixed",
+     "size": 314}
+    ', false),
+      new SchemaExample('{"type":"fixed","name":"ex","doc":"this should be ignored","size": 314}',
+                        true,
+                        '{"type":"fixed","name":"ex","size":314}'),
+      new SchemaExample('{"name": "bar",
+                          "namespace": "com.example",
+                          "type": "fixed",
+                          "size": 32 }', true,
+                        '{"type":"fixed","name":"bar","namespace":"com.example","size":32}'),
+      new SchemaExample('{"name": "com.example.bar",
+                          "type": "fixed",
+                          "size": 32 }', true,
+        '{"type":"fixed","name":"bar","namespace":"com.example","size":32}'));
+
+    $fixed_examples []= new SchemaExample(
+      '{"type":"fixed","name":"_x.bar","size":4}', true,
+      '{"type":"fixed","name":"bar","namespace":"_x","size":4}');
+    $fixed_examples []= new SchemaExample(
+      '{"type":"fixed","name":"baz._x","size":4}', true,
+      '{"type":"fixed","name":"_x","namespace":"baz","size":4}');
+    $fixed_examples []= new SchemaExample(
+      '{"type":"fixed","name":"baz.3x","size":4}', false);
+
+    $enum_examples = array(
+      new SchemaExample('{"type": "enum", "name": "Test", "symbols": ["A", "B"]}', true),
+      new SchemaExample('
+    {"type": "enum",
+     "name": "Status",
+     "symbols": "Normal Caution Critical"}
+    ', false),
+      new SchemaExample('
+    {"type": "enum",
+     "name": [ 0, 1, 1, 2, 3, 5, 8 ],
+     "symbols": ["Golden", "Mean"]}
+    ', false),
+      new SchemaExample('
+    {"type": "enum",
+     "symbols" : ["I", "will", "fail", "no", "name"]}
+    ', false),
+      new SchemaExample('
+    {"type": "enum",
+     "name": "Test"
+     "symbols" : ["AA", "AA"]}
+    ', false),
+      new SchemaExample('{"type":"enum","name":"Test","symbols":["AA", 16]}',
+                        false),
+      new SchemaExample('
+    {"type": "enum",
+     "name": "blood_types",
+     "doc": "AB is freaky.",
+     "symbols" : ["A", "AB", "B", "O"]}
+    ', true),
+      new SchemaExample('
+    {"type": "enum",
+     "name": "blood-types",
+     "doc": 16,
+     "symbols" : ["A", "AB", "B", "O"]}
+    ', false)
+      );
+
+
+    $record_examples = array();
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "Test",
+     "fields": [{"name": "f",
+                 "type": "long"}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "error",
+     "name": "Test",
+     "fields": [{"name": "f",
+                 "type": "long"}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "Node",
+     "fields": [{"name": "label", "type": "string"},
+                {"name": "children",
+                 "type": {"type": "array", "items": "Node"}}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "ListLink",
+     "fields": [{"name": "car", "type": "int"},
+                {"name": "cdr", "type": "ListLink"}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "Lisp",
+     "fields": [{"name": "value",
+                 "type": ["null", "string"]}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "Lisp",
+     "fields": [{"name": "value",
+                 "type": ["null", "string",
+                          {"type": "record",
+                           "name": "Cons",
+                           "fields": [{"name": "car", "type": "string"},
+                                      {"name": "cdr", "type": "string"}]}]}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "Lisp",
+     "fields": [{"name": "value",
+                 "type": ["null", "string",
+                          {"type": "record",
+                           "name": "Cons",
+                           "fields": [{"name": "car", "type": "Lisp"},
+                                      {"name": "cdr", "type": "Lisp"}]}]}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "HandshakeRequest",
+     "namespace": "org.apache.avro.ipc",
+     "fields": [{"name": "clientHash",
+                 "type": {"type": "fixed", "name": "MD5", "size": 16}},
+                {"name": "meta",
+                 "type": ["null", {"type": "map", "values": "bytes"}]}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "HandshakeRequest",
+     "namespace": "org.apache.avro.ipc",
+     "fields": [{"name": "clientHash",
+                 "type": {"type": "fixed", "name": "MD5", "size": 16}},
+                {"name": "clientProtocol", "type": ["null", "string"]},
+                {"name": "serverHash", "type": "MD5"},
+                {"name": "meta",
+                 "type": ["null", {"type": "map", "values": "bytes"}]}]}
+    ', true);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "HandshakeResponse",
+     "namespace": "org.apache.avro.ipc",
+     "fields": [{"name": "match",
+                 "type": {"type": "enum",
+                          "name": "HandshakeMatch",
+                          "symbols": ["BOTH", "CLIENT", "NONE"]}},
+                {"name": "serverProtocol", "type": ["null", "string"]},
+                {"name": "serverHash",
+                 "type": ["null",
+                          {"name": "MD5", "size": 16, "type": "fixed"}]},
+                {"name": "meta",
+                 "type": ["null", {"type": "map", "values": "bytes"}]}]}
+    ', true,
+     '{"type":"record","name":"HandshakeResponse","namespace":"org.apache.avro.ipc","fields":[{"name":"match","type":{"type":"enum","name":"HandshakeMatch","symbols":["BOTH","CLIENT","NONE"]}},{"name":"serverProtocol","type":["null","string"]},{"name":"serverHash","type":["null",{"type":"fixed","name":"MD5","size":16}]},{"name":"meta","type":["null",{"type":"map","values":"bytes"}]}]}'
+      );
+    $record_examples []= new SchemaExample('{"type": "record",
+ "namespace": "org.apache.avro",
+ "name": "Interop",
+ "fields": [{"type": {"fields": [{"type": {"items": "org.apache.avro.Node",
+                                           "type": "array"},
+                                  "name": "children"}],
+                      "type": "record",
+                      "name": "Node"},
+             "name": "recordField"}]}
+', true, '{"type":"record","name":"Interop","namespace":"org.apache.avro","fields":[{"name":"recordField","type":{"type":"record","name":"Node","fields":[{"name":"children","type":{"type":"array","items":"Node"}}]}}]}');
+    $record_examples [] = new SchemaExample('{"type": "record",
+ "namespace": "org.apache.avro",
+ "name": "Interop",
+ "fields": [{"type": {"symbols": ["A", "B", "C"], "type": "enum", "name": "Kind"},
+             "name": "enumField"},
+            {"type": {"fields": [{"type": "string", "name": "label"},
+                                 {"type": {"items": "org.apache.avro.Node", "type": "array"},
+                                  "name": "children"}],
+                      "type": "record",
+                      "name": "Node"},
+             "name": "recordField"}]}', true, '{"type":"record","name":"Interop","namespace":"org.apache.avro","fields":[{"name":"enumField","type":{"type":"enum","name":"Kind","symbols":["A","B","C"]}},{"name":"recordField","type":{"type":"record","name":"Node","fields":[{"name":"label","type":"string"},{"name":"children","type":{"type":"array","items":"Node"}}]}}]}');
+
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "Interop",
+     "namespace": "org.apache.avro",
+     "fields": [{"name": "intField", "type": "int"},
+                {"name": "longField", "type": "long"},
+                {"name": "stringField", "type": "string"},
+                {"name": "boolField", "type": "boolean"},
+                {"name": "floatField", "type": "float"},
+                {"name": "doubleField", "type": "double"},
+                {"name": "bytesField", "type": "bytes"},
+                {"name": "nullField", "type": "null"},
+                {"name": "arrayField",
+                 "type": {"type": "array", "items": "double"}},
+                {"name": "mapField",
+                 "type": {"type": "map",
+                          "values": {"name": "Foo",
+                                     "type": "record",
+                                     "fields": [{"name": "label",
+                                                 "type": "string"}]}}},
+                {"name": "unionField",
+                 "type": ["boolean",
+                          "double",
+                          {"type": "array", "items": "bytes"}]},
+                {"name": "enumField",
+                 "type": {"type": "enum",
+                          "name": "Kind",
+                          "symbols": ["A", "B", "C"]}},
+                {"name": "fixedField",
+                 "type": {"type": "fixed", "name": "MD5", "size": 16}},
+                {"name": "recordField",
+                 "type": {"type": "record",
+                          "name": "Node",
+                          "fields": [{"name": "label", "type": "string"},
+                                     {"name": "children",
+                                      "type": {"type": "array",
+                                               "items": "Node"}}]}}]}
+    ', true,
+    '{"type":"record","name":"Interop","namespace":"org.apache.avro","fields":[{"name":"intField","type":"int"},{"name":"longField","type":"long"},{"name":"stringField","type":"string"},{"name":"boolField","type":"boolean"},{"name":"floatField","type":"float"},{"name":"doubleField","type":"double"},{"name":"bytesField","type":"bytes"},{"name":"nullField","type":"null"},{"name":"arrayField","type":{"type":"array","items":"double"}},{"name":"mapField","type":{"type":"map","values":{"type":"record","name":"Foo","fields":[{"name":"label","type":"string"}]}}},{"name":"unionField","type":["boolean","double",{"type":"array","items":"bytes"}]},{"name":"enumField","type":{"type":"enum","name":"Kind","symbols":["A","B","C"]}},{"name":"fixedField","type":{"type":"fixed","name":"MD5","size":16}},{"name":"recordField","type":{"type":"record","name":"Node","fields":[{"name":"label","type":"string"},{"name":"children","type":{"type":"array","items":"Node"}}]}}]}');
+    $record_examples []= new SchemaExample('{"type": "record", "namespace": "org.apache.avro", "name": "Interop", "fields": [{"type": "int", "name": "intField"}, {"type": "long", "name": "longField"}, {"type": "string", "name": "stringField"}, {"type": "boolean", "name": "boolField"}, {"type": "float", "name": "floatField"}, {"type": "double", "name": "doubleField"}, {"type": "bytes", "name": "bytesField"}, {"type": "null", "name": "nullField"}, {"type": {"items": "double", "type": "array"}, "name": "arrayField"}, {"type": {"type": "map", "values": {"fields": [{"type": "string", "name": "label"}], "type": "record", "name": "Foo"}}, "name": "mapField"}, {"type": ["boolean", "double", {"items": "bytes", "type": "array"}], "name": "unionField"}, {"type": {"symbols": ["A", "B", "C"], "type": "enum", "name": "Kind"}, "name": "enumField"}, {"type": {"type": "fixed", "name": "MD5", "size": 16}, "name": "fixedField"}, {"type": {"fields": [{"type": "string", "name": "label"}, {"type"
 : {"items": "org.apache.avro.Node", "type": "array"}, "name": "children"}], "type": "record", "name": "Node"}, "name": "recordField"}]}
+', true, '{"type":"record","name":"Interop","namespace":"org.apache.avro","fields":[{"name":"intField","type":"int"},{"name":"longField","type":"long"},{"name":"stringField","type":"string"},{"name":"boolField","type":"boolean"},{"name":"floatField","type":"float"},{"name":"doubleField","type":"double"},{"name":"bytesField","type":"bytes"},{"name":"nullField","type":"null"},{"name":"arrayField","type":{"type":"array","items":"double"}},{"name":"mapField","type":{"type":"map","values":{"type":"record","name":"Foo","fields":[{"name":"label","type":"string"}]}}},{"name":"unionField","type":["boolean","double",{"type":"array","items":"bytes"}]},{"name":"enumField","type":{"type":"enum","name":"Kind","symbols":["A","B","C"]}},{"name":"fixedField","type":{"type":"fixed","name":"MD5","size":16}},{"name":"recordField","type":{"type":"record","name":"Node","fields":[{"name":"label","type":"string"},{"name":"children","type":{"type":"array","items":"Node"}}]}}]}');
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "ipAddr",
+     "fields": [{"name": "addr",
+                 "type": [{"name": "IPv6", "type": "fixed", "size": 16},
+                          {"name": "IPv4", "type": "fixed", "size": 4}]}]}
+    ', true,
+    '{"type":"record","name":"ipAddr","fields":[{"name":"addr","type":[{"type":"fixed","name":"IPv6","size":16},{"type":"fixed","name":"IPv4","size":4}]}]}');
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "Address",
+     "fields": [{"type": "string"},
+                {"type": "string", "name": "City"}]}
+    ', false);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "name": "Event",
+     "fields": [{"name": "Sponsor"},
+                {"name": "City", "type": "string"}]}
+    ', false);
+    $record_examples []= new SchemaExample('
+    {"type": "record",
+     "fields": "His vision, from the constantly passing bars,"
+     "name", "Rainer"}
+    ', false);
+     $record_examples []= new SchemaExample('
+    {"name": ["Tom", "Jerry"],
+     "type": "record",
+     "fields": [{"name": "name", "type": "string"}]}
+    ', false);
+     $record_examples []= new SchemaExample('
+    {"type":"record","name":"foo","doc":"doc string",
+     "fields":[{"name":"bar", "type":"int", "order":"ascending", "default":1}]}
+',
+                                            true,
+                                            '{"type":"record","name":"foo","doc":"doc string","fields":[{"name":"bar","type":"int","default":1,"order":"ascending"}]}');
+     $record_examples []= new SchemaExample('
+    {"type":"record", "name":"foo", "doc":"doc string",
+     "fields":[{"name":"bar", "type":"int", "order":"bad"}]}
+', false);
+
+    self::$examples = array_merge($primitive_examples,
+                                  $fixed_examples,
+                                  $enum_examples,
+                                  $array_examples,
+                                  $map_examples,
+                                  $union_examples,
+                                  $record_examples);
+    self::$valid_examples = array();
+    foreach (self::$examples as $example)
+    {
+      if ($example->is_valid)
+        self::$valid_examples []= $example;
+    }
+  }
+
+  function test_json_decode()
+  {
+    $this->assertEquals(json_decode('null', true), null);
+    $this->assertEquals(json_decode('32', true), 32);
+    $this->assertEquals(json_decode('"32"', true), '32');
+    $this->assertEquals((array) json_decode('{"foo": 27}'), array("foo" => 27));
+    $this->assertTrue(is_array(json_decode('{"foo": 27}', true)));
+    $this->assertEquals(json_decode('{"foo": 27}', true), array("foo" => 27));
+    $this->assertEquals(json_decode('["bar", "baz", "blurfl"]', true),
+                        array("bar", "baz", "blurfl"));
+    $this->assertFalse(is_array(json_decode('null', true)));
+    $this->assertEquals(json_decode('{"type": "null"}', true), array("type" => 'null'));
+    foreach (array('true', 'True', 'TRUE', 'tRue') as $truthy)
+    {
+      $this->assertEquals(json_decode($truthy, true), true, $truthy);
+    }
+    $this->assertEquals(json_decode('"boolean"'), 'boolean');
+  }
+
+  function schema_examples_provider()
+  {
+    self::make_examples();
+    $ary = array();
+    foreach (self::$examples as $example)
+      $ary []= array($example);
+    return $ary;
+    return array(array(1), array(2), array(3));
+  }
+
+  /**
+   * @dataProvider schema_examples_provider
+   */
+  function test_parse($example)
+  {
+    $schema_string = $example->schema_string;
+    try
+    {
+      $normalized_schema_string = $example->normalized_schema_string;
+      $schema = AvroSchema::parse($schema_string);
+      $this->assertTrue($example->is_valid,
+                        sprintf("schema_string: %s\n",
+                                $schema_string));
+      $this->assertEquals($normalized_schema_string, strval($schema));
+    }
+    catch (AvroSchemaParseException $e)
+    {
+      $this->assertFalse($example->is_valid,
+                         sprintf("schema_string: %s\n%s",
+                                 $schema_string,
+                                 $e->getMessage()));
+    }
+  }
+
+}

Added: avro/trunk/lang/php/test/StringIOTest.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/test/StringIOTest.php?rev=990860&view=auto
==============================================================================
--- avro/trunk/lang/php/test/StringIOTest.php (added)
+++ avro/trunk/lang/php/test/StringIOTest.php Mon Aug 30 16:50:40 2010
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+require_once('test_helper.php');
+
+class StringIOTest extends PHPUnit_Framework_TestCase
+{
+
+  public function test_write()
+  {
+    $strio = new AvroStringIO();
+    $this->assertEquals(0, $strio->tell());
+    $str = 'foo';
+    $strlen = strlen($str);
+    $this->assertEquals($strlen, $strio->write($str));
+    $this->assertEquals($strlen, $strio->tell());
+  }
+
+  public function test_seek()
+  {
+    $this->markTestIncomplete('This test has not been implemented yet.');
+  }
+
+  public function test_tell()
+  {
+    $this->markTestIncomplete('This test has not been implemented yet.');
+  }
+
+  public function test_read()
+  {
+    $this->markTestIncomplete('This test has not been implemented yet.');
+  }
+
+  public function test_string_rep()
+  {
+    $writers_schema_json = '"null"';
+    $writers_schema = AvroSchema::parse($writers_schema_json);
+    $datum_writer = new AvroIODatumWriter($writers_schema);
+    $strio = new AvroStringIO();
+    $this->assertEquals('', $strio->string());
+    $dw = new AvroDataIOWriter($strio, $datum_writer, $writers_schema_json);
+    $dw->close(); 
+
+    $this->assertEquals(57, strlen($strio->string()), 
+                        AvroDebug::ascii_string($strio->string()));
+
+    $read_strio = new AvroStringIO($strio->string());
+
+    $datum_reader = new AvroIODatumReader();
+    $dr = new AvroDataIOReader($read_strio, $datum_reader);
+    $read_data = $dr->data();
+    $datum_count = count($read_data);
+    $this->assertEquals(0, $datum_count);
+  }
+
+}

Added: avro/trunk/lang/php/test/generate_interop_data.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/test/generate_interop_data.php?rev=990860&view=auto
==============================================================================
--- avro/trunk/lang/php/test/generate_interop_data.php (added)
+++ avro/trunk/lang/php/test/generate_interop_data.php Mon Aug 30 16:50:40 2010
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+require_once('test_helper.php');
+
+$data_file = join(DIRECTORY_SEPARATOR, array(AVRO_BUILD_DATA_DIR, 'php.avro'));
+$datum = array('nullField' => null,
+               'boolField' => true,
+               'intField' => -42,
+               'longField' => (int) 2147483650,
+               'floatField' => 1234.0,
+               'doubleField' => -5432.6,
+               'stringField' => 'hello avro',
+               'bytesField' => "\x16\xa6",
+               'arrayField' => array(5.0, -6.0, -10.5),
+               'mapField' => array('a' => array('label' => 'a'),
+                                   'c' => array('label' => '3P0')),
+               'unionField' => 14.5,
+               'enumField' => 'C',
+               'fixedField' => '1019181716151413',
+               'recordField' => array('label' => 'blah',
+                                      'children' => array(
+                                        array('label' => 'inner',
+                                              'children' => array()))));
+
+$schema_json = file_get_contents(AVRO_INTEROP_SCHEMA);
+$io_writer = AvroDataIO::open_file($data_file, 'w', $schema_json);
+$io_writer->append($datum);
+$io_writer->close();

Added: avro/trunk/lang/php/test/test_helper.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/test/test_helper.php?rev=990860&view=auto
==============================================================================
--- avro/trunk/lang/php/test/test_helper.php (added)
+++ avro/trunk/lang/php/test/test_helper.php Mon Aug 30 16:50:40 2010
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+define('AVRO_TEST_HELPER_DIR', dirname(__FILE__));
+
+require_once(join(DIRECTORY_SEPARATOR, 
+                  array(dirname(AVRO_TEST_HELPER_DIR), 'lib', 'avro.php')));
+
+define('TEST_TEMP_DIR', join(DIRECTORY_SEPARATOR, 
+                             array(AVRO_TEST_HELPER_DIR, 'tmp')));
+
+define('AVRO_BASE_DIR', dirname(dirname(dirname(AVRO_TEST_HELPER_DIR))));
+define('AVRO_SHARE_DIR', join(DIRECTORY_SEPARATOR,
+                               array(AVRO_BASE_DIR, 'share')));
+define('AVRO_BUILD_DIR', join(DIRECTORY_SEPARATOR,
+                               array(AVRO_BASE_DIR, 'build')));
+define('AVRO_BUILD_DATA_DIR', join(DIRECTORY_SEPARATOR,
+                                    array(AVRO_BUILD_DIR, 'interop', 'data')));
+define('AVRO_TEST_SCHEMAS_DIR', join(DIRECTORY_SEPARATOR,
+                                     array(AVRO_SHARE_DIR, 'test', 'schemas')));
+define('AVRO_INTEROP_SCHEMA', join(DIRECTORY_SEPARATOR,
+                                   array(AVRO_TEST_SCHEMAS_DIR, 'interop.avsc')));
+
+$tz = ini_get('date.timezone');
+if (empty($x))
+  date_default_timezone_set('America/New_York');