boutique-inventory
This commit is contained in:
parent
f324155864
commit
ec644472b3
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"authors": [
|
||||
"angelikatyborska"
|
||||
],
|
||||
"contributors": [
|
||||
"neenjaw",
|
||||
"fmmatheus"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"lib/boutique_inventory.ex"
|
||||
],
|
||||
"test": [
|
||||
"test/boutique_inventory_test.exs"
|
||||
],
|
||||
"exemplar": [
|
||||
".meta/exemplar.ex"
|
||||
]
|
||||
},
|
||||
"language_versions": ">=1.10",
|
||||
"blurb": "Learn about the Enum module by preparing your fashion boutique for the big annual sale."
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"track":"elixir","exercise":"boutique-inventory","id":"cdb368dfafa84deaaad78b0b83747be0","url":"https://exercism.org/tracks/elixir/exercises/boutique-inventory","handle":"negrienko","is_requester":true,"auto_approve":false}
|
|
@ -0,0 +1,4 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
# The directory Mix will write compiled artifacts to.
|
||||
/_build/
|
||||
|
||||
# If you run "mix test --cover", coverage assets end up here.
|
||||
/cover/
|
||||
|
||||
# The directory Mix downloads your dependencies sources to.
|
||||
/deps/
|
||||
|
||||
# Where third-party dependencies like ExDoc output generated docs.
|
||||
/doc/
|
||||
|
||||
# Ignore .fetch files in case you like to edit your project deps locally.
|
||||
/.fetch
|
||||
|
||||
# If the VM crashes, it generates a dump, let's ignore it too.
|
||||
erl_crash.dump
|
||||
|
||||
# Also ignore archive artifacts (built via "mix archive.build").
|
||||
*.ez
|
||||
|
||||
# Ignore package tarball (built via "mix hex.build").
|
||||
nil-*.tar
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
From the terminal, change to the base directory of the exercise then execute the tests with:
|
||||
|
||||
```bash
|
||||
$ mix test
|
||||
```
|
||||
|
||||
This will execute the test file found in the `test` subfolder -- a file ending in `_test.exs`
|
||||
|
||||
Documentation:
|
||||
|
||||
* [`mix test` - Elixir's test execution tool](https://hexdocs.pm/mix/Mix.Tasks.Test.html)
|
||||
* [`ExUnit` - Elixir's unit test library](https://hexdocs.pm/ex_unit/ExUnit.html)
|
||||
|
||||
## Pending tests
|
||||
|
||||
In test suites of practice exercises, all but the first test have been tagged to be skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
If you wish to run all tests at once, you can include all skipped test by using the `--include` flag on the `mix test` command:
|
||||
|
||||
```bash
|
||||
$ mix test --include pending
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the `ExUnit.configure` line in the file `test/test_helper.exs`.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure(exclude: :pending, trace: true)
|
||||
```
|
||||
|
||||
## Useful `mix test` options
|
||||
|
||||
* `test/<FILE>.exs:LINENUM` - runs only a single test, the test from `<FILE>.exs` whose definition is on line `LINENUM`
|
||||
* `--failed` - runs only tests that failed the last time they ran
|
||||
* `--max-failures` - the suite stops evaluating tests when this number of test failures
|
||||
is reached
|
||||
* `--seed 0` - disables randomization so the tests in a single file will always be ran
|
||||
in the same order they were defined in
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit lib/boutique_inventory.ex` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [Elixir track's documentation](https://exercism.org/docs/tracks/elixir)
|
||||
- The [Elixir track's programming category on the forum](https://forum.exercism.org/c/programming/elixir)
|
||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
If you're stuck on something, it may help to look at some of the [available resources](https://exercism.org/docs/tracks/elixir/resources) out there where answers might be found.
|
|
@ -0,0 +1,42 @@
|
|||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- Read about the `Enum` module in the [official Getting Started guide][getting-started-enum] or on [elixirschool.com][elixir-school-enum].
|
||||
- Take a look in the documentation for the full [list of functions in the `Enum` module][enum-functions].
|
||||
|
||||
## 1. Sort items by price
|
||||
|
||||
- There is a [built-in function][enum-sort-by] for sorting enumerables using a sorter function.
|
||||
|
||||
## 2. Find all items with missing prices
|
||||
|
||||
- There is a [built-in function][enum-filter] for filtering enumerables.
|
||||
|
||||
## 3. Update item names
|
||||
|
||||
- There is a [built-in function][enum-map] for transforming every element in an enumerable.
|
||||
- There is a [built-in function][string-replace] that can replace all instances of one string with a different one.
|
||||
|
||||
## 4. Increment the item's quantity
|
||||
|
||||
- Maps implement the enumerable protocol.
|
||||
- `Enum` functions convert maps to a list of `{key, value}` tuples.
|
||||
- There are two different functions that can transform a list of `{key, value}` tuples back into a map using a transformation function. [One of them always returns a new map][map-new], while [the other lets you choose a collectible][enum-into].
|
||||
|
||||
## 5. Calculate the item's total quantity
|
||||
|
||||
- Maps implement the enumerable protocol.
|
||||
- `Enum` functions convert maps to a list of `{key, value}` tuples.
|
||||
- There is a [built-in function][enum-reduce] for reducing an enumerable to a single value.
|
||||
|
||||
[getting-started-enum]: https://elixir-lang.org/getting-started/enumerables-and-streams.html#enumerables
|
||||
[elixir-school-enum]: https://elixirschool.com/en/lessons/basics/enum/
|
||||
[enum-functions]: https://hexdocs.pm/elixir/Enum.html#functions
|
||||
[enum-sort-by]: https://hexdocs.pm/elixir/Enum.html#sort_by/3
|
||||
[enum-filter]: https://hexdocs.pm/elixir/Enum.html#filter/2
|
||||
[enum-map]: https://hexdocs.pm/elixir/Enum.html#map/2
|
||||
[enum-into]: https://hexdocs.pm/elixir/Enum.html#into/3
|
||||
[enum-reduce]: https://hexdocs.pm/elixir/Enum.html#reduce/3
|
||||
[map-new]: https://hexdocs.pm/elixir/Map.html#new/2
|
||||
[string-replace]: https://hexdocs.pm/elixir/String.html#replace/4
|
|
@ -0,0 +1,175 @@
|
|||
# Boutique Inventory
|
||||
|
||||
Welcome to Boutique Inventory on Exercism's Elixir Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
|
||||
|
||||
## Introduction
|
||||
|
||||
## Enum
|
||||
|
||||
`Enum` is a very useful module that provides a set of algorithms for working with enumerables. It offers sorting, filtering, grouping, counting, searching, finding min/max values, and much more.
|
||||
|
||||
In general, an _enumerable_ is any data that can be iterated over, a collection. In Elixir, an enumerable is any data type that implements the `Enumerable` [protocol][exercism-protocols]. The most common of those are [lists][exercism-lists] and [maps][exercism-maps].
|
||||
|
||||
Many `Enum` functions accept a function as an argument.
|
||||
|
||||
```elixir
|
||||
Enum.all?([1, 2, 3, 4, 5], fn x -> x > 3 end)
|
||||
# => false
|
||||
```
|
||||
|
||||
The most common `Enum` functions are `map` and `reduce`.
|
||||
|
||||
### `map/2`
|
||||
|
||||
`Enum.map/2` allows you to replace every element in an enumerable with another element. The second argument to `Enum.map/2` is a function that accepts the original element and returns its replacement.
|
||||
|
||||
### `reduce/3`
|
||||
|
||||
`Enum.reduce/3` allows you to _reduce_ the whole enumerable to a single value. To achieve this, a special variable called the _accumulator_ is used. The accumulator carries the intermediate state of the reduction between iterations.
|
||||
|
||||
The second argument to `Enum.reduce/3` is the initial value of the accumulator. The third argument is a function that accepts an element and an accumulator, and returns the new value for the accumulator.
|
||||
|
||||
### Working with maps
|
||||
|
||||
When using maps with `Enum` functions, the map gets automatically converted to a list of 2 `{key, value}` tuples.
|
||||
|
||||
To transform it back to a map, use `Enum.into/2`. `Enum.into/2` is a function that transforms an enumerable into a collectable - any data structure implementing the `Collectable` protocol. It can be thought of as the opposite of `Enum.reduce/3`.
|
||||
|
||||
`Enum` also has `Enum.into/3`. `Enum.into/3` is a variation of `Enum.into/2` that accepts a transformation function to be applied while transforming the enumerable into a collectable.
|
||||
|
||||
#### Mapping maps
|
||||
|
||||
Instead of using `Enum.into/3` or `Enum.map/2` plus `Enum.into/1` to apply a transformation (mapping) to a map, we can also use a dedicated `Map.new/2` function. It works exactly like `Enum.into/3` in that it accepts an enumerable and a transformation function, but it always returns a new map instead of letting us choose a collectible.
|
||||
|
||||
[exercism-protocols]: https://exercism.org/tracks/elixir/concepts/protocols
|
||||
[exercism-lists]: https://exercism.org/tracks/elixir/concepts/lists
|
||||
[exercism-maps]: https://exercism.org/tracks/elixir/concepts/maps
|
||||
|
||||
## Instructions
|
||||
|
||||
You are running an online fashion boutique. Your big annual sale is coming up, so you need to take stock of your inventory to make sure you're ready.
|
||||
|
||||
A single item in the inventory is represented by a map, and the whole inventory is a list of such maps.
|
||||
|
||||
```elixir
|
||||
%{
|
||||
name: "White Shirt",
|
||||
price: 40,
|
||||
quantity_by_size: %{s: 3, m: 7, l: 8, xl: 4}
|
||||
}
|
||||
```
|
||||
|
||||
## 1. Sort items by price
|
||||
|
||||
Implement the `sort_by_price/1` function. It should take the inventory and return it sorted by item price, ascending.
|
||||
|
||||
```elixir
|
||||
BoutiqueInventory.sort_by_price([
|
||||
%{price: 65, name: "Maxi Brown Dress", quantity_by_size: %{}},
|
||||
%{price: 50, name: "Red Short Skirt", quantity_by_size: %{}},
|
||||
%{price: 50, name: "Black Short Skirt", quantity_by_size: %{}},
|
||||
%{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}}
|
||||
])
|
||||
# => [
|
||||
# %{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}},
|
||||
# %{price: 50, name: "Red Short Skirt", quantity_by_size: %{}},
|
||||
# %{price: 50, name: "Black Short Skirt", quantity_by_size: %{}},
|
||||
# %{price: 65, name: "Maxi Brown Dress", price: 65, quantity_by_size: %{}}
|
||||
# ]
|
||||
```
|
||||
|
||||
## 2. Find all items with missing prices
|
||||
|
||||
After sorting your inventory by price, you noticed that you must have made a mistake when you were taking stock and forgot to fill out prices for a few items.
|
||||
|
||||
Implement the `with_missing_price/1` function. It should take the inventory and return a list of items that do not have prices.
|
||||
|
||||
```elixir
|
||||
BoutiqueInventory.with_missing_price([
|
||||
%{price: 40, name: "Black T-shirt", quantity_by_size: %{}},
|
||||
%{price: nil, name: "Denim Pants", quantity_by_size: %{}},
|
||||
%{price: nil, name: "Denim Skirt", quantity_by_size: %{}},
|
||||
%{price: 40, name: "Orange T-shirt", quantity_by_size: %{}}
|
||||
])
|
||||
# => [
|
||||
# %{price: nil, name: "Denim Pants", quantity_by_size: %{}},
|
||||
# %{price: nil, name: "Denim Skirt", quantity_by_size: %{}}
|
||||
# ]
|
||||
```
|
||||
|
||||
## 3. Update item names
|
||||
|
||||
You noticed that some item names have a word that you don't like to use anymore. Now you need to update all the item names with that word.
|
||||
|
||||
Implement the `update_names/3` function. It should take the inventory, the old word that you want to remove, and a new word that you want to use instead. It should return a list of items with updated names.
|
||||
|
||||
```elixir
|
||||
BoutiqueInventory.update_names(
|
||||
[
|
||||
%{price: 40, name: "Black T-shirt", quantity_by_size: %{}},
|
||||
%{price: 70, name: "Denim Pants", quantity_by_size: %{}},
|
||||
%{price: 65, name: "Denim Skirt", quantity_by_size: %{}},
|
||||
%{price: 40, name: "Orange T-shirt", quantity_by_size: %{}}
|
||||
],
|
||||
"T-shirt",
|
||||
"Tee"
|
||||
)
|
||||
# => [
|
||||
# %{price: 40, name: "Black Tee", quantity_by_size: %{}},
|
||||
# %{price: 70, name: "Denim Pants", quantity_by_size: %{}},
|
||||
# %{price: 65, name: "Denim Skirt", quantity_by_size: %{}},
|
||||
# %{price: 40, name: "Orange Tee", quantity_by_size: %{}}
|
||||
# ]
|
||||
```
|
||||
|
||||
|
||||
## 4. Increment the item's quantity
|
||||
|
||||
Some items were selling especially well, so you ordered more, in all sizes.
|
||||
|
||||
Implement the `increase_quantity/2` function. It should take a single item and a number `n`, and return that item with the quantity for each size increased by `n`.
|
||||
|
||||
```elixir
|
||||
BoutiqueInventory.increase_quantity(
|
||||
%{
|
||||
name: "Polka Dot Skirt",
|
||||
price: 68,
|
||||
quantity_by_size: %{s: 3, m: 5, l: 3, xl: 4}
|
||||
},
|
||||
6
|
||||
)
|
||||
# => %{
|
||||
# name: "Polka Dot Skirt",
|
||||
# price: 68,
|
||||
# quantity_by_size: %{l: 9, m: 11, s: 9, xl: 10}
|
||||
# }
|
||||
|
||||
```
|
||||
|
||||
## 5. Calculate the item's total quantity
|
||||
|
||||
To know how much space you need in your storage, you need to know how many of each item you have in total.
|
||||
|
||||
Implement the `total_quantity/1` function. It should take a single item and return how many pieces you have in total, in any size.
|
||||
|
||||
```elixir
|
||||
BoutiqueInventory.total_quantity(%{
|
||||
name: "Red Shirt",
|
||||
price: 62,
|
||||
quantity_by_size: %{s: 3, m: 6, l: 5, xl: 2}
|
||||
})
|
||||
# => 16
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @angelikatyborska
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @neenjaw
|
||||
- @fmmatheus
|
|
@ -0,0 +1,41 @@
|
|||
defmodule BoutiqueInventory do
|
||||
def sort_by_price(inventory) do
|
||||
Enum.sort_by(inventory, & &1[:price])
|
||||
end
|
||||
|
||||
def with_missing_price(inventory) do
|
||||
Enum.filter(inventory, &(!&1[:price]))
|
||||
end
|
||||
|
||||
def update_names(inventory, old_word, new_word) do
|
||||
inventory
|
||||
|> Enum.map(fn item ->
|
||||
new_name = String.replace(item.name, old_word, new_word)
|
||||
%{item | name: new_name}
|
||||
end)
|
||||
end
|
||||
|
||||
def increase_quantity(item, count) do
|
||||
item
|
||||
|> Map.get_and_update(:quantity_by_size, fn quantities ->
|
||||
{quantities, update_quantities(quantities, count)}
|
||||
end)
|
||||
|> elem(1)
|
||||
end
|
||||
|
||||
defp update_quantities(quantities, count) do
|
||||
quantities
|
||||
|> Map.to_list()
|
||||
|> Enum.map(&increase_size_quantity(&1, count))
|
||||
|> Enum.into(%{})
|
||||
end
|
||||
|
||||
defp increase_size_quantity({key, value}, count), do: {key, value + count}
|
||||
|
||||
def total_quantity(item) do
|
||||
item.quantity_by_size
|
||||
|> Enum.reduce(0, &sum_total_quantity/2)
|
||||
end
|
||||
|
||||
defp sum_total_quantity({_key, value}, acc), do: acc + value
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
defmodule BoutiqueInventory.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :boutique_inventory,
|
||||
version: "0.1.0",
|
||||
# elixir: "~> 1.10",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help compile.app" to learn about applications.
|
||||
def application do
|
||||
[
|
||||
extra_applications: [:logger]
|
||||
]
|
||||
end
|
||||
|
||||
# Run "mix help deps" to learn about dependencies.
|
||||
defp deps do
|
||||
[
|
||||
# {:dep_from_hexpm, "~> 0.3.0"},
|
||||
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
||||
]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,150 @@
|
|||
defmodule BoutiqueInventoryTest do
|
||||
use ExUnit.Case
|
||||
|
||||
describe "sort_by_price/1" do
|
||||
@tag task_id: 1
|
||||
test "works for an empty inventory" do
|
||||
assert BoutiqueInventory.sort_by_price([]) == []
|
||||
end
|
||||
|
||||
@tag task_id: 1
|
||||
test "sorts items by price" do
|
||||
assert BoutiqueInventory.sort_by_price([
|
||||
%{price: 65, name: "Maxi Yellow Summer Dress", quantity_by_size: %{}},
|
||||
%{price: 60, name: "Cream Linen Pants", quantity_by_size: %{}},
|
||||
%{price: 33, name: "Straw Hat", quantity_by_size: %{}}
|
||||
]) == [
|
||||
%{price: 33, name: "Straw Hat", quantity_by_size: %{}},
|
||||
%{price: 60, name: "Cream Linen Pants", quantity_by_size: %{}},
|
||||
%{price: 65, name: "Maxi Yellow Summer Dress", quantity_by_size: %{}}
|
||||
]
|
||||
end
|
||||
|
||||
@tag task_id: 1
|
||||
test "the order of items of equal price is preserved" do
|
||||
assert BoutiqueInventory.sort_by_price([
|
||||
%{price: 65, name: "Maxi Yellow Summer Dress", quantity_by_size: %{}},
|
||||
%{price: 60, name: "Cream Linen Pants", quantity_by_size: %{}},
|
||||
%{price: 33, name: "Straw Hat", quantity_by_size: %{}},
|
||||
%{price: 60, name: "Brown Linen Pants", quantity_by_size: %{}}
|
||||
]) == [
|
||||
%{price: 33, name: "Straw Hat", quantity_by_size: %{}},
|
||||
%{price: 60, name: "Cream Linen Pants", quantity_by_size: %{}},
|
||||
%{price: 60, name: "Brown Linen Pants", quantity_by_size: %{}},
|
||||
%{price: 65, name: "Maxi Yellow Summer Dress", quantity_by_size: %{}}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "with_missing_price/1" do
|
||||
@tag task_id: 2
|
||||
test "works for an empty inventory" do
|
||||
assert BoutiqueInventory.with_missing_price([]) == []
|
||||
end
|
||||
|
||||
@tag task_id: 2
|
||||
test "filters out items that do have a price" do
|
||||
assert BoutiqueInventory.with_missing_price([
|
||||
%{name: "Red Flowery Top", price: 50, quantity_by_size: %{}},
|
||||
%{name: "Purple Flowery Top", price: nil, quantity_by_size: %{}},
|
||||
%{name: "Bamboo Socks Avocado", price: 10, quantity_by_size: %{}},
|
||||
%{name: "Bamboo Socks Palm Trees", price: 10, quantity_by_size: %{}},
|
||||
%{name: "Bamboo Socks Kittens", price: nil, quantity_by_size: %{}}
|
||||
]) == [
|
||||
%{name: "Purple Flowery Top", price: nil, quantity_by_size: %{}},
|
||||
%{name: "Bamboo Socks Kittens", price: nil, quantity_by_size: %{}}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "update_names/3" do
|
||||
@tag task_id: 3
|
||||
test "works for an empty inventory" do
|
||||
assert BoutiqueInventory.update_names([], "T-Shirt", "Tee") == []
|
||||
end
|
||||
|
||||
@tag task_id: 3
|
||||
test "replaces the word in all the names" do
|
||||
assert BoutiqueInventory.update_names(
|
||||
[
|
||||
%{name: "Bambo Socks Avocado", price: 10, quantity_by_size: %{}},
|
||||
%{name: "3x Bambo Socks Palm Trees", price: 26, quantity_by_size: %{}},
|
||||
%{name: "Red Sequin Top", price: 87, quantity_by_size: %{}}
|
||||
],
|
||||
"Bambo",
|
||||
"Bamboo"
|
||||
) == [
|
||||
%{name: "Bamboo Socks Avocado", price: 10, quantity_by_size: %{}},
|
||||
%{name: "3x Bamboo Socks Palm Trees", price: 26, quantity_by_size: %{}},
|
||||
%{name: "Red Sequin Top", price: 87, quantity_by_size: %{}}
|
||||
]
|
||||
end
|
||||
|
||||
@tag task_id: 3
|
||||
test "replaces all the instances of the word within one name" do
|
||||
assert BoutiqueInventory.update_names(
|
||||
[
|
||||
%{name: "GO! GO! GO! Tee", price: 8, quantity_by_size: %{}}
|
||||
],
|
||||
"GO!",
|
||||
"Go!"
|
||||
) == [
|
||||
%{name: "Go! Go! Go! Tee", price: 8, quantity_by_size: %{}}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "increase_quantity/2" do
|
||||
@tag task_id: 4
|
||||
test "works for an empty quantity map" do
|
||||
assert BoutiqueInventory.increase_quantity(
|
||||
%{
|
||||
name: "Long Black Evening Dress",
|
||||
price: 105,
|
||||
quantity_by_size: %{}
|
||||
},
|
||||
1
|
||||
) == %{
|
||||
name: "Long Black Evening Dress",
|
||||
price: 105,
|
||||
quantity_by_size: %{}
|
||||
}
|
||||
end
|
||||
|
||||
@tag task_id: 4
|
||||
test "increases quantity of an item" do
|
||||
assert BoutiqueInventory.increase_quantity(
|
||||
%{
|
||||
name: "Green Swimming Shorts",
|
||||
price: 46,
|
||||
quantity_by_size: %{s: 1, m: 2, l: 4, xl: 1}
|
||||
},
|
||||
3
|
||||
) == %{
|
||||
name: "Green Swimming Shorts",
|
||||
price: 46,
|
||||
quantity_by_size: %{s: 4, m: 5, l: 7, xl: 4}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "total_quantity/1" do
|
||||
@tag task_id: 5
|
||||
test "works for an empty quantity map" do
|
||||
assert BoutiqueInventory.total_quantity(%{
|
||||
name: "Red Denim Pants",
|
||||
price: 77,
|
||||
quantity_by_size: %{}
|
||||
}) == 0
|
||||
end
|
||||
|
||||
@tag task_id: 5
|
||||
test "sums up total quantity" do
|
||||
assert BoutiqueInventory.total_quantity(%{
|
||||
name: "Black Denim Skirt",
|
||||
price: 50,
|
||||
quantity_by_size: %{s: 4, m: 11, l: 6, xl: 8}
|
||||
}) == 29
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
ExUnit.start()
|
||||
ExUnit.configure(exclude: :pending, trace: true, seed: 0)
|
Loading…
Reference in New Issue