nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: inbucket/inbucket
Pull request #550 (2024-10-20 19:28:27)

fix: AfterMessageStored message.size


Patch:
diff --git a/pkg/message/manager.go b/pkg/message/manager.go
index 324192e..0224035 100644
--- a/pkg/message/manager.go
+++ b/pkg/message/manager.go
@@ -122,6 +122,7 @@ func (s *StoreManager) Deliver(
 				To:      inbound.To,
 				Date:    now,
 				Subject: inbound.Subject,
+				Size:    inbound.Size,
 			},
 			Reader: io.MultiReader(strings.NewReader(recvd), bytes.NewReader(source)),
 		}


Test patch:
diff --git a/pkg/message/manager_test.go b/pkg/message/manager_test.go
index 74ab905..cf96b59 100644
--- a/pkg/message/manager_test.go
+++ b/pkg/message/manager_test.go
@@ -312,7 +312,7 @@ func TestDeliverEmitsAfterMessageStoredEvent(t *testing.T) {
 		origin,
 		[]*policy.Recipient{recip},
 		"Received: xyz\n",
-		[]byte("From: from@example.com\n\ntest email"),
+		[]byte("From: from@example.com\nSubject: events\n\ntest email."),
 	); err != nil {
 		t.Fatal(err)
 	}
