tabtest


Nametabtest JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryTableau の .twb .twbx ファイルを解析・テストするツール
upload_time2025-08-31 14:53:12
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseMIT
keywords tableau twb twbx parser testing
VCS
bugtrack_url
requirements lxml pydantic pytest
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # tabtest

Tableauの`.twb`/`.twbx`ファイルを解析し、pytestでテストを実行できるPythonライブラリです。

## 概要

tabtestは、Tableauワークブックの構造を解析し、pytestを使用してワークブックの内容をテストできるようにするツールです。以下のようなテストが可能です:

- データソースの存在確認
- 計算フィールドの存在確認
- ワークシートの設定確認
- ダッシュボードのレイアウト確認
- パラメータの設定確認
- フィルターの設定確認

## インストール

```bash
pip install tabtest
```

## 基本的な使用方法

### 1. ワークブックの解析

```python
from tabtest import WorkbookParser

# ワークブックを解析
parser = WorkbookParser("./path/to/your/workbook.twb")
workbook = parser.workbook

# 基本情報の確認
print(f"ワークブック名: {workbook.name}")
print(f"データソース数: {len(workbook.datasources)}")
print(f"ワークシート数: {len(workbook.sheets)}")
print(f"ダッシュボード数: {len(workbook.dashboards)}")
```

### 2. pytestでのテスト

```python
import pytest
from tabtest.suite.helpers import (
    assert_workbook_has_datasource,
    assert_workbook_has_sheet,
    assert_workbook_has_dashboard,
    assert_datasource_has_calculated_field,
)

def test_workbook_structure(workbook_fixture):
    """ワークブックの基本構造をテスト"""
    workbook = workbook_fixture
    
    # データソースの確認
    data_ds = assert_workbook_has_datasource(
        workbook, "mock_datasource"
    )
    
    # 計算フィールドの確認
    assert_datasource_has_calculated_field(
        data_ds, "mock_calculated_field"
    )
    
    # ワークシートの確認
    sheet = assert_workbook_has_sheet(workbook, "mock_sheet")
    assert sheet.mark_type == "bar"
    
    # ダッシュボードの確認
    dashboard = assert_workbook_has_dashboard(workbook, "mock_dashboard")
    assert dashboard.size_width == 1200
    assert dashboard.size_height == 800
```

### 3. 利用可能なフィクスチャ

#### 汎用フィクスチャ(tabtestライブラリ提供)

pytestで以下の汎用フィクスチャが利用できます:

- `workbook_parser`: カスタムワークブックパーサー
- `workbook`: 解析済みワークブック
- `workbook_fixture`: モックワークブック(tests/assets/mock_workbook.twb)

使用方法:
```python
@pytest.mark.parametrize("workbook_parser", ["./path/to/your/workbook.twb"], indirect=True)
def test_workbook(workbook_parser):
    assert workbook_parser.workbook.name == "Expected Name"

@pytest.mark.parametrize("workbook_parser", ["./path/to/your/workbook.twb"], indirect=True)
def test_workbook(workbook):
    assert workbook.name == "Expected Name"
    assert len(workbook.datasources) > 0

def test_with_mock_workbook(workbook_fixture):
    """モックワークブックを使用したテスト"""
    workbook = workbook_fixture
    assert workbook.name == "Mock Workbook"
    assert len(workbook.datasources) > 0
```

#### ユーザー固有フィクスチャ

ユーザーは`tests/fixtures.py`で固有のフィクスチャを定義できます:

```python
# tests/fixtures.py
import pytest
from tabtest import WorkbookParser

@pytest.fixture
def my_workbook():
    """ユーザー固有のワークブックフィクスチャ"""
    parser = WorkbookParser("./path/to/your/workbook.twb")
    return parser.workbook
```

### 4. ヘルパー関数

以下のヘルパー関数が利用できます:

```python
from tabtest.suite.helpers import (
    # ワークブックレベル
    assert_workbook_has_datasource,
    assert_workbook_has_sheet,
    assert_workbook_has_dashboard,
    
    # データソースレベル
    assert_datasource_has_field,
    assert_datasource_has_calculated_field,
    
    # ワークシートレベル
    assert_sheet_has_field_in_rows,
    assert_sheet_has_field_in_columns,
    assert_sheet_has_filter,
    
    # ダッシュボードレベル
    assert_dashboard_contains_sheet,
)
```

