tree_haver 4.0.5 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3f6764cb2c0399f4255cc4536745156cd8391fa1818b9b84db9d0b39ca17fa9
4
- data.tar.gz: d9e12364a4480307b8cd8a7ca0315bbeba7764c6bfe20747b3b8ff792e9fe2e7
3
+ metadata.gz: bf24354cab86e375d66426a05aa6afa5d852bc1941a8fe1235f0647a89891e77
4
+ data.tar.gz: 25f91798a18044f1e0b1b5deb83cc61fe734bd05f7391225a36dd11dbb47a941
5
5
  SHA512:
6
- metadata.gz: 6a95af29f397cea98bc29a93885f9285637ae82469417b62c981629d21861f5b64560ca0e2c21b0405abdc541d04b39f6c1848928273b82679ba3f169f885549
7
- data.tar.gz: bbd048585aed007eed86bdd117b18cff1e72e378fd20bbc07a252b6095ab38d4c5c9eb83fc572c21bcd07e515b2ad1bfae50f9705b75f69f4d955ecf65d4b844
6
+ metadata.gz: dcd6d8d3e481bd1e5201a83441d63d41af9be368eb8c746e7d27a44dfa7cb76345a014f7a426557e40c1becfecf9f9e9f60176d8c6d53a57978077146137f13d
7
+ data.tar.gz: 5f1dc4d8844b5da005d5d1ef59ac3a74c1794ee95d25de1c5c67a13198f671a06ad45ce82d3530e875230374339c5a749f2a3e96ffe555b194a05b7a6cc4a4ef
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ed# Changelog
1
+ # Changelog
2
2
 
3
3
  [![SemVer 2.0.0][📌semver-img]][📌semver] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog]
4
4
 