@@ -321,6 +321,17 @@ func TestDeliverEmitsAfterMessageStoredEvent(t *testing.T) {
 	require.NoError(t, err)
 	assert.NotNil(t, got, "No event received, or it was nil")
 	assertMessageCount(t, sm, "to@example.com", 1)
+
+	// Verify event content.
+	assert.Equal(t, "to@example.com", got.Mailbox)
+	assert.Equal(t, "from@example.com", got.From.Address)
+
+	assert.WithinDuration(t, time.Now(), got.Date, 5*time.Second)
+	assert.Equal(t, "events", got.Subject, nil)
+	assert.Equal(t, int64(51), got.Size)
+
+	require.Len(t, got.To, 1)
+	assert.Equal(t, "to@example.com", got.To[0].Address)
 }
 
 func TestDeliverBeforeAndAfterMessageStoredEvents(t *testing.T) {
Repository: anuraghazra/github-readme-stats
Pull request #2481 (2023-01-28 15:01:16)

chore: minor changes in pat info


Patch:
diff --git a/api/status/pat-info.js b/api/status/pat-info.js
index 720611d..775e068 100644
--- a/api/status/pat-info.js
+++ b/api/status/pat-info.js
@@ -6,7 +6,7 @@
  */
 
 import { logger, request, dateDiff } from "../../src/common/utils.js";
-export const RATE_LIMIT_SECONDS = 60 * 10; // 1 request per 10 minutes
+export const RATE_LIMIT_SECONDS = 60 * 5; // 1 request per 10 minutes
 
 /**
  * Simple uptime check fetcher for the PATs.
@@ -98,12 +98,20 @@ const getPATInfo = async (fetcher, variables) => {
     return Object.keys(details).filter((pat) => details[pat].status === status);
   };
 
+  const sortedDetails = Object.keys(details)
+    .sort()
+    .reduce((obj, key) => {
+      obj[key] = details[key];
+      return obj;
+    }, {});
+
   return {
     validPATs: filterPATsByStatus("valid"),
     expiredPATs: filterPATsByStatus("expired"),
-    exhaustedPATS: filterPATsByStatus("exhausted"),
+    exhaustedPATs: filterPATsByStatus("exhausted"),
+    suspendedPATs: filterPATsByStatus("suspended"),
     errorPATs: filterPATsByStatus("error"),
-    details,
+    details: sortedDetails,
   };
 };
 


Test patch:
diff --git a/tests/pat-info.test.js b/tests/pat-info.test.js
index 9635ab2..23aca8c 100644
--- a/tests/pat-info.test.js
+++ b/tests/pat-info.test.js
@@ -88,7 +88,8 @@ describe("Test /api/status/pat-info", () => {
         {
           validPATs: ["PAT_2", "PAT_3", "PAT_4"],
           expiredPATs: [],
-          exhaustedPATS: ["PAT_1"],
+          exhaustedPATs: ["PAT_1"],
+          suspendedPATs: [],
           errorPATs: [],
           details: {
             PAT_1: {
@@ -132,7 +133,8 @@ describe("Test /api/status/pat-info", () => {
         {
           validPATs: ["PAT_2", "PAT_3", "PAT_4"],
           expiredPATs: [],
-          exhaustedPATS: [],
+          exhaustedPATs: [],
+          suspendedPATs: [],
           errorPATs: ["PAT_1"],
           details: {
             PAT_1: {
@@ -178,7 +180,8 @@ describe("Test /api/status/pat-info", () => {
         {
           validPATs: ["PAT_2", "PAT_3", "PAT_4"],
           expiredPATs: ["PAT_1"],
-          exhaustedPATS: [],
+          exhaustedPATs: [],
+          suspendedPATs: [],
           errorPATs: [],
           details: {
             PAT_1: {
Repository: anuraghazra/github-readme-stats
Pull request #3431 (2023-10-27 17:55:37)

Fix typo in top-languages-fetcher.js

vercel[bot]: @eternityduck is attempting to deploy a commit to the **github readme stats** Team on [Vercel](https://vercel.com).

A member of the Team first needs to [authorize it](https://vercel.com/git/authorize?team=github%20readme%20stats&type=github&job=%7B%22headInfo%22%3A%7B%22sha%22%3A%2236e9ec80c83407c6686d1d9d95b08face50e07b9%22%7D%2C%22id%22%3A%22QmVfk38y2MUt18wkPji1BgDPHEcEkWFrEnwW31MgXUD4Qq%22%2C%22org%22%3A%22anuraghazra%22%2C%22prId%22%3A3431%2C%22repo%22%3A%22github-readme-stats%22%7D).


codecov[bot]: We're currently processing your upload.  This comment will be updated when the results are available.

Patch:
diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js
index faf4bc9..485cc8b 100644
--- a/src/fetchers/top-languages-fetcher.js
+++ b/src/fetchers/top-languages-fetcher.js
@@ -92,7 +92,7 @@ const fetchTopLanguages = async (
       );
     }
     throw new CustomError(
-      "Something went while trying to retrieve the language data using the GraphQL API.",
+      "Something went wrong while trying to retrieve the language data using the GraphQL API.",
       CustomError.GRAPHQL_ERROR,
     );
   }


Test patch:
diff --git a/tests/fetchTopLanguages.test.js b/tests/fetchTopLanguages.test.js
index 90648c3..e7bd54a 100644
--- a/tests/fetchTopLanguages.test.js
+++ b/tests/fetchTopLanguages.test.js
@@ -165,7 +165,7 @@ describe("FetchTopLanguages", () => {
     });
 
     await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow(
-      "Something went while trying to retrieve the language data using the GraphQL API.",
+      "Something went wrong while trying to retrieve the language data using the GraphQL API.",
     );
   });
 });
Repository: 0xs34n/starknet.js
Pull request #509 (2023-02-03 16:11:11)

fix: remove hex prefix should work insensitive, for both 0x and 0X
## Motivation and Resolution
Fix https://github.com/0xs34n/starknet.js/pull/508
Mentioned PR contains change so that call on function decodeShortString can handle both hex and decimal string, usage-related change.
```decodeShortString(value.toString(16)) -> decodeShortString(value)```
But removeHexPrefix removes only `0x` and not `0X`. That produces a hidden character on the string that encodes, visible with JSON.stringify.
The issue is that removeHexPrefix should be able to remove both, not just in the mentioned PR but in case someone does an uppercase transformation before the call.
...

### RPC version (if applicable)

...

## Usage related changes
removeHexPrefix is case insensitive `0x` and `0X`

## Checklist:

- [x] Performed a self-review of the code
- [x] Rebased to the last commit of the target branch (or merged it into my branch)
- [x] Linked the issues which this PR resolves
- [x] Documented the changes
- [ ] Updated the docs (www)
- [ ] Updated the tests
- [x] All tests are passing



Patch:
diff --git a/src/utils/encode.ts b/src/utils/encode.ts
index 03966d2c..27f98cc0 100644
--- a/src/utils/encode.ts
+++ b/src/utils/encode.ts
@@ -21,7 +21,7 @@ export function buf2hex(buffer: Uint8Array) {
  */
 
 export function removeHexPrefix(hex: string): string {
-  return hex.replace(/^0x/, '');
+  return hex.replace(/^0x/i, '');
 }
 
 export function addHexPrefix(hex: string): string {


Test patch:
diff --git a/__tests__/utils/shortString.test.ts b/__tests__/utils/shortString.test.ts
index 3be94903..7e8a526c 100644
--- a/__tests__/utils/shortString.test.ts
+++ b/__tests__/utils/shortString.test.ts
@@ -1,3 +1,4 @@
+import { removeHexPrefix } from '../../src/utils/encode';
 import { decodeShortString, encodeShortString } from '../../src/utils/shortString';
 
 describe('shortString', () => {
@@ -20,11 +21,11 @@ describe('shortString', () => {
   });
 
   test('should convert hex number string to string', () => {
-    expect(decodeShortString('0x68656c6c6f')).toMatchInlineSnapshot(`"hello"`);
+    expect(JSON.stringify(decodeShortString('0x68656c6c6f'))).toBe('"hello"');
   });
 
   test('should convert decimal number string to string', () => {
-    expect(decodeShortString('448378203247')).toMatch(`hello`);
+    expect(JSON.stringify(decodeShortString('448378203247'))).toBe('"hello"');
   });
 
   test('should throw if decode input is not ascii chars', () => {
@@ -38,4 +39,9 @@ describe('shortString', () => {
       `"Test is not Hex or decimal"`
     );
   });
+
+  test('explicitly test removeHexPrefix', () => {
+    expect(removeHexPrefix('0x01')).toBe('01');
+    expect(removeHexPrefix('0X01')).toBe('01');
+  });
 });
Repository: 0xs34n/starknet.js
Pull request #541 (2023-02-28 09:52:58)

fix: add new starknet id contracts (testnet)
## Motivation and Resolution

Just noticed that the testnet address contract is the old one. I just changed it with the right one.

## Usage-related changes

They will retrieve the current testnet contract and not the old one.


Patch:
diff --git a/src/utils/starknetId.ts b/src/utils/starknetId.ts
index 0799704d..54d0f45c 100644
--- a/src/utils/starknetId.ts
+++ b/src/utils/starknetId.ts
@@ -104,7 +104,7 @@ export function getStarknetIdContract(chainId: StarknetChainId): string {
   const starknetIdMainnetContract =
     '0x6ac597f8116f886fa1c97a23fa4e08299975ecaf6b598873ca6792b9bbfb678';
   const starknetIdTestnetContract =
-    '0x05cf267a0af6101667013fc6bd3f6c11116a14cda9b8c4b1198520d59f900b17';
+    '0x3bab268e932d2cecd1946f100ae67ce3dff9fd234119ea2f6da57d16d29fce';
 
   switch (chainId) {
     case StarknetChainId.SN_MAIN:


Test patch:
diff --git a/__tests__/utils/starknetId.test.ts b/__tests__/utils/starknetId.test.ts
index 04588a52..fa21f5d8 100644
--- a/__tests__/utils/starknetId.test.ts
+++ b/__tests__/utils/starknetId.test.ts
@@ -41,7 +41,7 @@ describe('Should tets StarknetId utils', () => {
 
   test('Should test getStarknetIdContract', () => {
     expect(getStarknetIdContract(StarknetChainId.SN_GOERLI)).toBe(
-      '0x05cf267a0af6101667013fc6bd3f6c11116a14cda9b8c4b1198520d59f900b17'
+      '0x3bab268e932d2cecd1946f100ae67ce3dff9fd234119ea2f6da57d16d29fce'
     );
 
     expect(() => {
Repository: ymrl/a11y-visualizer
Pull request #95 (2024-06-02 11:23:47)

:+1: stop display warning to no name section


Patch:
diff --git a/src/content/dom/tips/sectionTips.ts b/src/content/dom/tips/sectionTips.ts
index 3671ea4..f1a93e2 100644
--- a/src/content/dom/tips/sectionTips.ts
+++ b/src/content/dom/tips/sectionTips.ts
@@ -52,8 +52,8 @@ const hasSectionTag = (el: Element): boolean =>
 
 export const sectionTips = (el: Element): ElementTip[] => {
   const result: ElementTip[] = [];
+  const role = el.getAttribute("role");
   if (hasSectionRole(el)) {
-    const role = el.getAttribute("role");
     if (role) result.push({ type: "landmark", content: role });
   } else if (hasSectionTag(el)) {
     const tagName = el.tagName.toLowerCase();
@@ -61,8 +61,8 @@ export const sectionTips = (el: Element): ElementTip[] => {
     if (tagName === "section") {
       if (name) {
         result.push({ type: "landmark", content: "region" });
-      } else {
-        result.push({ type: "warning", content: "messages.noNameSection" });
+      } else if (!role) {
+        result.push({ type: "tagName", content: "section" });
       }
     } else if (tagName === "aside") {
       if (!el.parentElement?.closest("article, aside, nav, section") || name) {


Test patch:
diff --git a/src/content/dom/tips/sectionTips.test.ts b/src/content/dom/tips/sectionTips.test.ts
index 1ca0e62..3e4d2c2 100644
--- a/src/content/dom/tips/sectionTips.test.ts
+++ b/src/content/dom/tips/sectionTips.test.ts
@@ -59,8 +59,8 @@ describe("sectionTips()", () => {
     const result = sectionTips(element);
     expect(result).toHaveLength(1);
     expect(result[0]).toEqual({
-      type: "warning",
-      content: "messages.noNameSection",
+      type: "tagName",
+      content: "section",
     });
   });
Repository: ymrl/a11y-visualizer
Pull request #140 (2024-06-19 09:32:19)

:bug: fix closed detail descendants cannot be handled as hidden


Patch:
diff --git a/src/content/dom/isHidden.ts b/src/content/dom/isHidden.ts
index a760036..32c9202 100644
--- a/src/content/dom/isHidden.ts
+++ b/src/content/dom/isHidden.ts
@@ -1,5 +1,10 @@
 export const isHidden = (el: Element): boolean => {
-  if (el.matches("details:not([open]) > *:not(summary)")) return true;
+  if (el.matches("details:not([open]) *")) {
+    if (el.tagName.toLowerCase() === "summary" && el.parentElement) {
+      return isHidden(el.parentElement);
+    }
+    return true;
+  }
   if (el.matches("[hidden]")) return true;
 
   const d = el.ownerDocument;


Test patch:
diff --git a/src/content/dom/isHidden.test.ts b/src/content/dom/isHidden.test.ts
index db04e62..4b76f61 100644
--- a/src/content/dom/isHidden.test.ts
+++ b/src/content/dom/isHidden.test.ts
@@ -110,12 +110,24 @@ describe("isHidden", () => {
     const details = document.createElement("details");
     const summary = document.createElement("summary");
     const content = document.createElement("div");
+    const grandchild = document.createElement("div");
+    const grandchildDetails = document.createElement("details");
+    const grandchildSummary = document.createElement("summary");
+    const grandchildContent = document.createElement("div");
     details.appendChild(summary);
     details.appendChild(content);
+    content.appendChild(grandchild);
+    content.appendChild(grandchildDetails);
+    grandchildDetails.appendChild(grandchildSummary);
+    grandchildDetails.appendChild(grandchildContent);
     document.body.appendChild(details);
     expect(isHidden(details)).toBe(false);
     expect(isHidden(summary)).toBe(false);
     expect(isHidden(content)).toBe(true);
+    expect(isHidden(grandchild)).toBe(true);
+    expect(isHidden(grandchildDetails)).toBe(true);
+    expect(isHidden(grandchildSummary)).toBe(true);
+    expect(isHidden(grandchildContent)).toBe(true);
   });
 
   test("body > details[open] > summary + div", () => {
@@ -123,11 +135,23 @@ describe("isHidden", () => {
     details.open = true;
     const summary = document.createElement("summary");
     const content = document.createElement("div");
+    const grandchild = document.createElement("div");
+    const grandchildDetails = document.createElement("details");
+    const grandchildSummary = document.createElement("summary");
+    const grandchildContent = document.createElement("div");
     details.appendChild(summary);
     details.appendChild(content);
+    content.appendChild(grandchild);
+    content.appendChild(grandchildDetails);
+    grandchildDetails.appendChild(grandchildSummary);
+    grandchildDetails.appendChild(grandchildContent);
     document.body.appendChild(details);
     expect(isHidden(details)).toBe(false);
     expect(isHidden(summary)).toBe(false);
     expect(isHidden(content)).toBe(false);
+    expect(isHidden(grandchild)).toBe(false);
+    expect(isHidden(grandchildDetails)).toBe(false);
+    expect(isHidden(grandchildSummary)).toBe(false);
+    expect(isHidden(grandchildContent)).toBe(true);
   });
 });
Repository: ymrl/a11y-visualizer
Pull request #160 (2024-07-02 14:59:08)

:sparkles: add textContent condition of sibling to isInline
#88 


Patch:
diff --git a/src/content/dom/isInline.ts b/src/content/dom/isInline.ts
index 7ad0330..b5a62fc 100644
--- a/src/content/dom/isInline.ts
+++ b/src/content/dom/isInline.ts
@@ -9,7 +9,10 @@ const hasPreviousInlineSibling = (el: Element): boolean => {
       const style = window.getComputedStyle(prev as HTMLElement);
       if (style.position === "absolute" || style.position === "fixed") {
         /* no op */
-      } else if (style.display.startsWith("inline")) {
+      } else if (
+        style.display.startsWith("inline") &&
+        prev.textContent?.trim()
+      ) {
         return true;
       } else {
         break;


Test patch:
diff --git a/src/content/dom/isInline.test.ts b/src/content/dom/isInline.test.ts
index 63bd667..88d6275 100644
--- a/src/content/dom/isInline.test.ts
+++ b/src/content/dom/isInline.test.ts
@@ -68,18 +68,21 @@ describe("isInline", () => {
     el.style.display = "inline-block";
     el.getBoundingClientRect = () => ({ height: 19.2 }) as DOMRect;
     const sibling = document.createElement("span");
+    sibling.textContent = "test";
     sibling.style.display = "inline-block";
     parent.appendChild(sibling);
     parent.appendChild(el);
     document.body.appendChild(parent);
     expect(isInline(el)).toBe(true);
   });
+
   test("previous sibling is position: absolute", () => {
     const parent = document.createElement("div");
     const el = document.createElement("span");
     el.style.display = "inline-block";
     el.getBoundingClientRect = () => ({ height: 19.2 }) as DOMRect;
     const sibling = document.createElement("span");
+    sibling.textContent = "test";
     sibling.style.display = "inline-block";
     sibling.style.position = "absolute";
     parent.appendChild(sibling);
@@ -88,6 +91,19 @@ describe("isInline", () => {
     expect(isInline(el)).toBe(false);
   });
 
+  test("previous sibling does not have text content", () => {
+    const parent = document.createElement("div");
+    const el = document.createElement("span");
+    el.style.display = "inline-block";
+    el.getBoundingClientRect = () => ({ height: 19.2 }) as DOMRect;
+    const sibling = document.createElement("span");
+    sibling.style.display = "inline-block";
+    parent.appendChild(sibling);
+    parent.appendChild(el);
+    document.body.appendChild(parent);
+    expect(isInline(el)).toBe(false);
+  });
+
   test("has next inline sibling", () => {
     const parent = document.createElement("div");
     const el = document.createElement("span");
Repository: libp2p/go-libp2p
Pull request #603 (2019-04-17 23:32:26)

constructor: allow nil options
This can make it significantly easier to configure libp2p with optional options.


Patch:
diff --git a/config/config.go b/config/config.go
index 61b3c031..0b8c676b 100644
--- a/config/config.go
+++ b/config/config.go
@@ -242,6 +242,9 @@ type Option func(cfg *Config) error
 // encountered (if any).
 func (cfg *Config) Apply(opts ...Option) error {
 	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
 		if err := opt(cfg); err != nil {
 			return err
 		}
diff --git a/libp2p.go b/libp2p.go
index ad026ad4..252c9a29 100644
--- a/libp2p.go
+++ b/libp2p.go
@@ -19,6 +19,9 @@ type Option = config.Option
 func ChainOptions(opts ...Option) Option {
 	return func(cfg *Config) error {
 		for _, opt := range opts {
+			if opt == nil {
+				continue
+			}
 			if err := opt(cfg); err != nil {
 				return err
 			}


Test patch:
diff --git a/config/config_test.go b/config/config_test.go
new file mode 100644
index 00000000..7f99b833
--- /dev/null
+++ b/config/config_test.go
@@ -0,0 +1,23 @@
+package config
+
+import (
+	"testing"
+)
+
+func TestNilOption(t *testing.T) {
+	var cfg Config
+	optsRun := 0
+	opt := func(c *Config) error {
+		optsRun++
+		return nil
+	}
+	if err := cfg.Apply(nil); err != nil {
+		t.Fatal(err)
+	}
+	if err := cfg.Apply(opt, nil, nil, opt, opt, nil); err != nil {
+		t.Fatal(err)
+	}
+	if optsRun != 3 {
+		t.Fatalf("expected to have handled 3 options, handled %d", optsRun)
+	}
+}
diff --git a/libp2p_test.go b/libp2p_test.go
index 3ecedb3b..84aaa9e4 100644
--- a/libp2p_test.go
+++ b/libp2p_test.go
@@ -133,3 +133,28 @@ func makeRandomHost(t *testing.T, port int) (host.Host, error) {
 
 	return New(ctx, opts...)
 }
+
+func TestChainOptions(t *testing.T) {
+	var cfg Config
+	var optsRun []int
+	optcount := 0
+	newOpt := func() Option {
+		index := optcount
+		optcount++
+		return func(c *Config) error {
+			optsRun = append(optsRun, index)
+			return nil
+		}
+	}
+	if err := cfg.Apply(newOpt(), nil, ChainOptions(newOpt(), newOpt(), ChainOptions(), ChainOptions(nil, newOpt()))); err != nil {
+		t.Fatal(err)
+	}
+	if optcount != len(optsRun) {
+		t.Errorf("expected to have handled %d options, handled %d", optcount, len(optsRun))
+	}
+	for i, x := range optsRun {
+		if i != x {
+			t.Errorf("expected opt %d, got opt %d", i, x)
+		}
+	}
+}
Repository: libp2p/go-libp2p
Pull request #626 (2019-05-07 22:48:53)

ping: return a stream of results
Otherwise, we can't return errors. This is a breaking change but unlikely to have a large impact on anyone but go-ipfs.

This _also_ ensures canceling ping actually aborts the ping without waiting.

Part of https://github.com/ipfs/go-ipfs/issues/6298.


Patch:
diff --git a/p2p/protocol/ping/ping.go b/p2p/protocol/ping/ping.go
index b76133cc..d8e143bd 100644
--- a/p2p/protocol/ping/ping.go
+++ b/p2p/protocol/ping/ping.go
@@ -71,42 +71,62 @@ func (p *PingService) PingHandler(s inet.Stream) {
 	}
 }
 
-func (ps *PingService) Ping(ctx context.Context, p peer.ID) (<-chan time.Duration, error) {
+// Result is a result of a ping attempt, either an RTT or an error.
+type Result struct {
+	RTT   time.Duration
+	Error error
+}
+
+func (ps *PingService) Ping(ctx context.Context, p peer.ID) <-chan Result {
 	return Ping(ctx, ps.Host, p)
 }
 
-func Ping(ctx context.Context, h host.Host, p peer.ID) (<-chan time.Duration, error) {
+// Ping pings the remote peer until the context is canceled, returning a stream
+// of RTTs or errors.
+func Ping(ctx context.Context, h host.Host, p peer.ID) <-chan Result {
 	s, err := h.NewStream(ctx, p, ID)
 	if err != nil {
-		return nil, err
+		ch := make(chan Result, 1)
+		ch <- Result{Error: err}
+		close(ch)
+		return ch
 	}
 
-	out := make(chan time.Duration)
+	ctx, cancel := context.WithCancel(ctx)
+
+	out := make(chan Result)
 	go func() {
 		defer close(out)
-		defer s.Reset()
-		for {
+		defer cancel()
+
+		for ctx.Err() == nil {
+			var res Result
+			res.RTT, res.Error = ping(s)
+
+			// canceled, ignore everything.
+			if ctx.Err() != nil {
+				return
+			}
+
+			// No error, record the RTT.
+			if res.Error == nil {
+				h.Peerstore().RecordLatency(p, res.RTT)
+			}
+
 			select {
+			case out <- res:
 			case <-ctx.Done():
 				return
-			default:
-				t, err := ping(s)
-				if err != nil {
-					log.Debugf("ping error: %s", err)
-					return
-				}
-
-				h.Peerstore().RecordLatency(p, t)
-				select {
-				case out <- t:
-				case <-ctx.Done():
-					return
-				}
 			}
 		}
 	}()
+	go func() {
+		// forces the ping to abort.
+		<-ctx.Done()
+		s.Reset()
+	}()
 
-	return out, nil
+	return out
 }
 
 func ping(s inet.Stream) (time.Duration, error) {


Test patch:
diff --git a/p2p/protocol/ping/ping_test.go b/p2p/protocol/ping/ping_test.go
index f8ea0cc7..043eac0f 100644
--- a/p2p/protocol/ping/ping_test.go
+++ b/p2p/protocol/ping/ping_test.go
@@ -37,15 +37,15 @@ func TestPing(t *testing.T) {
 func testPing(t *testing.T, ps *ping.PingService, p peer.ID) {
 	pctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
-	ts, err := ps.Ping(pctx, p)
-	if err != nil {
-		t.Fatal(err)
-	}
+	ts := ps.Ping(pctx, p)
 
 	for i := 0; i < 5; i++ {
 		select {
-		case took := <-ts:
-			t.Log("ping took: ", took)
+		case res := <-ts:
+			if res.Error != nil {
+				t.Fatal(res.Error)
+			}
+			t.Log("ping took: ", res.RTT)
 		case <-time.After(time.Second * 4):
 			t.Fatal("failed to receive ping")
 		}