diff --git a/.gitignore b/.gitignore index d46777512b..8ccccf01b9 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,6 @@ .vscode .rebar/ .eunit/ -.hypothesis/ cover/ /core debian/ @@ -64,12 +63,14 @@ src/hqueue/ src/ibrowse/ src/idna/ src/jiffy/ +src/libgraph/ src/meck/ src/metrics/ src/mimerl/ src/mochiweb/ src/oauth/ src/parse_trans/ +src/propcheck/ src/proper/ src/rebar/ src/recon/ diff --git a/Makefile b/Makefile index 06578a6ebf..984e81d787 100644 --- a/Makefile +++ b/Makefile @@ -260,8 +260,12 @@ elixir-cluster-with-quorum: elixir-init devclean .PHONY: elixir # target: elixir - Run Elixir-based integration tests -elixir: export MIX_ENV=integration elixir: elixir-init devclean + @$(MAKE) elixir-test + +.PHONY: elixir-test +elixir-test: export MIX_ENV=integration +elixir-test: @dev/run "$(TEST_OPTS)" -n 1 -q -a adm:pass \ --enable-erlang-views \ --no-join \ @@ -289,6 +293,16 @@ else @echo "Warning: Clouseau is not enabled, \`elixir-search\` cannot be run." endif +.PHONY: elixir-test-search-props +elixir-test-search-props: export MIX_ENV=integration +elixir-test-search-props: + @dev/run "$(TEST_OPTS)" -n 1 -q -a adm:pass \ + --enable-erlang-views \ + --no-join \ + --locald-config test/elixir/test/config/test-config.ini \ + --erlang-config rel/files/eunit.config \ + --no-eval 'mix test --trace --only search_props $(EXUNIT_OPTS)' + .PHONY: elixir-source-checks # target: elixir-source-checks - Check source code formatting of Elixir test files elixir-source-checks: export MIX_ENV=integration diff --git a/README-DEV.rst b/README-DEV.rst index a2eec4b44f..f71a4de502 100644 --- a/README-DEV.rst +++ b/README-DEV.rst @@ -100,7 +100,7 @@ Gentoo-based Systems :: sudo emerge gnupg coreutils pkgconfig help2man sphinx python - sudo pip install hypothesis requests nose + sudo pip install requests nose Centos 7 and RHEL 7 ~~~~~~~~~~~~~~~~~~~ @@ -136,7 +136,7 @@ FreeBSD :: pkg install help2man gnupg py27-sphinx node - pip install nose requests hypothesis + pip install nose requests Windows ~~~~~~~ diff --git a/erlang_ls.config b/erlang_ls.config index 94483cfec2..3464e6fdd3 100644 --- a/erlang_ls.config +++ b/erlang_ls.config @@ -3,3 +3,8 @@ apps_dirs: include_dirs: - "src" - "src/*/include" +macros: + - name: WITH_PROPER + value: true + - name: TEST + value: true diff --git a/mix.exs b/mix.exs index 4f0cb4ba3f..1749758c59 100644 --- a/mix.exs +++ b/mix.exs @@ -66,12 +66,13 @@ defmodule CouchDBTest.Mixfile do tool: CoverTool, dirs: get_coverage_paths(), type: "html" - ] + ], + propcheck: [] ] end # Run "mix help compile.app" to learn about applications. - def application, do: [applications: [:logger, :httpotion]] + def application, do: [applications: [:logger, :httpotion, :propcheck]] # Specifies which paths to compile per environment. defp elixirc_paths(:test), do: ["test/elixir/lib", "test/elixir/test/support"] @@ -85,7 +86,8 @@ defmodule CouchDBTest.Mixfile do {:httpotion, ">= 3.2.0", only: [:dev, :test, :integration], runtime: false}, {:excoveralls, "~> 0.18.3", only: :test}, {:ibrowse, path: path("ibrowse"), override: true}, - {:credo, "~> 1.7.11", only: [:dev, :test, :integration], runtime: false} + {:credo, "~> 1.7.11", only: [:dev, :test, :integration], runtime: false}, + {:propcheck, "~> 1.5", only: [:dev, :test, :integration]} ] extra_deps = [:b64url, :jiffy, :jwtf, :meck, :mochiweb] diff --git a/src/mango/requirements.txt b/src/mango/requirements.txt index c8e8cff379..481fc3418e 100644 --- a/src/mango/requirements.txt +++ b/src/mango/requirements.txt @@ -1,5 +1,4 @@ -# nose2 0.13.0, requests, hypothesis version are driven +# nose2 0.13.0, requests version are driven # by the minimum version for python on centos 8 currently nose2==0.13.0 requests==2.32.4 -hypothesis==6.31.6 diff --git a/src/mango/test/06-basic-text-test.py b/src/mango/test/06-basic-text-test.py index da3eb6ff58..57a337ba98 100644 --- a/src/mango/test/06-basic-text-test.py +++ b/src/mango/test/06-basic-text-test.py @@ -15,9 +15,6 @@ import unittest import user_docs import math -from hypothesis import given, assume, example, settings -import hypothesis.strategies as st - @unittest.skipIf(mango.has_text_service(), "text service exists") class TextIndexCheckTests(mango.DbPerClass): @@ -564,39 +561,3 @@ def test_all_match(self): docs = self.db.find(q) assert len(docs) == 1 assert docs[0]["user_id"] == 15 - - -# Test numeric strings for $text -@unittest.skipUnless(mango.has_text_service(), "requires text service") -class NumStringTests(mango.DbPerClass): - @classmethod - def setUpClass(klass): - super(NumStringTests, klass).setUpClass() - klass.db.recreate() - klass.db.create_text_index() - - # not available for python 2.7.x - def isFinite(num): - not (math.isinf(num) or math.isnan(num)) - - @given(f=st.floats().filter(isFinite).map(str) | st.floats().map(lambda f: f.hex())) - @settings(deadline=1000) - @example("NaN") - @example("Infinity") - def test_floating_point_val(self, f): - doc = {"number_string": f} - self.db.save_doc(doc) - q = {"$text": f} - docs = self.db.find(q) - if len(docs) == 1: - assert docs[0]["number_string"] == f - if len(docs) == 2: - if docs[0]["number_string"] != f: - assert docs[1]["number_string"] == f - q = {"number_string": f} - docs = self.db.find(q) - if len(docs) == 1: - assert docs[0]["number_string"] == f - if len(docs) == 2: - if docs[0]["number_string"] != f: - assert docs[1]["number_string"] == f diff --git a/test/elixir/test/config/test-config.ini b/test/elixir/test/config/test-config.ini index 423cc492cb..53ac2cac79 100644 --- a/test/elixir/test/config/test-config.ini +++ b/test/elixir/test/config/test-config.ini @@ -1,5 +1,5 @@ [log] -level = warn +level = notice [chttpd] authentication_handlers = {chttpd_auth, jwt_authentication_handler}, {chttpd_auth, proxy_authentication_handler}, {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, default_authentication_handler} diff --git a/test/elixir/test/mango/06_basic_text_prop_test.exs b/test/elixir/test/mango/06_basic_text_prop_test.exs new file mode 100644 index 0000000000..26900bc6eb --- /dev/null +++ b/test/elixir/test/mango/06_basic_text_prop_test.exs @@ -0,0 +1,50 @@ +defmodule BasicTextTest do + use PropCheck + use CouchTestCase + + @moduletag :search_props + @db_name "changeme-proptest-db" + + property "test floating point value", + numtests: 1_000 do # takes about 10 seconds + MangoDatabase.recreate("/#{@db_name}") + forall f <- weighted_union([{100, float()}, {1, "NaN"}, {1, "Infinity"}]) do + # create doc with float + :ok == test_float(f) + end + end + + # this is used to test the inner logic, as that + # is a bit tricky from inside the property + test "single floating point test" do + MangoDatabase.recreate("/#{@db_name}") + test_float(3.14) + end + + def test_float(f) do + doc = %{"number_string" => f} + # save doc + Couch.post("/#{@db_name}", body: doc) + # run find with same float as $text + {:ok, docs} = MangoDatabase.find(@db_name, %{"$text" => f}) + # if result length = 1, assert docs[0] == f + assert_result(docs, f) + # run find again with same float as field name match + {:ok, docs} = MangoDatabase.find(@db_name, %{"number_text" => f}) + # repeat same tests + assert_result(docs, f) + :ok + end + + def assert_result(docs, f) do + cond do + Enum.count(docs) == 1 -> + assert Enum.at(docs, 0)["number_string"] == f + Enum.count(docs) == 2 -> + if Enum.at(docs, 0)["number_string"] != f do + assert Enum.at(docs, 1)["number_string"] == f + end + true -> true + end + end +end