1: -module(service_deps_SUITE).
    2: -compile([export_all, nowarn_export_all]).
    3: 
    4: -include_lib("eunit/include/eunit.hrl").
    5: 
    6: -import(mongoose_service_deps, [resolve_deps/1, sort_deps/1]).
    7: 
    8: all() ->
    9:     [
   10:      no_dependencies,
   11:      dependency,
   12:      dependency_chain,
   13:      dependency_dag,
   14:      fails_on_dependency_cycle,
   15:      preserves_dependency_opts
   16:     ].
   17: 
   18: init_per_testcase(_, C) ->
   19:     meck:new(test_services(), [non_strict]),
   20:     C.
   21: 
   22: end_per_testcase(_, _C) ->
   23:     meck:unload(test_services()).
   24: 
   25: %% Test cases
   26: 
   27: no_dependencies(_Config) ->
   28:     Services = #{service_a => #{}, service_b => #{}},
   29:     ?assertEqual(Services, resolve_deps(Services)).
   30: 
   31: dependency(_Config) ->
   32:     set_deps(#{service_a => [service_b]}),
   33:     ?assertMatch([{service_b, _}, {service_a, _}], add_deps(#{service_a => #{}})).
   34: 
   35: dependency_chain(_Config) ->
   36:     set_deps(#{service_a => [service_b], service_b => [service_c]}),
   37:     ?assertMatch([{service_c, _}, {service_b, _}, {service_a, _}], add_deps(#{service_a => #{}})).
   38: 
   39: dependency_dag(_Config) ->
   40:     set_deps(#{service_a => [service_b, service_c], service_b => [service_c]}),
   41:     ?assertMatch([{service_c, _}, {service_b, _}, {service_a, _}], add_deps(#{service_a => #{}})).
   42: 
   43: fails_on_dependency_cycle(_Config) ->
   44:     set_deps(#{service_a => [service_b], service_b => [service_c], service_c => [service_a]}),
   45:     ?assertError(#{what := resolving_dependencies_aborted}, add_deps(#{service_a => #{}})).
   46: 
   47: preserves_dependency_opts(_Config) ->
   48:     set_deps(#{service_a => [service_b]}),
   49:     ?assertMatch([{service_b, #{opt1 := 1}}, {service_a, _}],
   50:                  add_deps(#{service_a => #{}, service_b => #{opt1 => 1}})).
   51: 
   52: %% Helpers
   53: 
   54: add_deps(ServiceMap) ->
   55:     sort_deps(resolve_deps(ServiceMap)).
   56: 
   57: set_deps(DepsMap) ->
   58:     maps:map(fun(Service, Deps) -> meck:expect(Service, deps, fun() -> Deps end) end, DepsMap).
   59: 
   60: test_services() ->
   61:     [service_a, service_b, service_c].