mirror of
https://github.com/tiennm99/serena.git
synced 2026-09-04 08:19:48 +00:00
Fix CI failures: Add missing Elixir test repository source files
The lib/ directory was being ignored by the root .gitignore Python packaging rule. This caused CI failures because test files like models.ex, services.ex, etc. were missing from the repository. - Add exception to .gitignore for test/resources/repos/elixir/test_repo/lib - Add all missing Elixir source files: - examples.ex (example functions and data structures) - models.ex (User struct and related functions) - services.ex (UserService module) - test_repo.ex (main module) - utils.ex (utility functions) - ignored_dir/ignored_module.ex (for testing directory filtering) These files are essential for Elixir language server tests to function properly.
This commit is contained in:
@@ -224,3 +224,5 @@ tmp/
|
||||
|
||||
# Elixir
|
||||
/test/resources/repos/elixir/test_repo/deps
|
||||
# Exception: Don't ignore Elixir test repository lib directory (contains source code)
|
||||
!/test/resources/repos/elixir/test_repo/lib
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
defmodule TestRepo.Examples do
|
||||
@moduledoc """
|
||||
Examples module demonstrating usage of models and services.
|
||||
Similar to Python's examples directory, this shows how different modules work together.
|
||||
"""
|
||||
|
||||
alias TestRepo.Models.{User, Item}
|
||||
alias TestRepo.Services.{UserService, ItemService, OrderService}
|
||||
|
||||
defmodule UserManagement do
|
||||
@doc """
|
||||
Creates a complete user workflow example.
|
||||
"""
|
||||
def run_user_example do
|
||||
# Start user service
|
||||
{:ok, user_service} = UserService.start_link()
|
||||
|
||||
# Create users
|
||||
{:ok, alice} = UserService.create_user(user_service, "1", "Alice", "alice@example.com", ["admin"])
|
||||
{:ok, bob} = UserService.create_user(user_service, "2", "Bob", "bob@example.com", ["user"])
|
||||
|
||||
# Get users
|
||||
{:ok, retrieved_alice} = UserService.get_user(user_service, "1")
|
||||
|
||||
# List all users
|
||||
all_users = UserService.list_users(user_service)
|
||||
|
||||
# Clean up
|
||||
GenServer.stop(user_service)
|
||||
|
||||
%{
|
||||
created_alice: alice,
|
||||
created_bob: bob,
|
||||
retrieved_alice: retrieved_alice,
|
||||
all_users: all_users
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Demonstrates user role management.
|
||||
"""
|
||||
def manage_user_roles do
|
||||
user = User.new("role_user", "Role User", "role@example.com")
|
||||
|
||||
# Add roles
|
||||
user_with_admin = User.add_role(user, "admin")
|
||||
user_with_multiple = User.add_role(user_with_admin, "moderator")
|
||||
|
||||
# Check roles
|
||||
has_admin = User.has_role?(user_with_multiple, "admin")
|
||||
has_guest = User.has_role?(user_with_multiple, "guest")
|
||||
|
||||
%{
|
||||
original_user: user,
|
||||
user_with_roles: user_with_multiple,
|
||||
has_admin: has_admin,
|
||||
has_guest: has_guest
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule ShoppingExample do
|
||||
@doc """
|
||||
Creates a complete shopping workflow.
|
||||
"""
|
||||
def run_shopping_example do
|
||||
# Create user and items
|
||||
user = User.new("customer1", "Customer One", "customer@example.com")
|
||||
item1 = Item.new("widget1", "Super Widget", 19.99, "electronics")
|
||||
item2 = Item.new("gadget1", "Cool Gadget", 29.99, "electronics")
|
||||
|
||||
# Create order
|
||||
order = OrderService.create_order("order1", user)
|
||||
|
||||
# Add items to order
|
||||
order_with_item1 = OrderService.add_item_to_order(order, item1)
|
||||
order_with_items = OrderService.add_item_to_order(order_with_item1, item2)
|
||||
|
||||
# Process the order
|
||||
processed_order = OrderService.process_order(order_with_items)
|
||||
completed_order = OrderService.complete_order(processed_order)
|
||||
|
||||
%{
|
||||
user: user,
|
||||
items: [item1, item2],
|
||||
final_order: completed_order,
|
||||
total_cost: completed_order.total
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Demonstrates item filtering and searching.
|
||||
"""
|
||||
def item_filtering_example do
|
||||
# Start item service
|
||||
{:ok, item_service} = ItemService.start_link()
|
||||
|
||||
# Create various items
|
||||
ItemService.create_item(item_service, "laptop", "Gaming Laptop", 1299.99, "electronics")
|
||||
ItemService.create_item(item_service, "book", "Elixir Guide", 39.99, "books")
|
||||
ItemService.create_item(item_service, "phone", "Smartphone", 699.99, "electronics")
|
||||
ItemService.create_item(item_service, "novel", "Great Novel", 19.99, "books")
|
||||
|
||||
# Get all items
|
||||
all_items = ItemService.list_items(item_service)
|
||||
|
||||
# Filter by category
|
||||
electronics = ItemService.list_items(item_service, "electronics")
|
||||
books = ItemService.list_items(item_service, "books")
|
||||
|
||||
# Clean up
|
||||
Agent.stop(item_service)
|
||||
|
||||
%{
|
||||
all_items: all_items,
|
||||
electronics: electronics,
|
||||
books: books,
|
||||
total_items: length(all_items),
|
||||
electronics_count: length(electronics),
|
||||
books_count: length(books)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule IntegrationExample do
|
||||
@doc """
|
||||
Runs a complete e-commerce scenario.
|
||||
"""
|
||||
def run_full_scenario do
|
||||
# Setup services
|
||||
container = TestRepo.Services.create_service_container()
|
||||
TestRepo.Services.setup_sample_data(container)
|
||||
|
||||
# Get sample data
|
||||
{:ok, sample_user} = UserService.get_user(container.user_service, TestRepo.Services.sample_user_id())
|
||||
{:ok, sample_item} = ItemService.get_item(container.item_service, TestRepo.Services.sample_item_id())
|
||||
|
||||
# Create additional items
|
||||
{:ok, premium_item} = ItemService.create_item(
|
||||
container.item_service,
|
||||
"premium",
|
||||
"Premium Product",
|
||||
99.99,
|
||||
"premium"
|
||||
)
|
||||
|
||||
# Create order with multiple items
|
||||
order = OrderService.create_order("big_order", sample_user, [sample_item])
|
||||
order_with_premium = OrderService.add_item_to_order(order, premium_item)
|
||||
|
||||
# Process through order lifecycle
|
||||
processing_order = OrderService.process_order(order_with_premium)
|
||||
final_order = OrderService.complete_order(processing_order)
|
||||
|
||||
# Serialize everything for output
|
||||
serialized_user = TestRepo.Services.serialize_model(sample_user)
|
||||
serialized_order = TestRepo.Services.serialize_model(final_order)
|
||||
|
||||
# Clean up
|
||||
GenServer.stop(container.user_service)
|
||||
Agent.stop(container.item_service)
|
||||
|
||||
%{
|
||||
scenario: "full_ecommerce",
|
||||
user: serialized_user,
|
||||
order: serialized_order,
|
||||
total_revenue: final_order.total,
|
||||
items_sold: length(final_order.items)
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Demonstrates error handling scenarios.
|
||||
"""
|
||||
def error_handling_example do
|
||||
{:ok, user_service} = UserService.start_link()
|
||||
|
||||
# Try to create duplicate user
|
||||
{:ok, _user1} = UserService.create_user(user_service, "dup", "User", "user@example.com")
|
||||
duplicate_result = UserService.create_user(user_service, "dup", "Another User", "another@example.com")
|
||||
|
||||
# Try to get non-existent user
|
||||
missing_user_result = UserService.get_user(user_service, "nonexistent")
|
||||
|
||||
# Try to delete non-existent user
|
||||
delete_result = UserService.delete_user(user_service, "nonexistent")
|
||||
|
||||
GenServer.stop(user_service)
|
||||
|
||||
%{
|
||||
duplicate_user_error: duplicate_result,
|
||||
missing_user_error: missing_user_result,
|
||||
delete_missing_error: delete_result
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Main function to run all examples.
|
||||
"""
|
||||
def run_all_examples do
|
||||
%{
|
||||
user_management: UserManagement.run_user_example(),
|
||||
role_management: UserManagement.manage_user_roles(),
|
||||
shopping: ShoppingExample.run_shopping_example(),
|
||||
item_filtering: ShoppingExample.item_filtering_example(),
|
||||
integration: IntegrationExample.run_full_scenario(),
|
||||
error_handling: IntegrationExample.error_handling_example()
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
defmodule TestRepo.IgnoredDir.IgnoredModule do
|
||||
@moduledoc """
|
||||
This module is in a directory that should be ignored by the language server.
|
||||
It's used for testing directory filtering functionality.
|
||||
"""
|
||||
|
||||
alias TestRepo.Models.User
|
||||
|
||||
@doc """
|
||||
This function references the User model to test that ignored directories
|
||||
don't show up in symbol references.
|
||||
"""
|
||||
def create_ignored_user do
|
||||
User.new("ignored", "Ignored User", "ignored@example.com")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Another function that uses models.
|
||||
"""
|
||||
def process_ignored_user(user) do
|
||||
User.add_role(user, "ignored_role")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,166 @@
|
||||
defmodule TestRepo.Models do
|
||||
@moduledoc """
|
||||
Models module demonstrating various Elixir patterns including structs, protocols, and behaviours.
|
||||
"""
|
||||
|
||||
defprotocol Serializable do
|
||||
@doc "Convert model to map representation"
|
||||
def to_map(model)
|
||||
end
|
||||
|
||||
defmodule User do
|
||||
@type t :: %__MODULE__{
|
||||
id: String.t(),
|
||||
name: String.t() | nil,
|
||||
email: String.t(),
|
||||
roles: list(String.t())
|
||||
}
|
||||
|
||||
defstruct [:id, :name, :email, roles: []]
|
||||
|
||||
@doc """
|
||||
Creates a new user.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> TestRepo.Models.User.new("1", "Alice", "alice@example.com")
|
||||
%TestRepo.Models.User{id: "1", name: "Alice", email: "alice@example.com", roles: []}
|
||||
|
||||
"""
|
||||
def new(id, name, email, roles \\ []) do
|
||||
%__MODULE__{id: id, name: name, email: email, roles: roles}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if user has a specific role.
|
||||
"""
|
||||
def has_role?(%__MODULE__{roles: roles}, role) do
|
||||
role in roles
|
||||
end
|
||||
|
||||
@doc """
|
||||
Adds a role to the user.
|
||||
"""
|
||||
def add_role(%__MODULE__{roles: roles} = user, role) do
|
||||
%{user | roles: [role | roles]}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Item do
|
||||
@type t :: %__MODULE__{
|
||||
id: String.t(),
|
||||
name: String.t(),
|
||||
price: float(),
|
||||
category: String.t()
|
||||
}
|
||||
|
||||
defstruct [:id, :name, :price, :category]
|
||||
|
||||
@doc """
|
||||
Creates a new item.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> TestRepo.Models.Item.new("1", "Widget", 19.99, "electronics")
|
||||
%TestRepo.Models.Item{id: "1", name: "Widget", price: 19.99, category: "electronics"}
|
||||
|
||||
"""
|
||||
def new(id, name, price, category) do
|
||||
%__MODULE__{id: id, name: name, price: price, category: category}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Formats price for display.
|
||||
"""
|
||||
def display_price(%__MODULE__{price: price}) do
|
||||
"$#{:erlang.float_to_binary(price, decimals: 2)}"
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if item is in a specific category.
|
||||
"""
|
||||
def in_category?(%__MODULE__{category: category}, target_category) do
|
||||
category == target_category
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Order do
|
||||
alias TestRepo.Models.{User, Item}
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
id: String.t(),
|
||||
user: User.t(),
|
||||
items: list(Item.t()),
|
||||
total: float(),
|
||||
status: atom()
|
||||
}
|
||||
|
||||
defstruct [:id, :user, items: [], total: 0.0, status: :pending]
|
||||
|
||||
@doc """
|
||||
Creates a new order.
|
||||
"""
|
||||
def new(id, user, items \\ []) do
|
||||
total = calculate_total(items)
|
||||
%__MODULE__{id: id, user: user, items: items, total: total}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Adds an item to the order.
|
||||
"""
|
||||
def add_item(%__MODULE__{items: items} = order, item) do
|
||||
new_items = [item | items]
|
||||
%{order | items: new_items, total: calculate_total(new_items)}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates order status.
|
||||
"""
|
||||
def update_status(%__MODULE__{} = order, status) do
|
||||
%{order | status: status}
|
||||
end
|
||||
|
||||
defp calculate_total(items) do
|
||||
Enum.reduce(items, 0.0, fn item, acc -> acc + item.price end)
|
||||
end
|
||||
end
|
||||
|
||||
# Protocol implementations
|
||||
defimpl Serializable, for: User do
|
||||
def to_map(%User{id: id, name: name, email: email, roles: roles}) do
|
||||
%{id: id, name: name, email: email, roles: roles}
|
||||
end
|
||||
end
|
||||
|
||||
defimpl Serializable, for: Item do
|
||||
def to_map(%Item{id: id, name: name, price: price, category: category}) do
|
||||
%{id: id, name: name, price: price, category: category}
|
||||
end
|
||||
end
|
||||
|
||||
defimpl Serializable, for: Order do
|
||||
def to_map(%Order{id: id, user: user, items: items, total: total, status: status}) do
|
||||
%{
|
||||
id: id,
|
||||
user: Serializable.to_map(user),
|
||||
items: Enum.map(items, &Serializable.to_map/1),
|
||||
total: total,
|
||||
status: status
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Factory function to create a sample user.
|
||||
"""
|
||||
def create_sample_user do
|
||||
User.new("sample", "Sample User", "sample@example.com", ["user"])
|
||||
end
|
||||
|
||||
@doc """
|
||||
Factory function to create a sample item.
|
||||
"""
|
||||
def create_sample_item do
|
||||
Item.new("sample", "Sample Item", 9.99, "sample")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,257 @@
|
||||
defmodule TestRepo.Services do
|
||||
@moduledoc """
|
||||
Services module demonstrating function usage and dependencies.
|
||||
Similar to Python's services.py, this module uses the models defined in TestRepo.Models.
|
||||
"""
|
||||
|
||||
alias TestRepo.Models.{User, Item, Order, Serializable}
|
||||
|
||||
defmodule UserService do
|
||||
use GenServer
|
||||
|
||||
# Client API
|
||||
|
||||
@doc """
|
||||
Starts the UserService GenServer.
|
||||
"""
|
||||
def start_link(opts \\ []) do
|
||||
GenServer.start_link(__MODULE__, %{}, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a new user and stores it.
|
||||
"""
|
||||
def create_user(pid, id, name, email, roles \\ []) do
|
||||
GenServer.call(pid, {:create_user, id, name, email, roles})
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a user by ID.
|
||||
"""
|
||||
def get_user(pid, id) do
|
||||
GenServer.call(pid, {:get_user, id})
|
||||
end
|
||||
|
||||
@doc """
|
||||
Lists all users.
|
||||
"""
|
||||
def list_users(pid) do
|
||||
GenServer.call(pid, :list_users)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a user by ID.
|
||||
"""
|
||||
def delete_user(pid, id) do
|
||||
GenServer.call(pid, {:delete_user, id})
|
||||
end
|
||||
|
||||
# Server callbacks
|
||||
|
||||
@impl true
|
||||
def init(_) do
|
||||
{:ok, %{}}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call({:create_user, id, name, email, roles}, _from, users) do
|
||||
if Map.has_key?(users, id) do
|
||||
{:reply, {:error, "User with ID #{id} already exists"}, users}
|
||||
else
|
||||
user = User.new(id, name, email, roles)
|
||||
new_users = Map.put(users, id, user)
|
||||
{:reply, {:ok, user}, new_users}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call({:get_user, id}, _from, users) do
|
||||
case Map.get(users, id) do
|
||||
nil -> {:reply, {:error, :not_found}, users}
|
||||
user -> {:reply, {:ok, user}, users}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call(:list_users, _from, users) do
|
||||
user_list = Map.values(users)
|
||||
{:reply, user_list, users}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call({:delete_user, id}, _from, users) do
|
||||
if Map.has_key?(users, id) do
|
||||
new_users = Map.delete(users, id)
|
||||
{:reply, :ok, new_users}
|
||||
else
|
||||
{:reply, {:error, :not_found}, users}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defmodule ItemService do
|
||||
use Agent
|
||||
|
||||
@doc """
|
||||
Starts the ItemService Agent.
|
||||
"""
|
||||
def start_link(opts \\ []) do
|
||||
Agent.start_link(fn -> %{} end, opts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a new item and stores it.
|
||||
"""
|
||||
def create_item(pid, id, name, price, category) do
|
||||
Agent.get_and_update(pid, fn items ->
|
||||
if Map.has_key?(items, id) do
|
||||
{{:error, "Item with ID #{id} already exists"}, items}
|
||||
else
|
||||
item = Item.new(id, name, price, category)
|
||||
new_items = Map.put(items, id, item)
|
||||
{{:ok, item}, new_items}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets an item by ID.
|
||||
"""
|
||||
def get_item(pid, id) do
|
||||
Agent.get(pid, fn items ->
|
||||
case Map.get(items, id) do
|
||||
nil -> {:error, :not_found}
|
||||
item -> {:ok, item}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Lists all items, optionally filtered by category.
|
||||
"""
|
||||
def list_items(pid, category \\ nil) do
|
||||
Agent.get(pid, fn items ->
|
||||
item_list = Map.values(items)
|
||||
|
||||
case category do
|
||||
nil -> item_list
|
||||
cat -> Enum.filter(item_list, &Item.in_category?(&1, cat))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes an item by ID.
|
||||
"""
|
||||
def delete_item(pid, id) do
|
||||
Agent.get_and_update(pid, fn items ->
|
||||
if Map.has_key?(items, id) do
|
||||
new_items = Map.delete(items, id)
|
||||
{:ok, new_items}
|
||||
else
|
||||
{{:error, :not_found}, items}
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
defmodule OrderService do
|
||||
@doc """
|
||||
Creates a new order.
|
||||
"""
|
||||
def create_order(id, user, items \\ []) do
|
||||
Order.new(id, user, items)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Adds an item to an existing order.
|
||||
"""
|
||||
def add_item_to_order(order, item) do
|
||||
Order.add_item(order, item)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates the status of an order.
|
||||
"""
|
||||
def update_order_status(order, status) do
|
||||
Order.update_status(order, status)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Processes an order (changes status to :processing).
|
||||
"""
|
||||
def process_order(order) do
|
||||
update_order_status(order, :processing)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Completes an order (changes status to :completed).
|
||||
"""
|
||||
def complete_order(order) do
|
||||
update_order_status(order, :completed)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Cancels an order (changes status to :cancelled).
|
||||
"""
|
||||
def cancel_order(order) do
|
||||
update_order_status(order, :cancelled)
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Factory function to create a service container.
|
||||
"""
|
||||
def create_service_container do
|
||||
{:ok, user_service} = UserService.start_link()
|
||||
{:ok, item_service} = ItemService.start_link()
|
||||
|
||||
%{
|
||||
user_service: user_service,
|
||||
item_service: item_service,
|
||||
order_service: OrderService
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Helper function to serialize any model that implements the Serializable protocol.
|
||||
"""
|
||||
def serialize_model(model) do
|
||||
Serializable.to_map(model)
|
||||
end
|
||||
|
||||
# Module-level variables for testing
|
||||
@sample_user_id "sample_user"
|
||||
@sample_item_id "sample_item"
|
||||
|
||||
@doc """
|
||||
Gets the sample user ID.
|
||||
"""
|
||||
def sample_user_id, do: @sample_user_id
|
||||
|
||||
@doc """
|
||||
Gets the sample item ID.
|
||||
"""
|
||||
def sample_item_id, do: @sample_item_id
|
||||
|
||||
# Create some sample data at module load time
|
||||
def setup_sample_data(container) do
|
||||
# Create sample user
|
||||
UserService.create_user(
|
||||
container.user_service,
|
||||
@sample_user_id,
|
||||
"Sample User",
|
||||
"sample@example.com",
|
||||
["user", "customer"]
|
||||
)
|
||||
|
||||
# Create sample item
|
||||
ItemService.create_item(
|
||||
container.item_service,
|
||||
@sample_item_id,
|
||||
"Sample Widget",
|
||||
29.99,
|
||||
"electronics"
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
defmodule TestRepo do
|
||||
@moduledoc """
|
||||
Documentation for `TestRepo`.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Hello world.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> TestRepo.hello()
|
||||
:world
|
||||
|
||||
"""
|
||||
def hello do
|
||||
:world
|
||||
end
|
||||
|
||||
@doc """
|
||||
Adds two numbers together.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> TestRepo.add(2, 3)
|
||||
5
|
||||
|
||||
"""
|
||||
def add(a, b) do
|
||||
a + b
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
defmodule TestRepo.Utils do
|
||||
@moduledoc """
|
||||
Utility functions for TestRepo.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Converts a string to uppercase.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> TestRepo.Utils.upcase("hello")
|
||||
"HELLO"
|
||||
|
||||
"""
|
||||
def upcase(string) when is_binary(string) do
|
||||
String.upcase(string)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Calculates the factorial of a number.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> TestRepo.Utils.factorial(5)
|
||||
120
|
||||
|
||||
"""
|
||||
def factorial(0), do: 1
|
||||
def factorial(n) when n > 0 do
|
||||
n * factorial(n - 1)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if a number is even.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> TestRepo.Utils.even?(4)
|
||||
true
|
||||
|
||||
iex> TestRepo.Utils.even?(3)
|
||||
false
|
||||
|
||||
"""
|
||||
def even?(n) when is_integer(n) do
|
||||
rem(n, 2) == 0
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user