Unit Test Generator
Run ID: 69ccd96a3e7fb09ff16a5a082026-04-01Development
PantheraHive BOS
BOS Dashboard

Step 2 of 3: Unit Test Generation (gemini → generate_code)

This deliverable provides a comprehensive set of unit tests generated by Gemini, designed to ensure the robustness, correctness, and reliability of your codebase. This output is presented as production-ready code, complete with detailed explanations and best practices, ready for integration into your development workflow.


1. Introduction to Generated Unit Tests

Unit tests are a critical component of modern software development, providing immediate feedback on code changes and serving as living documentation of functionality. In this step, Gemini has analyzed the provided (or inferred) code structure and business logic to produce a suite of tests that cover various scenarios, including:

The generated code is designed to be clean, readable, well-commented, and easily adaptable to your specific project requirements.

2. Core Functionality: Unit Test Generation Process

Gemini employs a systematic approach to generate effective unit tests:

  1. Function/Method Identification: Automatically identifies all public functions, methods, and classes within the target code that require testing.
  2. Input/Output Analysis: Infers expected input types, return types, and potential side effects for each identified component.
  3. Scenario Generation: Develops a range of test scenarios, including typical use cases, boundary conditions (e.g., empty lists, zero values, maximum string lengths), and error conditions (e.g., None inputs, incorrect types, division by zero).
  4. Assertion Strategy: Selects appropriate assertion methods (assertEqual, assertTrue, assertRaises, etc.) to validate the outcomes of each test scenario.
  5. Dependency Management (Mocking/Patching): Where external dependencies (database calls, API requests, file system interactions) are detected or anticipated, the tests are designed to facilitate mocking, ensuring tests remain isolated and fast.
  6. Code Structure and Readability: Organizes tests into logical classes and methods, adhering to common testing frameworks (e.g., pytest or unittest in Python) for clarity and maintainability.

3. Generated Unit Test Code Example

To illustrate the output, let's consider a common scenario: a simple Calculator class.

3.1. Hypothetical Original Code (calculator.py)

text • 165 chars
#### 3.2. Generated Unit Tests (`test_calculator.py`)

This example uses the `pytest` framework, which is widely adopted for its simplicity and powerful features.

Sandboxed live preview

As part of the "Unit Test Generator" workflow, this document outlines a comprehensive and detailed study plan. This plan is designed to equip you with the necessary knowledge and practical skills to understand, design, and ultimately develop a robust Unit Test Generator. This deliverable serves as Step 1 of 3: gemini → plan_architecture, providing the foundational learning roadmap before diving into specific architectural design.


Study Plan: Developing a Unit Test Generator

1. Executive Summary

This study plan provides a structured, 6-week curriculum focused on mastering the concepts and technologies essential for building a Unit Test Generator. It encompasses foundational software testing principles, advanced code analysis techniques using Abstract Syntax Trees (ASTs), integration with popular testing frameworks, strategies for intelligent input data generation, and robust mocking/stubbing practices. The plan culminates in outlining a generator's architecture and developing a basic prototype, ensuring a practical and comprehensive learning experience.

2. Overall Goal

To acquire a deep theoretical understanding and practical implementation skills required to design, develop, and maintain an automated Unit Test Generator capable of analyzing source code and producing functional, maintainable unit tests for various programming languages.

3. Weekly Schedule

This schedule allocates approximately 10-15 hours per week, balancing theoretical learning with hands-on coding exercises.

Week 1: Foundations of Unit Testing & Code Analysis

  • Focus: Understanding core unit testing concepts, different testing paradigms, and the basics of code structure analysis.
  • Topics:

* What is Unit Testing? Principles, benefits, and best practices.

* Test-Driven Development (TDD) vs. Behavior-Driven Development (BDD) overview.

* Types of tests (unit, integration, end-to-end) and their scope.

* Introduction to Static Code Analysis.

* Basic code parsing: Identifying functions, classes, and variables in simple code.

* Introduction to Abstract Syntax Trees (ASTs) – what they are and why they are used.

Week 2: Deep Dive into Abstract Syntax Trees (AST) & Code Representation

  • Focus: Gaining proficiency in working with ASTs for detailed code understanding and manipulation.
  • Topics:

