Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Zend/Optimizer/zend_inference.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ static zend_always_inline uint32_t _const_op_type(const zval *zv) {
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
} else if (Z_TYPE_P(zv) == IS_STRING) {
tmp |= MAY_BE_RCN;
} else if (Z_TYPE_P(zv) == IS_ATOM) {
/* Atoms are not refcounted, but store their type precisely */
tmp = MAY_BE_ATOM;
}
return tmp;
}
Expand Down
78 changes: 78 additions & 0 deletions Zend/tests/atoms_array_keys.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
--TEST--
Atoms: Array keys functionality
--FILE--
<?php

// Test basic array operations with atom keys
$array = [
:name => 'John',
:age => 30,
:status => :active
];

// Test array access
var_dump($array[:name]);
var_dump($array[:age]);
var_dump($array[:status]);

// Test isset
var_dump(isset($array[:name]));
var_dump(isset($array[:nonexistent]));

// Test array_key_exists
var_dump(array_key_exists('name', $array));
var_dump(array_key_exists('nonexistent', $array));

// Test dynamic assignment
$array[:email] = '[email protected]';
var_dump($array[:email]);

// Test unset
unset($array[:age]);
var_dump(isset($array[:age]));

// Test nested arrays
$config = [
:database => [
:host => 'localhost',
:port => 3306,
:credentials => [
:username => 'admin',
:password => 'secret'
]
],
:cache => [
:enabled => true,
:driver => :redis
]
];

var_dump($config[:database][:host]);
var_dump($config[:database][:port]);
var_dump($config[:database][:credentials][:username]);
var_dump($config[:cache][:driver]);

// Test foreach
$simple = [:a => 1, :b => 2, :c => 3];
foreach ($simple as $key => $value) {
var_dump(string($key) . " => " . $value);
}

?>
--EXPECT--
string(4) "John"
int(30)
string(6) "active"
bool(true)
bool(false)
bool(true)
bool(false)
string(16) "[email protected]"
bool(false)
string(9) "localhost"
int(3306)
string(5) "admin"
string(5) "redis"
string(6) "a => 1"
string(6) "b => 2"
string(6) "c => 3"
50 changes: 50 additions & 0 deletions Zend/tests/atoms_basic.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
--TEST--
Atoms: Basic functionality
--FILE--
<?php

// Test atom literal creation
$atom1 = :test;
$atom2 = :hello;
$atom3 = :world;

// Test type checking
var_dump(is_atom($atom1));
var_dump(is_atom($atom2));
var_dump(is_atom("string"));
var_dump(is_atom(123));

// Test gettype
var_dump(gettype($atom1));
var_dump(gettype($atom2));

// Test is_scalar
var_dump(is_scalar($atom1));
var_dump(is_scalar($atom2));

// Test string conversion
var_dump(string($atom1));
var_dump(string($atom2));
var_dump(string($atom3));

// Test identity
var_dump($atom1 === :test);
var_dump($atom2 === :hello);
var_dump($atom1 === $atom2);

?>
--EXPECT--
bool(true)
bool(true)
bool(false)
bool(false)
string(4) "atom"
string(4) "atom"
bool(true)
bool(true)
string(4) "test"
string(5) "hello"
string(5) "world"
bool(true)
bool(true)
bool(false)
51 changes: 51 additions & 0 deletions Zend/tests/atoms_comparison.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
--TEST--
Atoms: Comparison operations
--FILE--
<?php

$atom1 = :test;
$atom2 = :test;
$atom3 = :other;

// Identity comparison
var_dump($atom1 === $atom2);
var_dump($atom1 === $atom3);
var_dump($atom1 !== $atom3);

// Equality comparison
var_dump($atom1 == $atom2);
var_dump($atom1 == $atom3);
var_dump($atom1 != $atom3);

// Comparison with strings
var_dump($atom1 === "test");
var_dump($atom1 == "test");

// Comparison with other types
var_dump($atom1 === 123);
var_dump($atom1 == 123);
var_dump($atom1 === null);
var_dump($atom1 == null);

// Different atoms
var_dump(:success === :success);
var_dump(:success === :error);
var_dump(:success !== :error);

?>
--EXPECT--
bool(true)
bool(false)
bool(true)
bool(true)
bool(false)
bool(true)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(true)
bool(false)
bool(true)
76 changes: 76 additions & 0 deletions Zend/tests/atoms_edge_cases.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
--TEST--
Atoms: Edge cases and special scenarios
--FILE--
<?php

