structurize 2.19.0__py3-none-any.whl → 2.20.0__py3-none-any.whl

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.
avrotize/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '2.19.0'
32
- __version_tuple__ = version_tuple = (2, 19, 0)
31
+ __version__ = version = '2.20.0'
32
+ __version_tuple__ = version_tuple = (2, 20, 0)
33
33
 
34
- __commit_id__ = commit_id = 'geec8f9840'
34
+ __commit_id__ = commit_id = 'gd4e6f7652'
avrotize/avrotots.py CHANGED
@@ -31,6 +31,7 @@ class AvroToTypeScript:
31
31
  self.output_dir = os.getcwd()
32
32
  self.src_dir = os.path.join(self.output_dir, "src")
33
33
  self.generated_types: Dict[str, str] = {}
34
+ self.generated_type_fields: Dict[str, List[Dict]] = {} # Store fields for test generation
34
35
  self.main_schema = None
35
36
  self.type_dict = None
36
37
  self.INDENT = ' ' * 4
@@ -160,6 +161,7 @@ class AvroToTypeScript:
160
161
  'is_array': field['definition']['is_array'],
161
162
  'is_union': field['definition']['is_union'],
162
163
  'docstring': field['docstring'],
164
+ 'test_value': self.generate_test_value(field['definition']['type'], field['definition']['is_enum']),
163
165
  } for field in fields]
164
166
 
165
167
  imports_with_paths: Dict[str, str] = {}
@@ -201,6 +203,7 @@ class AvroToTypeScript:
201
203
  if write_file:
202
204
  self.write_to_file(namespace, class_name, class_definition)
203
205
  self.generated_types[ts_qualified_name] = 'class'
206
+ self.generated_type_fields[ts_qualified_name] = fields # Store fields for test generation
204
207
  return ts_qualified_name
205
208
 
206
209
  def generate_enum(self, avro_schema: Dict, parent_namespace: str, write_file: bool = True) -> str:
@@ -242,6 +245,47 @@ class AvroToTypeScript:
242
245
  'is_enum': self.generated_types.get(import_name, '') == 'enum',
243
246
  }
244
247
 
248
+ def generate_test_value(self, field_type: str, is_enum: bool = False) -> str:
249
+ """Generate a test value for a TypeScript field type."""
250
+ # Strip nullable marker
251
+ is_nullable = field_type.endswith('?')
252
+ field_type = self.strip_nullable(field_type)
253
+
254
+ # Handle arrays
255
+ if field_type.endswith('[]'):
256
+ inner_type = field_type[:-2]
257
+ inner_value = self.generate_test_value(inner_type, is_enum)
258
+ return f'[{inner_value}]'
259
+
260
+ # Handle map/dict types
261
+ if field_type.startswith('{ [key: string]:'):
262
+ return "{ 'key': 'value' }"
263
+
264
+ # Handle union types (pipe-separated)
265
+ if '|' in field_type:
266
+ first_type = field_type.split('|')[0].strip()
267
+ return self.generate_test_value(first_type, is_enum)
268
+
269
+ # Handle enums - use first value (will be set via template)
270
+ if is_enum:
271
+ return f'{field_type}.values()[0]'
272
+
273
+ # Handle primitive types
274
+ primitive_values = {
275
+ 'string': "'sample-string'",
276
+ 'number': '42',
277
+ 'boolean': 'true',
278
+ 'null': 'null',
279
+ 'Date': "new Date('2024-01-01T00:00:00Z')",
280
+ 'any': "{ test: 'data' }",
281
+ }
282
+
283
+ if field_type in primitive_values:
284
+ return primitive_values[field_type]
285
+
286
+ # For complex types (classes), call their createInstance method
287
+ return f'{field_type}.createInstance()'
288
+
245
289
  def get_is_json_match_clause(self, field_name: str, field_type: str, field_is_enum: bool) -> str:
246
290
  """Generates the isJsonMatch clause for a field."""
247
291
  field_name_js = field_name.rstrip('_')
@@ -556,6 +600,57 @@ class AvroToTypeScript:
556
600
  with open(types_file_path, 'w', encoding='utf-8') as file:
557
601
  file.write(avro_js_types)
558
602
 
