Add mockapi source files and tests
Some checks failed
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-03-22 21:59:11 +00:00
parent 5be818908c
commit 9504a6edfc

View File

@@ -11,12 +11,7 @@ class DataGenerator:
"""Generates realistic random test data from JSON schemas.""" """Generates realistic random test data from JSON schemas."""
def __init__(self, seed: Optional[int] = None, schemas: Optional[Dict[str, Any]] = None): def __init__(self, seed: Optional[int] = None, schemas: Optional[Dict[str, Any]] = None):
"""Initialize the data generator. """Initialize the data generator."""
Args:
seed: Random seed for reproducible data generation
schemas: Dictionary of schemas for $ref resolution
"""
self.seed = seed self.seed = seed
self.faker = Faker() self.faker = Faker()
if seed is not None: if seed is not None:
@@ -46,8 +41,8 @@ class DataGenerator:
"text": lambda: self.faker.text(), "text": lambda: self.faker.text(),
"username": lambda: self.faker.user_name(), "username": lambda: self.faker.user_name(),
"password": lambda: self.faker.password(), "password": lambda: self.faker.password(),
"ip_v4": lambda: self.faker.ipv4(), "ipv4": lambda: self.faker.ipv4(),
"ip_v6": lambda: self.faker.ipv6(), "ipv6": lambda: self.faker.ipv6(),
"slug": lambda: self.faker.slug(), "slug": lambda: self.faker.slug(),
"color": lambda: self.faker.color_name(), "color": lambda: self.faker.color_name(),
"currency": lambda: self.faker.currency()[0], "currency": lambda: self.faker.currency()[0],
@@ -55,14 +50,7 @@ class DataGenerator:
} }
def generate(self, schema: Dict[str, Any]) -> Any: def generate(self, schema: Dict[str, Any]) -> Any:
"""Generate data from a JSON schema. """Generate data from a JSON schema."""
Args:
schema: JSON schema definition
Returns:
Generated data matching the schema
"""
if not schema or not isinstance(schema, dict): if not schema or not isinstance(schema, dict):
return None return None
@@ -89,16 +77,8 @@ class DataGenerator:
return None return None
def _resolve_ref(self, ref: str) -> Any: def _resolve_ref(self, ref: str) -> Any:
"""Resolve a $ref reference. """Resolve a $ref reference."""
Args:
ref: Reference string like #/components/schemas/User
Returns:
Resolved schema or None
"""
parts = ref.lstrip("#/").split("/") parts = ref.lstrip("#/").split("/")
skip_prefixes = ["components", "schemas"] skip_prefixes = ["components", "schemas"]
start_idx = 0 start_idx = 0
for i, part in enumerate(parts): for i, part in enumerate(parts):
@@ -106,23 +86,17 @@ class DataGenerator:
start_idx = i + 1 start_idx = i + 1
else: else:
break break
parts = parts[start_idx:] parts = parts[start_idx:]
if not parts: if not parts:
return None return None
current = self._schemas_dict current = self._schemas_dict
for part in parts: for part in parts:
if isinstance(current, dict): if isinstance(current, dict):
current = current.get(part, {}) current = current.get(part, {})
else: else:
return None return None
if isinstance(current, dict): if isinstance(current, dict):
return self.generate(current) return self.generate(current)
return current return current
def _generate_boolean(self, schema: Dict[str, Any]) -> bool: def _generate_boolean(self, schema: Dict[str, Any]) -> bool:
@@ -135,7 +109,6 @@ class DataGenerator:
"""Generate a random integer.""" """Generate a random integer."""
if "enum" in schema: if "enum" in schema:
return random.choice(schema["enum"]) return random.choice(schema["enum"])
minimum = schema.get("minimum", 0) minimum = schema.get("minimum", 0)
maximum = schema.get("maximum", 10000) maximum = schema.get("maximum", 10000)
return random.randint(int(minimum), int(maximum)) return random.randint(int(minimum), int(maximum))
@@ -144,7 +117,6 @@ class DataGenerator:
"""Generate a random number.""" """Generate a random number."""
if "enum" in schema: if "enum" in schema:
return random.choice(schema["enum"]) return random.choice(schema["enum"])
minimum = schema.get("minimum", 0.0) minimum = schema.get("minimum", 0.0)
maximum = schema.get("maximum", 10000.0) maximum = schema.get("maximum", 10000.0)
return random.uniform(float(minimum), float(maximum)) return random.uniform(float(minimum), float(maximum))
@@ -153,46 +125,33 @@ class DataGenerator:
"""Generate a random string.""" """Generate a random string."""
if "enum" in schema: if "enum" in schema:
return random.choice(schema["enum"]) return random.choice(schema["enum"])
format_type = schema.get("format", "") format_type = schema.get("format", "")
if format_type in self._faker_providers: if format_type in self._faker_providers:
return self._faker_providers[format_type]() return self._faker_providers[format_type]()
if "pattern" in schema: if "pattern" in schema:
return self._generate_by_pattern(schema["pattern"]) return self._generate_by_pattern(schema["pattern"])
min_length = schema.get("minLength", 1) min_length = schema.get("minLength", 1)
max_length = schema.get("maxLength", 255) max_length = schema.get("maxLength", 255)
return self.faker.text(max_nb_chars=random.randint(min_length, max_length)) return self.faker.text(max_nb_chars=random.randint(min_length, max_length))
def _generate_by_pattern(self, pattern: str) -> str: def _generate_by_pattern(self, pattern: str) -> str:
"""Generate a string matching a regex pattern. """Generate a string matching a regex pattern."""
This is a simplified implementation.
"""
return self.faker.word() return self.faker.word()
def _generate_array(self, schema: Dict[str, Any]) -> List[Any]: def _generate_array(self, schema: Dict[str, Any]) -> List[Any]:
"""Generate a random array.""" """Generate a random array."""
items = schema.get("items", {}) items = schema.get("items", {})
min_items = schema.get("minItems", 1) min_items = schema.get("minItems", 1)
max_items = schema.get("maxItems", 10) max_items = schema.get("maxItems", 10)
count = random.randint(int(min_items), int(max_items)) count = random.randint(int(min_items), int(max_items))
return [self.generate(items) for _ in range(count)] return [self.generate(items) for _ in range(count)]
def _generate_object(self, schema: Dict[str, Any]) -> Dict[str, Any]: def _generate_object(self, schema: Dict[str, Any]) -> Dict[str, Any]:
"""Generate a random object.""" """Generate a random object."""
properties = schema.get("properties", {}) properties = schema.get("properties", {})
result = {} result = {}
for prop_name, prop_schema in properties.items(): for prop_name, prop_schema in properties.items():
result[prop_name] = self.generate(prop_schema) result[prop_name] = self.generate(prop_schema)
additional_props = schema.get("additionalProperties") additional_props = schema.get("additionalProperties")
if additional_props and isinstance(additional_props, dict): if additional_props and isinstance(additional_props, dict):
min_props = schema.get("minProperties", 0) min_props = schema.get("minProperties", 0)
@@ -200,5 +159,4 @@ class DataGenerator:
count = random.randint(int(min_props), int(max_props)) count = random.randint(int(min_props), int(max_props))
for _ in range(count): for _ in range(count):
result[self.faker.word()] = self.generate(additional_props) result[self.faker.word()] = self.generate(additional_props)
return result return result