// Test atoms with underscores and numbers
$atom1 = :test_case;
$atom2 = :item_123;
$atom3 = :_private;

var_dump(string($atom1));
var_dump(string($atom2));
var_dump(string($atom3));

// Test long atom names
$long_atom = :this_is_a_very_long_atom_name_for_testing_purposes;
var_dump(string($long_atom));

// Test atom deduplication across different creation methods
$literal = :dedup_test;
$function_created = atom('dedup_test');
var_dump($literal === $function_created);

// Test in array functions
$array = [:apple, :banana, :cherry];
var_dump(in_array(:banana, $array));
var_dump(in_array(:grape, $array));

// Test array_search
var_dump(array_search(:banana, $array));
var_dump(array_search(:grape, $array));

// Test with array_unique
$duplicates = [:test, :test, :other, :test, :other];
$unique = array_unique($duplicates);
var_dump(count($unique));
foreach ($unique as $atom) {
var_dump(string($atom));
}

// Test atoms in object properties
class TestClass {
public $status = :ready;
private $state = :initialized;

public function getState() {
return $this->state;
}
}

$obj = new TestClass();
var_dump($obj->status);
var_dump(string($obj->getState()));

// Test empty array with atom keys
$empty = [];
$empty[:first] = 'value1';
var_dump($empty[:first]);

?>
--EXPECT--
string(9) "test_case"
string(7) "item_123"
string(8) "_private"
string(53) "this_is_a_very_long_atom_name_for_testing_purposes"
bool(true)
bool(true)
bool(false)
int(1)
bool(false)
int(2)
string(4) "test"
string(5) "other"
atom(:ready)
string(11) "initialized"
string(6) "value1"
76 changes: 76 additions & 0 deletions Zend/tests/atoms_error_handling.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
--TEST--
Atoms: Error handling
--FILE--
<?php

// Test invalid atom names
try {
atom('');
echo "Should not reach here\n";
} catch (ValueError $e) {
var_dump("Empty string rejected");
}

try {
atom('123invalid');
echo "Should not reach here\n";
} catch (ValueError $e) {
var_dump("Invalid identifier rejected");
}

// Test with null
try {
atom(null);
echo "Should not reach here\n";
} catch (TypeError $e) {
var_dump("Null rejected");
}

// Test with non-string
try {
atom(123);
echo "Should not reach here\n";
} catch (TypeError $e) {
var_dump("Non-string rejected");
}

// Test string() function with non-atom
try {
string("not an atom");
echo "Should not reach here\n";
} catch (TypeError $e) {
var_dump("string() rejects non-atom");
}

try {
string(123);
echo "Should not reach here\n";
} catch (TypeError $e) {
var_dump("string() rejects integer");
}

// Test atom_exists with invalid input
try {
atom_exists(null);
echo "Should not reach here\n";
} catch (TypeError $e) {
var_dump("atom_exists rejects null");
}

try {
atom_exists(123);
echo "Should not reach here\n";
} catch (TypeError $e) {
var_dump("atom_exists rejects integer");
}

?>
--EXPECT--
string(20) "Empty string rejected"
string(26) "Invalid identifier rejected"
string(13) "Null rejected"
string(18) "Non-string rejected"
string(26) "string() rejects non-atom"
string(24) "string() rejects integer"
string(24) "atom_exists rejects null"
string(27) "atom_exists rejects integer"
41 changes: 41 additions & 0 deletions Zend/tests/atoms_function.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
Atoms: atom() function
--FILE--
<?php

// Test dynamic atom creation
$atom1 = atom('dynamic');
$atom2 = atom('test');
$atom3 = atom('dynamic'); // Should be same as atom1

var_dump(is_atom($atom1));
var_dump(is_atom($atom2));
var_dump(string($atom1));
var_dump(string($atom2));

// Test identity with dynamic atoms
var_dump($atom1 === $atom3);
var_dump($atom1 === atom('dynamic'));

// Test identity with literal atoms
var_dump($atom2 === :test);
var_dump(atom('hello') === :hello);

// Test with variable names
$name = 'variable';
$atom4 = atom($name);
var_dump(string($atom4));
var_dump($atom4 === :variable);

?>
--EXPECT--
bool(true)
bool(true)
string(7) "dynamic"
string(4) "test"
bool(true)
bool(true)
bool(true)
bool(true)
string(8) "variable"
bool(true)
Loading