Skip to content
Draft
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
56 changes: 56 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Stubs
*_arginfo.h
vendor/

# Build products
*.so
*.lo
*.la
*.dep

# Build directories
.libs/
build/

# Configuration files
config.h
config.h.in
config.log
config.nice
config.status
configure
configure.ac

# Makefiles
Makefile
Makefile.fragments
Makefile.objects

# Autom4te cache
autom4te.cache/

# Libtool files
libtool

# Test files
run-tests.php

# IDE/Editor files
.idea/
.vscode/
*.swp
*.swo

# macOS
.DS_Store

# Editor backup files
*~

# PHPT test artifacts
tests/phpt/*.diff
tests/phpt/*.exp
tests/phpt/*.log
tests/phpt/*.out
tests/phpt/*.php
tests/phpt/*.sh
8 changes: 8 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Development

## Dependencies

- PHP 8.2+
- [Composer](https://getcomposer.org)
- [Task](https://taskfile.dev)
- [Reflex](https://github.com/cespare/reflex)
94 changes: 92 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,92 @@
# template-ext
Modern PHP extension template - PestPHP + C unit tests 🧪
# Template Extension

**Template Extension** is a PHP extension template with string to_snake_case conversion functionality.

## Features

- `to_snake(string $input)` - Converts strings to snake_case format

## Supported Conversions

- camelCase → snake_case
- PascalCase → snake_case
- kebab-case → snake_case
- Space separated → snake_case
- Already snake_case → snake_case (unchanged)

## Installation

```bash
# Build and install the extension
phpize && ./configure --enable-template-ext
make
make install
```

## Usage

```php
<?php

use TemplateExt\to_snake;

// camelCase to snake_case
to_snake('camelCase'); // Returns: "camel_case"
to_snake('longVariableName'); // Returns: "long_variable_name"

// PascalCase to snake_case
to_snake('FirstName'); // Returns: "first_name"
to_snake('HTTPResponse'); // Returns: "http_response"

// kebab-case to snake_case
to_snake('first-name'); // Returns: "first_name"

// Space separated to snake_case
to_snake('first name'); // Returns: "first_name"

// Already snake_case
to_snake('first_name'); // Returns: "first_name"
```

## Development

### Prerequisites

- PHP 8.1 or later
- Ceedling for C unit tests
- Composer for PHP tests

### Building

```bash
task build
```

### Testing

```bash
# Run all tests (C unit tests + PHP integration tests)
task test

# Run C unit tests only
task test:unit

# Run PHP integration tests only
task test:integration

# Run linter
task lint
```

## Testing Structure

- **C Unit Tests**: Located in `tests/c/` using Ceedling with Unity test framework
- Uses `TEST_CASE` and `TEST_MATRIX` macros for parameterized testing
- Tests string to snake_case conversion logic

- **PHP Integration Tests**: Located in `tests/php/` using PestPHP
- Tests the PHP extension functions

## License

Template Extension is open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**.
97 changes: 97 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# yaml-language-server: $schema=https://taskfile.dev/schema.json

version: '3'

vars:
VENDOR_DIR: vendor

tasks:
_ensure-vendor:
internal: true
cmds:
- test -d {{.VENDOR_DIR}} || composer install

_ensure-gen_stub:
internal: true
cmds:
- test -f build/gen_stub.php || task build

build:
desc: Build the PHP extension
cmds:
# phpize & ./configure only need to run if Makefiles don't exist yet.
# Using standard "make" handles incremental C compilation efficiently.
- |
if [ ! -f Makefile ]; then
phpize && ./configure --enable-template-ext
fi
- make

watch:
desc: Watch source files and automatically rebuild the PHP extension
cmds:
- reflex --inverse-regex='^config.h' -r '\.(c|h|m4|w32)$' -- task build

stubs:
desc: Generate arginfo stubs
deps:
- _ensure-gen_stub
cmds:
- php build/gen_stub.php

lint:
desc: Run Pint linter on test files
deps:
- _ensure-vendor
cmds:
- ./vendor/bin/pint tests/php

test:lint:
desc: Run Pint linter in test mode
deps:
- _ensure-vendor
cmds:
- ./vendor/bin/pint --test tests/php

test:coverage:
desc: Run Pest tests with coverage
deps:
- _ensure-vendor
cmds:
- ./vendor/bin/pest --coverage tests/php

test:unit:
desc: Run C unit tests via Ceedling
cmds:
- ceedling

test:integration:
desc: Run PHP integration tests
deps:
- _ensure-vendor
cmds:
- ./vendor/bin/pest --colors=always tests/php

test:
desc: Run all tests (lint, unit, integration)
deps:
- test:lint
- test:unit
- test:integration

clean:src:
desc: Clean extension build artifacts
cmds:
- make clean || true
- phpize --clean || true

clean:test:
desc: Clean Ceedling test artifacts
cmds:
- ceedling clean

clean:
desc: Clean all build and test artifacts
deps:
- clean:src
- clean:test
30 changes: 30 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "attributes-php/template-ext",
"type": "library",
"description": "Template PHP extension with string to_snake_case conversion",
"keywords": [
"template",
"snake_case",
"string",
"extension"
],
"license": "MIT",
"require": {
"php": "^8.1"
},
"autoload-dev": {
"psr-4": {
"TemplateExt\\Tests\\": "tests/php/"
}
},
"require-dev": {
"laravel/pint": "1.30",
"pestphp/pest": "^3.0"
},
"prefer-stable": true,
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
}
}
}
14 changes: 14 additions & 0 deletions config.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
PHP_ARG_ENABLE(template_ext, whether to enable template_ext support,
[ --enable-template-ext Enable template_ext support])

if test "$PHP_TEMPLATE_EXT" != "no"; then
PHP_REQUIRE_CC()

# Require PHP 8.2 or later (ZEND_MODULE_API_NO 20220829)
if test "$PHP_API_VERSION" -lt 20220829; then
AC_MSG_ERROR([PHP 8.2 or later is required])
fi

PHP_ADD_LIBRARY(stdc++, 1, TEMPLATE_EXT_SHARED_LIBADD)
PHP_NEW_EXTENSION(template_ext, template_ext.c, $ext_shared)
fi
21 changes: 21 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="Default">
<directory>tests/php/</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_STORE" value="array"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
<env name="MAIL_MAILER" value="array"/>
<env name="PULSE_ENABLED" value="false"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit>
Loading