## データモデル

### WorkbookModel

ワークブック全体の情報を表すモデルです。

```python
class WorkbookModel:
    name: str                    # ワークブック名
    datasources: List[DatasourceModel]  # データソース一覧
    sheets: Dict[str, WorksheetModel]   # ワークシート一覧
    dashboards: List[DashboardModel]    # ダッシュボード一覧
    parameters: List[ParameterModel]     # パラメータ一覧
```

### DatasourceModel

データソースの情報を表すモデルです。

```python
class DatasourceModel:
    name: Optional[str]          # データソース名
    caption: Optional[str]       # キャプション
    fields: List[DatasourceFieldModel]  # フィールド一覧
```

### WorksheetModel

ワークシートの情報を表すモデルです。

```python
class WorksheetModel:
    name: str                    # ワークシート名
    datasource_name: str         # データソース名
    filters: List[FilterModel]   # フィルター一覧
    rows: List[str]              # 行に配置されたフィールド
    columns: List[str]           # 列に配置されたフィールド
    mark_type: Optional[str]     # マークタイプ
```

### DashboardModel

ダッシュボードの情報を表すモデルです。

```python
class DashboardModel:
    name: Optional[str]          # ダッシュボード名
    dashboard_sheets: List[DashboardSheetModel]  # ダッシュボード内のワークシート
    size_width: int              # ダッシュボード幅
    size_height: int             # ダッシュボード高さ
```

## 使用例

詳細な使用例は`examples/`ディレクトリを参照してください:

- `examples/basic_usage.py`: 基本的な使用方法
- `examples/pytest_example.py`: pytestでのテスト例

## 開発

### セットアップ

```bash
# リポジトリをクローン
git clone https://github.com/your-username/tabtest.git
cd tabtest

# 仮想環境を作成
python -m venv .venv
source .venv/bin/activate  # Linux/Mac
# または
.venv\Scripts\activate     # Windows

# 依存関係をインストール
pip install -e .
pip install -e ".[dev]"
```

### テストの実行

```bash
# すべてのテストを実行
pytest

# 特定のテストファイルを実行
pytest tests/test_workbook_parser.py

# 詳細な出力でテストを実行
pytest -v
```

### コード品質チェック

```bash
# リンターを実行
ruff check .

# 型チェックを実行
mypy .

# フォーマットを実行
ruff format .
```

## ライセンス

このプロジェクトはMITライセンスの下で公開されています。

## 貢献

プルリクエストやイシューの報告を歓迎します。貢献する前に、以下の手順を確認してください:

1. このリポジトリをフォーク
2. 機能ブランチを作成 (`git checkout -b feature/amazing-feature`)
3. 変更をコミット (`git commit -m 'Add some amazing feature'`)
4. ブランチにプッシュ (`git push origin feature/amazing-feature`)
5. プルリクエストを作成

## サポート

問題や質問がある場合は、GitHubのイシューを作成してください。

## ライセンス