603
+ def generate_tests(self, output_dir: str):
604
+ """Generate Jest test files for all generated TypeScript classes."""
605
+ test_directory_path = os.path.join(output_dir, "test")
606
+ if not os.path.exists(test_directory_path):
607
+ os.makedirs(test_directory_path, exist_ok=True)
608
+
609
+ for qualified_name, type_kind in self.generated_types.items():
610
+ if type_kind == 'class':
611
+ self.generate_test_class(qualified_name, test_directory_path)
612
+
613
+ def generate_test_class(self, qualified_name: str, test_directory_path: str):
614
+ """Generate a Jest test file for a TypeScript class."""
615
+ parts = qualified_name.split('.')
616
+ class_name = parts[-1]
617
+ namespace = '.'.join(parts[:-1])
618
+ test_class_name = f"{class_name}.test"
619
+
620
+ fields = self.generated_type_fields.get(qualified_name, [])
621
+
622
+ # Build imports for nested types
623
+ imports_with_paths: Dict[str, str] = {}
624
+ for field in fields:
625
+ field_type = field.get('type_no_null', '')
626
+ if not self.is_typescript_primitive(field_type.replace('[]', '')):
627
+ # It's a reference type, need to import it
628
+ type_name = field_type.replace('[]', '').replace('?', '')
629
+ if type_name and type_name not in ['null', 'any', 'Date']:
630
+ # Build relative path from test dir to src dir
631
+ src_path = '/'.join(parts)
632
+ imports_with_paths[type_name] = f'../src/{src_path.rsplit("/", 1)[0]}/{type_name}.js' if '/' in src_path else f'../src/{parts[0]}/{type_name}.js'
633
+
634
+ # Calculate relative path from test directory to class file
635
+ class_path_parts = namespace.split('.') if namespace else []
636
+ relative_path = '../src/' + '/'.join(class_path_parts + [class_name]) + '.js'
637
+
638
+ test_definition = process_template(
639
+ "avrotots/class_test.ts.jinja",
640
+ class_name=class_name,
641
+ fields=fields,
642
+ imports=imports_with_paths,
643
+ typed_json_annotation=self.typed_json_annotation,
644
+ avro_annotation=self.avro_annotation,
645
+ )
646
+
647
+ # Update the import path in the generated test
648
+ test_definition = test_definition.replace(f"from './{class_name}.js'", f"from '{relative_path}'")
649
+
650
+ test_file_path = os.path.join(test_directory_path, f"{test_class_name}.ts")
651
+ with open(test_file_path, 'w', encoding='utf-8') as file:
652
+ file.write(test_definition)
653
+
559
654
  def convert_schema(self, schema: Union[List[Dict], Dict], output_dir: str, write_file: bool = True):
560
655
  """Convert Avro schema to TypeScript classes with namespace support."""
561
656
  self.output_dir = output_dir
@@ -571,6 +666,7 @@ class AvroToTypeScript:
571
666
  self.generate_enum(avro_schema, '', write_file)
572
667
  self.generate_index_file()
573
668
  self.generate_project_files(output_dir)
669
+ self.generate_tests(output_dir)
574
670
 
575
671
  def convert(self, avro_schema_path: str, output_dir: str):
576
672
  """Convert Avro schema to TypeScript classes."""
@@ -8,9 +8,9 @@
8
8
  "kafkajs": "^2.2.4"
9
9
  },
10
10
  "devDependencies": {
11
- "@types/node": "^22.10.0",
11
+ "@types/node": "^24.10.1",
12
12
  "typescript": "^5.7.2",
13
- "jest": "^29.7.0",
14
- "@types/jest": "^29.5.14"
13
+ "jest": "^30.2.0",
14
+ "@types/jest": "^30.0.0"
15
15
  }
16
16
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: structurize
3
- Version: 2.19.0
3
+ Version: 2.20.0
4
4
  Summary: Tools to convert from and to JSON Structure from various other schema languages.
5
5
  Author-email: Clemens Vasters <clemensv@microsoft.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,6 +1,6 @@
1
1
  avrotize/__init__.py,sha256=JjPSX7c686TV00J_x0Py9JwXS0aJl8vpLn81Y0ondkw,3606
2
2
  avrotize/__main__.py,sha256=5pY8dYAURcOnFRvgb6fgaOIa_SOzPLIWbU8-ZTQ0jG4,88
3
- avrotize/_version.py,sha256=whWmGdYhR_wJ7JC69oWgfcPaP80_UeZLbA-k7pBts8I,714
3
+ avrotize/_version.py,sha256=k6AktVcjkwCwPVjLLE5w1umWJ_ZzoBYOaSjo2XT-C7E,714
4
4
  avrotize/asn1toavro.py,sha256=QDNwfBfXMxSH-k487CA3CaGCGDzOLs4PpVbbENm5uF0,8386
5
5
  avrotize/avrotize.py,sha256=VHFpBltMVBpyt0ju3ZWW725BKjQ4Fk-nrAy8udW-X44,5713
