├── .github
├── ISSUE_TEMPLATE
│ ├── sweep-bugfix.yml
│ ├── sweep-feature.yml
│ └── sweep-refactor.yml
└── workflows
│ ├── on-new-issue.yml
│ └── pr-agent.yaml
├── .gitignore
├── .pr_agent.toml
├── README.md
├── examples
├── README.md
├── __init__.py
├── bank_account
│ ├── _.codiumai.toml
│ ├── __init__.py
│ ├── bank_account.py
│ └── bank_account_modified.py
├── bank_account_2
│ ├── README.md
│ ├── __init__.py
│ ├── bank_account_2.py
│ ├── bank_account_2_modified.py
│ ├── bank_account_2_with_included_tests.py
│ ├── test_bank_account.py
│ ├── test_bank_account_free_functions.py
│ └── test_bank_account_unittest.py
├── bank_account_3_context_games
│ ├── README.md
│ ├── __init__.py
│ ├── bank_account_3.py
│ ├── bank_account_3_helpers.py
│ ├── test_bank_account_3.py
│ └── test_bank_account_3_free_functions.py
├── bulleted_list
│ ├── __init__.py
│ ├── parse_bulleted_list.py
│ ├── parse_bulleted_list_modified.py
│ └── test_parse_bulleted_list.py
├── client_age_generation
│ ├── __init__.py
│ ├── client_age_generation.py
│ └── test_client_age_generation.py
├── example.svg
├── library
│ ├── __init__.py
│ └── library.py
├── library_2
│ ├── __init__.py
│ ├── book_2.py
│ ├── library_2.py
│ ├── random_data_gen.py
│ └── test_library_2.py
├── library_3
│ ├── __init__.py
│ ├── active_borrow.py
│ ├── admin.py
│ ├── admin_management.py
│ ├── admin_management_factory.py
│ ├── audit_log.py
│ ├── audit_log_db.py
│ ├── book_borrowing_db.py
│ ├── book_info.py
│ ├── book_inventory_listing.py
│ ├── book_listing.py
│ ├── copy_of_test_library.py
│ ├── in_memory_library_book_db.py
│ ├── in_memory_user_db.py
│ ├── librarian.py
│ ├── librarian_book_management.py
│ ├── librarian_book_management_factory.py
│ ├── library_3.py
│ ├── library_factory.py
│ ├── member.py
│ ├── member_book_management.py
│ ├── member_book_management_factory.py
│ ├── permissions.py
│ ├── test_library.py
│ ├── user.py
│ ├── user_book_management.py
│ └── user_management.py
├── quick_sort
│ ├── __init__.py
│ ├── quick_sort.py
│ └── test_quick_sort.py
├── user.sql
└── yaml_strip
│ ├── __init__.py
│ ├── test_yaml_strip.py
│ └── yaml_strip.py
├── media
└── docs
│ ├── Closedalphabanner.png
│ ├── Generatetests013_org_long.gif
│ ├── GeneratetestsV2.gif
│ ├── Joincommunity.png
│ ├── Step1.png
│ ├── Step2.png
│ ├── Step3.png
│ ├── Step4.png
│ ├── Step5.png
│ ├── Step6.png
│ ├── Step7.png
│ ├── Step8.png
│ ├── TestGeneration.gif
│ ├── Tip1.png
│ ├── auth1.png
│ ├── auth2.png
│ ├── auth3.png
│ ├── auth4.png
│ ├── generateButtons.png
│ ├── installed.png
│ ├── signin.png
│ └── uninstallS1.png
└── requirements.txt
/.github/ISSUE_TEMPLATE/sweep-bugfix.yml:
--------------------------------------------------------------------------------
1 | name: Bugfix
2 | title: 'Sweep: '
3 | description: Write something like "We notice ... behavior when ... happens instead of ...""
4 | labels: sweep
5 | body:
6 | - type: textarea
7 | id: description
8 | attributes:
9 | label: Details
10 | description: More details about the bug
11 | placeholder: The bug might be in ... file
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/sweep-feature.yml:
--------------------------------------------------------------------------------
1 | name: Feature Request
2 | title: 'Sweep: '
3 | description: Write something like "Write an api endpoint that does "..." in the "..." file"
4 | labels: sweep
5 | body:
6 | - type: textarea
7 | id: description
8 | attributes:
9 | label: Details
10 | description: More details for Sweep
11 | placeholder: The new endpoint should use the ... class from ... file because it contains ... logic
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/sweep-refactor.yml:
--------------------------------------------------------------------------------
1 | name: Refactor
2 | title: 'Sweep: '
3 | description: Write something like "Modify the ... api endpoint to use ... version and ... framework"
4 | labels: sweep
5 | body:
6 | - type: textarea
7 | id: description
8 | attributes:
9 | label: Details
10 | description: More details for Sweep
11 | placeholder: We are migrating this function to ... version because ...
--------------------------------------------------------------------------------
/.github/workflows/on-new-issue.yml:
--------------------------------------------------------------------------------
1 | name: Run pr agent on every opened issue, respond to user comments on an issue
2 |
3 | #When the action is triggered
4 | on:
5 | issues:
6 | types: [opened] #New issue
7 |
8 | # Read env. variables
9 | env:
10 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
11 | GITHUB_API_URL: ${{ github.api_url }}
12 | GIT_REPO_URL: ${{ github.event.repository.clone_url }}
13 | ISSUE_URL: ${{ github.event.issue.html_url || github.event.comment.html_url }}
14 | ISSUE_BODY: ${{ github.event.issue.body || github.event.comment.body }}
15 | OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
16 |
17 | # The actual set of actions
18 | jobs:
19 | issue_agent:
20 | runs-on: ubuntu-latest
21 | if: ${{ github.event.sender.type != 'Bot' }}
22 |
23 | # Set required permissions
24 | permissions:
25 | contents: read # For reading repository contents
26 | issues: write # For commenting on issues
27 |
28 | steps:
29 | - name: Run PR Agent on Issues
30 | if: ${{ env.ISSUE_URL != '' }}
31 | uses: docker://codiumai/pr-agent:latest
32 | with:
33 | entrypoint: /bin/bash #Replace invoking cli.py directly with a shell
34 | args: |
35 | -c "cd /app && \
36 | echo 'Running Issue Agent action step on ISSUE_URL=$ISSUE_URL' && \
37 | export config__git_provider='github' && \
38 | export github__user_token=$GITHUB_TOKEN && \
39 | export github__base_url=$GITHUB_API_URL && \
40 | export openai__key=$OPENAI_KEY && \
41 | export config__verbosity_level=2 && \
42 | python -m pr_agent.cli --issue_url=$ISSUE_URL help_docs --pr_help_docs.repo_url=https://github.com/qodo-ai/pr-agent.git \"$ISSUE_BODY\""
43 |
44 |
--------------------------------------------------------------------------------
/.github/workflows/pr-agent.yaml:
--------------------------------------------------------------------------------
1 | name: Qode Merge PR-Agent (OpenAI)
2 |
3 | on:
4 | pull_request:
5 | types: [ opened, reopened, ready_for_review ]
6 | issue_comment:
7 | jobs:
8 | pr_agent_job:
9 | if: ${{ github.event.sender.type != 'Bot' }}
10 | runs-on: ubuntu-latest
11 | permissions:
12 | issues: write
13 | pull-requests: write
14 | contents: write
15 | name: Run pr agent on every pull request, respond to user comments
16 | steps:
17 | - name: PR Agent action step
18 | id: pragent
19 | uses: Codium-ai/pr-agent@main
20 | env:
21 | OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 | github_action_config.auto_review: "true" # enable\disable auto review
24 | github_action_config.auto_describe: "true" # enable\disable auto describe
25 | github_action_config.auto_improve: "true" # enable\disable auto improve
26 | github_action_config.pr_actions: '["opened", "reopened", "ready_for_review", "review_requested"]'
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | env/
4 |
5 | # Compiled python modules.
6 | *.pyc
7 |
8 | # Setuptools distribution folder.
9 | /dist/
10 | /build/
11 |
12 | # Python egg metadata, regenerated from source files by setuptools.
13 | /*.egg-info
14 | /*.egg
15 |
16 |
17 | __pycache__
18 |
19 | .idea
20 | .hypothesis
21 | .testmondata
22 |
23 | .vscode
24 |
25 | .coverage
26 | .env
27 |
28 | # pyenv
29 | .python-version
30 |
--------------------------------------------------------------------------------
/.pr_agent.toml:
--------------------------------------------------------------------------------
1 |
2 | [pr_reviewer]
3 | extra_instructions = ""
4 | enable_review_labels_security = false
5 | enable_review_labels_effort = false
6 | require_can_be_split_review = true
7 | enable_auto_approval = true
8 | maximal_review_effort = 1
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodiumAI - Meaningful tests for busy devs
2 |
3 | [](https://www.codium.ai/#Contact-us)
4 |
5 | ---
6 |
7 | > CodiumAI analyzes your Python code and generates meaningful tests to catch bugs before you ship. With Codium, you can easily and quickly create comprehensive test suites that help you ensure the reliability and correctness of your software.
8 |
9 | ---
10 |
11 | 
12 |
13 | _Closed Alpha Version 1.0.0 - Supported in VSCode version 1.58.0 and above_
14 |
15 | ## Features
16 |
17 | #### 🤖 Generates unit tests automatically
18 |
19 | Simply press the "generate tests" button above your Python class or function, and CodiumAI will generate a set of suggested tests for different use cases.
20 |
21 | #### ✨ Works seamlessly with VSCode
22 |
23 | The generated tests will be displayed in a new tab in your VSCode IDE, along with your code description, so you can easily review and edit them as needed.
24 |
25 | #### 🚀 Helps you improve code quality
26 |
27 | By creating comprehensive test suites, our tool helps you catch and fix bugs early, and ensures that your code is reliable and maintainable.
28 |
29 | ---
30 |
31 | ## Installing / Getting started
32 |
33 | 
34 |
35 |
36 | 
37 |
38 |
39 | 
40 |
41 |
42 | 
43 |
44 |
45 | 
46 |
47 |
48 | 
49 |
50 |
51 | 
52 |
53 |
54 | 
55 |
56 |
57 | 1. After installation, you should receive a notification on the bottom of the VSCode editor. Click "Sign in" button in the notification popup to activate Codium with your GitHub account.
58 |
59 | > If you can't see the notification on the bottom right of the editor window, click the button labeled Codium in the bottom status bar.
60 |
61 | 2. You will be redirected to the GitHub login page.
62 |
63 | 3. Once you confirm the activation you should be redirected back to the editor. Status notification should show your GitHub username when the activation was successful.
64 |
65 | 4. Open existing Python file or write a new Python class/function and press the "Generate Tests" on top of the class/function.
66 |
67 | 5. A new tab will open in your VSCode IDE with the generated tests, along with your code description and test strategies description.
68 |
69 | 6. Review tests and edit tests strategies to improve the quality of the next tests generation.
70 |
71 | 7. Use "Redo tests" to refine your tests according to your edits.
72 |
73 | 8. "Accept" to add the generated tests to a new file.
74 |
75 | > Tip 1: If you can't see the `Generate Tests` button you might have to set `"editor.codeLens": true,` in your VSCode configuration file.
76 | > Tip 2: You can show and hide Codium panel in the extension settings or from the command palette.
77 |
78 | 
79 |
80 |
81 | ## How to uninstall
82 |
83 | 1. Select "Codium" button in the bottom status bar.
84 | 2. Hover over the authentication notification, select the settings icon and "Manage Extension" option from the dropdown.
85 | 3. Codium Extension will open in a new tab. Select Uninstall and Reload VSCode.
86 |
87 | ## Links
88 |
89 | [](https://discord.gg/TqNxGqFW)
90 |
91 | - Discord community: https://discord.gg/TqNxGqFW
92 | - Code examples: https://github.com/Codium-ai/codium-code-examples
93 | - Project homepage: https://codium.ai
94 | - Blog: https://www.codium.ai/blog
95 |
96 | ## Terms of use
97 |
98 | - Terms of use: https://www.codium.ai/terms-of-use
99 | - Privacy policy: https://www.codium.ai/platform-privacy-policy
100 | - Please notice - similar to other popular generative-AI tools (such as copilot), we also transmit code snippets to our servers.
101 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | # Codium code examples
2 | These are code examples intended for serving as reference while evaluating Codium.
3 |
4 | # What to test
5 | Try creating tests for these files:
6 | ```
7 | examples/bank_account/bank_account.py
8 | examples/colors/colors.py
9 | examples/library/library.py
10 | ```
11 |
--------------------------------------------------------------------------------
/examples/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/__init__.py
--------------------------------------------------------------------------------
/examples/bank_account/_.codiumai.toml:
--------------------------------------------------------------------------------
1 | [tests]
2 |
3 | ## Testing framework to use - this can affect the content of the generated tests
4 | ## as well as the test run command.
5 | ## Possible values are:
6 | ## Python: Pytest, Unittest
7 | ## Javascript / Typescript: Jest, Mocha, Vitest, Karma, Jasmine, QUnit, React Testing Library
8 | ## HOWEVER: running tests in JS / TS is at the moment only supported
9 | ## for Jest, Mocha, Vitest, and React Testing Library
10 | # framework = "Mocha"
11 |
12 | ## An additional Javascript utility library used to test your code, if any.
13 | ## Possible values are None, Testing Library, Enzyme, or Chai. Not applicable to Python projects.
14 | # utility_library = "Chai"
15 |
16 | ## A hint to the test generator about whether to use mocks or not. Possible values are true or false.
17 | # use_mocks = false
18 |
19 | ## How many tests should be generated by default. Fewer tests is faster.
20 | ## Does not apply at the moment to extend-suite tests.
21 | # num_desired_tests = 2
22 |
23 |
24 | ## A multiline string, delimited with triple-quotes (""") serving as an example test that represents
25 | ## what you would like the generated tests to look like in terms of style, setup, etc.
26 | reference_test = """
27 |
28 |
29 | def test_deposit_positive_amount(self):
30 | # Always use lord of the rings characters for testing
31 | account = BankAccount("Gandalf", True)
32 | initial_balance = account.balance()
33 | account.deposit(100)
34 | assert account.balance() == initial_balance + 97.5
35 |
36 |
37 | """
38 |
39 |
40 | [tests.javascript]
41 |
42 | ## When running Javascript / Typescript tests, use this directory as the test process "current working directory".
43 | ## This is a path relative to the location of the config file.
44 | ## Default: The directory containing the config file.
45 | ## Note: the typical setup is to place the config file in the same directory as the relevant `package.json` file,
46 | ## and leave this commented-out.
47 | # overrideTestRunCwd = "./test"
48 |
49 | ## This is the command that's used to run tests.
50 | ## PLEASE READ CAREFULLY:
51 | ##
52 | ## When running tests, CodiumAI generates a temporary file that contains the test code for a single test,
53 | ## and runs that file.
54 | ## When the tests are done, the temporary file is deleted.
55 | ## For component-oriented tests (when you click "test this class" or "test this function"), the temporary file
56 | ## is created next to the file being tested.
57 | ## For extend-suite tests (when you click "add more tests" on a test-suite), the temporary file is created next
58 | ## to the test-suite file.
59 | ##
60 | ## Typically, you're going to want to take the test script defined in your package.json file, and tweak it a
61 | ## little to make it compatible with CodiumAI.
62 | ##
63 | ## You almost always want to start with 'npx' (e.g. 'npx jest', not 'npm jest' or 'yarn test').
64 | ##
65 | ## Note that the test command must be able to run test files that are located in the same directory as the
66 | ## file under test.
67 | ## A common issue is that the test command in the package.json file selects only from
68 | ## a "tests" directory, causing the CodiumAI tests be "not found" - please remove any such restriction from
69 | ## the command / configuration.
70 | ##
71 | ## The placeholder TEST_FILEPATH will be replaced with the actual test file path - this is how we find
72 | ## the file to run.
73 | ##
74 | ## EXAMPLES:
75 | ## Mocha:
76 | ## npx ts-mocha TEST_FILEPATH --require ./test/mocha/setup.ts
77 | ## Jest:
78 | ## npx jest --runTestsByPath TEST_FILEPATH
79 | ##
80 | ## DEBUGGING NOTE:
81 | ## To help debug run-tests issues, you can view run logs in vscode's OUTPUT
82 | ## (select codium-ai from the dropdown).
83 | ## It's helpful to clear the output (right-click -> clear) and then run the tests again.
84 | ##
85 | # overrideTestRunScript = "npx jest --runTestsByPath TEST_FILEPATH"
86 |
87 | ## A multiline string, delimited with triple-quotes ("""),
88 | ## containing import declarations that will be added at the beginning to each test file.
89 | # overrideImports = """
90 | # import {expect} from 'chai'; """
--------------------------------------------------------------------------------
/examples/bank_account/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/bank_account/__init__.py
--------------------------------------------------------------------------------
/examples/bank_account/bank_account.py:
--------------------------------------------------------------------------------
1 | class BankAccount:
2 | """ Create a new bank account """
3 | def __init__(self, name, hasCommissionDiscount):
4 | self._name = name
5 | self._hasCommissionDiscount = hasCommissionDiscount
6 | self._balance = 0
7 | self._commission_rate = BankAccount._calc_commission_rate(hasCommissionDiscount)
8 |
9 | def info(self):
10 | """ Account information """
11 | return {
12 | "name": self._name,
13 | "current_balance": self._balance,
14 | }
15 |
16 | def deposit(self, amount):
17 | """ deposit money """
18 | if amount > 0:
19 | self._balance -= amount - self._calc_commission_rate(self._hasCommissionDiscount)
20 | else:
21 | raise ValueError("deposit amount must be larger than 0")
22 |
23 | def balance(self):
24 | return self._balance
25 |
26 | def withdraw(self, amount):
27 | """ withdraw money """
28 | if self._balance >= amount > 0:
29 | self._balance += (amount + self._calc_commission_rate(self._hasCommissionDiscount))
30 | else:
31 | raise ValueError("Insufficient funds for withdraw")
32 |
33 | def transfer_to_other_account(self, amount, other_account):
34 | """ transfer money """
35 | if amount <= 0:
36 | raise ValueError("Transfer amount must be larger than 0")
37 | amount_including_commission = amount + self._commission_rate
38 | if self._balance >= amount_including_commission > 0:
39 | self._balance -= amount_including_commission
40 | other_account._balance += amount
41 | else:
42 | raise ValueError("Insufficient funds for transfer")
43 |
44 | @staticmethod
45 | def _calc_commission_rate(hasCommisionDiscount):
46 | """ Get the rate of commission for this account """
47 | if hasCommisionDiscount:
48 | return 2.5
49 | else:
50 | return 5
51 |
--------------------------------------------------------------------------------
/examples/bank_account/bank_account_modified.py:
--------------------------------------------------------------------------------
1 | class BankAccount:
2 | """ Create a new bank account """
3 | def __init__(self, name, hasCommissionDiscount):
4 | self._name = name
5 | self._hasCommissionDiscount = hasCommissionDiscount
6 | self._balance = 0
7 | self._commission_rate = BankAccount._calc_commission_rate(hasCommissionDiscount)
8 |
9 | def info(self):
10 | """ Account information """
11 | return {
12 | "name": self._name,
13 | "current_balance": self._balance,
14 | }
15 |
16 | def deposit(self, amount):
17 | """ deposit money """
18 | if amount > 0:
19 | self._balance += amount - self._calc_commission_rate(self._hasCommissionDiscount)
20 | else:
21 | raise ValueError("deposit amount must be larger than 0")
22 |
23 | def balance(self):
24 | return self._balance
25 |
26 | def withdraw(self, amount):
27 | """ withdraw money """
28 | if self._balance >= amount > 0:
29 | self._balance -= (amount + self._calc_commission_rate(self._hasCommissionDiscount))
30 | else:
31 | raise ValueError("Insufficient funds for withdraw")
32 |
33 | def can_withdraw(self, amount):
34 | return self._balance >= amount > 0
35 |
36 | def transfer_to_other_account(self, amount, other_account):
37 | """ transfer money """
38 | if amount <= 0:
39 | raise ValueError("Transfer amount must be larger than 0")
40 | amount_including_commission = amount + self._commission_rate
41 | if self._balance >= amount_including_commission > 0:
42 | self._balance -= amount_including_commission
43 | other_account._balance += amount
44 | else:
45 | raise ValueError("Insufficient funds for transfer")
46 |
47 | @staticmethod
48 | def _calc_commission_rate(hasCommisionDiscount):
49 | """ Get the rate of commission for this account """
50 | if hasCommisionDiscount:
51 | return 2.5
52 | else:
53 | return 9
54 |
--------------------------------------------------------------------------------
/examples/bank_account_2/README.md:
--------------------------------------------------------------------------------
1 | # Why another bank_account example?
2 | Because for demoing component-oriented tests, we want that test files for the other example won't exist -
3 | but for testing add-test-to-suite we do need them.
--------------------------------------------------------------------------------
/examples/bank_account_2/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/bank_account_2/__init__.py
--------------------------------------------------------------------------------
/examples/bank_account_2/bank_account_2.py:
--------------------------------------------------------------------------------
1 | class BankAccount2:
2 | """ Create a new bank account """
3 | def __init__(self, name, hasCommissionDiscount):
4 | self._name = name
5 | self._hasCommissionDiscount = hasCommissionDiscount
6 | self._balance = 0
7 | self._commission_rate = BankAccount2._calc_commission_rate(hasCommissionDiscount)
8 |
9 | def info(self):
10 | """ Account information """
11 | return {
12 | "name": self._name,
13 | "current_balance": self._balance,
14 | }
15 |
16 | def deposit(self, amount):
17 | """ deposit money """
18 | if amount > 0:
19 | self._balance += amount - self._calc_commission_rate(self._hasCommissionDiscount)
20 | else:
21 | raise ValueError("deposit amount must be larger than 0")
22 |
23 | def balance(self):
24 | return self._balance
25 |
26 | def withdraw(self, amount):
27 | """ withdraw money """
28 | if self._balance >= amount > 0:
29 | self._balance -= (amount + self._calc_commission_rate(self._hasCommissionDiscount))
30 | else:
31 | raise ValueError("Insufficient funds for withdraw")
32 |
33 | def transfer_to_other_account(self, amount, other_account):
34 | """ transfer money """
35 | if amount <= 0:
36 | raise ValueError("Transfer amount must be larger than 0")
37 | amount_including_commission = amount + self._commission_rate
38 | if self._balance >= amount_including_commission > 0:
39 | self._balance -= amount_including_commission
40 | other_account._balance += amount
41 | else:
42 | raise ValueError("Insufficient funds for transfer")
43 |
44 | @staticmethod
45 | def _calc_commission_rate(hasCommisionDiscount):
46 | """ Get the rate of commission for this account """
47 | if hasCommisionDiscount:
48 | return 2.5
49 | else:
50 | return 5
51 |
--------------------------------------------------------------------------------
/examples/bank_account_2/bank_account_2_modified.py:
--------------------------------------------------------------------------------
1 | class BankAccount2:
2 | """ Create a new bank account """
3 | def __init__(self, name, hasCommissionDiscount):
4 | self._name = name
5 | self._hasCommissionDiscount = hasCommissionDiscount
6 | self._balance = 0
7 | self._commission_rate = BankAccount2._calc_commission_rate(hasCommissionDiscount)
8 |
9 | def info(self):
10 | """ Account information """
11 | return {
12 | "name": self._name,
13 | "current_balance": self._balance,
14 | }
15 |
16 | def deposit(self, amount):
17 | """ deposit money """
18 | if amount > 0:
19 | self._balance += amount - self._calc_commission_rate(self._hasCommissionDiscount)
20 | else:
21 | raise ValueError("deposit amount must be larger than 0")
22 |
23 | def balance(self):
24 | return self._balance
25 |
26 | def withdraw(self, amount):
27 | """ withdraw money """
28 | if self._balance >= amount > 0:
29 | self._balance -= (amount + self._calc_commission_rate(self._hasCommissionDiscount))
30 | else:
31 | raise ValueError("Insufficient funds for withdraw")
32 |
33 | def can_withdraw(self, amount):
34 | return self._balance >= amount > 0
35 |
36 | def transfer_to_other_account(self, amount, other_account):
37 | """ transfer money """
38 | if amount <= 0:
39 | raise ValueError("Transfer amount must be larger than 0")
40 | amount_including_commission = amount + self._commission_rate
41 | if self._balance >= amount_including_commission > 0:
42 | self._balance -= amount_including_commission
43 | other_account._balance += amount
44 | else:
45 | raise ValueError("Insufficient funds for transfer")
46 |
47 | @staticmethod
48 | def _calc_commission_rate(hasCommisionDiscount):
49 | """ Get the rate of commission for this account """
50 | if hasCommisionDiscount:
51 | return 2.5
52 | else:
53 | return 9
54 |
--------------------------------------------------------------------------------
/examples/bank_account_2/bank_account_2_with_included_tests.py:
--------------------------------------------------------------------------------
1 | class BankAccount2:
2 | """ Create a new bank account """
3 | def __init__(self, name, hasCommissionDiscount):
4 | self._name = name
5 | self._hasCommissionDiscount = hasCommissionDiscount
6 | self._balance = 0
7 | self._commission_rate = BankAccount2._calc_commission_rate(hasCommissionDiscount)
8 |
9 | def info(self):
10 | """ Account information """
11 | return {
12 | "name": self._name,
13 | "current_balance": self._balance,
14 | }
15 |
16 | def deposit(self, amount):
17 | """ deposit money """
18 | if amount > 0:
19 | self._balance += amount - self._calc_commission_rate(self._hasCommissionDiscount)
20 | else:
21 | raise ValueError("deposit amount must be larger than 0")
22 |
23 | def balance(self):
24 | return self._balance
25 |
26 | def withdraw(self, amount):
27 | """ withdraw money """
28 | if self._balance >= amount > 0:
29 | self._balance -= (amount + self._calc_commission_rate(self._hasCommissionDiscount))
30 | else:
31 | raise ValueError("Insufficient funds for withdraw")
32 |
33 | def transfer_to_other_account(self, amount, other_account):
34 | """ transfer money """
35 | if amount <= 0:
36 | raise ValueError("Transfer amount must be larger than 0")
37 | amount_including_commission = amount + self._commission_rate
38 | if self._balance >= amount_including_commission > 0:
39 | self._balance -= amount_including_commission
40 | other_account._balance += amount
41 | else:
42 | raise ValueError("Insufficient funds for transfer")
43 |
44 | @staticmethod
45 | def _calc_commission_rate(hasCommisionDiscount):
46 | """ Get the rate of commission for this account """
47 | if hasCommisionDiscount:
48 | return 2.5
49 | else:
50 | return 5
51 |
52 |
53 | def test_deposit_positive_amount():
54 | gandalf = BankAccount2("Gandalf", True)
55 | initial_balance = gandalf.balance()
56 | gandalf.deposit(100)
57 | assert gandalf.balance() == initial_balance + 97.5
58 |
59 | def test_withdraw_positive_amount():
60 | frodo = BankAccount2("Frodo", True)
61 | frodo.deposit(100)
62 | initial_balance = frodo.balance()
63 | frodo.withdraw(50)
64 | assert frodo.balance() == initial_balance - 52.5
65 |
66 | def test_withdraw_more_than_balance():
67 | gandalf = BankAccount2("Gandalf", True)
68 | gandalf.deposit(100)
69 | with pytest.raises(ValueError):
70 | gandalf.withdraw(150)
71 |
72 | # Cannot transfer a negative amount from one bank account to another
73 | def test_transfer_negative_amount():
74 | gandalf = BankAccount2("Gandalf", True)
75 | aragorn = BankAccount2("Aragorn", False)
76 | gandalf.deposit(200)
77 | with pytest.raises(ValueError):
78 | gandalf.transfer_to_other_account(-100, aragorn)
79 |
80 | # Can transfer a positive amount from one bank account to another
81 | def test_transfer_positive_amount():
82 | frodo = BankAccount2("Frodo", True)
83 | gandalf = BankAccount2("Gandalf", False)
84 | frodo.deposit(200)
85 | gandalf.deposit(0)
86 | initial_frodo_balance = frodo.balance()
87 | initial_gandalf_balance = gandalf.balance()
88 | frodo.transfer_to_other_account(100, gandalf)
89 | assert frodo.balance() == initial_frodo_balance - 102.5
90 | assert gandalf.balance() == initial_gandalf_balance + 100
91 |
92 | # Cannot deposit a negative amount into the bank account
93 | def test_deposit_negative_amount():
94 | gandalf = BankAccount2("Gandalf", True)
95 | with pytest.raises(ValueError):
96 | gandalf.deposit(-50)
97 |
98 | # Cannot withdraw a negative amount from the bank account
99 | def test_withdraw_negative_amount():
100 | frodo = BankAccount2("Frodo", True)
101 | frodo.deposit(100)
102 | with pytest.raises(ValueError):
103 | frodo.withdraw(-50)
104 |
105 |
106 |
--------------------------------------------------------------------------------
/examples/bank_account_2/test_bank_account.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from examples.bank_account_2.bank_account_2 import BankAccount2
4 |
5 | class TestBankAccount2:
6 | def setup_method(self):
7 | self.account1 = BankAccount2("John", True)
8 | self.account2 = BankAccount2("Jane", False)
9 |
10 | # Tests that depositing a positive amount increases the account balance.
11 | def test_deposit_positive_amount(self):
12 | initial_balance = self.account1.balance()
13 | self.account1.deposit(100)
14 | assert self.account1.balance() == initial_balance + 97.5
15 |
16 | def test_withdraw_positive_amount(self):
17 | self.account1.deposit(100)
18 | initial_balance = self.account1.balance()
19 | self.account1.withdraw(50)
20 | assert self.account1.balance() == initial_balance - 52.5
21 |
22 | def test_withdraw_more_than_balance(self):
23 | self.account1.deposit(100)
24 | with pytest.raises(ValueError):
25 | self.account1.withdraw(150)
26 |
27 | def test_transfer_more_than_balance(self):
28 | self.account1.deposit(100)
29 | with pytest.raises(ValueError):
30 | self.account1.transfer_to_other_account(150, self.account2)
31 |
32 |
33 | def test_transfer_positive_amount(self):
34 | self.account1.deposit(100)
35 | initial_balance1 = self.account1.balance()
36 | initial_balance2 = self.account2.balance()
37 | self.account1.transfer_to_other_account(50, self.account2)
38 | assert self.account1.balance() == initial_balance1 - 52.5
39 | assert self.account2.balance() == initial_balance2 + 50
40 |
41 |
42 |
43 | class TestBankAccountSimpson:
44 | def setup_method(self):
45 | self.homer = BankAccount2("Homer", True)
46 | self.marge = BankAccount2("Marge", False)
47 |
48 | def test_deposit_negative_amount(self):
49 | with pytest.raises(ValueError):
50 | self.homer.deposit(-100)
51 |
--------------------------------------------------------------------------------
/examples/bank_account_2/test_bank_account_free_functions.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from examples.bank_account_2.bank_account_2 import BankAccount2
4 |
5 |
6 | def test_deposit_positive_amount():
7 | gandalf = BankAccount2("Gandalf", True)
8 | initial_balance = gandalf.balance()
9 | gandalf.deposit(100)
10 | assert gandalf.balance() == initial_balance + 97.5
11 |
12 | def test_withdraw_positive_amount():
13 | frodo = BankAccount2("Frodo", True)
14 | frodo.deposit(100)
15 | initial_balance = frodo.balance()
16 | frodo.withdraw(50)
17 | assert frodo.balance() == initial_balance - 52.5
18 |
19 | def test_withdraw_more_than_balance():
20 | gandalf = BankAccount2("Gandalf", True)
21 | gandalf.deposit(100)
22 | with pytest.raises(ValueError):
23 | gandalf.withdraw(150)
24 |
--------------------------------------------------------------------------------
/examples/bank_account_2/test_bank_account_unittest.py:
--------------------------------------------------------------------------------
1 |
2 | import unittest
3 |
4 | from .bank_account_2 import BankAccount2
5 |
6 | class TestBankAccount(unittest.TestCase):
7 | def setUp(self):
8 | self.account1 = BankAccount2("John", True)
9 | self.account2 = BankAccount2("Jane", False)
10 |
11 | def test_deposit_positive_amount(self):
12 | initial_balance = self.account1.balance()
13 | self.account1.deposit(100)
14 | self.assertEqual(self.account1.balance(), initial_balance + 97.5)
15 |
16 | def test_withdraw_positive_amount(self):
17 | self.account1.deposit(100)
18 | initial_balance = self.account1.balance()
19 | self.account1.withdraw(50)
20 | self.assertEqual(self.account1.balance(), initial_balance - 52.5)
21 |
22 | def test_withdraw_more_than_balance(self):
23 | self.account1.deposit(100)
24 | with self.assertRaises(ValueError):
25 | self.account1.withdraw(150)
26 |
27 | def test_transfer_more_than_balance(self):
28 | self.account1.deposit(100)
29 | with self.assertRaises(ValueError):
30 | self.account1.transfer_to_other_account(150, self.account2)
31 |
32 | def test_transfer_positive_amount(self):
33 | self.account1.deposit(100)
34 | initial_balance1 = self.account1.balance()
35 | initial_balance2 = self.account2.balance()
36 | self.account1.transfer_to_other_account(50, self.account2)
37 | self.assertEqual(self.account1.balance(), initial_balance1 - 52.5)
38 | self.assertEqual(self.account2.balance(), initial_balance2 + 50)
39 |
40 |
41 | if __name__ == '__main__':
42 | unittest.main()
43 |
--------------------------------------------------------------------------------
/examples/bank_account_3_context_games/README.md:
--------------------------------------------------------------------------------
1 | # Why another bank_account example?
2 | This is a variation of the bank account, where it was divided to several files, so it won't be as easy to get
3 | the context.
4 | Specifically, it's for testing extend-suite, which currently doesn't know how to bring in context for things that the
5 | CUT uses - so we need to add the context manually.
6 |
7 | The functionality has also been greatly reduced, so we'll always get relevant tests.
8 | Specifically - the premium account has 3 attributes - commision size, max deposit and max balance.
9 | And the values of all these attributes are in the separate file - so no matter what, we'll always
10 | have tests that check for them and have the wrong values if we don't manually add the context.
11 |
12 | There's a top-level-functions test file and a class-test file, so we can test both.
13 |
--------------------------------------------------------------------------------
/examples/bank_account_3_context_games/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/bank_account_3_context_games/__init__.py
--------------------------------------------------------------------------------
/examples/bank_account_3_context_games/bank_account_3.py:
--------------------------------------------------------------------------------
1 | from examples.bank_account_3_context_games.bank_account_3_helpers import calc_commission_rate, is_deposit_over_balance, is_more_than_max_deposit
2 |
3 |
4 | class BankAccount3:
5 | """ Create a new bank account """
6 | def __init__(self, name, is_premium_account):
7 | self._name = name
8 | self._is_premium_account = is_premium_account
9 | self._balance = 0
10 |
11 | def deposit(self, amount):
12 | """ deposit money """
13 | if amount <= 0:
14 | raise IOError("deposit amount must be larger than 0")
15 |
16 | if is_more_than_max_deposit(self._is_premium_account, amount):
17 | raise ValueError("deposit amount exceeds maximum allowed")
18 |
19 | if is_deposit_over_balance(self._is_premium_account, amount, self._balance):
20 | raise ValueError("deposit amount will exceed maximum allowed balance")
21 |
22 | self._balance += amount - calc_commission_rate(self._is_premium_account)
23 |
24 | def balance(self):
25 | return self._balance
26 |
--------------------------------------------------------------------------------
/examples/bank_account_3_context_games/bank_account_3_helpers.py:
--------------------------------------------------------------------------------
1 | MAX_DEPOSIT_PREMIUM = 1_000_000
2 | MAX_DEPOSIT_NON_PREMIUM = 10_000
3 |
4 | MAX_BALANCE_PREMIUM = 10_000_000
5 | MAX_BALANCE_NON_PREMIUM = 100_000
6 |
7 | def calc_commission_rate(is_premium_account):
8 | if is_premium_account:
9 | return 1.5
10 | else:
11 | return 8
12 |
13 |
14 | def is_more_than_max_deposit(is_premium_account, deposit_amount):
15 | if is_premium_account:
16 | return deposit_amount > MAX_DEPOSIT_PREMIUM
17 | else:
18 | return deposit_amount > MAX_DEPOSIT_NON_PREMIUM
19 |
20 |
21 | def is_deposit_over_balance(is_premium_account, deposit_amount, balance):
22 | expected_balance = balance + deposit_amount - calc_commission_rate(is_premium_account)
23 |
24 | if is_premium_account:
25 | return expected_balance > MAX_BALANCE_PREMIUM
26 | else:
27 | return expected_balance > MAX_BALANCE_NON_PREMIUM
28 |
--------------------------------------------------------------------------------
/examples/bank_account_3_context_games/test_bank_account_3.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from examples.bank_account_3_context_games.bank_account_3 import BankAccount3
3 |
4 |
5 | class TestBankAccountSimpson:
6 | def setup_method(self):
7 | self.homer = BankAccount3("Homer", True)
8 | self.marge = BankAccount3("Marge", False)
9 |
10 | def test_deposit_with_commission_discount_true(self):
11 | initial_balance = self.homer.balance()
12 | deposit_amount = 100
13 | expected_commission = 1.5
14 | expected_balance = initial_balance + deposit_amount - expected_commission
15 |
16 | self.homer.deposit(deposit_amount)
17 |
18 | assert self.homer.balance() == expected_balance
19 |
--------------------------------------------------------------------------------
/examples/bank_account_3_context_games/test_bank_account_3_free_functions.py:
--------------------------------------------------------------------------------
1 | from examples.bank_account_3_context_games.bank_account_3 import BankAccount3
2 |
3 | def test_deposit_with_premium_account_true():
4 | homer = BankAccount3("Homer", True)
5 | initial_balance = homer.balance()
6 | deposit_amount = 100
7 | expected_commission = 1.5
8 | expected_balance = initial_balance + deposit_amount - expected_commission
9 |
10 | homer.deposit(deposit_amount)
11 |
12 | assert homer.balance() == expected_balance
13 |
--------------------------------------------------------------------------------
/examples/bulleted_list/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/bulleted_list/__init__.py
--------------------------------------------------------------------------------
/examples/bulleted_list/parse_bulleted_list.py:
--------------------------------------------------------------------------------
1 | from typing import List, Literal, Optional
2 |
3 |
4 | def parse_bullet_list(list_str: str) -> Optional[List[str]]:
5 | try:
6 | if list_str is None:
7 | return []
8 | if list_str.strip() == "":
9 | return []
10 | list_str = list_str.replace("\n*", "\n-").replace("\n%", "\n-")
11 | items = list_str.split("\n-")
12 | items = [line.strip().strip("- \n\t").strip("* \n\t").strip("% \n\t") for line in items]
13 | items = [line for line in items if line != ""]
14 | if len(items) == 0:
15 | return []
16 | return items
17 | except Exception as e:
18 | return []
19 |
20 |
21 | def select_testing_framework_from_str(data_str: str) -> Literal["pytest", "unittest"]:
22 | if "unittest" in data_str.lower():
23 | return "unittest"
24 | else:
25 | return "pytest"
--------------------------------------------------------------------------------
/examples/bulleted_list/parse_bulleted_list_modified.py:
--------------------------------------------------------------------------------
1 | from typing import List, Literal, Optional
2 |
3 |
4 | def parse_bullet_list(list_str: str) -> Optional[List[str]]:
5 | try:
6 | if list_str is None:
7 | return []
8 | if list_str.strip() == "":
9 | return []
10 | list_str = list_str.replace("\n*", "\n-").replace("\n%", "\n-")
11 | items = list_str.split("\n-")
12 | items = [line.strip().strip("- \n\t").strip("* \n\t").strip("% \n\t") for line in items]
13 | items = [line for line in items if line != ""]
14 | if len(items) == 0:
15 | return []
16 | return items
17 | except Exception as e:
18 | return []
19 |
20 |
21 | def select_testing_framework_from_str(data_str: str) -> Literal["pytest", "unittest"]:
22 | if "unittest" in data_str.lower():
23 | return "unittest"
24 | else:
25 | return "pytest"
--------------------------------------------------------------------------------
/examples/bulleted_list/test_parse_bulleted_list.py:
--------------------------------------------------------------------------------
1 | from examples.bulleted_list.parse_bulleted_list import parse_bullet_list
2 |
3 |
4 | class TestParseBulletedList:
5 | def test_parse_multiline_items(self):
6 | """
7 | Testes the following features:
8 | - For each item, prefix or suffix of whitespaces and / or '-' are ignored.
9 | - Items can be multiline (delimited by '\n-')
10 | """
11 | data = """
12 |
13 | - first
14 | still first
15 | --second
16 |
17 | -- -- - third
18 |
19 | It is still third ------
20 |
21 | """
22 | expected_first = """first
23 | still first"""
24 | expected_second = "second"
25 | expected_third = """third
26 |
27 | It is still third"""
28 | expected = [
29 | expected_first,
30 | expected_second,
31 | expected_third,
32 | ]
33 | assert parse_bullet_list(data) == expected
34 |
--------------------------------------------------------------------------------
/examples/client_age_generation/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/client_age_generation/__init__.py
--------------------------------------------------------------------------------
/examples/client_age_generation/client_age_generation.py:
--------------------------------------------------------------------------------
1 | def get_client_age_generation_py(client):
2 | age = client.get('age')
3 | if age is None or age < 0:
4 | return {'set': False}
5 |
6 | if age <= 18:
7 | generation = 'Gen.Z'
8 | elif age < 34:
9 | generation = 'Gen.Y'
10 | else:
11 | generation = 'Gen.X'
12 |
13 | return {'gen': generation, 'set': True}
14 |
15 | def test_valid_client_age_under_18():
16 | client = {'age': 8}
17 | expected_res = {'gen': 'Gen.Z', 'set': True}
18 | assert get_client_age_generation_py(client) == expected_res
19 |
--------------------------------------------------------------------------------
/examples/client_age_generation/test_client_age_generation.py:
--------------------------------------------------------------------------------
1 | # Generated by CodiumAI
2 | from examples.client_age_generation.client_age_generation import get_client_age_generation_py
3 |
4 |
5 | import pytest
6 |
7 | class TestGetClientAgeGenerationPy:
8 |
9 | # Returns {'gen': 'Gen.Z', 'set': True} when client age is 18 or less
10 | def test_client_age_under_18(self):
11 | client = {'age': 8}
12 | expected_res = {'gen': 'Gen.Z', 'set': True}
13 | assert get_client_age_generation_py(client) == expected_res
14 |
15 | # Returns {'gen': 'Gen.Y', 'set': True} when client age is between 18 and 34
16 | def test_client_age_between_18_and_34(self):
17 | client = {'age': 25}
18 | expected_res = {'gen': 'Gen.Y', 'set': True}
19 | assert get_client_age_generation_py(client) == expected_res
20 |
21 | # Returns {'gen': 'Gen.X', 'set': True} when client age is greater than 34
22 | def test_client_age_greater_than_34(self):
23 | client = {'age': 40}
24 | expected_res = {'gen': 'Gen.X', 'set': True}
25 | assert get_client_age_generation_py(client) == expected_res
26 |
27 | # Returns {'set': False} when client age is None
28 | def test_client_age_none(self):
29 | client = {'age': None}
30 | expected_res = {'set': False}
31 | assert get_client_age_generation_py(client) == expected_res
32 |
33 | # Returns {'set': False} when client age is negative
34 | def test_client_age_negative(self):
35 | client = {'age': -10}
36 | expected_res = {'set': False}
37 | assert get_client_age_generation_py(client) == expected_res
38 |
39 | # Returns {'gen': 'Gen.Z', 'set': True} when client age is 0
40 | def test_client_age_zero(self):
41 | client = {'age': 0}
42 | expected_res = {'gen': 'Gen.Z', 'set': True}
43 | assert get_client_age_generation_py(client) == expected_res
44 |
--------------------------------------------------------------------------------
/examples/example.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/examples/library/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/library/__init__.py
--------------------------------------------------------------------------------
/examples/library/library.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 | from typing import List, Optional
5 |
6 |
7 | class Library:
8 | def __init__(self) -> None:
9 | self._available_books: List[Book] = []
10 | self._borrowed_books: List[Book] = []
11 |
12 | def add_new_book_to_library(self, book: Book) -> None:
13 | self._available_books.append(book)
14 |
15 | def remove_book(self, book: Book) -> None:
16 | if book in self._available_books:
17 | self._available_books.remove(book)
18 | if book in self._borrowed_books:
19 | self._borrowed_books.remove(book)
20 |
21 | def borrow_book(self, book: Book) -> None:
22 | if book not in self._available_books:
23 | raise ValueError(f"Book {book} is not available for borrowing")
24 | self._available_books.remove(book)
25 | self._borrowed_books.append(book)
26 |
27 | def return_borrowed_book(self, book: Book) -> None:
28 | if book not in self._borrowed_books:
29 | if not book in self._available_books:
30 | self._available_books.append(book)
31 | raise ValueError(f"Book {book} is not in borrowed books list")
32 | self._borrowed_books.remove(book)
33 | self._available_books.append(book)
34 |
35 | def find_available_book_by_title(self, title: int) -> Optional[Book]:
36 | for book in self._available_books:
37 | if book.title == title:
38 | return book
39 | return None
40 |
41 | def find_available_book_by_author(self, author: int) -> Optional[Book]:
42 | for book in self._available_books:
43 | if book.author == author:
44 | return book
45 | return None
46 |
47 |
48 | @dataclass(frozen=True)
49 | class Book:
50 | title: str
51 | author: str
52 |
--------------------------------------------------------------------------------
/examples/library_2/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/library_2/__init__.py
--------------------------------------------------------------------------------
/examples/library_2/book_2.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 |
5 |
6 | @dataclass(frozen=True)
7 | class Book2:
8 | title: str
9 | author: str
10 |
--------------------------------------------------------------------------------
/examples/library_2/library_2.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from typing import List, Optional
4 |
5 | from examples.library_2.book_2 import Book2
6 |
7 |
8 | class Library2:
9 | def __init__(self) -> None:
10 | self._available_books: List[Book2] = []
11 | self._borrowed_books: List[Book2] = []
12 |
13 | def add_new_book_to_library(self, book: Book2) -> None:
14 | self._available_books.append(book)
15 |
16 | def remove_book(self, book: Book2) -> None:
17 | if book in self._available_books:
18 | self._available_books.remove(book)
19 | if book in self._borrowed_books:
20 | self._borrowed_books.remove(book)
21 |
22 | def borrow_book(self, book: Book2) -> None:
23 | if book not in self._available_books:
24 | raise ValueError(f"Book {book} is not available for borrowing")
25 | self._available_books.remove(book)
26 | self._borrowed_books.append(book)
27 |
28 | def return_borrowed_book(self, book: Book2) -> None:
29 | if book not in self._borrowed_books:
30 | if not book in self._available_books:
31 | self._available_books.append(book)
32 | raise ValueError(f"Book {book} is not in borrowed books list")
33 | self._borrowed_books.remove(book)
34 | self._available_books.append(book)
35 |
36 | def find_available_book_by_title(self, title: int) -> Optional[Book2]:
37 | for book in self._available_books:
38 | if book.title == title:
39 | return book
40 | return None
41 |
42 | def find_available_book_by_author(self, author: int) -> Optional[Book2]:
43 | for book in self._available_books:
44 | if book.author == author:
45 | return book
46 | return None
47 |
--------------------------------------------------------------------------------
/examples/library_2/random_data_gen.py:
--------------------------------------------------------------------------------
1 |
2 | from examples.library_2.book_2 import Book2
3 | import random
4 |
5 |
6 | def random_book() -> Book2:
7 | # https://datavizblog.com/2018/12/21/dataviz-humor-oreilly-programming-book-parody-covers/
8 | BOOK_TITLES = [
9 | "Blaming the user",
10 | "Vague understanding of computer science",
11 | "Writing code that nobody else can read",
12 | "Pointless meetings",
13 | "Coding drunk",
14 | "Buzzword-first design",
15 | ]
16 |
17 | AUTHORS = [
18 | "Bright-eyed junior",
19 | "Disillusioned senior",
20 | "A tired developer",
21 | "Dev with unrealistic deadlines",
22 | ]
23 | return Book2(
24 | title=random.choice(BOOK_TITLES),
25 | author=random.choice(AUTHORS),
26 | )
27 |
--------------------------------------------------------------------------------
/examples/library_2/test_library_2.py:
--------------------------------------------------------------------------------
1 |
2 | from examples.library_2.book_2 import Book2
3 | from examples.library_2.library_2 import Library2
4 | from examples.library_2.random_data_gen import random_book
5 |
6 | class TestLibrary2:
7 | def setup_method(self):
8 | self.library = Library2()
9 |
10 | def test_add_new_book_to_library(self):
11 | book: Book2 = random_book()
12 | self.library.add_new_book_to_library(book)
13 | assert book in self.library._available_books
14 |
--------------------------------------------------------------------------------
/examples/library_3/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/library_3/__init__.py
--------------------------------------------------------------------------------
/examples/library_3/active_borrow.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 |
4 | @dataclass()
5 | class ActiveBorrow:
6 | uid: str
7 | book_id: str
8 | user_id: str
9 |
--------------------------------------------------------------------------------
/examples/library_3/admin.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.user import User
2 |
3 |
4 | class Admin(User):
5 | def __init__(self, uid, username, password):
6 | super().__init__(uid, username, password)
7 |
--------------------------------------------------------------------------------
/examples/library_3/admin_management.py:
--------------------------------------------------------------------------------
1 | class AdminManagement:
2 | def __init__(self, acting_user, user_db):
3 | self._user_db = user_db
4 | self._acting_user = acting_user
5 |
6 | def new_user(self, role, username, password):
7 | return self._user_db.new_user(role, username, password)
8 |
9 | def get_user_by_username(self, username):
10 | return self._user_db.get_user_by_username(username)
11 |
12 | def delete_user(self, uid):
13 | self._user_db.remove_user(uid)
14 |
15 | def update_user(self, user):
16 | # Update user info
17 | pass
18 |
19 |
--------------------------------------------------------------------------------
/examples/library_3/admin_management_factory.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.admin_management import AdminManagement
2 |
3 |
4 | class AdminManagementFactory:
5 | def __init__(self, user_db):
6 | self._user_db = user_db
7 |
8 | def get_admin_management(self, user):
9 | return AdminManagement(user, self._user_db)
10 |
--------------------------------------------------------------------------------
/examples/library_3/audit_log.py:
--------------------------------------------------------------------------------
1 | class AuditLog:
2 | def __init__(self, library):
3 | self.library = library
4 | self.audit_log_db = library.audit_log
5 |
6 | def add_audit_log(self, action):
7 | # Add an audit log
8 | pass
9 |
10 | def find_audit_logs(self, user, action):
11 | # Find audit logs by user and action
12 | pass
13 |
--------------------------------------------------------------------------------
/examples/library_3/audit_log_db.py:
--------------------------------------------------------------------------------
1 | class AuditLogDB:
2 | def __init__(self):
3 | self.audit_logs = []
4 |
5 | def add_audit_log(self, action, user):
6 | self.audit_logs.append((action, user))
7 |
--------------------------------------------------------------------------------
/examples/library_3/book_borrowing_db.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.active_borrow import ActiveBorrow
2 |
3 |
4 | class BookBorrowingDB:
5 | def __init__(self):
6 | self._active_borrows = {}
7 | self._next_uid = 1
8 |
9 | def _get_next_id(self):
10 | uid = self._next_uid
11 | self._next_uid += 1
12 | return uid
13 |
14 | def borrow(self, book_id, user_id):
15 | active_borrow = ActiveBorrow(
16 | self._get_next_id(),
17 | book_id,
18 | user_id,
19 | )
20 | self._active_borrows[active_borrow.uid] = active_borrow
21 | return active_borrow
22 |
23 | def return_book(self, book_id, user):
24 | for borrow in self._active_borrows.values():
25 | if borrow.book_id == book_id and borrow.user_id == user.uid:
26 | self._active_borrows.pop(borrow.uid)
27 | else:
28 | raise ValueError(f"Book with UID {book_id} is not borrowed by user {user.uid}")
29 |
30 | def get_active_borrows(self, book_id):
31 | return [borrow for borrow in self._active_borrows.values() if borrow.book_id == book_id]
32 |
--------------------------------------------------------------------------------
/examples/library_3/book_info.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | @dataclass()
4 | class BookInfo:
5 | uid: str
6 | title: str
7 | author: str
8 |
--------------------------------------------------------------------------------
/examples/library_3/book_inventory_listing.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | from examples.library_3.book_info import BookInfo
4 |
5 | @dataclass()
6 | class BookInventoryListing:
7 | """
8 | The listing inside the inventory, that doesn't change as we borrow books.
9 | """
10 | uid: str
11 | book_info: BookInfo
12 | existing_copies_count: int
13 |
--------------------------------------------------------------------------------
/examples/library_3/book_listing.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 |
3 | from examples.library_3.book_info import BookInfo
4 |
5 | @dataclass()
6 | class BookListing:
7 | uid: str
8 | book_info: BookInfo
9 | existing_copies_count: int
10 | available_copies_count: int
11 |
--------------------------------------------------------------------------------
/examples/library_3/copy_of_test_library.py:
--------------------------------------------------------------------------------
1 | # from examples.library_3.admin import Admin
2 | # from examples.library_3.member import Member
3 | # from examples.library_3.librarian import Librarian
4 | # from examples.library_3.permissions import UserRole
5 | # from examples.library_3.library_factory import make_new_library
6 |
7 |
8 | # class TestLibrary3:
9 | # def setup_method(self):
10 | # self.library, self.root_user = make_new_library("root", "super-secret-root-pass")
11 |
12 | # def test_create_new_user(self):
13 | # admin_mgmt = self.library.get_admin_management(self.root_user)
14 | # librarian_created = admin_mgmt.new_user(UserRole.LIBRARIAN, "giles", "watcher-on-the-wall")
15 |
16 | # librarian_retrieved = admin_mgmt.get_user_by_username("giles")
17 |
18 | # assert librarian_retrieved.uid == librarian_created.uid
19 |
20 |
21 |
22 |
23 |
24 | # # def test_borrow_book(library):
25 | # # user_book_management = library.get_user_book_management(Member("John", "pass1234"))
26 | # # book = BookListing("Book Title", "Author Name", "2022-01-01", 2)
27 | # # user_book_management.borrow_book(book, Member("John", "pass1234"))
28 | # # assert book.available_count == 1
29 |
30 | # # root_admin = Admin("root", "rootpass")
31 |
32 | # # library = Library(root_admin)
33 |
34 | # # global_book_db = GlobalBookDB()
35 | # # library_book_db = LibraryBookDB()
36 | # # book_borrowing_db = BookBorrowingDB()
37 | # # user_book_management = UserBookManagement(library)
38 | # # librarian_book_management = LibrarianBookManagement(library)
39 | # # user_management = UserManagement(library)
40 | # # admin_management = AdminManagement(library)
41 | # # user_db = UserDB()
42 | # # audit_log_db = AuditLogDB()
43 | # # audit_log = AuditLog(library)
44 |
45 | # # library.set_librarian_book_management(librarian_book_management)
46 | # # library.set_user_book_management(user_book_management)
47 | # # library.set_user_management(user_management)
48 | # # library.set_admin_management(admin_management)
49 | # # library.set_audit_log(audit_log)
50 |
51 | # # test_borrow_book(library)
--------------------------------------------------------------------------------
/examples/library_3/in_memory_library_book_db.py:
--------------------------------------------------------------------------------
1 | class InMemoryLibraryBookDB:
2 | """
3 | Books that are available in the library.
4 | Does not track borrowing actions - only the full inventory.
5 | """
6 | def __init__(self):
7 | self._books = {}
8 |
9 | def add_book(self, book_listing):
10 | if book_listing.uid in self._books:
11 | raise ValueError(f"Book with UID {book_listing.uid} already exists")
12 | self._books[book_listing.uid] = book_listing
13 |
14 | def find_books(self, author=None, title=None):
15 | with_author = self.filter_books_by_author(author, self._books.values())
16 | with_author_and_title = self.filter_books_by_title(title, with_author)
17 |
18 | return with_author_and_title
19 |
20 | def filter_books_by_author(self, author, orig_list):
21 | if author is None:
22 | return orig_list
23 | else:
24 | return [book for book in orig_list if book.book_info.author == author]
25 |
26 | def filter_books_by_title(self, title, orig_list):
27 | if title is None:
28 | return orig_list
29 | else:
30 | return [book for book in orig_list if book.book_info.title == title]
31 |
32 | def find_book_by_id(self, book_id):
33 | return self._books.get(book_id)
34 |
35 | def update_copies_count(self, book_id, copies_count):
36 | if copies_count < 0:
37 | raise ValueError("Copies count cannot be negative")
38 | if book_id not in self._books:
39 | raise ValueError(f"Book with UID {book_id} does not exist")
40 | if copies_count == 0:
41 | del self._books[book_id]
42 | else:
43 | self._books[book_id].existing_copies_count = copies_count
44 |
45 |
46 | def remove_book(self, book_id):
47 | self.update_copies_count(book_id, 0)
48 |
--------------------------------------------------------------------------------
/examples/library_3/in_memory_user_db.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.admin import Admin
2 | from examples.library_3.member import Member
3 | from examples.library_3.librarian import Librarian
4 | from examples.library_3.permissions import UserRole
5 |
6 | class InMemoryUserDB:
7 | def __init__(self, root_user):
8 | self._user_id_to_user = {
9 | root_user.uid: root_user,
10 | }
11 | self._next_uid = root_user.uid + 1
12 |
13 | def new_user(self, role, username, password):
14 | user = self._mk_new_user(role, username, password)
15 | self._user_id_to_user[user.uid] = user
16 | return user
17 |
18 | def _mk_new_user(self, role, username, password):
19 | for user in self._user_id_to_user.values():
20 | if user.username == username:
21 | raise ValueError(f"Username {username} is already exists")
22 | if role == UserRole.ADMIN:
23 | return Admin(self._get_next_user_id(), username, password)
24 | elif role == UserRole.MEMBER:
25 | return Member(self._get_next_user_id(), username, password)
26 | elif role == UserRole.LIBRARIAN:
27 | return Librarian(self._get_next_user_id(), username, password)
28 | else:
29 | raise ValueError(f"Unknown role: {role}")
30 |
31 | def _get_next_user_id(self):
32 | uid = self._next_uid
33 | self._next_uid += 1
34 | return uid
35 |
36 | def remove_user(self, uid):
37 | self._user_id_to_user.pop(uid)
38 |
39 | def get_user(self, uid):
40 | return self._user_id_to_user.get(uid)
41 |
42 | def get_user_by_username(self, username):
43 | for user in self._user_id_to_user.values():
44 | if user.username == username:
45 | return user
46 | return None
47 |
48 | def get_user_by_username_and_password(self, username, password):
49 | for user in self._user_id_to_user.values():
50 | if user.username == username and user.password == password:
51 | return user
52 | return None
53 |
54 |
55 | # def update_user(self, user):
56 | # # Update user info
57 | # pass
58 |
--------------------------------------------------------------------------------
/examples/library_3/librarian.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.user import User
2 |
3 |
4 | class Librarian(User):
5 | def __init__(self, uid, username, password):
6 | super().__init__(uid, username, password)
7 |
--------------------------------------------------------------------------------
/examples/library_3/librarian_book_management.py:
--------------------------------------------------------------------------------
1 | class LibrarianBookManagement:
2 | def __init__(self,
3 | acting_user,
4 | library_book_db,
5 | book_borrowing_db,
6 | ):
7 | self._acting_user = acting_user
8 | self._library_book_db = library_book_db
9 | self._book_borrowing_db = book_borrowing_db
10 |
11 | def add_book(self, book_listing):
12 | self._library_book_db.add_book(book_listing)
13 |
14 |
15 | def find_books(self, author=None, title=None):
16 | return self._library_book_db.find_books(author, title)
17 |
18 | def borrow_book(self, book, user):
19 | # Borrow a book on behalf of a user
20 | pass
21 |
22 | def return_book(self, book, user):
23 | # Return a book on behalf of a user
24 | pass
25 |
--------------------------------------------------------------------------------
/examples/library_3/librarian_book_management_factory.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.librarian_book_management import LibrarianBookManagement
2 |
3 |
4 | class LibrarianBookManagementFactory:
5 | def __init__(
6 | self,
7 | library_book_db,
8 | book_borrowing_db,
9 | ):
10 | self._library_book_db = library_book_db
11 | self._book_borrowing_db = book_borrowing_db
12 |
13 | def get_librarian_book_management(self, acting_user):
14 | return LibrarianBookManagement(
15 | acting_user=acting_user,
16 | library_book_db=self._library_book_db,
17 | book_borrowing_db=self._book_borrowing_db,
18 | )
19 |
--------------------------------------------------------------------------------
/examples/library_3/library_3.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.permissions import (
2 | is_admin,
3 | is_librarian,
4 | is_member,
5 | )
6 |
7 |
8 | class Library3:
9 | def __init__(
10 | self,
11 | librarian_book_management_factory,
12 | member_book_management_factory,
13 | # user_management,
14 | admin_management_factory,
15 | # audit_log,
16 | ):
17 | self._librarian_book_management_factory = librarian_book_management_factory
18 | self._member_book_management_factory = member_book_management_factory
19 | # self.user_book_management = None
20 | # self.user_management = None
21 | self._admin_management_factory = admin_management_factory
22 | # self.audit_log = None
23 |
24 | def get_librarian_book_management(self, acting_user):
25 | if is_librarian(acting_user):
26 | return self._librarian_book_management_factory.get_librarian_book_management(acting_user)
27 | else:
28 | raise Exception("User is not authorized to access LibrarianBookManagement")
29 |
30 | def get_member_book_management(self, acting_user):
31 | if is_member(acting_user):
32 | return self._member_book_management_factory.get_member_book_management(acting_user)
33 | else:
34 | raise Exception("User is not authorized to access LibrarianBookManagement")
35 |
36 | # def get_user_book_management(self, user):
37 | # if user.is_member():
38 | # return self.user_book_management
39 | # else:
40 | # raise Exception("User is not authorized to access UserBookManagement")
41 |
42 | # def get_user_management(self, user):
43 | # if user.is_admin() or user.is_librarian():
44 | # return self.user_management
45 | # else:
46 | # raise Exception("User is not authorized to access UserManagement")
47 |
48 | def get_admin_management(self, user):
49 | if is_admin(user):
50 | return self._admin_management_factory.get_admin_management(user)
51 | else:
52 | raise Exception("User is not authorized to access AdminManagement")
53 |
--------------------------------------------------------------------------------
/examples/library_3/library_factory.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.admin import Admin
2 | from examples.library_3.librarian_book_management_factory import LibrarianBookManagementFactory
3 | from examples.library_3.library_3 import Library3
4 | from examples.library_3.in_memory_user_db import InMemoryUserDB
5 | from examples.library_3.admin_management_factory import AdminManagementFactory
6 | from examples.library_3.librarian_book_management import LibrarianBookManagement
7 | from examples.library_3.member_book_management import MemberBookManagement
8 | from examples.library_3.in_memory_library_book_db import InMemoryLibraryBookDB
9 | from examples.library_3.book_borrowing_db import BookBorrowingDB
10 | from examples.library_3.member_book_management_factory import MemberBookManagementFactory
11 |
12 |
13 | def make_new_library(root_username, root_password):
14 | root_user = Admin(1, root_username, root_password)
15 |
16 | user_db = InMemoryUserDB(root_user)
17 | admin_management_factory = AdminManagementFactory(user_db)
18 |
19 | book_db = InMemoryLibraryBookDB()
20 | borrowing_db = BookBorrowingDB()
21 |
22 | librarian_book_management_factory = LibrarianBookManagementFactory(
23 | library_book_db=book_db,
24 | book_borrowing_db=borrowing_db,
25 | )
26 |
27 | member_book_management_factory = MemberBookManagementFactory(
28 | library_book_db=book_db,
29 | book_borrowing_db=borrowing_db,
30 | )
31 |
32 | library = Library3(
33 | librarian_book_management_factory=librarian_book_management_factory,
34 | member_book_management_factory=member_book_management_factory,
35 | admin_management_factory=admin_management_factory,
36 | )
37 | return library, root_user
38 |
--------------------------------------------------------------------------------
/examples/library_3/member.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.user import User
2 |
3 |
4 | class Member(User):
5 | def __init__(self, uid, username, password):
6 | super().__init__(uid, username, password)
7 |
--------------------------------------------------------------------------------
/examples/library_3/member_book_management.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.book_listing import BookListing
2 |
3 |
4 | class MemberBookManagement:
5 | def __init__(
6 | self,
7 | acting_user,
8 | library_book_db,
9 | book_borrowing_db,
10 | ):
11 | self._acting_user = acting_user
12 | self._library_book_db = library_book_db
13 | self._book_borrowing_db = book_borrowing_db
14 |
15 | def find_books(self, author=None, title=None):
16 | inventory_books = self._library_book_db.find_books(author, title)
17 |
18 | def listing_for_inventory_listing(self, book_inventory_listing):
19 | book_id = book_inventory_listing.uid
20 | active_borrows = self._book_borrowing_db.get_active_borrows(book_id)
21 | available_copies_count = book_inventory_listing.existing_copies_count - len(active_borrows)
22 |
23 | return BookListing(
24 | uid=book_inventory_listing.uid,
25 | book_info=book_inventory_listing.book_info,
26 | existing_copies_count=book_inventory_listing.existing_copies_count,
27 | available_copies_count=available_copies_count,
28 | )
29 |
30 | def borrow_book(self, book_id):
31 | book_listing = self._library_book_db.find_book_by_id(book_id)
32 | active_borrows = self._book_borrowing_db.get_active_borrows(book_id)
33 |
34 | if book_listing.existing_copies_count - len(active_borrows) <= 0:
35 | raise ValueError("There are no copies of this book available for borrowing")
36 | return self._book_borrowing_db.borrow(book_listing.uid, self._acting_user.uid)
37 |
38 | def return_book(self, book, user):
39 | # Return a book
40 | pass
41 |
--------------------------------------------------------------------------------
/examples/library_3/member_book_management_factory.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.member_book_management import MemberBookManagement
2 |
3 |
4 | class MemberBookManagementFactory:
5 | def __init__(
6 | self,
7 | library_book_db,
8 | book_borrowing_db,
9 | ):
10 | self._library_book_db = library_book_db
11 | self._book_borrowing_db = book_borrowing_db
12 |
13 | def get_member_book_management(self, acting_user):
14 | return MemberBookManagement(
15 | acting_user=acting_user,
16 | library_book_db=self._library_book_db,
17 | book_borrowing_db=self._book_borrowing_db,
18 | )
19 |
--------------------------------------------------------------------------------
/examples/library_3/permissions.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.admin import Admin
2 | from examples.library_3.member import Member
3 | from examples.library_3.librarian import Librarian
4 |
5 |
6 | def is_admin(user):
7 | return isinstance(user, Admin)
8 |
9 | def is_member(user):
10 | return isinstance(user, Member)
11 |
12 | def is_librarian(user):
13 | return isinstance(user, Librarian)
14 |
15 | class UserRole:
16 | MEMBER = "member"
17 | LIBRARIAN = "librarian"
18 | ADMIN = "admin"
19 |
--------------------------------------------------------------------------------
/examples/library_3/test_library.py:
--------------------------------------------------------------------------------
1 | from examples.library_3.admin import Admin
2 | from examples.library_3.book_info import BookInfo
3 | from examples.library_3.book_inventory_listing import BookInventoryListing
4 | from examples.library_3.book_listing import BookListing
5 | from examples.library_3.member import Member
6 | from examples.library_3.librarian import Librarian
7 | from examples.library_3.permissions import UserRole
8 | from examples.library_3.library_factory import make_new_library
9 |
10 |
11 | class TestLibrary3:
12 | def setup_method(self):
13 | self.library, self.root_user = make_new_library("root", "super-secret-root-pass")
14 |
15 | def test_admin_can_create_new_librarian_user(self):
16 | admin_mgmt = self.library.get_admin_management(self.root_user)
17 | librarian_created = admin_mgmt.new_user(UserRole.LIBRARIAN, "Giles", "watcher-on-the-wall")
18 |
19 | librarian_retrieved = admin_mgmt.get_user_by_username("Giles")
20 |
21 | assert librarian_retrieved.uid == librarian_created.uid
22 |
23 | def test_admin_can_delete_user(self):
24 | admin_mgmt = self.library.get_admin_management(self.root_user)
25 | librarian_created = admin_mgmt.new_user(UserRole.LIBRARIAN, "Giles", "watcher-on-the-wall")
26 |
27 | # Verify the user exists
28 | librarian_retrieved = admin_mgmt.get_user_by_username("Giles")
29 | assert librarian_retrieved.uid == librarian_created.uid
30 |
31 | admin_mgmt.delete_user(librarian_created.uid)
32 | librarian_retrieved_after_delete = admin_mgmt.get_user_by_username("Giles")
33 | assert librarian_retrieved_after_delete is None
34 |
35 | def test_librarian_can_add_books(self):
36 | admin_mgmt = self.library.get_admin_management(self.root_user)
37 | librarian = admin_mgmt.new_user(UserRole.LIBRARIAN, "Giles", "watcher-on-the-wall")
38 |
39 | librarian_book_mgmt = self.library.get_librarian_book_management(librarian)
40 |
41 | book_info = BookInfo(
42 | uid="book-info-uid-1",
43 | author="Dracula",
44 | title="Yummy Humans",
45 | )
46 | book_listing = BookInventoryListing(
47 | uid="book-listing-uid-1",
48 | book_info=book_info,
49 | existing_copies_count=3,
50 | )
51 | librarian_book_mgmt.add_book(book_listing)
52 |
53 | book_listing_retrieved = librarian_book_mgmt.find_books(author="Dracula")
54 | assert book_listing_retrieved == [book_listing]
55 |
56 |
57 | def test_user_can_borrow_book(self):
58 | admin_mgmt = self.library.get_admin_management(self.root_user)
59 | librarian = admin_mgmt.new_user(UserRole.LIBRARIAN, "Giles", "watcher-on-the-wall")
60 | member = admin_mgmt.new_user(UserRole.MEMBER, "Willow", "its-magic")
61 |
62 | librarian_book_mgmt = self.library.get_librarian_book_management(librarian)
63 |
64 | book_info = BookInfo(
65 | uid="book-info-uid-1",
66 | author="Dracula",
67 | title="Yummy Humans",
68 | )
69 | book_listing = BookInventoryListing(
70 | uid="book-listing-uid-1",
71 | book_info=book_info,
72 | existing_copies_count=3,
73 | )
74 | librarian_book_mgmt.add_book(book_listing)
75 |
76 | member_book_mgmt = self.library.get_member_book_management(member)
77 |
78 | borrow = member_book_mgmt.borrow_book(book_listing.uid)
79 |
80 | assert borrow is not None
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/examples/library_3/user.py:
--------------------------------------------------------------------------------
1 | class User:
2 | def __init__(self, uid, username, password):
3 | self.uid = uid
4 | self.username = username
5 | self.password = password
6 |
--------------------------------------------------------------------------------
/examples/library_3/user_book_management.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/library_3/user_book_management.py
--------------------------------------------------------------------------------
/examples/library_3/user_management.py:
--------------------------------------------------------------------------------
1 | class UserManagement:
2 | def __init__(self, library):
3 | self.library = library
4 |
5 | def create_user(self, username, password, role):
6 | # Create a new user
7 | pass
8 |
9 | def delete_user(self, user):
10 | # Delete a user
11 | pass
12 |
13 | def update_user(self, user):
14 | # Update user info
15 | pass
16 |
17 |
--------------------------------------------------------------------------------
/examples/quick_sort/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/quick_sort/__init__.py
--------------------------------------------------------------------------------
/examples/quick_sort/quick_sort.py:
--------------------------------------------------------------------------------
1 | def qsort(lst):
2 | if len(lst) < 2:
3 | return lst
4 |
5 | first_item = lst[0]
6 | rest_of_list = lst[1:]
7 |
8 | smaller_than_first = [k for k in rest_of_list if k <= first_item]
9 | larger_than_first = [k for k in rest_of_list if k > first_item]
10 |
11 | return qsort(smaller_than_first) + [first_item] + qsort(larger_than_first)
12 |
--------------------------------------------------------------------------------
/examples/quick_sort/test_quick_sort.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from hypothesis import given
3 | import hypothesis.strategies as some
4 |
5 | from examples.quick_sort.quick_sort import qsort
6 |
7 | class TestQuickSort:
8 | @pytest.mark.parametrize(
9 | "l,expected",
10 | [
11 | ([], []),
12 | ([1], [1]),
13 | ]
14 | )
15 | def test_sort_simple_lists(self, l, expected):
16 | expected_copy = expected[:]
17 | assert qsort(l) == expected_copy
18 |
19 | class TestQuickSortPBT:
20 | @given(some.lists(some.integers()))
21 | def test_sort_is_idempotent(self, lst):
22 | assert qsort(qsort(lst)) == qsort(lst)
23 |
--------------------------------------------------------------------------------
/examples/user.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE User (
2 | id INT NOT NULL AUTO_INCREMENT,
3 | username VARCHAR(255) NOT NULL,
4 | email VARCHAR(255) NOT NULL,
5 | password VARCHAR(255) NOT NULL,
6 | created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7 | last_login TIMESTAMP,
8 | PRIMARY KEY (id),
9 | UNIQUE KEY (username),
10 | UNIQUE KEY (email)
11 | );
12 |
--------------------------------------------------------------------------------
/examples/yaml_strip/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/examples/yaml_strip/__init__.py
--------------------------------------------------------------------------------
/examples/yaml_strip/test_yaml_strip.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from examples.yaml_strip.yaml_strip import yaml_safe_load
3 |
4 | class TestYamlStrip:
5 | @pytest.mark.parametrize(
6 | "yaml_str,expected",
7 | [
8 | ("""\
9 | foo: bar""", {"foo": "bar"}),
10 | ]
11 | )
12 | def test_clean_yaml(self, yaml_str, expected):
13 | assert yaml_safe_load(yaml_str) == expected
14 |
--------------------------------------------------------------------------------
/examples/yaml_strip/yaml_strip.py:
--------------------------------------------------------------------------------
1 | import re
2 | from typing import Optional
3 | import yaml
4 |
5 | def yaml_safe_load(s):
6 | try:
7 | return yaml.safe_load(strip_yaml(s))
8 | except Exception:
9 | return None
10 |
11 | def strip_yaml(yaml_str: Optional[str]) -> Optional[str]:
12 | if yaml_str is None:
13 | return None
14 | return re.sub(r'^```yaml', '', yaml_str).rstrip('`')
15 |
--------------------------------------------------------------------------------
/media/docs/Closedalphabanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Closedalphabanner.png
--------------------------------------------------------------------------------
/media/docs/Generatetests013_org_long.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Generatetests013_org_long.gif
--------------------------------------------------------------------------------
/media/docs/GeneratetestsV2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/GeneratetestsV2.gif
--------------------------------------------------------------------------------
/media/docs/Joincommunity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Joincommunity.png
--------------------------------------------------------------------------------
/media/docs/Step1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Step1.png
--------------------------------------------------------------------------------
/media/docs/Step2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Step2.png
--------------------------------------------------------------------------------
/media/docs/Step3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Step3.png
--------------------------------------------------------------------------------
/media/docs/Step4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Step4.png
--------------------------------------------------------------------------------
/media/docs/Step5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Step5.png
--------------------------------------------------------------------------------
/media/docs/Step6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Step6.png
--------------------------------------------------------------------------------
/media/docs/Step7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Step7.png
--------------------------------------------------------------------------------
/media/docs/Step8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Step8.png
--------------------------------------------------------------------------------
/media/docs/TestGeneration.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/TestGeneration.gif
--------------------------------------------------------------------------------
/media/docs/Tip1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/Tip1.png
--------------------------------------------------------------------------------
/media/docs/auth1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/auth1.png
--------------------------------------------------------------------------------
/media/docs/auth2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/auth2.png
--------------------------------------------------------------------------------
/media/docs/auth3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/auth3.png
--------------------------------------------------------------------------------
/media/docs/auth4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/auth4.png
--------------------------------------------------------------------------------
/media/docs/generateButtons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/generateButtons.png
--------------------------------------------------------------------------------
/media/docs/installed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/installed.png
--------------------------------------------------------------------------------
/media/docs/signin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/signin.png
--------------------------------------------------------------------------------
/media/docs/uninstallS1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codium-ai/codium-code-examples/1e05b7cc4244cb6054fc7593cb3ddcd5c4bd168d/media/docs/uninstallS1.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pytest
2 | text-unidecode == 1.3
3 | Unidecode == 1.1.1
4 |
--------------------------------------------------------------------------------