MIT License

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "tabtest",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "tableau, twb, twbx, parser, testing",
    "author": null,
    "author_email": "Kamegrueon <niwaniwaniwaniwatori.gairuze@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/a4/cb/54f8735a0065c153b25a1115167b515814b1560091ce68681050d3ef0ccd/tabtest-0.1.0.tar.gz",
    "platform": null,
    "description": "# tabtest\n\nTableau\u306e`.twb`/`.twbx`\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u3057\u3001pytest\u3067\u30c6\u30b9\u30c8\u3092\u5b9f\u884c\u3067\u304d\u308bPython\u30e9\u30a4\u30d6\u30e9\u30ea\u3067\u3059\u3002\n\n## \u6982\u8981\n\ntabtest\u306f\u3001Tableau\u30ef\u30fc\u30af\u30d6\u30c3\u30af\u306e\u69cb\u9020\u3092\u89e3\u6790\u3057\u3001pytest\u3092\u4f7f\u7528\u3057\u3066\u30ef\u30fc\u30af\u30d6\u30c3\u30af\u306e\u5185\u5bb9\u3092\u30c6\u30b9\u30c8\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\u30c4\u30fc\u30eb\u3067\u3059\u3002\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u30c6\u30b9\u30c8\u304c\u53ef\u80fd\u3067\u3059\uff1a\n\n- \u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u5b58\u5728\u78ba\u8a8d\n- \u8a08\u7b97\u30d5\u30a3\u30fc\u30eb\u30c9\u306e\u5b58\u5728\u78ba\u8a8d\n- \u30ef\u30fc\u30af\u30b7\u30fc\u30c8\u306e\u8a2d\u5b9a\u78ba\u8a8d\n- \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u306e\u30ec\u30a4\u30a2\u30a6\u30c8\u78ba\u8a8d\n- \u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u8a2d\u5b9a\u78ba\u8a8d\n- \u30d5\u30a3\u30eb\u30bf\u30fc\u306e\u8a2d\u5b9a\u78ba\u8a8d\n\n## \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n\n```bash\npip install tabtest\n```\n\n## \u57fa\u672c\u7684\u306a\u4f7f\u7528\u65b9\u6cd5\n\n### 1. \u30ef\u30fc\u30af\u30d6\u30c3\u30af\u306e\u89e3\u6790\n\n```python\nfrom tabtest import WorkbookParser\n\n# \u30ef\u30fc\u30af\u30d6\u30c3\u30af\u3092\u89e3\u6790\nparser = WorkbookParser(\"./path/to/your/workbook.twb\")\nworkbook = parser.workbook\n\n# \u57fa\u672c\u60c5\u5831\u306e\u78ba\u8a8d\nprint(f\"\u30ef\u30fc\u30af\u30d6\u30c3\u30af\u540d: {workbook.name}\")\nprint(f\"\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u6570: {len(workbook.datasources)}\")\nprint(f\"\u30ef\u30fc\u30af\u30b7\u30fc\u30c8\u6570: {len(workbook.sheets)}\")\nprint(f\"\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u6570: {len(workbook.dashboards)}\")\n```\n\n### 2. pytest\u3067\u306e\u30c6\u30b9\u30c8\n\n```python\nimport pytest\nfrom tabtest.suite.helpers import (\n    assert_workbook_has_datasource,\n    assert_workbook_has_sheet,\n    assert_workbook_has_dashboard,\n    assert_datasource_has_calculated_field,\n)\n\ndef test_workbook_structure(workbook_fixture):\n    \"\"\"\u30ef\u30fc\u30af\u30d6\u30c3\u30af\u306e\u57fa\u672c\u69cb\u9020\u3092\u30c6\u30b9\u30c8\"\"\"\n    workbook = workbook_fixture\n    \n    # \u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u78ba\u8a8d\n    data_ds = assert_workbook_has_datasource(\n        workbook, \"mock_datasource\"\n    )\n    \n    # \u8a08\u7b97\u30d5\u30a3\u30fc\u30eb\u30c9\u306e\u78ba\u8a8d\n    assert_datasource_has_calculated_field(\n        data_ds, \"mock_calculated_field\"\n    )\n    \n    # \u30ef\u30fc\u30af\u30b7\u30fc\u30c8\u306e\u78ba\u8a8d\n    sheet = assert_workbook_has_sheet(workbook, \"mock_sheet\")\n    assert sheet.mark_type == \"bar\"\n    \n    # \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u306e\u78ba\u8a8d\n    dashboard = assert_workbook_has_dashboard(workbook, \"mock_dashboard\")\n    assert dashboard.size_width == 1200\n    assert dashboard.size_height == 800\n```\n\n### 3. \u5229\u7528\u53ef\u80fd\u306a\u30d5\u30a3\u30af\u30b9\u30c1\u30e3\n\n#### \u6c4e\u7528\u30d5\u30a3\u30af\u30b9\u30c1\u30e3\uff08tabtest\u30e9\u30a4\u30d6\u30e9\u30ea\u63d0\u4f9b\uff09\n\npytest\u3067\u4ee5\u4e0b\u306e\u6c4e\u7528\u30d5\u30a3\u30af\u30b9\u30c1\u30e3\u304c\u5229\u7528\u3067\u304d\u307e\u3059\uff1a\n\n- `workbook_parser`: \u30ab\u30b9\u30bf\u30e0\u30ef\u30fc\u30af\u30d6\u30c3\u30af\u30d1\u30fc\u30b5\u30fc\n- `workbook`: \u89e3\u6790\u6e08\u307f\u30ef\u30fc\u30af\u30d6\u30c3\u30af\n- `workbook_fixture`: \u30e2\u30c3\u30af\u30ef\u30fc\u30af\u30d6\u30c3\u30af\uff08tests/assets/mock_workbook.twb\uff09\n\n\u4f7f\u7528\u65b9\u6cd5\uff1a\n```python\n@pytest.mark.parametrize(\"workbook_parser\", [\"./path/to/your/workbook.twb\"], indirect=True)\ndef test_workbook(workbook_parser):\n    assert workbook_parser.workbook.name == \"Expected Name\"\n\n@pytest.mark.parametrize(\"workbook_parser\", [\"./path/to/your/workbook.twb\"], indirect=True)\ndef test_workbook(workbook):\n    assert workbook.name == \"Expected Name\"\n    assert len(workbook.datasources) > 0\n\ndef test_with_mock_workbook(workbook_fixture):\n    \"\"\"\u30e2\u30c3\u30af\u30ef\u30fc\u30af\u30d6\u30c3\u30af\u3092\u4f7f\u7528\u3057\u305f\u30c6\u30b9\u30c8\"\"\"\n    workbook = workbook_fixture\n    assert workbook.name == \"Mock Workbook\"\n    assert len(workbook.datasources) > 0\n```\n\n#### \u30e6\u30fc\u30b6\u30fc\u56fa\u6709\u30d5\u30a3\u30af\u30b9\u30c1\u30e3\n\n\u30e6\u30fc\u30b6\u30fc\u306f`tests/fixtures.py`\u3067\u56fa\u6709\u306e\u30d5\u30a3\u30af\u30b9\u30c1\u30e3\u3092\u5b9a\u7fa9\u3067\u304d\u307e\u3059\uff1a\n\n```python\n# tests/fixtures.py\nimport pytest\nfrom tabtest import WorkbookParser\n\n@pytest.fixture\ndef my_workbook():\n    \"\"\"\u30e6\u30fc\u30b6\u30fc\u56fa\u6709\u306e\u30ef\u30fc\u30af\u30d6\u30c3\u30af\u30d5\u30a3\u30af\u30b9\u30c1\u30e3\"\"\"\n    parser = WorkbookParser(\"./path/to/your/workbook.twb\")\n    return parser.workbook\n```\n\n### 4. \u30d8\u30eb\u30d1\u30fc\u95a2\u6570\n\n\u4ee5\u4e0b\u306e\u30d8\u30eb\u30d1\u30fc\u95a2\u6570\u304c\u5229\u7528\u3067\u304d\u307e\u3059\uff1a\n\n```python\nfrom tabtest.suite.helpers import (\n    # \u30ef\u30fc\u30af\u30d6\u30c3\u30af\u30ec\u30d9\u30eb\n    assert_workbook_has_datasource,\n    assert_workbook_has_sheet,\n    assert_workbook_has_dashboard,\n    \n    # \u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30ec\u30d9\u30eb\n    assert_datasource_has_field,\n    assert_datasource_has_calculated_field,\n    \n    # \u30ef\u30fc\u30af\u30b7\u30fc\u30c8\u30ec\u30d9\u30eb\n    assert_sheet_has_field_in_rows,\n    assert_sheet_has_field_in_columns,\n    assert_sheet_has_filter,\n    \n    # \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u30ec\u30d9\u30eb\n    assert_dashboard_contains_sheet,\n)\n```\n\n## \u30c7\u30fc\u30bf\u30e2\u30c7\u30eb\n\n### WorkbookModel\n\n\u30ef\u30fc\u30af\u30d6\u30c3\u30af\u5168\u4f53\u306e\u60c5\u5831\u3092\u8868\u3059\u30e2\u30c7\u30eb\u3067\u3059\u3002\n\n```python\nclass WorkbookModel:\n    name: str                    # \u30ef\u30fc\u30af\u30d6\u30c3\u30af\u540d\n    datasources: List[DatasourceModel]  # \u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u4e00\u89a7\n    sheets: Dict[str, WorksheetModel]   # \u30ef\u30fc\u30af\u30b7\u30fc\u30c8\u4e00\u89a7\n    dashboards: List[DashboardModel]    # \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u4e00\u89a7\n    parameters: List[ParameterModel]     # \u30d1\u30e9\u30e1\u30fc\u30bf\u4e00\u89a7\n```\n\n### DatasourceModel\n\n\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u60c5\u5831\u3092\u8868\u3059\u30e2\u30c7\u30eb\u3067\u3059\u3002\n\n```python\nclass DatasourceModel:\n    name: Optional[str]          # \u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d\n    caption: Optional[str]       # \u30ad\u30e3\u30d7\u30b7\u30e7\u30f3\n    fields: List[DatasourceFieldModel]  # \u30d5\u30a3\u30fc\u30eb\u30c9\u4e00\u89a7\n```\n\n### WorksheetModel\n\n\u30ef\u30fc\u30af\u30b7\u30fc\u30c8\u306e\u60c5\u5831\u3092\u8868\u3059\u30e2\u30c7\u30eb\u3067\u3059\u3002\n\n```python\nclass WorksheetModel:\n    name: str                    # \u30ef\u30fc\u30af\u30b7\u30fc\u30c8\u540d\n    datasource_name: str         # \u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d\n    filters: List[FilterModel]   # \u30d5\u30a3\u30eb\u30bf\u30fc\u4e00\u89a7\n    rows: List[str]              # \u884c\u306b\u914d\u7f6e\u3055\u308c\u305f\u30d5\u30a3\u30fc\u30eb\u30c9\n    columns: List[str]           # \u5217\u306b\u914d\u7f6e\u3055\u308c\u305f\u30d5\u30a3\u30fc\u30eb\u30c9\n    mark_type: Optional[str]     # \u30de\u30fc\u30af\u30bf\u30a4\u30d7\n```\n\n### DashboardModel\n\n\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u306e\u60c5\u5831\u3092\u8868\u3059\u30e2\u30c7\u30eb\u3067\u3059\u3002\n\n```python\nclass DashboardModel:\n    name: Optional[str]          # \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u540d\n    dashboard_sheets: List[DashboardSheetModel]  # \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u5185\u306e\u30ef\u30fc\u30af\u30b7\u30fc\u30c8\n    size_width: int              # \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u5e45\n    size_height: int             # \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u9ad8\u3055\n```\n\n## \u4f7f\u7528\u4f8b\n\n\u8a73\u7d30\u306a\u4f7f\u7528\u4f8b\u306f`examples/`\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\uff1a\n\n- `examples/basic_usage.py`: \u57fa\u672c\u7684\u306a\u4f7f\u7528\u65b9\u6cd5\n- `examples/pytest_example.py`: pytest\u3067\u306e\u30c6\u30b9\u30c8\u4f8b\n\n## \u958b\u767a\n\n### \u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\n\n```bash\n# \u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u30af\u30ed\u30fc\u30f3\ngit clone https://github.com/your-username/tabtest.git\ncd tabtest\n\n# \u4eee\u60f3\u74b0\u5883\u3092\u4f5c\u6210\npython -m venv .venv\nsource .venv/bin/activate  # Linux/Mac\n# \u307e\u305f\u306f\n.venv\\Scripts\\activate     # Windows\n\n# \u4f9d\u5b58\u95a2\u4fc2\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\npip install -e .\npip install -e \".[dev]\"\n```\n\n### \u30c6\u30b9\u30c8\u306e\u5b9f\u884c\n\n```bash\n# \u3059\u3079\u3066\u306e\u30c6\u30b9\u30c8\u3092\u5b9f\u884c\npytest\n\n# \u7279\u5b9a\u306e\u30c6\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u5b9f\u884c\npytest tests/test_workbook_parser.py\n\n# \u8a73\u7d30\u306a\u51fa\u529b\u3067\u30c6\u30b9\u30c8\u3092\u5b9f\u884c\npytest -v\n```\n\n### \u30b3\u30fc\u30c9\u54c1\u8cea\u30c1\u30a7\u30c3\u30af\n\n```bash\n# \u30ea\u30f3\u30bf\u30fc\u3092\u5b9f\u884c\nruff check .\n\n# \u578b\u30c1\u30a7\u30c3\u30af\u3092\u5b9f\u884c\nmypy .\n\n# \u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3092\u5b9f\u884c\nruff format .\n```\n\n## \u30e9\u30a4\u30bb\u30f3\u30b9\n\n\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306fMIT\u30e9\u30a4\u30bb\u30f3\u30b9\u306e\u4e0b\u3067\u516c\u958b\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n\n## \u8ca2\u732e\n\n\u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u3084\u30a4\u30b7\u30e5\u30fc\u306e\u5831\u544a\u3092\u6b53\u8fce\u3057\u307e\u3059\u3002\u8ca2\u732e\u3059\u308b\u524d\u306b\u3001\u4ee5\u4e0b\u306e\u624b\u9806\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\uff1a\n\n1. \u3053\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u30d5\u30a9\u30fc\u30af\n2. \u6a5f\u80fd\u30d6\u30e9\u30f3\u30c1\u3092\u4f5c\u6210 (`git checkout -b feature/amazing-feature`)\n3. \u5909\u66f4\u3092\u30b3\u30df\u30c3\u30c8 (`git commit -m 'Add some amazing feature'`)\n4. \u30d6\u30e9\u30f3\u30c1\u306b\u30d7\u30c3\u30b7\u30e5 (`git push origin feature/amazing-feature`)\n5. \u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u4f5c\u6210\n\n## \u30b5\u30dd\u30fc\u30c8\n\n\u554f\u984c\u3084\u8cea\u554f\u304c\u3042\u308b\u5834\u5408\u306f\u3001GitHub\u306e\u30a4\u30b7\u30e5\u30fc\u3092\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n\n## \u30e9\u30a4\u30bb\u30f3\u30b9\n\nMIT License\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Tableau \u306e .twb .twbx \u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u30fb\u30c6\u30b9\u30c8\u3059\u308b\u30c4\u30fc\u30eb",
    "version": "0.1.0",
    "project_urls": {
        "Documentation": "https://github.com/Kamegrueon/tabtest#readme",
        "Homepage": "https://github.com/Kamegrueon/tabtest",
        "Issues": "https://github.com/Kamegrueon/tabtest/issues",
        "Repository": "https://github.com/Kamegrueon/tabtest"
    },
    "split_keywords": [
        "tableau",
        " twb",
        " twbx",
        " parser",
        " testing"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bfbc4429b1552492bc81b8cba0773505548c3ad004daa41430fbb4396d3da654",
                "md5": "5bcd9d4410e670fc57a24831ec9bd4be",
                "sha256": "e19821464af59e2576ffca4c800d0578754b0489549eb769b3161c525cf7a6aa"
            },
            "downloads": -1,
            "filename": "tabtest-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5bcd9d4410e670fc57a24831ec9bd4be",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 29562,
            "upload_time": "2025-08-31T14:53:10",
            "upload_time_iso_8601": "2025-08-31T14:53:10.705978Z",
            "url": "https://files.pythonhosted.org/packages/bf/bc/4429b1552492bc81b8cba0773505548c3ad004daa41430fbb4396d3da654/tabtest-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a4cb54f8735a0065c153b25a1115167b515814b1560091ce68681050d3ef0ccd",
                "md5": "a055672a792ee0c1ca3b30f6210d76de",
                "sha256": "5e2029b132d347210c7cbf0a966facf20d6298deb882814e66fea5c71a964368"
            },
            "downloads": -1,
            "filename": "tabtest-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "a055672a792ee0c1ca3b30f6210d76de",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 32774,
            "upload_time": "2025-08-31T14:53:12",
            "upload_time_iso_8601": "2025-08-31T14:53:12.272356Z",
            "url": "https://files.pythonhosted.org/packages/a4/cb/54f8735a0065c153b25a1115167b515814b1560091ce68681050d3ef0ccd/tabtest-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-31 14:53:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Kamegrueon",
    "github_project": "tabtest#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "lxml",
            "specs": [
                [
                    ">=",
                    "5.4.0"
                ]
            ]
        },
        {
            "name": "pydantic",
            "specs": [
                [
                    ">=",
                    "2.11.7"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    ">=",
                    "8.4.1"
                ]
            ]
        }
    ],
    "lcname": "tabtest"
}
        
Elapsed time: 4.04585s