@@ -30,6 +30,195 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [5.0.1] - 2026-01-11
34
+
35
+ - TAG: [v5.0.1][5.0.1t]
36
+ - COVERAGE: 90.79% -- 2308/2542 lines in 30 files
37
+ - BRANCH COVERAGE: 78.09% -- 930/1191 branches in 30 files
38
+ - 94.76% documented
39
+
40
+ ### Added
41
+
42
+ - `TreeHaver::RSpec::TestableNode` - A testable node class for creating mock TreeHaver::Node instances
43
+ in tests without requiring an actual parser backend. Available via `require "tree_haver/rspec/testable_node"`
44
+ or automatically when using `require "tree_haver/rspec"`.
45
+ - `TestableNode.create(type:, text:, ...)` - Create a single test node
46
+ - `TestableNode.create_list(...)` - Create multiple test nodes
47
+ - `MockInnerNode` - The underlying mock that simulates backend-specific nodes
48
+ - Top-level `TestableNode` constant for convenience in specs
49
+ - **Fully Dynamic Tag Registration** in `TreeHaver::BackendRegistry`:
50
+ - `register_tag(tag_name, category:, backend_name:, require_path:)` - Register a complete dependency tag
51
+ with lazy loading support. External gems can now get full RSpec tag support without any hardcoded
52
+ knowledge in tree_haver.
53
+ - `tag_available?(tag_name)` - Check if a tag's dependency is available, with automatic lazy loading
54
+ via the registered `require_path`
55
+ - `registered_tags` - Get all registered tag names
56
+ - `tags_by_category(category)` - Get tags filtered by category (:backend, :gem, :parsing, :grammar, :engine, :other)
57
+ - `tag_metadata(tag_name)` - Get full metadata for a registered tag
58
+ - `tag_summary` - Get availability status of all registered tags
59
+
60
+ ### Changed
61
+
62
+ - **Fully Dynamic Backend Availability** in `BackendRegistry` and `DependencyTags`:
63
+ - `register_tag` now dynamically defines `*_available?` methods on `DependencyTags` at registration time
64
+ - External gems automatically get availability methods when they call `register_tag`
65
+ - No changes to tree_haver are needed for new external backend gems
66
+ - Built-in backends (prism, psych, citrus, parslet) retain explicit methods
67
+ - `summary` method dynamically includes registered backends from BackendRegistry
68
+ - `backend_availability_methods` and `backend_tags` hashes are built dynamically
69
+ - RSpec exclusion filters for backend tags are configured dynamically from BackendRegistry
70
+
71
+ ### Fixed
72
+
73
+ - **`TreeHaver::Parser#unwrap_language` bug fix for MRI and Rust backends**
74
+ - `:mri` and `:rust` cases were not returning the unwrapped language value
75
+ - The code called `lang.to_language` / `lang.inner_language` / `lang.name` but didn't `return` the result
76
+ - Now properly returns the unwrapped language for all backend types
77
+ - `any_markdown_backend_available?` now uses `BackendRegistry.tag_available?` instead of calling
78
+ `markly_available?` and `commonmarker_available?` directly. This fixes `NoMethodError` when
79
+ the external markdown backend gems haven't registered their tags yet.
80
+
81
+ ## [5.0.0] - 2026-01-11
82
+
83
+ - TAG: [v5.0.0][5.0.0t]
84
+ - COVERAGE: 92.04% -- 2289/2487 lines in 30 files
85
+ - BRANCH COVERAGE: 79.33% -- 929/1171 branches in 30 files
86
+ - 96.21% documented
87
+
88
+ ### Added
89
+
90
+ - **Shared Example Groups for Backend API Compliance Testing**
91
+ - `node_api_examples.rb` - Tests for Node API compliance:
92
+ - `"node api compliance"` - Core Node interface (type, start_byte, end_byte, children)
93
+ - `"node position api"` - Position API (start_point, end_point, start_line, end_line, source_position)
94
+ - `"node children api"` - Children traversal (#child, #first_child, #last_child)
95
+ - `"node enumerable behavior"` - Enumerable methods (#each, #map, #select, #find)
96
+ - `"node comparison behavior"` - Comparison and equality (#==, #<=>, #hash)
97
+ - `"node text extraction"` - Text content (#text, #to_s)
98
+ - `"node inspection"` - Debug output (#inspect)
99
+ - `tree_api_examples.rb` - Tests for Tree API compliance:
100
+ - `"tree api compliance"` - Core Tree interface (root_node, source, errors, warnings, comments)
101
+ - `"tree error handling"` - Error detection (#has_error?, #errors)
102
+ - `"tree traversal"` - Depth-first traversal via root_node
103
+ - `parser_api_examples.rb` - Tests for Parser API compliance:
104
+ - `"parser api compliance"` - Core Parser interface (#parse, #parse_string, #language=)
105
+ - `"parser incremental parsing"` - Incremental parsing support
106
+ - `"parser error handling"` - Error recovery behavior
107
+ - `language_api_examples.rb` - Tests for Language API compliance:
108
+ - `"language api compliance"` - Core Language interface (#backend, #name/#language_name)
109
+ - `"language comparison"` - Comparison and equality
110
+ - `"language factory methods"` - Factory methods (.from_library, .from_path)
111
+ - `backend_api_examples.rb` - Tests for Backend module API compliance:
112
+ - `"backend module api"` - Backend availability and capabilities
113
+ - `"backend class structure"` - Nested class verification
114
+ - `"backend integration"` - Full parse cycle testing
115
+ - `spec/support/shared_examples.rb` - Master loader for all shared examples
116
+ - `spec/integration/backend_api_compliance_spec.rb` - Integration tests using all shared examples
117
+ - **Parslet Backend**: New pure Ruby PEG parser backend (`TreeHaver::Backends::Parslet`)
118
+ - Wraps Parslet-based parsers (like the `toml` gem) to provide a pure Ruby alternative to tree-sitter
119
+ - `Parslet.available?` - Check if parslet gem is available
120
+ - `Parslet.capabilities` - Returns `{ backend: :parslet, query: false, bytes_field: true, incremental: false, pure_ruby: true }`
121
+ - `Parslet::Language` - Wrapper for Parslet grammar classes
122
+ - `Language.new(grammar_class)` - Create from a Parslet::Parser subclass
123
+ - `Language.from_library(path, symbol:, name:)` - API-compatible lookup via LanguageRegistry
124
+ - `#language_name` / `#name` - Derive language name from grammar class
125
+ - `Parslet::Parser` - Wrapper that creates parser instances from grammar classes
126
+ - Accepts both raw grammar class and Language wrapper (normalized API)
127
+ - `Parslet::Tree` - Wraps Parslet parse results, inherits from `Base::Tree`
128
+ - `Parslet::Node` - Unified node interface, inherits from `Base::Node`
129
+ - Supports both Hash nodes (with named children) and Array nodes (with indexed children)
130
+ - `#type` - Returns the node type (key name or "array"/"document")
131
+ - `#children` - Returns child nodes
132
+ - `#child_by_field_name(name)` - Access named children in Hash nodes
133
+ - `#text` - Returns the matched text from Parslet::Slice
134
+ - `#start_byte`, `#end_byte` - Byte positions from Parslet::Slice
135
+ - `#start_point`, `#end_point` - Line/column positions (computed from source)
136
+ - Registered with `BackendRegistry.register_availability_checker(:parslet)`
137
+ - **RSpec Dependency Tags**: Added `parslet_available?` method
138
+ - Checks if parslet gem is installed via `BackendRegistry.available?(:parslet)`
139
+ - `:parslet_backend` tag for specs requiring Parslet
140
+ - `:not_parslet_backend` negated tag for specs that should skip when Parslet is available
141
+ - **RSpec Dependency Tags**: Added `toml_gem_available?` method and updated `any_toml_backend_available?`
142
+ - `:toml_gem` tag for specs requiring the `toml` gem to be available
143
+ - `:not_toml_gem` negated tag for specs that should skip when the `toml` gem is not available
144
+ - **ParsletGrammarFinder**: Utility for discovering and registering Parslet grammar gems
145
+ - `ParsletGrammarFinder.new(language:, gem_name:, grammar_const:, require_path:)` - Find Parslet grammars
146
+ - `#available?` - Check if the Parslet grammar gem is installed and functional
147
+ - `#grammar_class` - Get the resolved Parslet::Parser subclass
148
+ - `#register!` - Register the grammar with TreeHaver
149
+ - Auto-loads via `TreeHaver::PARSLET_DEFAULTS` for known languages (toml)
150
+ - **TreeHaver.register_language**: Extended with `grammar_class:` parameter for Parslet grammars
151
+ - **TreeHaver.parser_for**: Extended with `parslet_config:` parameter for explicit Parslet configuration
152
+ - `MRI::Language#language_name` / `#name` - Derive language name from symbol or path
153
+ - `FFI::Language#language_name` / `#name` - Derive language name from symbol or path
154
+ - **spec_helper.rb**: Added `require "toml"` to load the toml gem for Parslet backend tests
155
+
156
+ ### Changed
157
+
158
+ - **BREAKING: `TreeHaver::Language` converted from class to module**
159
+ - Previously `TreeHaver::Language` was a class that wrapped backend language objects
160
+ - Now `TreeHaver::Language` is a module providing factory methods (`method_missing` for dynamic language loading)
161
+ - Backend-specific language classes (e.g., `TreeHaver::Backends::MRI::Language`) are now the concrete implementations
162
+ - Code that instantiated `TreeHaver::Language.new(...)` directly must be updated to use backend-specific classes or the factory methods
163
+ - **BREAKING: `TreeHaver::Tree` now inherits from `TreeHaver::Base::Tree`**
164
+ - `TreeHaver::Tree` is now a proper subclass of `TreeHaver::Base::Tree`
165
+ - Inherits `inner_tree`, `source`, `lines` attributes from base class
166
+ - Base class provides default implementations; subclass documents divergence
167
+ - **BREAKING: `TreeHaver::Node` now inherits from `TreeHaver::Base::Node`**
168
+ - `TreeHaver::Node` is now a proper subclass of `TreeHaver::Base::Node`
169
+ - Inherits `inner_node`, `source`, `lines` attributes from base class
170
+ - Base class documents the API contract; subclass documents divergence
171
+ - **BREAKING: `Citrus::Node` and `Citrus::Tree` now inherit from Base classes**
172
+ - `Citrus::Node` now inherits from `TreeHaver::Base::Node`
173
+ - `Citrus::Tree` now inherits from `TreeHaver::Base::Tree`
174
+ - Removes duplicated methods, uses inherited implementations
175
+ - Adds `#language_name` / `#name` methods for API compliance
176
+ - **BREAKING: `Parslet::Node` and `Parslet::Tree` now inherit from Base classes**
177
+ - `Parslet::Node` now inherits from `TreeHaver::Base::Node`
178
+ - `Parslet::Tree` now inherits from `TreeHaver::Base::Tree`
179
+ - Removes duplicated methods, uses inherited implementations
180
+ - **Base::Node#child now returns nil for negative indices** (tree-sitter API compatibility)
181
+ - **Citrus::Parser#language= now accepts Language wrapper or raw grammar module**
182
+ - Both patterns now work: `parser.language = TomlRB::Document` or `parser.language = Citrus::Language.new(TomlRB::Document)`
183
+ - **Parslet::Parser#language= now accepts Language wrapper or raw grammar class**
184
+ - Both patterns now work: `parser.language = TOML::Parslet` or `parser.language = Parslet::Language.new(TOML::Parslet)`
185
+ - **TreeHaver::Parser#unwrap_language** now passes Language wrappers directly to Citrus/Parslet backends
186
+ - Previously unwrapped to raw grammar; now backends handle their own Language wrappers
187
+ - **Language.method_missing**: Now recognizes `:parslet` backend type and creates `Parslet::Language` instances
188
+ - **Parser**: Updated to recognize Parslet languages and switch to Parslet parser automatically
189
+ - `#backend` now returns `:parslet` for Parslet-based parsers
190
+ - `#language=` detects `Parslet::Language` and switches implementation
191
+ - `handle_parser_creation_failure` tries Parslet as fallback after Citrus
192
+ - `unwrap_language` extracts `grammar_class` for Parslet languages
193
+
194
+ ### Fixed
195
+
196
+ - **FFI Backend Compliance Tests**: Fixed tests to use `TreeHaver::Parser` wrapper instead of raw `FFI::Parser`
197
+ - Raw FFI classes (`FFI::Tree`, `FFI::Node`) don't have full API (missing `#children`, `#text`, `#source`, etc.)
198
+ - TreeHaver wrapper classes (`TreeHaver::Tree`, `TreeHaver::Node`) provide the complete unified API
199
+ - Tests now properly test the wrapped API that users actually interact with
200
+ - **Parslet TOML Sources**: Fixed test sources to be valid for the `toml` gem's Parslet grammar
201
+ - Grammar requires table sections (not bare key-value pairs at root)
202
+ - Grammar requires trailing newlines
203
+ - **Examples**: Fixed broken markdown examples that referenced non-existent TreeHaver backends
204
+ - `commonmarker_markdown.rb` - Rewrote to use commonmarker gem directly (not a TreeHaver backend)
205
+ - `markly_markdown.rb` - Rewrote to use markly gem directly with correct `source_position` API
206
+ - `commonmarker_merge_example.rb` - Fixed to use `commonmarker/merge` gem properly
207
+ - `markly_merge_example.rb` - Fixed to use `markly/merge` gem properly
208
+ - `parslet_toml.rb` - Rewrote to properly use TreeHaver's Parslet backend with language registration
209
+ - **Examples**: Fixed `run_all.rb` test runner
210
+ - Added parslet example to the test list
211
+ - Changed markdown examples to use `backend: "standalone"` (they're not TreeHaver backends)
212
+ - Added MRI+TOML to known incompatibilities (parse returns nil)
213
+ - Added proper skip reason messages for all known incompatibilities
214
+ - **Examples**: Updated `examples/README.md` documentation
215
+ - Added Parslet backend section with usage examples
216
+ - Renamed "Commonmarker Backend" and "Markly Backend" to "Commonmarker (Standalone)" and "Markly (Standalone)"
217
+ - Clarified that commonmarker and markly are standalone parsers, not TreeHaver backends
218
+ - **Duplicate Constants**: Removed duplicate `CITRUS_DEFAULTS` and `PARSLET_DEFAULTS` definitions
219
+ - Constants were defined twice in `tree_haver.rb` (lines 170 and 315)
220
+ - This was causing "already initialized constant" warnings on every require
221
+
33
222
  ## [4.0.5] - 2026-01-09
34
223
 
35
224
  - TAG: [v4.0.5][4.0.5t]
@@ -1070,7 +1259,11 @@ Despite the major version bump to 3.0.0 (following semver due to the breaking `L
1070
1259
 
1071
1260
  - Initial release
1072
1261
 
1073
- [Unreleased]: https://github.com/kettle-rb/tree_haver/compare/v4.0.5...HEAD
1262
+ [Unreleased]: https://github.com/kettle-rb/tree_haver/compare/v5.0.1...HEAD
1263
+ [5.0.1]: https://github.com/kettle-rb/tree_haver/compare/v5.0.0...v5.0.1
1264
+ [5.0.1t]: https://github.com/kettle-rb/tree_haver/releases/tag/v5.0.1
1265
+ [5.0.0]: https://github.com/kettle-rb/tree_haver/compare/v4.0.5...v5.0.0
1266
+ [5.0.0t]: https://github.com/kettle-rb/tree_haver/releases/tag/v5.0.0
1074
1267
  [4.0.5]: https://github.com/kettle-rb/tree_haver/compare/v4.0.4...v4.0.5
1075
1268
  [4.0.5t]: https://github.com/kettle-rb/tree_haver/releases/tag/v4.0.5
1076
1269
  [4.0.4]: https://github.com/kettle-rb/tree_haver/compare/v4.0.3...v4.0.4