From 4b32095f910f6641651be4529fa0d4cc1fae2c64 Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Sat, 7 Dec 2024 10:00:51 +0100 Subject: [PATCH 01/10] Update CI with OTP27 --- .github/workflows/ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 155cd05..34aceb9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,9 +12,9 @@ jobs: name: OTP ${{matrix.otp_vsn}} strategy: matrix: - otp_vsn: ['26.2', '25.3', '24.3'] - rebar_vsn: ['3.22.0'] - runs-on: 'ubuntu-22.04' + otp_vsn: ['27', '26', '25'] + rebar_vsn: ['3.24.0'] + runs-on: 'ubuntu-24.04' env: OTPVER: ${{ matrix.otp }} steps: @@ -23,7 +23,7 @@ jobs: with: otp-version: ${{ matrix.otp_vsn }} rebar3-version: ${{ matrix.rebar_vsn }} - - uses: actions/cache@v3 + - uses: actions/cache@v4 name: Cache with: path: _build @@ -34,8 +34,9 @@ jobs: - run: rebar3 dialyzer - run: rebar3 as test codecov analyze - run: gcov -o c_src exml - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v5 with: name: Upload coverage reports to Codecov token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true + verbose: true From 77fe626cb4345d1e5d0f6d9eead4cf1cbba54f8e Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Mon, 17 Jun 2024 16:59:51 +0200 Subject: [PATCH 02/10] nowarn_export_all in test suites --- test/exml_properties_tests.erl | 4 ++-- test/exml_stream_tests.erl | 2 +- test/exml_tests.erl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/exml_properties_tests.erl b/test/exml_properties_tests.erl index c5e8b4c..773c750 100644 --- a/test/exml_properties_tests.erl +++ b/test/exml_properties_tests.erl @@ -2,8 +2,8 @@ -include_lib("proper/include/proper.hrl"). -include_lib("eunit/include/eunit.hrl"). --include_lib("exml.hrl"). --compile(export_all). + +-compile([export_all, nowarn_export_all]). p(Name, Property) -> ?assert(proper:quickcheck diff --git a/test/exml_stream_tests.erl b/test/exml_stream_tests.erl index e5e43c7..f280a65 100644 --- a/test/exml_stream_tests.erl +++ b/test/exml_stream_tests.erl @@ -3,7 +3,7 @@ -include("exml_stream.hrl"). -include_lib("eunit/include/eunit.hrl"). --compile(export_all). +-compile([export_all, nowarn_export_all]). basic_parse_test() -> {ok, Parser0} = exml_stream:new_parser(), diff --git a/test/exml_tests.erl b/test/exml_tests.erl index 9fccca1..9052f24 100644 --- a/test/exml_tests.erl +++ b/test/exml_tests.erl @@ -13,7 +13,7 @@ -include_lib("exml/include/exml.hrl"). -include_lib("exml/include/exml_stream.hrl"). --compile(export_all). +-compile([export_all, nowarn_export_all]). application_test() -> ?assertEqual(ok, application:start(exml)), From 63d09f8c5826d66188e07cab683414c1af772276 Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Sat, 7 Dec 2024 10:00:13 +0100 Subject: [PATCH 03/10] Minor test redundancy improvement --- include/exml.hrl | 27 ++++++++++++++------------- test/exml_tests.erl | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/exml.hrl b/include/exml.hrl index a2ef4b4..5e5eed7 100644 --- a/include/exml.hrl +++ b/include/exml.hrl @@ -12,22 +12,23 @@ attrs = [] :: [exml:attr()], children = [] :: [exml:element() | exml:cdata()]}). -%% Implementation of the exmlAssertEqual/2 macro is an exact copy of +%% Implementation of the exmlAssertEqual/2 macro is a modification of %% https://github.com/erszcz/rxml/commit/e8483408663f0bc2af7896e786c1cdea2e86e43d#diff-2cb5d18741df32f4ead70c21fdd221d1 %% See assertEqual in $ERLANG/lib/stdlib-2.6/include/assert.hrl for the original. --define(exmlAssertEqual(Example, Expr), +-define(exmlAssertEqual(Expect, Expr), begin - ((fun (__E, __V) -> - case __V of - __E -> ok; - __V -> erlang:error({exmlAssertEqual, - [{module, ?MODULE}, - {line, ?LINE}, - {expression, (??Expr)}, - {expected, __E}, - {value, __V}]}) - end - end)(exml:xml_sort((Example)), exml:xml_sort((Expr)))) + ((fun () -> + X__X = (exml:xml_sort(Expect)), + case (exml:xml_sort(Expr)) of + X__X -> ok; + X__V -> erlang:error({exmlAssertEqual, + [{module, ?MODULE}, + {line, ?LINE}, + {expression, (??Expr)}, + {expected, Expect}, + {value, X__V}]}) + end + end)()) end). -endif. diff --git a/test/exml_tests.erl b/test/exml_tests.erl index 9052f24..64f9452 100644 --- a/test/exml_tests.erl +++ b/test/exml_tests.erl @@ -107,7 +107,7 @@ assert_xmlel_equal_macro_positive_test() -> children = [#xmlcdata{ content = <<"some value">> }] }, El2 = El1#xmlel{ attrs = lists:reverse(Attrs) }, - ?assertEqual(ok, ?exmlAssertEqual(El1, El2)). + ?exmlAssertEqual(El1, El2). assert_xmlel_equal_macro_negative_test() -> El1 = #xmlel{ From 1011275cec5262c8eb5cd0265a7d8167286bfefe Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Sat, 7 Dec 2024 10:03:52 +0100 Subject: [PATCH 04/10] Enforce tracking the lockfile --- .gitignore | 1 - rebar.lock | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 rebar.lock diff --git a/.gitignore b/.gitignore index ae2791b..c65dbac 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,5 @@ _build/ /logs/ /priv/*so *.beam -*.lock /rebar3 doc/ diff --git a/rebar.lock b/rebar.lock new file mode 100644 index 0000000..57afcca --- /dev/null +++ b/rebar.lock @@ -0,0 +1 @@ +[]. From a96d81ccc737b6ada23628672bf37ef7e8ee8311 Mon Sep 17 00:00:00 2001 From: Radek Szymczyszyn Date: Tue, 19 Mar 2024 16:41:01 +0100 Subject: [PATCH 05/10] Fix some elp type errors in src/exml_nif.erl --- src/exml_nif.erl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/exml_nif.erl b/src/exml_nif.erl index 9509a4e..2c244b3 100644 --- a/src/exml_nif.erl +++ b/src/exml_nif.erl @@ -25,9 +25,15 @@ load() -> PrivDir = case code:priv_dir(?MODULE) of {error, _} -> - EbinDir = filename:dirname(code:which(?MODULE)), - AppPath = filename:dirname(EbinDir), - filename:join(AppPath, "priv"); + case code:which(?MODULE) of + Path when is_list(Path) -> + EbinDir = filename:dirname(Path), + AppPath = filename:dirname(EbinDir), + filename:join(AppPath, "priv"); + _ -> + %% cover_compiled | preloaded | non_existing + erlang:error({cannot_get_load_path, ?MODULE}) + end; Path -> Path end, From 0fc0f5a6eb23be561eb0d7dcac5c83550259eee3 Mon Sep 17 00:00:00 2001 From: Radek Szymczyszyn Date: Tue, 19 Mar 2024 16:36:17 +0100 Subject: [PATCH 06/10] Fix some elp type errors in src/exml.erl --- src/exml.erl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/exml.erl b/src/exml.erl index 486ae47..7bbbf35 100644 --- a/src/exml.erl +++ b/src/exml.erl @@ -50,7 +50,8 @@ xml_size(#xmlstreamstart{ name = Name, attrs = Attrs }) -> byte_size(Name) + 2 + xml_size(Attrs); xml_size(#xmlstreamend{ name = Name }) -> byte_size(Name) + 3; -xml_size({Key, Value}) -> +xml_size({Key, Value}) when is_binary(Key) -> + % Attributes byte_size(Key) + 4 % ="" and whitespace before + byte_size(Value). @@ -66,7 +67,12 @@ xml_size({Key, Value}) -> %% @end %% The implementation of this function is a subtle modification of %% https://github.com/erszcz/rxml/commit/e8483408663f0bc2af7896e786c1cdea2e86e43d --spec xml_sort(item() | [item()]) -> item() | [item()]. +-spec xml_sort([item()]) -> [item()]; + (element()) -> element(); + (attr()) -> attr(); + (cdata()) -> cdata(); + (exml_stream:start()) -> exml_stream:start(); + (exml_stream:stop()) -> exml_stream:stop(). xml_sort(#xmlcdata{} = Cdata) -> Cdata; xml_sort(#xmlel{ attrs = Attrs, children = Children } = El) -> From 6e0d321645626a6938ac718abb799ce6f96b69e8 Mon Sep 17 00:00:00 2001 From: Radek Szymczyszyn Date: Wed, 20 Mar 2024 10:23:11 +0100 Subject: [PATCH 07/10] Fix elp error: subelement/3 might return 'undefined' --- src/exml_query.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exml_query.erl b/src/exml_query.erl index 2f7dadc..c17ee79 100644 --- a/src/exml_query.erl +++ b/src/exml_query.erl @@ -74,7 +74,7 @@ path(Element, Path) -> %% ''' %% will return `<<"Message from bob to alice">>' %% @end --spec path(exml:element(), path(), Default) -> exml:element() | binary() | Default. +-spec path(exml:element() | undefined, path(), Default) -> exml:element() | binary() | Default. path(#xmlel{} = Element, [], _) -> Element; path(#xmlel{} = Element, [{element, Name} | Rest], Default) -> From a16598228678e440688e4a03c2d9c782a01a63e5 Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Sat, 7 Dec 2024 10:09:54 +0100 Subject: [PATCH 08/10] Keep well separated project plugins from plugins --- rebar.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rebar.config b/rebar.config index 7c017f5..657ec81 100644 --- a/rebar.config +++ b/rebar.config @@ -25,8 +25,8 @@ ]} ]}. -{project_plugins, [rebar3_ex_doc]}. -{plugins, [pc, rebar3_hex]}. +{project_plugins, [rebar3_hex, rebar3_ex_doc]}. +{plugins, [pc]}. % Interrupt compilation, if the artifact is not found {artifacts, ["priv/exml_nif.so"]}. From 44fccb13724656a8707853dc676c18d3bef2aafd Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Sat, 7 Dec 2024 12:04:21 +0100 Subject: [PATCH 09/10] Cover attr order case --- src/exml.erl | 2 ++ test/exml_tests.erl | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/exml.erl b/src/exml.erl index 7bbbf35..c6a30d9 100644 --- a/src/exml.erl +++ b/src/exml.erl @@ -84,6 +84,8 @@ xml_sort(#xmlstreamstart{ attrs = Attrs } = StreamStart) -> StreamStart#xmlstreamstart{ attrs = lists:sort(Attrs) }; xml_sort(#xmlstreamend{} = StreamEnd) -> StreamEnd; +xml_sort({Key, Value}) -> + {Key, Value}; xml_sort(Elements) when is_list(Elements) -> lists:sort([ xml_sort(E) || E <- Elements ]). diff --git a/test/exml_tests.erl b/test/exml_tests.erl index 64f9452..b7479a2 100644 --- a/test/exml_tests.erl +++ b/test/exml_tests.erl @@ -40,6 +40,11 @@ sort_xmlel_identity_test() -> }, ?assertEqual(El, exml:xml_sort(El)). +sort_xmlel_attributes_test() -> + Attrs = [{<<"attr1">>, <<"foo">>}, {<<"attr2">>, <<"bar">>}], + ToOrder = [{<<"attr2">>, <<"bar">>}, {<<"attr1">>, <<"foo">>}], + ?assertEqual(Attrs, exml:xml_sort(ToOrder)). + sort_xmlel_test() -> Attrs = [{<<"attr1">>, <<"bar">>}, {<<"attr2">>, <<"baz">>}], El1 = #xmlel{ From 4c4de35e06c5a96de6fcc8632c0065af1fc9591d Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Sat, 7 Dec 2024 12:21:42 +0100 Subject: [PATCH 10/10] Fix redundantly given type module --- src/exml.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exml.erl b/src/exml.erl index c6a30d9..12c7b0f 100644 --- a/src/exml.erl +++ b/src/exml.erl @@ -110,7 +110,7 @@ to_pretty_iolist(Element) -> to_iolist(Element, pretty). %% @doc Parses a binary or a list of binaries into an XML `t:element()'. --spec parse(binary() | [binary()]) -> {ok, exml:element()} | {error, any()}. +-spec parse(binary() | [binary()]) -> {ok, element()} | {error, any()}. parse(XML) -> exml_nif:parse(XML).