* Language-specific AST structures (e.g., Python's ast module, JavaParser, Roslyn for C#).

* Parsing source code into an AST.

* Traversing and navigating AST nodes (visitors, walkers).

* Extracting detailed information: function signatures, parameter types, return types, variable declarations, control flow statements.

* Identifying dependencies and external calls within code.

Week 3: Test Frameworks & Assertion Generation

  • Focus: Understanding how unit tests are structured using popular frameworks and generating appropriate assertions.
  • Topics:

* Overview of popular unit testing frameworks (e.g., Pytest/unittest for Python, JUnit for Java, Jest for JavaScript, NUnit for C#).

* Structure of a unit test: test classes, test methods, setup/teardown.

* Types of assertions: equality, truthiness, comparisons, exception handling.

* Strategies for generating basic assertions based on function return types and expected outcomes.

* Introduction to parameterization of tests.

Week 4: Intelligent Input Data Generation & Edge Cases

  • Focus: Developing strategies for generating diverse and effective test inputs, including handling edge cases.
  • Topics:

* Heuristics for generating meaningful input data (e.g., based on parameter types, default values).

* Identifying and handling edge cases: null values, empty collections, boundary conditions (min/max), zero, negative numbers.

* Introduction to property-based testing concepts (e.g., Hypothesis, QuickCheck) for automated input generation.

* Fuzzing concepts for discovering unexpected inputs.

* Data structures for representing generated inputs.

Week 5: Mocking, Stubbing & Dependency Management

  • Focus: Understanding and applying techniques to isolate units under test by controlling their dependencies.
  • Topics:

* The importance of test isolation: mocks, stubs, fakes, spies.

* Practical application of mocking frameworks (e.g., unittest.mock for Python, Mockito for Java, Jest mocks for JavaScript).

* Generating mock objects and defining their behavior.

* Strategies for identifying and replacing external dependencies (database calls, API calls, file system operations).

* Dependency Injection and its role in testable code.

Week 6: Architecture & Prototype of a Unit Test Generator

  • Focus: Synthesizing all learned concepts into a coherent architectural design for a Unit Test Generator and building a basic prototype.
  • Topics:

* High-level architecture design for a Unit Test Generator: input (source code), analysis engine (AST), test generation logic, output (test files).

* Modularity and extensibility: supporting multiple languages, test frameworks.

* Configuration options for users (e.g., target framework, output directory).

* Code generation templates (e.g., using Jinja2 or similar templating engines).

* Error handling and reporting.

* Building a minimal viable prototype for a specific function type.

4. Learning Objectives

Upon completion of this study plan, you will be able to:

  • Comprehend the fundamental principles and best practices of unit testing and their role in software quality.
  • Analyze source code effectively using Abstract Syntax Trees (ASTs) to extract structural and semantic information.
  • Identify key code elements (functions, classes, parameters, dependencies) necessary for test generation.
  • Design test case structures and generate appropriate assertions for various scenarios using common testing frameworks.
  • Devise strategies for generating diverse and meaningful input data, including handling edge cases and boundary conditions.
  • Implement mocking and stubbing techniques to isolate units under test and manage external dependencies.
  • Architect a scalable and extensible Unit Test Generator, considering language-specific nuances and framework integration.
  • Develop a functional prototype of a Unit Test Generator capable of producing basic unit tests for a given code snippet.

5. Recommended Resources

Books:

  • "Working Effectively with Legacy Code" by Michael C. Feathers: Essential for understanding how to approach testing existing, untestable codebases.
  • "Refactoring: Improving the Design of Existing Code" by Martin Fowler: Provides insights into creating more testable code.
  • "Design Patterns: Elements of Reusable Object-Oriented Software" by Erich Gamma et al. (Gang of Four): For understanding extensible software design.
  • Language-Specific AST Books/Documentation:

* Python: Official ast module documentation, "Fluent Python" by Luciano Ramalho (for deeper Python understanding).

* Java: "The Definitive ANTLR 4 Reference" by Terence Parr, JavaParser official documentation.

* C#: Roslyn SDK documentation.

Online Courses & Tutorials:

  • Coursera/Udemy/edX: Courses on Software Testing, Compiler Design, Programming Language Parsers, specific language AST manipulation.
  • Official Documentation: For chosen programming languages, their AST modules/libraries, and unit testing frameworks (e.g., Pytest, JUnit, Jest, NUnit).
  • Blogs & Articles: Search for "code generation," "static analysis," "AST manipulation," "automated test generation" on platforms like Medium, Dev.to, Towards Data Science, or specific tech blogs.
  • Open-Source Projects: Explore existing tools for code analysis, linting, formatting, and test generation (e.g., Pylint, Black, SpotBugs, Cobertura, specific test generation tools if available for your language).

Tools & Libraries (Examples, choose based on target language):

  • AST Parsers: Python's ast module, JavaParser (Java), ANTLR (general-purpose parser generator), Roslyn (C#).
  • Testing Frameworks: Pytest/unittest (Python), JUnit (Java), Jest (JavaScript), NUnit (C#).
  • Mocking Libraries: unittest.mock (Python), Mockito (Java), Jest mocks (JavaScript).
  • Templating Engines: Jinja2 (Python), Handlebars (JavaScript), FreeMarker (Java).
  • Fuzzing/Property-based Testing: Hypothesis (Python), QuickCheck (Haskell/other ports).

6. Milestones

Achievement of these milestones signifies significant progress and mastery of the study plan's objectives.

  • End of Week 1: Successfully parse a simple code file (e.g., a Python script with 2-3 functions) and extract its top-level function and class names using an AST.
  • End of Week 2: Implement an AST visitor/walker that can traverse a more complex code file (e.g., a class with methods, variables, and control flow) and identify function parameters, local variables, and external calls.
  • End of Week 3: Manually write a comprehensive set of unit tests (using a chosen framework) for a given moderately complex function, demonstrating various assertion types and test setup/teardown.
  • End of Week 4: Develop a module that, given a function's signature (parameter names and types), can suggest a diverse set of input values, including common edge cases (e.g., 0, null, empty string, boundary numbers).
  • End of Week 5: Refactor a provided code snippet to make it more testable with dependency injection, and then write unit tests for it using a mocking framework to isolate external dependencies.
  • **End of Week

4. Explanation of the Generated Tests

The generated test_calculator.py file demonstrates several key aspects of effective unit testing:

  • Pytest Fixtures (@pytest.fixture): The calculator_instance fixture ensures that a fresh instance of Calculator is available for all tests in the module. Using scope="module" means the instance is created once and reused, optimizing test execution time.
  • Parameterized Testing (@pytest.mark.parametrize): This powerful pytest feature allows running the same test logic with multiple sets of inputs and expected outputs. This reduces code duplication and makes tests more readable and maintainable.

* Valid Inputs: Each _valid_inputs test uses parametrize to cover a wide range of typical and edge-case numerical inputs (integers, floats, positive, negative, zero, large numbers).

* Floating Point Precision: For floating-point arithmetic, pytest.approx() is used to compare results with a tolerance, accounting for potential precision issues inherent in floating-point calculations.

  • Error Handling Tests (pytest.raises):

* test_add_invalid_inputs_raises_type_error, test_subtract_invalid_inputs_raises_type_error, etc., specifically test that the methods correctly raise TypeError when non-numeric inputs are provided. The match parameter verifies the exact error message, making the test more robust.

* test_divide_by_zero_raises_value_error specifically checks for ValueError when division by zero is attempted.

  • Clear Naming Conventions: Test methods are named descriptively (e.g., test_add_valid_inputs, test_divide_by_zero_raises_value_error), making it easy to understand what each test is verifying.
  • Comments: Extensive comments explain the purpose of classes, methods, and specific test parameters, aiding in understanding and future maintenance.
  • Isolation: Each test is designed to be independent, meaning its outcome does not depend on the order of execution or the state left by other tests. This is crucial for reliable and repeatable testing.

5. Key Principles for Effective Unit Testing

To maximize the value of these generated tests and your overall testing strategy, consider the F.I.R.S.T principles:

  • Fast: Tests should run quickly to provide rapid feedback.
gemini Output

Deliverable: Unit Test Generation & Documentation

This document presents the comprehensive unit tests generated by the "Unit Test Generator" workflow, specifically completing the "review_and_document" phase. The initial tests were generated by the Gemini model and subsequently refined, validated, and documented by our team to ensure correctness, completeness, and adherence to best practices.


1. Summary of Generated Tests

This deliverable focuses on providing robust unit tests for a core service component, demonstrating how the generated tests cover critical business logic and edge cases.

  • Target Component: UserService (a common backend service responsible for user management operations).
  • Purpose: To ensure the UserService methods (createUser, getUser, updateUser, deleteUser) function correctly in isolation, handling both successful scenarios and anticipated failure modes.
  • Key Scenarios Covered:

* Successful creation, retrieval, update, and deletion of users.

* Handling of invalid input (e.g., null or empty fields).

* Behavior when a user is not found.

* Detection of duplicate user creations.

* Proper interaction with mocked dependencies (e.g., UserRepository).


2. Generated Unit Tests: UserService Example

Below is an example of the original UserService class and the corresponding generated unit tests.

2.1. Original Code: UserService.java (For Context)


// src/main/java/com/example/service/UserService.java
package com.example.service;

import com.example.model.User;
import com.example.repository.UserRepository;
import com.example.exception.UserNotFoundException;
import com.example.exception.DuplicateUserException;

import java.util.List;
import java.util.Optional;

public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User createUser(User user) {
        if (user == null || user.getEmail() == null || user.getEmail().isEmpty()) {
            throw new IllegalArgumentException("User and email cannot be null or empty.");
        }
        if (userRepository.findByEmail(user.getEmail()).isPresent()) {
            throw new DuplicateUserException("User with email " + user.getEmail() + " already exists.");
        }
        // Assign a simple ID for demonstration if not already set (in a real app, this would be generated by DB)
        if (user.getId() == null) {
            user.setId(generateUniqueId()); // Simplified ID generation
        }
        return userRepository.save(user);
    }

    public User getUserById(String id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new UserNotFoundException("User with ID " + id + " not found."));
    }

    public User getUserByEmail(String email) {
        return userRepository.findByEmail(email)
                .orElseThrow(() -> new UserNotFoundException("User with email " + email + " not found."));
    }

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    public User updateUser(String id, User updatedUser) {
        if (updatedUser == null) {
            throw new IllegalArgumentException("Updated user cannot be null.");
        }
        User existingUser = userRepository.findById(id)
                .orElseThrow(() -> new UserNotFoundException("User with ID " + id + " not found."));

        existingUser.setName(updatedUser.getName());
        existingUser.setEmail(updatedUser.getEmail());
        // Potentially add more fields to update

        return userRepository.save(existingUser);
    }

    public void deleteUser(String id) {
        if (!userRepository.existsById(id)) {
            throw new UserNotFoundException("User with ID " + id + " not found for deletion.");
        }
        userRepository.deleteById(id);
    }

    private String generateUniqueId() {
        return "user-" + System.nanoTime(); // Simple, non-production ID generation
    }
}

2.2. Generated Unit Tests: UserServiceTest.java


// src/test/java/com/example/service/UserServiceTest.java
package com.example.service;

import com.example.model.User;
import com.example.repository.UserRepository;
import com.example.exception.DuplicateUserException;
import com.example.exception.UserNotFoundException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
@DisplayName("UserService Unit Tests")
class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    private User user1;
    private User user2;

    @BeforeEach
    void setUp() {
        user1 = new User("1", "John Doe", "john.doe@example.com");
        user2 = new User("2", "Jane Smith", "jane.smith@example.com");
    }

    // --- CREATE USER TESTS ---
    @Test
    @DisplayName("createUser should successfully create a new user")
    void createUser_Success() {
        when(userRepository.findByEmail(user1.getEmail())).thenReturn(Optional.empty());
        when(userRepository.save(any(User.class))).thenReturn(user1);

        User createdUser = userService.createUser(user1);

        assertNotNull(createdUser);
        assertEquals(user1.getEmail(), createdUser.getEmail());
        verify(userRepository, times(1)).findByEmail(user1.getEmail());
        verify(userRepository, times(1)).save(any(User.class));
    }

    @Test
    @DisplayName("createUser should throw IllegalArgumentException for null user")
    void createUser_NullUser_ThrowsException() {
        assertThrows(IllegalArgumentException.class, () -> userService.createUser(null));
        verify(userRepository, never()).findByEmail(anyString());
        verify(userRepository, never()).save(any(User.class));
    }

    @Test
    @DisplayName("createUser should throw IllegalArgumentException for null email")
    void createUser_NullEmail_ThrowsException() {
        User userWithNullEmail = new User("3", "Test User", null);
        assertThrows(IllegalArgumentException.class, () -> userService.createUser(userWithNullEmail));
        verify(userRepository, never()).findByEmail(anyString());
        verify(userRepository, never()).save(any(User.class));
    }

    @Test
    @DisplayName("createUser should throw IllegalArgumentException for empty email")
    void createUser_EmptyEmail_ThrowsException() {
        User userWithEmptyEmail = new User("3", "Test User", "");
        assertThrows(IllegalArgumentException.class, () -> userService.createUser(userWithEmptyEmail));
        verify(userRepository, never()).findByEmail(anyString());
        verify(userRepository, never()).save(any(User.class));
    }

    @Test
    @DisplayName("createUser should throw DuplicateUserException if user with email already exists")
    void createUser_DuplicateEmail_ThrowsException() {
        when(userRepository.findByEmail(user1.getEmail())).thenReturn(Optional.of(user1));

        assertThrows(DuplicateUserException.class, () -> userService.createUser(user1));
        verify(userRepository, times(1)).findByEmail(user1.getEmail());
        verify(userRepository, never()).save(any(User.class));
    }

    // --- GET USER TESTS ---
    @Test
    @DisplayName("getUserById should return user when found")
    void getUserById_UserFound_ReturnsUser() {
        when(userRepository.findById(user1.getId())).thenReturn(Optional.of(user1));

        User foundUser = userService.getUserById(user1.getId());

        assertNotNull(foundUser);
        assertEquals(user1.getId(), foundUser.getId());
        verify(userRepository, times(1)).findById(user1.getId());
    }

    @Test
    @DisplayName("getUserById should throw UserNotFoundException when user not found")
    void getUserById_UserNotFound_ThrowsException() {
        when(userRepository.findById("nonExistentId")).thenReturn(Optional.empty());

        assertThrows(UserNotFoundException.class, () -> userService.getUserById("nonExistentId"));
        verify(userRepository, times(1)).findById("nonExistentId");
    }

    @Test
    @DisplayName("getUserByEmail should return user when found")
    void getUserByEmail_UserFound_ReturnsUser() {
        when(userRepository.findByEmail(user1.getEmail())).thenReturn(Optional.of(user1));

        User foundUser = userService.getUserByEmail(user1.getEmail());

        assertNotNull(foundUser);
        assertEquals(user1.getEmail(), foundUser.getEmail());
        verify(userRepository, times(1)).findByEmail(user1.getEmail());
    }

    @Test
    @DisplayName("getUserByEmail should throw UserNotFoundException when user not found")
    void getUserByEmail_UserNotFound_ThrowsException() {
        when(userRepository.findByEmail("nonexistent@example.com")).thenReturn(Optional.empty());

        assertThrows(UserNotFoundException.class, () -> userService.getUserByEmail("nonexistent@example.com"));
        verify(userRepository, times(1)).findByEmail("nonexistent@example.com");
    }

    @Test
    @DisplayName("getAllUsers should return a list of all users")
    void getAllUsers_ReturnsAllUsers() {
        List<User> users = Arrays.asList(user1, user2);
        when(userRepository.findAll()).thenReturn(users);

        List<User> result = userService.getAllUsers();

        assertNotNull(result);
        assertEquals(2, result.size());
        assertTrue(result.contains(user1));
        assertTrue(result.contains(user2));
        verify(userRepository, times(1)).findAll();
    }

    @Test
    @DisplayName("getAllUsers should return an empty list when no users exist")
    void getAllUsers_NoUsers_ReturnsEmptyList() {
        when(userRepository.findAll()).thenReturn(Collections.emptyList());

        List<User> result = userService.getAllUsers();

        assertNotNull(result);
        assertTrue(result.isEmpty());
        verify(userRepository, times(1)).findAll();
    }

    // --- UPDATE USER TESTS ---
    @Test
    @DisplayName("updateUser should successfully update an existing user")
    void updateUser_Success() {
        User updatedDetails = new User(null, "Johnathan Doe", "john.doe.updated@example.com"); // ID is not updated via payload
        User existingUser = new
unit_test_generator.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')!).render( ) "); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react' import './App.css' function App(){ return(

"+slugTitle(pn)+"

Built with PantheraHive BOS

) } export default App "); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e} .app{min-height:100vh;display:flex;flex-direction:column} .app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px} h1{font-size:2.5rem;font-weight:700} "); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` ## Open in IDE Open the project folder in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{ "name": "'+pn+'", "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview" }, "dependencies": { "vue": "^3.5.13", "vue-router": "^4.4.5", "pinia": "^2.3.0", "axios": "^1.7.9" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.1", "typescript": "~5.7.3", "vite": "^6.0.5", "vue-tsc": "^2.2.0" } } '); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': resolve(__dirname,'src') } } }) "); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]} '); zip.file(folder+"tsconfig.app.json",'{ "compilerOptions":{ "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"], "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true, "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue", "strict":true,"paths":{"@/*":["./src/*"]} }, "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"] } '); zip.file(folder+"env.d.ts","/// "); zip.file(folder+"index.html"," "+slugTitle(pn)+"
"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import './assets/main.css' const app = createApp(App) app.use(createPinia()) app.mount('#app') "); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue"," "); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547} "); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` Open in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{ "name": "'+pn+'", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test" }, "dependencies": { "@angular/animations": "^19.0.0", "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", "@angular/core": "^19.0.0", "@angular/forms": "^19.0.0", "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { "@angular-devkit/build-angular": "^19.0.0", "@angular/cli": "^19.0.0", "@angular/compiler-cli": "^19.0.0", "typescript": "~5.6.0" } } '); zip.file(folder+"angular.json",'{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "'+pn+'": { "projectType": "application", "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/'+pn+'", "index": "src/index.html", "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "styles": ["src/styles.css"], "scripts": [] } }, "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"} } } } } '); zip.file(folder+"tsconfig.json",'{ "compileOnSave": false, "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]}, "references":[{"path":"./tsconfig.app.json"}] } '); zip.file(folder+"tsconfig.app.json",'{ "extends":"./tsconfig.json", "compilerOptions":{"outDir":"./dist/out-tsc","types":[]}, "files":["src/main.ts"], "include":["src/**/*.d.ts"] } '); zip.file(folder+"src/index.html"," "+slugTitle(pn)+" "); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig) .catch(err => console.error(err)); "); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; } "); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = '"+pn+"'; } "); zip.file(folder+"src/app/app.component.html","

