Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5591ab2dff | ||
|
|
59910fff71 | ||
|
|
f179a23675 | ||
|
|
bfa16ebf35 | ||
|
|
4906beeb2d | ||
|
|
7ab6d2e982 | ||
|
|
ac502ebee2 | ||
|
|
4fd0c4e013 | ||
|
|
05fecbcbcf | ||
|
|
448f473d08 | ||
|
|
eb8d293ac5 | ||
|
|
59588ca424 | ||
|
|
64ffd185cc | ||
|
|
40beaf4f07 | ||
|
|
139d2eac59 | ||
|
|
84b33461f3 | ||
|
|
e88a1b6738 | ||
|
|
2e4c7abe4d | ||
|
|
a6723dcbc6 | ||
|
|
e878ddee4c |
@@ -46,6 +46,14 @@ Note: Erlang 17.1 contains a regression in its wildcard implementation that
|
||||
causes tools like rebar to fail. If you have a project with rebar dependencies
|
||||
and is using Erlang 17.1, remember to update to at least Erlang 17.3.
|
||||
|
||||
## v1.1.1 (2015-09-28)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* [Enum] Fix non-integer member checks with ranges
|
||||
* [ExUnit] Fix assertion errors with more than 1 pinned var
|
||||
* [Mix] Ensure umbrella apps can boot with build_embedded is true
|
||||
|
||||
## v1.1.0 (2015-09-25)
|
||||
|
||||
### 1. Enhancements
|
||||
@@ -199,3 +207,7 @@ and is using Erlang 17.1, remember to update to at least Erlang 17.3.
|
||||
* [Kernel] `?\xHEX` is deprecated in favor of `0xHEX`. There is no situation where the former should be used in favor of the latter and the latter is always cleaner
|
||||
* [Kernel] Giving `as: true | false` to `alias/2` and `require/2` have been deprecated (it was undocumented behaviour)
|
||||
* [String] Passing an empty string to `starts_with?`, `contains?` and `ends_with?` had dubious behaviour and have been deprecated to help developers identify possible bugs in their source code
|
||||
|
||||
## v1.0
|
||||
|
||||
The CHANGELOG for v1.0 releases can be found [in the v1.0 branch](https://github.com/elixir-lang/elixir/blob/v1.0/CHANGELOG.md).
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
REBAR ?= "$(CURDIR)/rebar"
|
||||
PREFIX ?= /usr/local
|
||||
DOCS := master
|
||||
DOCS := v1.1
|
||||
CANONICAL := stable
|
||||
ELIXIRC := bin/elixirc --verbose --ignore-module-conflict
|
||||
ERLC := erlc -I lib/elixir/include
|
||||
ERL := erl -I lib/elixir/include -noshell -pa lib/elixir/ebin
|
||||
@@ -130,7 +131,7 @@ clean_exbeam:
|
||||
|
||||
LOGO_PATH = $(shell test -f ../docs/logo.png && echo "--logo ../docs/logo.png")
|
||||
SOURCE_REF = $(shell head="$$(git rev-parse HEAD)" tag="$$(git tag --points-at $$head | tail -1)" ; echo "$${tag:-$$head}\c")
|
||||
COMPILE_DOCS = bin/elixir ../ex_doc/bin/ex_doc "$(1)" "$(VERSION)" "lib/$(2)/ebin" -m "$(3)" -u "https://github.com/elixir-lang/elixir" --source-ref "$(call SOURCE_REF)" $(call LOGO_PATH) -o doc/$(2) -p http://elixir-lang.org/docs.html
|
||||
COMPILE_DOCS = bin/elixir ../ex_doc/bin/ex_doc "$(1)" "$(VERSION)" "lib/$(2)/ebin" -m "$(3)" -u "https://github.com/elixir-lang/elixir" --source-ref "v$(VERSION)" $(call LOGO_PATH) -o doc/$(2) -a http://elixir-lang.org/docs/$(CANONICAL)/$(2)/ -p http://elixir-lang.org/docs.html
|
||||
|
||||
docs: compile ../ex_doc/bin/ex_doc docs_elixir docs_eex docs_mix docs_iex docs_ex_unit docs_logger
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ defmodule Code do
|
||||
"Converts an atom to a char list."
|
||||
|
||||
# Module doesn't exist
|
||||
iex> docs = Code.get_docs(ModuleNotGood, :all)
|
||||
iex> Code.get_docs(ModuleNotGood, :all)
|
||||
nil
|
||||
|
||||
"""
|
||||
|
||||
+10
-2
@@ -1039,8 +1039,14 @@ defmodule Enum do
|
||||
|
||||
"""
|
||||
@spec map(t, (element -> any)) :: list
|
||||
def map(collection, fun) when is_list(collection) do
|
||||
for item <- collection, do: fun.(item)
|
||||
def map(enumerable, fun)
|
||||
|
||||
def map([], _fun) do
|
||||
[]
|
||||
end
|
||||
|
||||
def map([head | tail], fun) do
|
||||
[fun.(head) | map(tail, fun)]
|
||||
end
|
||||
|
||||
def map(collection, fun) do
|
||||
@@ -1174,6 +1180,8 @@ defmodule Enum do
|
||||
|
||||
iex> Enum.member?(1..10, 5)
|
||||
true
|
||||
iex> Enum.member?(1..10, 5.0)
|
||||
false
|
||||
|
||||
iex> Enum.member?([:a, :b, :c], :d)
|
||||
false
|
||||
|
||||
@@ -48,7 +48,7 @@ defmodule File.Stat do
|
||||
|
||||
The time type returned in `atime`, `mtime`, and `ctime` is dependent on the
|
||||
time type set in options. `{:time, type}` where type can be `:local`,
|
||||
`:universal`, or `:posix`. Default is `:local`.
|
||||
`:universal`, or `:posix`. Default is `:universal`.
|
||||
"""
|
||||
|
||||
record = Record.extract(:file_info, from_lib: "kernel/include/file.hrl")
|
||||
|
||||
@@ -290,7 +290,7 @@ defmodule GenEvent do
|
||||
@type manager :: pid | name | {atom, node}
|
||||
|
||||
@typedoc "Supported values for new handlers"
|
||||
@type handler :: atom | {atom, term} | {pid, reference}
|
||||
@type handler :: atom | {atom, term}
|
||||
|
||||
@doc false
|
||||
defmacro __using__(_) do
|
||||
|
||||
@@ -131,12 +131,12 @@ defmodule IO.ANSI do
|
||||
|
||||
@doc "Clears screen"
|
||||
defsequence :clear, "2", "J"
|
||||
|
||||
|
||||
@doc "Clears line"
|
||||
defsequence :clear_line, "2", "K"
|
||||
|
||||
defp format_sequence(other) do
|
||||
raise ArgumentError, "invalid ANSI sequence specification: #{other}"
|
||||
raise ArgumentError, "invalid ANSI sequence specification: #{inspect other}"
|
||||
end
|
||||
|
||||
@doc ~S"""
|
||||
|
||||
@@ -65,6 +65,9 @@ defmodule Keyword do
|
||||
iex> Keyword.new([{:b, 1}, {:a, 2}])
|
||||
[a: 2, b: 1]
|
||||
|
||||
iex> Keyword.new([{:a, 1}, {:a, 2}, {:a, 3}])
|
||||
[a: 3]
|
||||
|
||||
"""
|
||||
@spec new(Enum.t) :: t
|
||||
def new(pairs) do
|
||||
@@ -80,17 +83,18 @@ defmodule Keyword do
|
||||
|
||||
## Examples
|
||||
|
||||
iex> Keyword.new([:a, :b], fn (x) -> {x, x} end)
|
||||
[b: :b, a: :a]
|
||||
iex> Keyword.new([:a, :b], fn (x) -> {x, x} end) |> Enum.sort
|
||||
[a: :a, b: :b]
|
||||
|
||||
"""
|
||||
@spec new(Enum.t, (term -> {key, value})) :: t
|
||||
def new(pairs, transform) when is_function(transform, 1) do
|
||||
def new(pairs, transform) do
|
||||
fun = fn el, acc ->
|
||||
{k, v} = transform.(el)
|
||||
put_new(acc, k, v)
|
||||
end
|
||||
:lists.foldr(fun, [], Enum.reverse(pairs))
|
||||
keywords = :lists.foldl(fun, [], Enum.reverse(pairs))
|
||||
:lists.reverse(keywords)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
||||
@@ -77,7 +77,7 @@ defimpl Enumerable, for: Range do
|
||||
{:done, acc}
|
||||
end
|
||||
|
||||
def member?(first .. last, value) do
|
||||
def member?(first .. last, value) when is_integer(value) do
|
||||
validate_range!(first, last)
|
||||
if first <= last do
|
||||
{:ok, first <= value and value <= last}
|
||||
@@ -86,6 +86,10 @@ defimpl Enumerable, for: Range do
|
||||
end
|
||||
end
|
||||
|
||||
def member?(_ .. _, _value) do
|
||||
{:ok, false}
|
||||
end
|
||||
|
||||
def count(first .. last) do
|
||||
validate_range!(first, last)
|
||||
if first <= last do
|
||||
|
||||
@@ -487,7 +487,7 @@ tokenize([T|Rest], Line, Column, Scope, Tokens) when ?is_horizontal_space(T) ->
|
||||
end;
|
||||
|
||||
tokenize([T|Rest], Line, Column, _Scope, Tokens) ->
|
||||
Message = io_lib:format("\"~s\" (column ~p, codepoint U+~4.16.0B)", [[T], Column, T]),
|
||||
Message = io_lib:format("\"~ts\" (column ~p, codepoint U+~4.16.0B)", [[T], Column, T]),
|
||||
{error, {Line, "unexpected token: ", Message}, Rest, Tokens}.
|
||||
|
||||
strip_horizontal_space(T) ->
|
||||
|
||||
@@ -87,8 +87,11 @@ defmodule IO.ANSITest do
|
||||
end
|
||||
|
||||
test "format invalid sequence" do
|
||||
assert_raise ArgumentError, "invalid ANSI sequence specification: brigh", fn ->
|
||||
assert_raise ArgumentError, "invalid ANSI sequence specification: :brigh", fn ->
|
||||
IO.ANSI.format([:brigh, "Hello!"], true)
|
||||
end
|
||||
assert_raise ArgumentError, "invalid ANSI sequence specification: nil", fn ->
|
||||
IO.ANSI.format(["Hello!", nil], true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,8 +11,8 @@ defmodule Kernel.ErrorsTest do
|
||||
|
||||
test "invalid token" do
|
||||
assert_compile_fail SyntaxError,
|
||||
"nofile:1: unexpected token: \" \" (column 7, codepoint U+00A0)",
|
||||
'[foo: \u00A0]\noops'
|
||||
"nofile:1: unexpected token: \"\u200B\" (column 7, codepoint U+200B)",
|
||||
'[foo: \u200B]\noops'
|
||||
end
|
||||
|
||||
test "invalid quoted token" do
|
||||
|
||||
@@ -353,7 +353,9 @@ defmodule ExUnit.Assertions do
|
||||
|
||||
defp pinned_vars([]), do: ""
|
||||
defp pinned_vars(pins) do
|
||||
content = Enum.map(pins, fn(var) ->
|
||||
content = Enum.reverse(pins)
|
||||
|> Enum.uniq_by(&elem(&1, 0))
|
||||
|> Enum.map(fn(var) ->
|
||||
binary = Macro.to_string(var)
|
||||
quote do
|
||||
"\n " <> unquote(binary) <> " = " <> inspect(unquote(var))
|
||||
@@ -361,7 +363,7 @@ defmodule ExUnit.Assertions do
|
||||
end)
|
||||
|
||||
quote do
|
||||
"\nThe following variables were pinned:" <> unquote_splicing(content)
|
||||
<<"\nThe following variables were pinned:", unquote_splicing(content)>>
|
||||
end
|
||||
end
|
||||
|
||||
@@ -384,7 +386,7 @@ defmodule ExUnit.Assertions do
|
||||
assert_raise ArithmeticError, "bad argument in arithmetic expression", fn ->
|
||||
1 + "test"
|
||||
end
|
||||
|
||||
|
||||
assert_raise RuntimeError, ~r/^Today's lucky number is 0\.\d+!$/, fn ->
|
||||
raise "Today's lucky number is #{:random.uniform}!"
|
||||
end
|
||||
|
||||
@@ -127,6 +127,46 @@ defmodule ExUnit.AssertionsTest do
|
||||
end
|
||||
end
|
||||
|
||||
test "assert received with multiple identical pinned variables" do
|
||||
status = :valid
|
||||
send self(), {:status, :invalid, :invalid}
|
||||
try do
|
||||
"This should never be tested" = assert_received {
|
||||
:status,
|
||||
^status,
|
||||
^status
|
||||
}
|
||||
rescue
|
||||
error in [ExUnit.AssertionError] ->
|
||||
"No message matching {:status, ^status, ^status} after 0ms.\n" <>
|
||||
"The following variables were pinned:\n" <>
|
||||
" status = :valid\n" <>
|
||||
"Process mailbox:\n" <>
|
||||
" {:status, :invalid, :invalid}" = error.message
|
||||
end
|
||||
end
|
||||
|
||||
test "assert received with multiple unique pinned variables" do
|
||||
status = :valid
|
||||
other_status = :invalid
|
||||
send self(), {:status, :invalid, :invalid}
|
||||
try do
|
||||
"This should never be tested" = assert_received {
|
||||
:status,
|
||||
^status,
|
||||
^other_status
|
||||
}
|
||||
rescue
|
||||
error in [ExUnit.AssertionError] ->
|
||||
"No message matching {:status, ^status, ^other_status} after 0ms.\n" <>
|
||||
"The following variables were pinned:\n" <>
|
||||
" status = :valid\n" <>
|
||||
" other_status = :invalid\n" <>
|
||||
"Process mailbox:\n" <>
|
||||
" {:status, :invalid, :invalid}" = error.message
|
||||
end
|
||||
end
|
||||
|
||||
test "assert received when empty mailbox" do
|
||||
try do
|
||||
"This should never be tested" = assert_received :hello
|
||||
|
||||
@@ -83,7 +83,8 @@ defmodule IEx.CLI do
|
||||
{:badrpc, reason} ->
|
||||
abort "Could not contact remote node #{remote}, reason: #{inspect reason}. Aborting..."
|
||||
{:module, IEx} ->
|
||||
{remote, :erlang, :apply, [remote_start_function, []]}
|
||||
{mod, fun, args} = remote_start_mfa()
|
||||
{remote, mod, fun, args}
|
||||
_ ->
|
||||
abort "Could not find IEx on remote node #{remote}. Aborting..."
|
||||
end
|
||||
@@ -108,7 +109,7 @@ defmodule IEx.CLI do
|
||||
&local_start/0
|
||||
end
|
||||
|
||||
defp remote_start_function do
|
||||
defp remote_start_mfa do
|
||||
ref = make_ref
|
||||
opts = options()
|
||||
|
||||
@@ -120,9 +121,7 @@ defmodule IEx.CLI do
|
||||
end
|
||||
end
|
||||
|
||||
fn ->
|
||||
IEx.start(opts, {__MODULE__, :remote_start, [parent, ref]})
|
||||
end
|
||||
{IEx, :start, [opts, {__MODULE__, :remote_start, [parent, ref]}]}
|
||||
end
|
||||
|
||||
defp options do
|
||||
|
||||
@@ -74,11 +74,16 @@ defmodule Logger.Backends.Console do
|
||||
enabled: Keyword.get(colors, :enabled, IO.ANSI.enabled?)}
|
||||
end
|
||||
|
||||
defp log_event(level, msg, ts, md, %{colors: colors} = state) do
|
||||
defp log_event(level, msg, ts, md, %{colors: colors, device: device} = state) do
|
||||
output =
|
||||
format_event(level, msg, ts, md, state)
|
||||
|> color_event(level, colors)
|
||||
IO.write(state.device, output)
|
||||
try do
|
||||
IO.write(device, output)
|
||||
rescue
|
||||
ArgumentError ->
|
||||
IO.write(device, Logger.Formatter.prune(output))
|
||||
end
|
||||
end
|
||||
|
||||
defp format_event(level, msg, ts, md, %{format: format, metadata: keys}) do
|
||||
|
||||
@@ -44,6 +44,26 @@ defmodule Logger.Formatter do
|
||||
@type pattern :: :date | :level | :levelpad | :message | :metadata | :node | :time
|
||||
@valid_patterns [:time, :date, :message, :level, :node, :metadata, :levelpad]
|
||||
@default_pattern "\n$time $metadata[$level] $levelpad$message\n"
|
||||
@replacement "�"
|
||||
|
||||
@doc """
|
||||
Prune non-valid UTF-8 codepoints.
|
||||
|
||||
Typically called after formatting when the data cannot be printed.
|
||||
"""
|
||||
@spec prune(IO.chardata) :: IO.chardata
|
||||
def prune(binary) when is_binary(binary), do: prune_binary(binary, "")
|
||||
def prune([h|t]) when h in 0..1114111, do: [h|prune(t)]
|
||||
def prune([h|t]), do: [prune(h)|prune(t)]
|
||||
def prune([]), do: []
|
||||
def prune(_), do: @replacement
|
||||
|
||||
defp prune_binary(<<h::utf8, t::binary>>, acc),
|
||||
do: prune_binary(t, <<acc::binary, h::utf8>>)
|
||||
defp prune_binary(<<_, t::binary>>, acc),
|
||||
do: prune_binary(t, <<acc::binary, @replacement>>)
|
||||
defp prune_binary(<<>>, acc),
|
||||
do: acc
|
||||
|
||||
@doc ~S"""
|
||||
Compiles a format string into an array that the `format/5` can handle.
|
||||
|
||||
@@ -10,9 +10,9 @@ defmodule Logger.Watcher do
|
||||
"""
|
||||
def start_link(m, f, a) do
|
||||
import Supervisor.Spec
|
||||
child = worker(__MODULE__, [],
|
||||
[function: :watcher, restart: :transient])
|
||||
options = [strategy: :simple_one_for_one, name: @name]
|
||||
child = worker(__MODULE__, [], [function: :watcher, restart: :transient])
|
||||
options = [strategy: :simple_one_for_one, name: @name,
|
||||
max_restarts: 30, max_seconds: 3]
|
||||
case Supervisor.start_link([child], options) do
|
||||
{:ok, _} = ok ->
|
||||
_ = for {mod, handler, args} <- apply(m, f, a) do
|
||||
|
||||
@@ -4,6 +4,14 @@ defmodule Logger.FormatterTest do
|
||||
|
||||
import Logger.Formatter
|
||||
|
||||
test "prune/1" do
|
||||
assert prune(1) == "�"
|
||||
assert prune(<<"hí", 233>>) == "hí�"
|
||||
assert prune(["hi"|233]) == ["hi"|"�"]
|
||||
assert prune([233|"hi"]) == [233|"hi"]
|
||||
assert prune([[]|[]]) == [[]]
|
||||
end
|
||||
|
||||
defmodule CompileMod do
|
||||
def format(_level, _msg, _ts, _md) do
|
||||
true
|
||||
|
||||
@@ -80,16 +80,16 @@ defmodule Logger.UtilsTest do
|
||||
{'~ts~ts~ts', ["abcdeabcde", "", ""]}
|
||||
end
|
||||
|
||||
test "timestamp" do
|
||||
test "timestamp/1" do
|
||||
assert {{_, _, _}, {_, _, _, _}} = timestamp(true)
|
||||
end
|
||||
|
||||
test "format_date" do
|
||||
test "format_date/1" do
|
||||
date = {2015, 1, 30}
|
||||
assert format_date(date) == ["2015", ?-, [?0, "1"], ?-, "30"]
|
||||
end
|
||||
|
||||
test "format_time" do
|
||||
test "format_time/1" do
|
||||
time = {12, 30, 10, 1}
|
||||
assert format_time(time) == ["12", ?:, "30", ?:, "10", ?., [?0, ?0, "1"]]
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ defmodule Mix.Dep.Converger do
|
||||
|
||||
# When in_upper is true
|
||||
#
|
||||
# When a parent dependency specifies only that is a subset
|
||||
# When a parent dependency specifies :only that is a subset
|
||||
# of a child dependency, we are going to abort as the parent
|
||||
# dependency must explicitly outline a superset of child
|
||||
# dependencies.
|
||||
|
||||
@@ -209,20 +209,14 @@ defmodule Mix.Dep.Loader do
|
||||
## Fetching
|
||||
|
||||
# We need to override the dependencies so they mirror
|
||||
# the :only requirement in the parent. Furthermore, if
|
||||
# a dependency has :only, we must remove it as deps
|
||||
# always run in a given environment (which does not
|
||||
# necessarily mirror the application one unless
|
||||
# configured otherwise).
|
||||
# the :only requirement in the parent.
|
||||
defp attach_only(deps, opts) do
|
||||
if only = opts[:only] do
|
||||
Enum.map(deps, fn %{opts: opts} = dep ->
|
||||
%{dep | opts: Keyword.put(opts, :only, only)}
|
||||
end)
|
||||
else
|
||||
Enum.map(deps, fn %{opts: opts} = dep ->
|
||||
%{dep | opts: Keyword.delete(opts, :only)}
|
||||
end)
|
||||
deps
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@ defmodule Mix.Project do
|
||||
app = config[:app] ->
|
||||
Path.join([build_path(config), "lib", Atom.to_string(app)])
|
||||
config[:apps_path] ->
|
||||
Mix.raise "Trying to access app_path for an umbrella project but umbrellas have no app"
|
||||
raise "Trying to access app_path for an umbrella project but umbrellas have no app"
|
||||
true ->
|
||||
Mix.raise "Cannot access build without an application name, " <>
|
||||
"please ensure you are in a directory with a mix.exs file and it defines " <>
|
||||
@@ -314,7 +314,9 @@ defmodule Mix.Project do
|
||||
"""
|
||||
def compile(args, config \\ config()) do
|
||||
if config[:build_embedded] do
|
||||
if not File.exists?(compile_path(config)) do
|
||||
path = if umbrella?(config), do: build_path(config), else: compile_path(config)
|
||||
|
||||
unless File.exists?(path) do
|
||||
Mix.raise "Cannot execute task because the project was not yet compiled. " <>
|
||||
"When build_embedded is set to true, \"MIX_ENV=#{Mix.env} mix compile\" " <>
|
||||
"must be explicitly executed"
|
||||
|
||||
@@ -111,11 +111,11 @@ defmodule Mix.Shell do
|
||||
{:unix, _} ->
|
||||
command = command
|
||||
|> String.replace("\"", "\\\"")
|
||||
|> :binary.bin_to_list
|
||||
|> String.to_char_list
|
||||
'sh -c "' ++ command ++ '"'
|
||||
|
||||
{:win32, osname} ->
|
||||
command = :binary.bin_to_list(command)
|
||||
command = String.to_char_list(command)
|
||||
case {System.get_env("COMSPEC"), osname} do
|
||||
{nil, :windows} -> 'command.com /c ' ++ command
|
||||
{nil, _} -> 'cmd /c ' ++ command
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
defmodule Mix.Tasks.App.Start do
|
||||
use Mix.Task
|
||||
|
||||
# Do not mark this task as recursive as it is
|
||||
# responsible for loading consolidated protocols.
|
||||
@shortdoc "Starts all registered apps"
|
||||
|
||||
@moduledoc """
|
||||
|
||||
@@ -2,12 +2,9 @@ defmodule DepsRepo do
|
||||
use Mix.Project
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :deps_repo,
|
||||
version: "0.1.0",
|
||||
deps: [
|
||||
{:git_repo, "0.1.0", git: MixTest.Case.fixture_path("git_repo")}
|
||||
]
|
||||
]
|
||||
opts = Process.get(:custom_deps_git_repo_opts) || []
|
||||
[app: :deps_repo,
|
||||
version: "0.1.0",
|
||||
deps: [{:git_repo, "0.1.0", [git: MixTest.Case.fixture_path("git_repo")] ++ opts}]]
|
||||
end
|
||||
end
|
||||
@@ -273,7 +273,35 @@ defmodule Mix.DepTest do
|
||||
end
|
||||
end
|
||||
|
||||
test "nested deps on only matching" do
|
||||
# deps_repo wants git_repo for test, git_repo is restricted to only test
|
||||
# We assert the dependencies match as expected, happens in umbrella apps
|
||||
Process.put(:custom_deps_git_repo_opts, [only: :test])
|
||||
|
||||
# We need to pass env: :test so the child dependency is loaded
|
||||
# in the first place (otherwise only :prod deps are loaded)
|
||||
deps = [{:deps_repo, "0.1.0", path: "custom/deps_repo", env: :test},
|
||||
{:git_repo, "0.2.0", git: MixTest.Case.fixture_path("git_repo"), only: :test}]
|
||||
|
||||
with_deps deps, fn ->
|
||||
in_fixture "deps_status", fn ->
|
||||
loaded = Mix.Dep.loaded([])
|
||||
assert [:git_repo, :deps_repo] = Enum.map(loaded, &(&1.app))
|
||||
assert [unavailable: _, noappfile: _] = Enum.map(loaded, &(&1.status))
|
||||
|
||||
loaded = Mix.Dep.loaded([env: :dev])
|
||||
assert [:deps_repo] = Enum.map(loaded, &(&1.app))
|
||||
assert [noappfile: _] = Enum.map(loaded, &(&1.status))
|
||||
|
||||
loaded = Mix.Dep.loaded([env: :test])
|
||||
assert [:git_repo, :deps_repo] = Enum.map(loaded, &(&1.app))
|
||||
assert [unavailable: _, noappfile: _] = Enum.map(loaded, &(&1.status))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "nested deps on only conflict" do
|
||||
# deps_repo wants all git_repo, git_repo is restricted to only test
|
||||
deps = [{:deps_repo, "0.1.0", path: "custom/deps_repo"},
|
||||
{:git_repo, "0.2.0", git: MixTest.Case.fixture_path("git_repo"), only: :test}]
|
||||
|
||||
@@ -300,6 +328,7 @@ defmodule Mix.DepTest do
|
||||
end
|
||||
|
||||
test "nested deps with valid only subset" do
|
||||
# deps_repo wants git_repo for prod, git_repo is restricted to only prod and test
|
||||
deps = [{:deps_repo, "0.1.0", path: "custom/deps_repo", only: :prod},
|
||||
{:git_repo, "0.2.0", git: MixTest.Case.fixture_path("git_repo"), only: [:prod, :test]}]
|
||||
|
||||
@@ -324,6 +353,7 @@ defmodule Mix.DepTest do
|
||||
end
|
||||
|
||||
test "nested deps with invalid only subset" do
|
||||
# deps_repo wants git_repo for dev, git_repo is restricted to only test
|
||||
deps = [{:deps_repo, "0.1.0", path: "custom/deps_repo", only: :dev},
|
||||
{:git_repo, "0.2.0", git: MixTest.Case.fixture_path("git_repo"), only: [:test]}]
|
||||
|
||||
@@ -349,7 +379,7 @@ defmodule Mix.DepTest do
|
||||
end
|
||||
end
|
||||
|
||||
test "nested deps on only diverged" do
|
||||
test "nested deps converge and diverge only not in_upper" do
|
||||
loaded_only = fn deps ->
|
||||
with_deps deps, fn ->
|
||||
in_fixture "deps_status", fn ->
|
||||
|
||||
@@ -34,9 +34,13 @@ defmodule Mix.UmbrellaTest do
|
||||
end
|
||||
end
|
||||
|
||||
test "compiles umbrella with protocol consolidation" do
|
||||
test "compiles umbrella with build embedded (and protocol consolidation)" do
|
||||
in_fixture "umbrella_dep/deps/umbrella", fn ->
|
||||
Mix.Project.in_project(:umbrella, ".", [consolidate_protocols: true], fn _ ->
|
||||
Mix.Project.in_project(:umbrella, ".", [build_embedded: true], fn _ ->
|
||||
assert_raise Mix.Error, ~r"Cannot execute task because the project was not yet compiled", fn ->
|
||||
Mix.Tasks.App.Start.run []
|
||||
end
|
||||
|
||||
Mix.Task.run "compile"
|
||||
|
||||
assert_received {:mix_shell, :info, ["Generated bar app"]}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{application, elixir,
|
||||
[{description, "elixir"},
|
||||
{vsn, "1.1.0"},
|
||||
{vsn, "1.1.1"},
|
||||
{modules, [
|
||||
elixir
|
||||
]},
|
||||
|
||||
Reference in New Issue
Block a user