From 000307710b44c5c21c676584986f37bd7b58e7ef Mon Sep 17 00:00:00 2001 From: JB Date: Mon, 20 Mar 2023 17:52:08 -0700 Subject: [PATCH] examples --- test/examples/humanized_weather_test.exs | 26 +++++++++++ test/support/weather_api.ex | 59 ++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 test/examples/humanized_weather_test.exs create mode 100644 test/support/weather_api.ex diff --git a/test/examples/humanized_weather_test.exs b/test/examples/humanized_weather_test.exs new file mode 100644 index 0000000..321601c --- /dev/null +++ b/test/examples/humanized_weather_test.exs @@ -0,0 +1,26 @@ +defmodule MyApp.HumanizedWeatherTest do + use ExUnit.Case, async: true + + alias MyApp.HumanizedWeather + alias MyApp.WeatherAPI + + test "gets and formats temperature" do + protomock = + ProtoMock.new() + |> ProtoMock.expect(&WeatherAPI.temperature/2, fn _lat_long -> {:ok, 30} end) + + assert HumanizedWeather.display_temp({50.06, 19.94}, protomock) == + "Current temperature is 30 degrees" + + ProtoMock.verify!(protomock) + end + + test "gets and formats humidity" do + protomock = + ProtoMock.new() + |> ProtoMock.stub(&WeatherAPI.humidity/2, fn _lat_long -> {:ok, 60} end) + + assert HumanizedWeather.display_humidity({50.06, 19.94}, protomock) == + "Current humidity is 60%" + end +end diff --git a/test/support/weather_api.ex b/test/support/weather_api.ex new file mode 100644 index 0000000..6d17b53 --- /dev/null +++ b/test/support/weather_api.ex @@ -0,0 +1,59 @@ +defprotocol MyApp.WeatherAPI do + @type lat_long :: {float(), float()} + @type api_result :: {:ok, integer()} | {:error, any()} + + @spec temperature(t(), lat_long()) :: api_result() + def temperature(weather_api, lat_long) + + @spec humidity(t(), lat_long()) :: api_result() + def humidity(weather_api, lat_long) +end + +defmodule AcmeWeather.ApiConfig do + defstruct [] +end + +defmodule AcmeWeather.Client do + def get_temperature(_lat, _long, _config), do: 0 + def get_humidity(_lat, _long, _config), do: 0 +end + +defimpl MyApp.WeatherAPI, for: AcmeWeather.ApiConfig do + def temperature(api_config, {lat, long}) do + AcmeWeather.Client.get_temperature(lat, long, api_config) + end + + def humidity(api_config, {lat, long}) do + AcmeWeather.Client.get_humidity(lat, long, api_config) + end +end + +defimpl MyApp.WeatherAPI, for: ProtoMock do + def temperature(protomock, lat_long) do + ProtoMock.invoke(protomock, &MyApp.WeatherAPI.temperature/2, [lat_long]) + end + + def humidity(protomock, lat_long) do + ProtoMock.invoke(protomock, &MyApp.WeatherAPI.humidity/2, [lat_long]) + end +end + +# ProtoMock.create_impl(MyApp.WeatherAPI) + +defmodule MyApp.HumanizedWeather do + alias MyApp.WeatherAPI + + def display_temp({lat, long}, weather_api \\ default_weather_api()) do + {:ok, temp} = WeatherAPI.temperature(weather_api, {lat, long}) + "Current temperature is #{temp} degrees" + end + + def display_humidity({lat, long}, weather_api \\ default_weather_api()) do + {:ok, humidity} = WeatherAPI.humidity(weather_api, {lat, long}) + "Current humidity is #{humidity}%" + end + + defp default_weather_api() do + Application.get_env(MyApp, :weather_api) + end +end