6
6
  avrotize/avrotocpp.py,sha256=hRZV247_TDD7Sm6_8sFx-UH5SueLLx2Wg6TvAVUX0iE,25693
@@ -22,7 +22,7 @@ avrotize/avrotoparquet.py,sha256=qm5hfia5elW1Yn4KACG8bbudLAqQSwGk3fIkTvdT5Rg,908
22
22
  avrotize/avrotoproto.py,sha256=STqbdGjVrgKrlKXt-6dZlekW_Oq0W0StRx80St1XqIc,22486
23
23
  avrotize/avrotopython.py,sha256=sPsSLseSq-toKHnsFsYRRtGePGYospRz2mwGLep-POw,31147
24
24
  avrotize/avrotorust.py,sha256=QMIBNkFpDlH44kuQo24k5D-f0lmdhoA5b7hEbhKsnMw,22214
25
- avrotize/avrotots.py,sha256=EalaA9feiHMyw7lfD8rifs24LsUVigmuPOu7nPh-wUc,29002
25
+ avrotize/avrotots.py,sha256=81k-6ZiIeRJENPXuUzPZchBGxr9Oper4Ra4GdFypWnA,33418
26
26
  avrotize/avrotoxsd.py,sha256=iGQq_8kC0kfKsqvqS6s_mO-kJ8N5G8vXOwqRI_DZUxc,17744
27
27
  avrotize/cddltostructure.py,sha256=MA2c-P3CIEAxEaBX-FF299gR55xcLEV3FrfTr2QfayM,74491
28
28
  avrotize/commands.json,sha256=afZ36gTItJdtM8z-qOTOw0MazKz1WKZMztY86JUHcgU,88538
@@ -61,10 +61,10 @@ avrotize/structuretots.py,sha256=PLV6W8k-yd7xkspUaQ-Vj90F26PTkB5HO0OkPJolkJ0,308
61
61
  avrotize/structuretoxsd.py,sha256=01VpasyWSMOx04sILHLP7H-WkhGdXAEGKohUUfgrNf0,32797
62
62
  avrotize/xsdtoavro.py,sha256=nQtNH_3pEZBp67oUCPqzhvItEExHTe-8obsIfNRXt8Y,19064
63
63
  avrotize/dependencies/cpp/vcpkg/vcpkg.json,sha256=se5qnUVQ1Q6wN_DqgIioqKg_y7ouh9oly2iBAJJXkgw,414
64
- avrotize/dependencies/typescript/node22/package.json,sha256=qAJ_dHE0YefuIRqkuN5tsXsHWSL8u6qZGRbYwVB_zq0,388
65
- structurize-2.19.0.dist-info/licenses/LICENSE,sha256=xGtQGygTETTtDQJafZCUbpsed3GxO6grmqig-jGEuSk,11348
66
- structurize-2.19.0.dist-info/METADATA,sha256=9e5yUdsXaK2Vy7TPQCPfHhbzqlQfOfwxTgHoIgG7WGc,3670
67
- structurize-2.19.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
68
- structurize-2.19.0.dist-info/entry_points.txt,sha256=biIH7jA5auhVqfbwHVk2gmD_gvrPYKgjpCAn0JWZ-Rs,55
69
- structurize-2.19.0.dist-info/top_level.txt,sha256=yn-yQ0Cm1O9fbF8KJgv4IIvX4YRGelKgPqZF1wS5P50,9
70
- structurize-2.19.0.dist-info/RECORD,,
64
+ avrotize/dependencies/typescript/node22/package.json,sha256=oAW_2X-b715kV7aajwuONZEMkyQUJGviG3GwnoUa7hU,387
65
+ structurize-2.20.0.dist-info/licenses/LICENSE,sha256=xGtQGygTETTtDQJafZCUbpsed3GxO6grmqig-jGEuSk,11348
66
+ structurize-2.20.0.dist-info/METADATA,sha256=W6TemISuPyp8M-b1MYe0rednFusDl4dCLblyFti6BQ8,3670
67
+ structurize-2.20.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
68
+ structurize-2.20.0.dist-info/entry_points.txt,sha256=biIH7jA5auhVqfbwHVk2gmD_gvrPYKgjpCAn0JWZ-Rs,55
69
+ structurize-2.20.0.dist-info/top_level.txt,sha256=yn-yQ0Cm1O9fbF8KJgv4IIvX4YRGelKgPqZF1wS5P50,9
70
+ structurize-2.20.0.dist-info/RECORD,,