nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: keathley/finch
Pull request #3 (2020-04-06 21:33:18)

If the connection has been closed, don't try to transfer it back to the pool


Patch:
diff --git a/lib/finch/conn.ex b/lib/finch/conn.ex
index 52275a2..8e71565 100644
--- a/lib/finch/conn.ex
+++ b/lib/finch/conn.ex
@@ -27,6 +27,9 @@ defmodule Finch.Conn do
     end
   end
 
+  def open?(%{mint: nil}), do: false
+  def open?(%{mint: mint}), do: HTTP.open?(mint)
+
   def set_mode(%{mint: nil}, _), do: {:error, "Connection is dead"}
 
   def set_mode(conn, mode) when mode in [:active, :passive] do
diff --git a/lib/finch/pool.ex b/lib/finch/pool.ex
index 039cfa1..97db997 100644
--- a/lib/finch/pool.ex
+++ b/lib/finch/pool.ex
@@ -26,9 +26,8 @@ defmodule Finch.Pool do
       fn {conn, pool} ->
         conn = Conn.connect(conn)
 
-        with {:ok, conn, response} <- Conn.request(conn, req, receive_timeout),
-             {:ok, conn} <- Conn.transfer(conn, pool) do
-          {{:ok, response}, conn}
+        with {:ok, conn, response} <- Conn.request(conn, req, receive_timeout) do
+          {{:ok, response}, transfer_conn(conn, pool)}
         else
           {:error, conn, error} ->
             {{:error, error}, conn}
@@ -93,4 +92,13 @@ defmodule Finch.Pool do
     Conn.close(conn)
     :ok
   end
+
+  defp transfer_conn(conn, pid) do
+    if Conn.open?(conn) do
+      {:ok, conn} = Conn.transfer(conn, pid)
+      conn
+    else
+      conn
+    end
+  end
 end


Test patch:
diff --git a/test/finch_test.exs b/test/finch_test.exs
index 3d3bc1a..82297c2 100644
--- a/test/finch_test.exs
+++ b/test/finch_test.exs
@@ -90,6 +90,24 @@ defmodule FinchTest do
                end)
     end
 
+    test "properly handles connection: close", %{bypass: bypass} do
+      start_supervised({Finch, name: MyFinch})
+
+      Bypass.expect(bypass, fn conn ->
+        conn
+        |> Plug.Conn.put_resp_header("connection", "close")
+        |> Plug.Conn.send_resp(200, "OK")
+      end)
+
+      assert {:ok, %{status: 200, data: "OK"}} =
+               Finch.request(
+                 MyFinch,
+                 :get,
+                 endpoint(bypass),
+                 [{"connection", "keep-alive"}]
+               )
+    end
+
     test "returns error when request times out", %{bypass: bypass} do
       start_supervised({Finch, name: MyFinch})
Repository: keathley/finch
Pull request #13 (2020-04-08 10:17:31)

Make sure we do not lose the request query string
During testing I noticed that my query string params were not being sent :)


Patch:
diff --git a/lib/finch.ex b/lib/finch.ex
index 603cefc..1ceea9f 100644
--- a/lib/finch.ex
+++ b/lib/finch.ex
@@ -110,7 +110,8 @@ defmodule Finch do
       method: build_method(method),
       path: uri.path || "/",
       headers: headers,
-      body: body
+      body: body,
+      query: uri.query
     }
 
     pool = PoolManager.get_pool(name, req.scheme, req.host, req.port)
diff --git a/lib/finch/conn.ex b/lib/finch/conn.ex
index 4c9df1d..b282dd2 100644
--- a/lib/finch/conn.ex
+++ b/lib/finch/conn.ex
@@ -57,7 +57,9 @@ defmodule Finch.Conn do
   def request(%{mint: nil} = conn, _, _), do: {:error, conn, "Could not connect"}
 
   def request(conn, req, receive_timeout) do
-    case HTTP.request(conn.mint, req.method, req.path, req.headers, req.body) do
+    full_path = request_path(req)
+
+    case HTTP.request(conn.mint, req.method, full_path, req.headers, req.body) do
       {:ok, mint, ref} ->
         receive_response([], %{conn | mint: mint}, ref, %{}, receive_timeout)
 
@@ -73,6 +75,9 @@ defmodule Finch.Conn do
     %{conn | mint: mint}
   end
 
+  defp request_path(%{path: path, query: nil}), do: path
+  defp request_path(%{path: path, query: query}), do: "#{path}?#{query}"
+
   defp receive_response([], conn, ref, response, timeout) do
     case HTTP.recv(conn.mint, 0, timeout) do
       {:ok, mint, entries} ->