"+slugTitle(pn)+"

Built with PantheraHive BOS

"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1} "); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes) ] }; "); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router'; export const routes: Routes = []; "); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install ng serve # or: npm start ``` ## Build ```bash ng build ``` Open in VS Code with Angular Language Service extension. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local .angular/ "); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join(" "):"# add dependencies here "; zip.file(folder+"main.py",src||"# "+title+" # Generated by PantheraHive BOS print(title+" loaded") "); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ## Run ```bash python main.py ``` "); zip.file(folder+".gitignore",".venv/ __pycache__/ *.pyc .env .DS_Store "); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+" "; zip.file(folder+"package.json",pkgJson); var fallback="const express=require("express"); const app=express(); app.use(express.json()); app.get("/",(req,res)=>{ res.json({message:""+title+" API"}); }); const PORT=process.env.PORT||3000; app.listen(PORT,()=>console.log("Server on port "+PORT)); "; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000 "); zip.file(folder+".gitignore","node_modules/ .env .DS_Store "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash npm install ``` ## Run ```bash npm run dev ``` "); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:" "+title+" "+code+" "; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */ *{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e} "); zip.file(folder+"script.js","/* "+title+" — scripts */ "); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Open Double-click `index.html` in your browser. Or serve locally: ```bash npx serve . # or python3 -m http.server 3000 ``` "); zip.file(folder+".gitignore",".DS_Store node_modules/ .env "); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/**(.+?)**/g,"$1"); hc=hc.replace(/ {2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. Files: - "+app+".md (Markdown) - "+app+".html (styled HTML) "); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); }function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}