class-metrix 0.1.2 โ 1.0.0
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 +4 -4
- data/.editorconfig +48 -0
- data/.vscode/README.md +72 -0
- data/.vscode/extensions.json +28 -0
- data/.vscode/launch.json +32 -0
- data/.vscode/settings.json +88 -0
- data/.vscode/tasks.json +99 -0
- data/CHANGELOG.md +71 -4
- data/README.md +41 -7
- data/docs/ARCHITECTURE.md +501 -0
- data/examples/README.md +161 -114
- data/examples/basic_usage.rb +88 -0
- data/examples/debug_levels_demo.rb +65 -0
- data/examples/debug_mode_demo.rb +75 -0
- data/examples/inheritance_and_modules.rb +155 -0
- data/lib/class_metrix/extractor.rb +106 -11
- data/lib/class_metrix/extractors/constants_extractor.rb +155 -21
- data/lib/class_metrix/extractors/methods_extractor.rb +186 -21
- data/lib/class_metrix/extractors/multi_type_extractor.rb +6 -5
- data/lib/class_metrix/formatters/components/footer_component.rb +1 -1
- data/lib/class_metrix/formatters/components/table_component/column_width_calculator.rb +56 -0
- data/lib/class_metrix/formatters/components/table_component/row_processor.rb +138 -0
- data/lib/class_metrix/formatters/components/table_component/table_data_extractor.rb +54 -0
- data/lib/class_metrix/formatters/components/table_component/table_renderer.rb +55 -0
- data/lib/class_metrix/formatters/components/table_component.rb +30 -244
- data/lib/class_metrix/formatters/shared/markdown_table_builder.rb +10 -5
- data/lib/class_metrix/formatters/shared/table_builder.rb +84 -21
- data/lib/class_metrix/formatters/shared/value_processor.rb +72 -16
- data/lib/class_metrix/utils/debug_logger.rb +159 -0
- data/lib/class_metrix/version.rb +1 -1
- metadata +17 -9
- data/examples/advanced/error_handling.rb +0 -199
- data/examples/advanced/hash_expansion.rb +0 -180
- data/examples/basic/01_simple_constants.rb +0 -56
- data/examples/basic/02_simple_methods.rb +0 -99
- data/examples/basic/03_multi_type_extraction.rb +0 -116
- data/examples/components/configurable_reports.rb +0 -201
- data/examples/csv_output_demo.rb +0 -237
- data/examples/real_world/microservices_audit.rb +0 -312
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
# ClassMetrix Architecture
|
|
2
|
+
|
|
3
|
+
This document provides an overview of ClassMetrix's architecture, component relationships, and code flow. It will be updated whenever the architecture changes to help developers quickly understand the codebase.
|
|
4
|
+
|
|
5
|
+
## ๐๏ธ High-Level Architecture
|
|
6
|
+
|
|
7
|
+
ClassMetrix follows a **modular, layered architecture** with clear separation of concerns:
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
graph TD
|
|
11
|
+
subgraph "Public API Layer"
|
|
12
|
+
API["ClassMetrix.extract(:constants, :class_methods)<br/>.from([Class1, Class2])<br/>.include_inherited<br/>.expand_hashes<br/>.to_markdown()"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
subgraph "Core Extraction Layer"
|
|
16
|
+
Extractor["Extractor<br/>(Coordinator)"]
|
|
17
|
+
ClassResolver["Class Resolver<br/>(Utilities)"]
|
|
18
|
+
ValueProcessor["Value Processor<br/>(Utilities)"]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
subgraph "Specialized Extractors"
|
|
22
|
+
ConstantsExtractor["Constants<br/>Extractor"]
|
|
23
|
+
MethodsExtractor["Methods<br/>Extractor"]
|
|
24
|
+
MultiTypeExtractor["Multi-Type<br/>Extractor"]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
subgraph "Formatting Layer"
|
|
28
|
+
MarkdownFormatter["Markdown<br/>Formatter"]
|
|
29
|
+
CsvFormatter["CSV<br/>Formatter"]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
subgraph "Component Layer"
|
|
33
|
+
subgraph "Report Components"
|
|
34
|
+
HeaderComponent["Header<br/>Component"]
|
|
35
|
+
TableComponent["Table<br/>Component"]
|
|
36
|
+
FooterComponent["Footer<br/>Component"]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
subgraph "Table Sub-Components"
|
|
40
|
+
TableDataExtractor["Table Data<br/>Extractor"]
|
|
41
|
+
RowProcessor["Row<br/>Processor"]
|
|
42
|
+
ColumnWidthCalculator["Column Width<br/>Calculator"]
|
|
43
|
+
TableRenderer["Table<br/>Renderer"]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
API --> Extractor
|
|
48
|
+
Extractor --> ClassResolver
|
|
49
|
+
Extractor --> ValueProcessor
|
|
50
|
+
Extractor --> ConstantsExtractor
|
|
51
|
+
Extractor --> MethodsExtractor
|
|
52
|
+
Extractor --> MultiTypeExtractor
|
|
53
|
+
|
|
54
|
+
ConstantsExtractor --> MarkdownFormatter
|
|
55
|
+
MethodsExtractor --> MarkdownFormatter
|
|
56
|
+
MultiTypeExtractor --> MarkdownFormatter
|
|
57
|
+
|
|
58
|
+
ConstantsExtractor --> CsvFormatter
|
|
59
|
+
MethodsExtractor --> CsvFormatter
|
|
60
|
+
MultiTypeExtractor --> CsvFormatter
|
|
61
|
+
|
|
62
|
+
MarkdownFormatter --> HeaderComponent
|
|
63
|
+
MarkdownFormatter --> TableComponent
|
|
64
|
+
MarkdownFormatter --> FooterComponent
|
|
65
|
+
|
|
66
|
+
TableComponent --> TableDataExtractor
|
|
67
|
+
TableComponent --> RowProcessor
|
|
68
|
+
TableComponent --> ColumnWidthCalculator
|
|
69
|
+
TableComponent --> TableRenderer
|
|
70
|
+
|
|
71
|
+
style API fill:#e1f5fe
|
|
72
|
+
style Extractor fill:#f3e5f5
|
|
73
|
+
style MarkdownFormatter fill:#e8f5e8
|
|
74
|
+
style TableComponent fill:#fff3e0
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## ๐ Directory Structure
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
lib/class_metrix/
|
|
81
|
+
โโโ class_metrix.rb # Main entry point
|
|
82
|
+
โโโ version.rb # Version information
|
|
83
|
+
โโโ extractor.rb # Core coordinator class
|
|
84
|
+
โโโ extractors/ # Specialized extraction logic
|
|
85
|
+
โ โโโ constants_extractor.rb # Constants extraction & inheritance
|
|
86
|
+
โ โโโ methods_extractor.rb # Methods extraction & inheritance
|
|
87
|
+
โ โโโ multi_type_extractor.rb # Multi-type combining logic
|
|
88
|
+
โโโ formatters/ # Output formatting
|
|
89
|
+
โ โโโ base/
|
|
90
|
+
โ โ โโโ base_formatter.rb # Base formatter class
|
|
91
|
+
โ โ โโโ base_component.rb # Base component class
|
|
92
|
+
โ โโโ shared/ # Shared formatting utilities
|
|
93
|
+
โ โ โโโ table_builder.rb # Table building base class
|
|
94
|
+
โ โ โโโ markdown_table_builder.rb # Markdown table implementation
|
|
95
|
+
โ โ โโโ csv_table_builder.rb # CSV table implementation
|
|
96
|
+
โ โ โโโ value_processor.rb # Value processing utilities
|
|
97
|
+
โ โโโ components/ # Modular components
|
|
98
|
+
โ โ โโโ table_component/ # Refactored table components
|
|
99
|
+
โ โ โ โโโ table_data_extractor.rb # Data extraction logic
|
|
100
|
+
โ โ โ โโโ row_processor.rb # Row processing & hash expansion
|
|
101
|
+
โ โ โ โโโ column_width_calculator.rb # Column width calculation
|
|
102
|
+
โ โ โ โโโ table_renderer.rb # Table rendering & formatting
|
|
103
|
+
โ โ โโโ table_component.rb # Main table component coordinator
|
|
104
|
+
โ โ โโโ header_component.rb # Report headers
|
|
105
|
+
โ โ โโโ generic_header_component.rb # Multi-format headers
|
|
106
|
+
โ โ โโโ missing_behaviors_component.rb # Missing behavior analysis
|
|
107
|
+
โ โ โโโ footer_component.rb # Report footers
|
|
108
|
+
โ โโโ markdown_formatter.rb # Markdown output formatter
|
|
109
|
+
โ โโโ csv_formatter.rb # CSV output formatter
|
|
110
|
+
โโโ processors/ # Value processing utilities
|
|
111
|
+
โ โโโ value_processor.rb # Handle all Ruby value types
|
|
112
|
+
โโโ utils/ # General utilities
|
|
113
|
+
โโโ class_resolver.rb # Class name resolution
|
|
114
|
+
โโโ debug_logger.rb # Centralized debug logging & safety
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## ๐ Debug System
|
|
118
|
+
|
|
119
|
+
ClassMetrix includes a comprehensive debug system designed to handle problematic objects and provide detailed tracing:
|
|
120
|
+
|
|
121
|
+
### Debug Logger (`Utils::DebugLogger`)
|
|
122
|
+
|
|
123
|
+
The centralized debug logger provides:
|
|
124
|
+
|
|
125
|
+
- **Safe Object Inspection**: Handles objects with unusual `inspect`, `to_s`, `class`, or `keys` behavior
|
|
126
|
+
- **Consistent Logging Format**: Standardized `[DEBUG ComponentName]` format across all components
|
|
127
|
+
- **Error-Resistant Operations**: All inspection methods wrapped in exception handling
|
|
128
|
+
- **Component-Specific Loggers**: Each component gets its own logger instance
|
|
129
|
+
|
|
130
|
+
### Safety Features
|
|
131
|
+
|
|
132
|
+
ClassMetrix includes robust safety measures for handling unusual objects:
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
# Safe inspection methods that handle problematic objects
|
|
136
|
+
logger.safe_inspect(value) # Won't crash on inspect failures
|
|
137
|
+
logger.safe_class(value) # Won't crash on class failures
|
|
138
|
+
logger.safe_keys(hash) # Won't crash on keys failures
|
|
139
|
+
logger.safe_to_s(value) # Won't crash on to_s failures
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Hash Detection Safety
|
|
143
|
+
|
|
144
|
+
The system uses strict hash detection to prevent issues with proxy objects:
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
# Only real Hash objects are considered for expansion
|
|
148
|
+
value.is_a?(Hash) && value.class == Hash && value.respond_to?(:keys)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
This prevents objects like `Delayed::Backend::ActiveRecord::Job` (which may respond to `is_a?(Hash)` due to method delegation) from being treated as expandable hashes.
|
|
152
|
+
|
|
153
|
+
### Debug Components
|
|
154
|
+
|
|
155
|
+
- **Extractor**: Logs extraction flow and data structure information
|
|
156
|
+
- **ConstantsExtractor**: Logs constant extraction and value details
|
|
157
|
+
- **TableBuilder**: Logs hash expansion decisions and value processing
|
|
158
|
+
- **ValueProcessor**: Logs value processing and type handling
|
|
159
|
+
|
|
160
|
+
## ๐ Data Flow
|
|
161
|
+
|
|
162
|
+
### 1. **API Entry Point**
|
|
163
|
+
```ruby
|
|
164
|
+
ClassMetrix.extract(:constants, :class_methods)
|
|
165
|
+
.from([DatabaseService, CacheService])
|
|
166
|
+
.include_inherited
|
|
167
|
+
.expand_hashes
|
|
168
|
+
.to_markdown()
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 2. **Request Processing Flow**
|
|
172
|
+
|
|
173
|
+
```mermaid
|
|
174
|
+
graph TD
|
|
175
|
+
UserRequest["User Request<br/>ClassMetrix.extract()"]
|
|
176
|
+
|
|
177
|
+
ClassMetrix["ClassMetrix<br/>.extract()"]
|
|
178
|
+
Extractor["Extractor<br/>(Main Coordinator)"]
|
|
179
|
+
ClassResolver["ClassResolver<br/>.normalize()"]
|
|
180
|
+
|
|
181
|
+
Router["Route to<br/>Appropriate<br/>Extractor"]
|
|
182
|
+
|
|
183
|
+
ConstantsExtractor["Constants<br/>Extractor"]
|
|
184
|
+
MethodsExtractor["Methods<br/>Extractor"]
|
|
185
|
+
MultiTypeExtractor["Multi-Type<br/>Extractor"]
|
|
186
|
+
|
|
187
|
+
RawTableData["Raw Table Data<br/>{headers:[], rows:[]}"]
|
|
188
|
+
|
|
189
|
+
Formatter["Formatter<br/>(Markdown/CSV)"]
|
|
190
|
+
|
|
191
|
+
FormattedOutput["Formatted Output<br/>(String)"]
|
|
192
|
+
|
|
193
|
+
UserRequest --> ClassMetrix
|
|
194
|
+
ClassMetrix --> Extractor
|
|
195
|
+
Extractor --> ClassResolver
|
|
196
|
+
Extractor --> Router
|
|
197
|
+
|
|
198
|
+
Router --> ConstantsExtractor
|
|
199
|
+
Router --> MethodsExtractor
|
|
200
|
+
Router --> MultiTypeExtractor
|
|
201
|
+
|
|
202
|
+
ConstantsExtractor --> RawTableData
|
|
203
|
+
MethodsExtractor --> RawTableData
|
|
204
|
+
MultiTypeExtractor --> RawTableData
|
|
205
|
+
|
|
206
|
+
RawTableData --> Formatter
|
|
207
|
+
Formatter --> FormattedOutput
|
|
208
|
+
|
|
209
|
+
style UserRequest fill:#e3f2fd
|
|
210
|
+
style Extractor fill:#f3e5f5
|
|
211
|
+
style Router fill:#fff3e0
|
|
212
|
+
style RawTableData fill:#e8f5e8
|
|
213
|
+
style FormattedOutput fill:#e1f5fe
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 3. **Table Component Data Flow** (After Refactoring)
|
|
217
|
+
|
|
218
|
+
```mermaid
|
|
219
|
+
graph TD
|
|
220
|
+
TableDataInput["Table Data Input<br/>{headers:[], rows:[]}"]
|
|
221
|
+
|
|
222
|
+
TableComponent["TableComponent<br/>(Main Coordinator)<br/>- Orchestrates<br/>- Delegates"]
|
|
223
|
+
|
|
224
|
+
TableDataExtractor["TableDataExtractor<br/>โข has_type_column?()<br/>โข extract_row_data()<br/>โข collect_hash_keys()"]
|
|
225
|
+
|
|
226
|
+
RowProcessor["RowProcessor<br/>โข process_simple_rows()<br/>โข process_expanded_rows()<br/>โข expand_row() (hash expansion)"]
|
|
227
|
+
|
|
228
|
+
ColumnWidthCalculator["ColumnWidthCalculator<br/>โข calculate_widths()<br/>โข initialize_column_widths()<br/>โข apply_minimum_widths()"]
|
|
229
|
+
|
|
230
|
+
TableRenderer["TableRenderer<br/>โข render_table()<br/>โข build_row()<br/>โข format_cells()"]
|
|
231
|
+
|
|
232
|
+
FinalRenderedTable["Final Rendered Table<br/>(Markdown/CSV String)"]
|
|
233
|
+
|
|
234
|
+
TableDataInput --> TableComponent
|
|
235
|
+
|
|
236
|
+
TableComponent --> TableDataExtractor
|
|
237
|
+
TableComponent --> RowProcessor
|
|
238
|
+
TableComponent --> ColumnWidthCalculator
|
|
239
|
+
TableComponent --> TableRenderer
|
|
240
|
+
|
|
241
|
+
TableDataExtractor --> RowProcessor
|
|
242
|
+
RowProcessor --> ColumnWidthCalculator
|
|
243
|
+
ColumnWidthCalculator --> TableRenderer
|
|
244
|
+
|
|
245
|
+
TableRenderer --> FinalRenderedTable
|
|
246
|
+
|
|
247
|
+
style TableDataInput fill:#e3f2fd
|
|
248
|
+
style TableComponent fill:#fff3e0
|
|
249
|
+
style TableDataExtractor fill:#e8f5e8
|
|
250
|
+
style RowProcessor fill:#f3e5f5
|
|
251
|
+
style ColumnWidthCalculator fill:#e1f5fe
|
|
252
|
+
style TableRenderer fill:#fce4ec
|
|
253
|
+
style FinalRenderedTable fill:#e8f5e8
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## ๐งฉ Core Components
|
|
257
|
+
|
|
258
|
+
### **1. Extractor (Coordinator)**
|
|
259
|
+
- **Purpose**: Main API interface and request coordination
|
|
260
|
+
- **Responsibilities**:
|
|
261
|
+
- Parse user configuration
|
|
262
|
+
- Route to appropriate extractors
|
|
263
|
+
- Apply global filters and options
|
|
264
|
+
- Coordinate inheritance/module options
|
|
265
|
+
- **Key Methods**: `from()`, `filter()`, `include_inherited()`, `to_markdown()`
|
|
266
|
+
|
|
267
|
+
### **2. Specialized Extractors**
|
|
268
|
+
|
|
269
|
+
#### **ConstantsExtractor**
|
|
270
|
+
- **Purpose**: Extract constants with inheritance/module support
|
|
271
|
+
- **Key Features**:
|
|
272
|
+
- Own constants: `Class.constants(false)`
|
|
273
|
+
- Inherited constants: Walk superclass chain
|
|
274
|
+
- Module constants: Scan `included_modules`
|
|
275
|
+
- Source tracking for debugging
|
|
276
|
+
|
|
277
|
+
#### **MethodsExtractor**
|
|
278
|
+
- **Purpose**: Extract class methods with inheritance/module support
|
|
279
|
+
- **Key Features**:
|
|
280
|
+
- Own methods: `Class.singleton_methods(false)`
|
|
281
|
+
- Inherited methods: Walk superclass chain
|
|
282
|
+
- Module methods: Scan `singleton_class.included_modules`
|
|
283
|
+
- Method resolution order handling
|
|
284
|
+
|
|
285
|
+
#### **MultiTypeExtractor**
|
|
286
|
+
- **Purpose**: Combine multiple extraction types into unified table
|
|
287
|
+
- **Key Features**:
|
|
288
|
+
- Add "Type" column to distinguish behavior types
|
|
289
|
+
- Merge different extractor results
|
|
290
|
+
- Maintain consistent table structure
|
|
291
|
+
|
|
292
|
+
### **3. Table Component Architecture** (Refactored)
|
|
293
|
+
|
|
294
|
+
The table component was recently refactored from a monolithic 269-line class into focused, reusable components:
|
|
295
|
+
|
|
296
|
+
#### **TableComponent** (Main Coordinator - 42 lines)
|
|
297
|
+
- **Purpose**: Orchestrate table generation process
|
|
298
|
+
- **Responsibilities**: Initialize sub-components, coordinate data flow
|
|
299
|
+
- **Pattern**: Composition over inheritance
|
|
300
|
+
|
|
301
|
+
#### **TableDataExtractor** (55 lines)
|
|
302
|
+
- **Purpose**: Data structure analysis and extraction utilities
|
|
303
|
+
- **Key Methods**: `has_type_column?()`, `extract_row_data()`, `collect_hash_keys()`
|
|
304
|
+
- **Responsibility**: Understand table structure and extract metadata
|
|
305
|
+
|
|
306
|
+
#### **RowProcessor** (125 lines)
|
|
307
|
+
- **Purpose**: Process table rows and handle hash expansion
|
|
308
|
+
- **Key Methods**: `process_simple_rows()`, `process_expanded_rows()`, `expand_row()`
|
|
309
|
+
- **Responsibility**: Transform raw data into renderable format
|
|
310
|
+
|
|
311
|
+
#### **ColumnWidthCalculator** (57 lines)
|
|
312
|
+
- **Purpose**: Calculate optimal column widths for table rendering
|
|
313
|
+
- **Key Methods**: `calculate_widths()`, `apply_minimum_widths()`
|
|
314
|
+
- **Responsibility**: Ensure proper table formatting
|
|
315
|
+
|
|
316
|
+
#### **TableRenderer** (56 lines)
|
|
317
|
+
- **Purpose**: Render final table with proper formatting
|
|
318
|
+
- **Key Methods**: `render_table()`, `build_row()`, `format_cells()`
|
|
319
|
+
- **Responsibility**: Generate final markdown table output
|
|
320
|
+
|
|
321
|
+
### **4. Formatters**
|
|
322
|
+
|
|
323
|
+
#### **MarkdownFormatter**
|
|
324
|
+
- **Purpose**: Generate rich markdown reports
|
|
325
|
+
- **Key Features**:
|
|
326
|
+
- Modular component architecture
|
|
327
|
+
- Professional report structure
|
|
328
|
+
- Hash expansion support
|
|
329
|
+
- Missing behavior analysis
|
|
330
|
+
|
|
331
|
+
#### **CsvFormatter**
|
|
332
|
+
- **Purpose**: Generate CSV output for data analysis
|
|
333
|
+
- **Key Features**:
|
|
334
|
+
- Clean CSV structure
|
|
335
|
+
- Configurable separators and quotes
|
|
336
|
+
- Hash flattening options
|
|
337
|
+
|
|
338
|
+
### **5. Support Components**
|
|
339
|
+
|
|
340
|
+
#### **ValueProcessor**
|
|
341
|
+
- **Purpose**: Process all Ruby value types consistently
|
|
342
|
+
- **Handles**: Strings, numbers, booleans, arrays, hashes, nil, errors
|
|
343
|
+
- **Visual Indicators**: โ
(true), โ (false/nil), ๐ซ (errors), โ ๏ธ (warnings)
|
|
344
|
+
|
|
345
|
+
#### **ClassResolver**
|
|
346
|
+
- **Purpose**: Normalize class inputs (strings vs class objects)
|
|
347
|
+
- **Handles**: Class objects, string class names, error cases
|
|
348
|
+
|
|
349
|
+
## ๐ง Key Design Patterns
|
|
350
|
+
|
|
351
|
+
### **1. Fluent Interface**
|
|
352
|
+
```ruby
|
|
353
|
+
ClassMetrix.extract(:constants)
|
|
354
|
+
.from([Class1, Class2])
|
|
355
|
+
.include_inherited
|
|
356
|
+
.filter(/config/)
|
|
357
|
+
.expand_hashes
|
|
358
|
+
.to_markdown()
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### **2. Strategy Pattern**
|
|
362
|
+
- Different extractors for different extraction types
|
|
363
|
+
- Different formatters for different output formats
|
|
364
|
+
- Pluggable components for different behaviors
|
|
365
|
+
|
|
366
|
+
### **3. Composition Pattern**
|
|
367
|
+
- Table component composed of focused sub-components
|
|
368
|
+
- Formatters composed of reusable components
|
|
369
|
+
- Modular architecture throughout
|
|
370
|
+
|
|
371
|
+
### **4. Template Method Pattern**
|
|
372
|
+
- Base classes define structure
|
|
373
|
+
- Subclasses implement specific behaviors
|
|
374
|
+
- Consistent interfaces across components
|
|
375
|
+
|
|
376
|
+
## ๐ Extension Points
|
|
377
|
+
|
|
378
|
+
### **Adding New Extraction Types**
|
|
379
|
+
1. Create new extractor in `extractors/`
|
|
380
|
+
2. Implement standard interface (`extract` method)
|
|
381
|
+
3. Add type routing in `MultiTypeExtractor`
|
|
382
|
+
4. Add API method in `Extractor`
|
|
383
|
+
|
|
384
|
+
### **Adding New Output Formats**
|
|
385
|
+
1. Create new formatter in `formatters/`
|
|
386
|
+
2. Extend base formatter class
|
|
387
|
+
3. Implement format-specific logic
|
|
388
|
+
4. Add API method in `Extractor`
|
|
389
|
+
|
|
390
|
+
### **Adding New Components**
|
|
391
|
+
1. Create component in `formatters/components/`
|
|
392
|
+
2. Extend `BaseComponent`
|
|
393
|
+
3. Implement `generate` method
|
|
394
|
+
4. Integrate into formatters
|
|
395
|
+
|
|
396
|
+
## ๐งช Testing Architecture
|
|
397
|
+
|
|
398
|
+
### **Test Structure**
|
|
399
|
+
|
|
400
|
+
```mermaid
|
|
401
|
+
graph TD
|
|
402
|
+
subgraph "Test Structure"
|
|
403
|
+
APITests["API Integration Tests<br/>class_metrix_spec.rb"]
|
|
404
|
+
ExtractorTests["Core Coordinator Tests<br/>extractor_spec.rb"]
|
|
405
|
+
|
|
406
|
+
subgraph "Unit Tests"
|
|
407
|
+
ExtractorUnitTests["Extractor Unit Tests<br/>extractors/"]
|
|
408
|
+
FormatterUnitTests["Formatter Tests<br/>formatters/"]
|
|
409
|
+
ProcessorUnitTests["Processor Tests<br/>processors/"]
|
|
410
|
+
UtilsUnitTests["Utility Tests<br/>utils/"]
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
subgraph "Test Classes Hierarchy"
|
|
415
|
+
TestParent["TestParent<br/>PARENT_CONSTANT<br/>parent_method()"]
|
|
416
|
+
TestChild["TestChild<br/>CHILD_CONSTANT<br/>child_method()"]
|
|
417
|
+
TestGrandchild["TestGrandchild<br/>GRANDCHILD_CONSTANT<br/>grandchild_method()"]
|
|
418
|
+
|
|
419
|
+
TestParent --> TestChild
|
|
420
|
+
TestChild --> TestGrandchild
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
subgraph "Test Modules"
|
|
424
|
+
TestModule["TestModule<br/>TEST_MODULE_CONSTANT<br/>module_method()"]
|
|
425
|
+
AnotherTestModule["AnotherTestModule<br/>ANOTHER_CONSTANT<br/>another_module_method()"]
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
subgraph "Realistic Examples"
|
|
429
|
+
TestUser["TestUser<br/>ROLE_NAME = 'user'<br/>config()"]
|
|
430
|
+
TestAdmin["TestAdmin<br/>ROLE_NAME = 'admin'<br/>admin_config()"]
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
TestChild -.->|includes| TestModule
|
|
434
|
+
TestGrandchild -.->|includes| AnotherTestModule
|
|
435
|
+
|
|
436
|
+
APITests --> ExtractorTests
|
|
437
|
+
ExtractorTests --> ExtractorUnitTests
|
|
438
|
+
ExtractorTests --> FormatterUnitTests
|
|
439
|
+
|
|
440
|
+
ExtractorUnitTests -.->|uses| TestParent
|
|
441
|
+
ExtractorUnitTests -.->|uses| TestChild
|
|
442
|
+
ExtractorUnitTests -.->|uses| TestGrandchild
|
|
443
|
+
ExtractorUnitTests -.->|uses| TestModule
|
|
444
|
+
ExtractorUnitTests -.->|uses| AnotherTestModule
|
|
445
|
+
ExtractorUnitTests -.->|uses| TestUser
|
|
446
|
+
ExtractorUnitTests -.->|uses| TestAdmin
|
|
447
|
+
|
|
448
|
+
style APITests fill:#e3f2fd
|
|
449
|
+
style ExtractorTests fill:#f3e5f5
|
|
450
|
+
style TestParent fill:#e8f5e8
|
|
451
|
+
style TestChild fill:#fff3e0
|
|
452
|
+
style TestGrandchild fill:#fce4ec
|
|
453
|
+
style TestModule fill:#e1f5fe
|
|
454
|
+
style AnotherTestModule fill:#e1f5fe
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### **Test Coverage**
|
|
458
|
+
- โ
**Basic Extraction**: Constants and methods from simple classes
|
|
459
|
+
- โ
**Inheritance**: Multi-level inheritance chains
|
|
460
|
+
- โ
**Modules**: Module inclusion and method resolution
|
|
461
|
+
- โ
**Error Handling**: Missing methods, constants, class resolution failures
|
|
462
|
+
- โ
**Value Types**: All Ruby value types and edge cases
|
|
463
|
+
- โ
**Integration**: End-to-end functionality with real-world scenarios
|
|
464
|
+
|
|
465
|
+
## ๐ Performance Considerations
|
|
466
|
+
|
|
467
|
+
### **Lazy Evaluation**
|
|
468
|
+
- Extractors only process data when `to_markdown()`/`to_csv()` is called
|
|
469
|
+
- Filters applied efficiently during extraction
|
|
470
|
+
- Minimal memory usage for large class sets
|
|
471
|
+
|
|
472
|
+
### **Inheritance Optimization**
|
|
473
|
+
- Superclass chain traversal is optimized
|
|
474
|
+
- Core Ruby classes (`Object`, `BasicObject`) are skipped
|
|
475
|
+
- Module resolution uses efficient set operations
|
|
476
|
+
|
|
477
|
+
### **Table Rendering Optimization**
|
|
478
|
+
- Column width calculation is performed once
|
|
479
|
+
- Row processing is streamlined
|
|
480
|
+
- String operations are minimized
|
|
481
|
+
|
|
482
|
+
## ๐ Future Architecture Plans
|
|
483
|
+
|
|
484
|
+
### **Plugin System**
|
|
485
|
+
- Plugin architecture for custom extractors
|
|
486
|
+
- Extension points for custom components
|
|
487
|
+
- Configuration system for plugin management
|
|
488
|
+
|
|
489
|
+
### **Caching Layer**
|
|
490
|
+
- Cache class metadata for performance
|
|
491
|
+
- Invalidation strategies for development
|
|
492
|
+
- Configurable caching backends
|
|
493
|
+
|
|
494
|
+
### **Parallel Processing**
|
|
495
|
+
- Parallel extraction for large class sets
|
|
496
|
+
- Worker pool for I/O operations
|
|
497
|
+
- Memory-efficient streaming for large datasets
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
*This architecture document is maintained alongside code changes.*
|