Test patch:
diff --git a/test/finch_test.exs b/test/finch_test.exs
index 4b6c330..5193652 100644
--- a/test/finch_test.exs
+++ b/test/finch_test.exs
@@ -58,15 +58,30 @@ defmodule FinchTest do
   end
 
   describe "request/5" do
-    test "successful post request", %{bypass: bypass} do
+    test "successful get request, with query string", %{bypass: bypass} do
+      start_supervised({Finch, name: MyFinch})
+      query_string = "query=value"
+
+      Bypass.expect_once(bypass, "GET", "/", fn conn ->
+        assert conn.query_string == query_string
+        Plug.Conn.send_resp(conn, 200, "OK")
+      end)
+
+      assert {:ok, %{status: 200}} =
+               Finch.request(MyFinch, :get, endpoint(bypass, "?" <> query_string))
+    end
+
+    test "successful post request, with body and query string", %{bypass: bypass} do
       start_supervised({Finch, name: MyFinch})
 
       req_body = "{\"response\":\"please\"}"
       response_body = "{\"right\":\"here\"}"
       header_key = "content-type"
       header_val = "application/json"
+      query_string = "query=value"
 
       Bypass.expect_once(bypass, "POST", "/", fn conn ->
+        assert conn.query_string == query_string
         assert {:ok, ^req_body, conn} = Plug.Conn.read_body(conn)
 
         conn
@@ -78,7 +93,7 @@ defmodule FinchTest do
                Finch.request(
                  MyFinch,
                  :post,
-                 endpoint(bypass),
+                 endpoint(bypass, "?" <> query_string),
                  [{header_key, header_val}],
                  req_body
                )
Repository: keathley/norm
Pull request #6 (2019-08-31 02:32:10)

primitive type generators (is_float test)
Hi Chris! I really enjoyed your talk at ElixirConf. Inter-service contracts are something I feel like get implemented from scratch in so many api style code bases (and ultimately is solved by throwing hours at bugs or custom casting/validation/whatever modules).

I'll definitely be trying out Norm and look forward to checking out some of the resources you provided in the talk!

I guess I mostly wanted to open this PR to see how I could contribute (rather than an issue). I noticed one of your asks for early contributions was supporting generators for other primitive types. I'd love to help there! Curious if a PR adding some of them in would be helpful.

I haven't really contributed to open source or libraries, so I thought I'd put up a WIP where I added support for ```gen(spec(is_float()))```. I'm not sure if this is what you had in mind for that task / TODO.

If you had something else in mind, I'd love to get feedback and still try and help contribute! If this is OK, I'll start including other primitives!

P.s. sorry for the spacing in the files, I think that was my auto-formatter. LMK if you'd also like me to remove the noise or if its OK

keathley: Hey @joeyrosztoczy this looks great. I'll set up the formatter on this project so you won't have to churn those files. Once that's done if you wouldn't mind rebasing we should be good to merge this :+1:
joeyrosztoczy: Sweet, @keathley happy to configure / format as well if you want in a separate PR as well and rebase this one after. I would imagine that's kind of an annoying PR to get as a maintainer though because its essentially all noise but need to see if anythings materially changed, so no worries if not!
keathley: No worries @joeyrosztoczy. I've run the formatter on the project so if you want to rebase your branch it should merge cleanly now :+1:

Patch:
diff --git a/lib/norm/spec.ex b/lib/norm/spec.ex
index 42a191e..7a8abac 100644
--- a/lib/norm/spec.ex
+++ b/lib/norm/spec.ex
@@ -81,6 +81,9 @@ defmodule Norm.Spec do
           :is_integer ->
             {:ok, StreamData.integer()}
 
+          :is_float ->
+            {:ok, StreamData.float()}
+
           :is_binary ->
             {:ok, StreamData.binary()}
 


Test patch:
diff --git a/test/norm/generators/primitives_test.exs b/test/norm/generators/primitives_test.exs
new file mode 100644
index 0000000..fd233e2
--- /dev/null
+++ b/test/norm/generators/primitives_test.exs
@@ -0,0 +1,14 @@
+defmodule Norm.Generators.GeneratorTest do
+  use ExUnit.Case, async: true
+  import Norm
+
+  alias Norm.Generator
+
+  describe "generates primitive types" do
+    test "generates values from spec(is_float())" do
+      [output | _] = is_float() |> spec() |> gen() |> Enum.take(1)
+
+      assert is_float(output)
+    end
+  end
+end
Repository: keathley/norm
Pull request #15 (2019-09-15 21:13:07)

Add inspect implementation
This allows pretty printing that is not used in Norm itself, but is
useful for tools built on top.


Patch:
diff --git a/lib/norm/spec.ex b/lib/norm/spec.ex
index 8362211..b411feb 100644
--- a/lib/norm/spec.ex
+++ b/lib/norm/spec.ex
@@ -129,4 +129,15 @@ defmodule Norm.Spec do
       %{path: path, input: input, msg: msg, at: nil}
     end
   end
+
+  @doc false
+  def __inspect__(spec) do
+    spec.predicate
+  end
+
+  defimpl Inspect do
+    def inspect(spec, _) do
+      Inspect.Algebra.concat(["#Norm.Spec<", spec.predicate, ">"])
+    end
+  end
 end
diff --git a/lib/norm/spec/and.ex b/lib/norm/spec/and.ex
index 6c7ba6b..050712d 100644
--- a/lib/norm/spec/and.ex
+++ b/lib/norm/spec/and.ex
@@ -48,4 +48,17 @@ defmodule Norm.Spec.And do
       end
     end
   end
+
+  @doc false
+  def __inspect__(%{left: left, right: right}) do
+    left = left.__struct__.__inspect__(left)
+    right = right.__struct__.__inspect__(right)
+    Inspect.Algebra.concat([left, " and ", right])
+  end
+
+  defimpl Inspect do
+    def inspect(struct, _) do
+      Inspect.Algebra.concat(["#Norm.Spec<", @for.__inspect__(struct), ">"])
+    end
+  end
 end
diff --git a/lib/norm/spec/or.ex b/lib/norm/spec/or.ex
index a230f39..6759fb4 100644
--- a/lib/norm/spec/or.ex
+++ b/lib/norm/spec/or.ex
@@ -35,4 +35,17 @@ defmodule Norm.Spec.Or do
       end
     end
   end
+
+  @doc false
+  def __inspect__(%{left: left, right: right}) do
+    left = left.__struct__.__inspect__(left)
+    right = right.__struct__.__inspect__(right)
+    Inspect.Algebra.concat([left, " or ", right])
+  end
+
+  defimpl Inspect do
+    def inspect(struct, _) do
+      Inspect.Algebra.concat(["#Norm.Spec<", @for.__inspect__(struct), ">"])
+    end
+  end
 end


Test patch:
diff --git a/test/norm/spec_test.exs b/test/norm/spec_test.exs
index 171b4d3..99826a8 100644
--- a/test/norm/spec_test.exs
+++ b/test/norm/spec_test.exs
@@ -108,4 +108,24 @@ defmodule Norm.SpecTest do
       end
     end
   end
+
+  describe "inspect" do
+    test "predicate" do
+      assert inspect(spec(is_integer())) == "#Norm.Spec<is_integer()>"
+    end
+
+    test "lambda" do
+      assert inspect(spec(&(&1 >= 21))) == "#Norm.Spec<&(&1 >= 21)>"
+    end
+
+    test "and" do
+      assert inspect(spec(is_integer() and (&(&1 >= 21)))) ==
+               "#Norm.Spec<is_integer() and &(&1 >= 21)>"
+    end
+
+    test "or" do
+      assert inspect(spec(is_integer() or is_float())) ==
+               "#Norm.Spec<is_integer() or is_float()>"
+    end
+  end
 end
Repository: keathley/norm
Pull request #19 (2019-10-04 22:29:17)

Short-circuit 'and'
Before this patch both left and right were _always_ conformed which caused this to fail:

    iex> hex = spec(is_binary() and (&String.starts_with?(&1, "#")))
    iex> conform!(nil, hex)
    ** (FunctionClauseError) no function clause matching in String.starts_with?/2

    The following arguments were given to String.starts_with?/2:

        # 1
        nil

        # 2
        "#"


Patch:
diff --git a/lib/norm/spec/and.ex b/lib/norm/spec/and.ex
index 050712d..b8c4b4f 100644
--- a/lib/norm/spec/and.ex
+++ b/lib/norm/spec/and.ex
@@ -23,16 +23,8 @@ defmodule Norm.Spec.And do
     alias Norm.Conformer.Conformable
 
     def conform(%{left: l, right: r}, input, path) do
-      errors =
-        [l, r]
-        |> Enum.map(fn spec -> Conformable.conform(spec, input, path) end)
-        |> Enum.filter(fn {result, _} -> result == :error end)
-        |> Enum.flat_map(fn {_, msg} -> msg end)
-
-      if Enum.any?(errors) do
-        {:error, errors}
-      else
-        {:ok, input}
+      with {:ok, _} <- Conformable.conform(l, input, path) do
+        Conformable.conform(r, input, path)
       end
     end
   end


Test patch:
diff --git a/test/norm/spec_test.exs b/test/norm/spec_test.exs
index 99826a8..3f5890c 100644
--- a/test/norm/spec_test.exs
+++ b/test/norm/spec_test.exs
@@ -11,13 +11,13 @@ defmodule Norm.SpecTest do
 
   describe "spec/1" do
     test "can compose specs with 'and'" do
-      can_drink = spec(is_integer() and (&(&1 >= 21)))
+      hex = spec(is_binary() and (&String.starts_with?(&1, "#")))
 
-      assert 21 == conform!(21, can_drink)
-      assert {:error, errors} = conform("21", can_drink)
-      assert errors == ["val: \"21\" fails: is_integer()"]
-      assert {:error, errors} = conform(20, can_drink)
-      assert errors == ["val: 20 fails: &(&1 >= 21)"]
+      assert "#000000" == conform!("#000000", hex)
+      assert {:error, errors} = conform(nil, hex)
+      assert errors == ["val: nil fails: is_binary()"]
+      assert {:error, errors} = conform("bad", hex)
+      assert errors == ["val: \"bad\" fails: &(String.starts_with?(&1, \"#\"))"]
     end
 
     test "'and' and 'or' can be chained" do
Repository: keathley/norm
Pull request #52 (2020-03-10 15:14:52)

Don't crash if using nested selection with non-map input


Patch:
diff --git a/lib/norm/core/selection.ex b/lib/norm/core/selection.ex
index ff842b1..f4d2abc 100644
--- a/lib/norm/core/selection.ex
+++ b/lib/norm/core/selection.ex
@@ -115,6 +115,7 @@ defmodule Norm.Core.Selection do
       end
     end
 
+    defp ensure_key(_key, conformed, _path) when not is_map(conformed), do: :ok
     defp ensure_key(key, conformed, path) do
       if Map.has_key?(conformed, key) do
         :ok


Test patch:
diff --git a/test/norm/core/selection_test.exs b/test/norm/core/selection_test.exs
index 183ffd0..e98ecf4 100644
--- a/test/norm/core/selection_test.exs
+++ b/test/norm/core/selection_test.exs
@@ -48,6 +48,8 @@ defmodule Norm.Core.SelectionTest do
       assert errors == [%{spec: ":required", input: %{name: "chris"}, path: [:user, :age]}]
       assert {:error, errors} = conform(%{fauxuser: %{age: 31}}, selection)
       assert errors == [%{spec: ":required", input: %{fauxuser: %{age: 31}}, path: [:user]}]
+      assert {:error, errors} = conform(%{user: nil}, selection)
+      assert errors == [%{input: nil, path: [:user], spec: "not a map"}]
     end
 
     test "works with nested selections"  do
Repository: aantron/lambdasoup
Pull request #45 (2022-01-29 16:10:39)

Add `Soup.prepend_root`
There's `Soup.append_root` but there's no `Soup.prepend_root`, and without it, inserting something before the very first node in a soup seems impossible.

This patch fixes that and also adds a test for append/prepend root functions specifically.

aantron: Can you prepend a node using [`insert_before`](https://aantron.github.io/lambdasoup/#VALinsert_before)? It would be a bit awkward.

Patch:
diff --git a/src/soup.ml b/src/soup.ml
index 96b6502..84e8b31 100644
--- a/src/soup.ml
+++ b/src/soup.ml
@@ -1195,6 +1195,11 @@ let append_root document node =
   mutate_child_list (fun f -> f @ [forget_type node]) document;
   node.parent <- Some document
 
+let prepend_root document node =
+  delete node;
+  mutate_child_list (fun f -> (forget_type node)::f) document;
+  node.parent <- Some document
+
 let set_name new_name = function
   | {values = `Element e; _} ->
     e.name <- new_name |> String.trim |> String.lowercase_ascii
diff --git a/src/soup.mli b/src/soup.mli
index f36c376..3ed4e8e 100644
--- a/src/soup.mli
+++ b/src/soup.mli
@@ -636,6 +636,9 @@ val unwrap : (_ node) -> unit
 val append_root : soup node -> (_ node) -> unit
 (** [append_root soup node] adds [node] as the last root node of [soup]. *)
 
+val prepend_root : soup node -> (_ node) -> unit
+(** [prepend_root soup node] adds [node] as the first root node of [soup]. *)
+
 val set_name : string -> element node -> unit
 (** Sets the tag name of the given element. *)
 


Test patch:
diff --git a/test/test.ml b/test/test.ml
index 4455f8a..378b9a5 100644
--- a/test/test.ml
+++ b/test/test.ml
@@ -869,6 +869,12 @@ let suites = [
         (element |> texts)
         ["five"; "three"; "four"; "one"; "six"; "two"; "seven"]);
 
+    ("append-prepend-root" >:: fun _ ->
+      let soup = parse "test2" in
+      append_root soup (parse "test3");
+      prepend_root soup (parse "test1");
+      assert_equal (soup |> texts) ["test1"; "test2"; "test3"]);
+
     ("delete" >:: fun _ ->
       let body = page "list" |> parse $ "body" in
       let ul = body $ "ul" in