ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/Atomic8Test.java
(Generate patch)

Comparing jsr166/src/test/tck/Atomic8Test.java (file contents):
Revision 1.1 by dl, Sun Sep 8 23:00:36 2013 UTC vs.
Revision 1.2 by jsr166, Mon Sep 9 06:23:16 2013 UTC

# Line 37 | Line 37 | public class Atomic8Test extends JSR166T
37      volatile int anIntField;
38      volatile Integer anIntegerField;
39  
40 +    AtomicLongFieldUpdater aLongFieldUpdater() {
41 +        return AtomicLongFieldUpdater.newUpdater
42 +            (Atomic8Test.class, "aLongField");
43 +    }
44 +
45 +    AtomicIntegerFieldUpdater anIntFieldUpdater() {
46 +        return AtomicIntegerFieldUpdater.newUpdater
47 +            (Atomic8Test.class, "anIntField");
48 +    }
49 +
50 +    AtomicReferenceFieldUpdater<Atomic8Test,Integer> anIntegerFieldUpdater() {
51 +        return AtomicReferenceFieldUpdater.newUpdater
52 +            (Atomic8Test.class, Integer.class, "anIntegerField");
53 +    }
54 +
55      /**
56       * AtomicLong getAndUpdate returns previous value and updates
57       * result of supplied function
# Line 77 | Line 92 | public class Atomic8Test extends JSR166T
92          AtomicLong a = new AtomicLong(1L);
93          assertEquals(7L, a.accumulateAndGet(6L, Long::sum));
94          assertEquals(10L, a.accumulateAndGet(3L, Long::sum));
95 +        assertEquals(10L, a.get());
96      }
97  
98      /**
# Line 98 | Line 114 | public class Atomic8Test extends JSR166T
114          AtomicInteger a = new AtomicInteger(1);
115          assertEquals(18, a.updateAndGet(Atomic8Test::addInt17));
116          assertEquals(35, a.updateAndGet(Atomic8Test::addInt17));
117 +        assertEquals(35, a.get());
118      }
119  
120      /**
# Line 119 | Line 136 | public class Atomic8Test extends JSR166T
136          AtomicInteger a = new AtomicInteger(1);
137          assertEquals(7, a.accumulateAndGet(6, Integer::sum));
138          assertEquals(10, a.accumulateAndGet(3, Integer::sum));
139 +        assertEquals(10, a.get());
140      }
141  
142      /**
# Line 140 | Line 158 | public class Atomic8Test extends JSR166T
158          AtomicReference<Integer> a = new AtomicReference<Integer>(one);
159          assertEquals(new Integer(18), a.updateAndGet(Atomic8Test::addInteger17));
160          assertEquals(new Integer(35), a.updateAndGet(Atomic8Test::addInteger17));
161 +        assertEquals(new Integer(35), a.get());
162      }
163  
164      /**
# Line 161 | Line 180 | public class Atomic8Test extends JSR166T
180          AtomicReference<Integer> a = new AtomicReference<Integer>(one);
181          assertEquals(new Integer(7), a.accumulateAndGet(6, Atomic8Test::sumInteger));
182          assertEquals(new Integer(10), a.accumulateAndGet(3, Atomic8Test::sumInteger));
183 +        assertEquals(new Integer(10), a.get());
184      }
185  
186  
# Line 185 | Line 205 | public class Atomic8Test extends JSR166T
205          a.set(0, 1);
206          assertEquals(18L, a.updateAndGet(0, Atomic8Test::addLong17));
207          assertEquals(35L, a.updateAndGet(0, Atomic8Test::addLong17));
208 +        assertEquals(35L, a.get(0));
209      }
210  
211      /**
# Line 208 | Line 229 | public class Atomic8Test extends JSR166T
229          a.set(0, 1);
230          assertEquals(7L, a.accumulateAndGet(0, 6L, Long::sum));
231          assertEquals(10L, a.accumulateAndGet(0, 3L, Long::sum));
232 +        assertEquals(10L, a.get(0));
233      }
234  
235      /**
# Line 231 | Line 253 | public class Atomic8Test extends JSR166T
253          a.set(0, 1);
254          assertEquals(18, a.updateAndGet(0, Atomic8Test::addInt17));
255          assertEquals(35, a.updateAndGet(0, Atomic8Test::addInt17));
256 +        assertEquals(35, a.get(0));
257      }
258  
259      /**
# Line 307 | Line 330 | public class Atomic8Test extends JSR166T
330       * result of supplied function
331       */
332      public void testLongFieldUpdaterGetAndUpdate() {
333 <        AtomicLongFieldUpdater a = AtomicLongFieldUpdater.
311 <            newUpdater(Atomic8Test.class, "aLongField");
333 >        AtomicLongFieldUpdater a = aLongFieldUpdater();
334          a.set(this, 1);
335          assertEquals(1L, a.getAndUpdate(this, Atomic8Test::addLong17));
336          assertEquals(18L, a.getAndUpdate(this, Atomic8Test::addLong17));
337          assertEquals(35L, a.get(this));
338 +        assertEquals(35L, aLongField);
339      }
340  
341      /**
# Line 320 | Line 343 | public class Atomic8Test extends JSR166T
343       * returns result.
344       */
345      public void testLongFieldUpdaterUpdateAndGet() {
346 <        AtomicLongFieldUpdater a = AtomicLongFieldUpdater.
324 <            newUpdater(Atomic8Test.class, "aLongField");
346 >        AtomicLongFieldUpdater a = aLongFieldUpdater();
347          a.set(this, 1);
348          assertEquals(18L, a.updateAndGet(this, Atomic8Test::addLong17));
349          assertEquals(35L, a.updateAndGet(this, Atomic8Test::addLong17));
350 +        assertEquals(35L, a.get(this));
351 +        assertEquals(35L, aLongField);
352      }
353  
354      /**
# Line 332 | Line 356 | public class Atomic8Test extends JSR166T
356       * and updates with supplied function.
357       */
358      public void testLongFieldUpdaterGetAndAccumulate() {
359 <        AtomicLongFieldUpdater a = AtomicLongFieldUpdater.
336 <            newUpdater(Atomic8Test.class, "aLongField");
359 >        AtomicLongFieldUpdater a = aLongFieldUpdater();
360          a.set(this, 1);
361          assertEquals(1L, a.getAndAccumulate(this, 2L, Long::sum));
362          assertEquals(3L, a.getAndAccumulate(this, 3L, Long::sum));
363          assertEquals(6L, a.get(this));
364 +        assertEquals(6L, aLongField);
365      }
366  
367      /**
# Line 345 | Line 369 | public class Atomic8Test extends JSR166T
369       * function and returns result.
370       */
371      public void testLongFieldUpdaterAccumulateAndGet() {
372 <        AtomicLongFieldUpdater a = AtomicLongFieldUpdater.
349 <            newUpdater(Atomic8Test.class, "aLongField");
372 >        AtomicLongFieldUpdater a = aLongFieldUpdater();
373          a.set(this, 1);
374          assertEquals(7L, a.accumulateAndGet(this, 6L, Long::sum));
375          assertEquals(10L, a.accumulateAndGet(this, 3L, Long::sum));
376 +        assertEquals(10L, a.get(this));
377 +        assertEquals(10L, aLongField);
378      }
379  
380      /**
# Line 357 | Line 382 | public class Atomic8Test extends JSR166T
382       * result of supplied function
383       */
384      public void testIntegerFieldUpdaterGetAndUpdate() {
385 <        AtomicIntegerFieldUpdater a = AtomicIntegerFieldUpdater.
361 <            newUpdater(Atomic8Test.class, "anIntField");
385 >        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
386          a.set(this, 1);
387          assertEquals(1, a.getAndUpdate(this, Atomic8Test::addInt17));
388          assertEquals(18, a.getAndUpdate(this, Atomic8Test::addInt17));
389          assertEquals(35, a.get(this));
390 +        assertEquals(35, anIntField);
391      }
392  
393      /**
# Line 370 | Line 395 | public class Atomic8Test extends JSR166T
395       * returns result.
396       */
397      public void testIntegerFieldUpdaterUpdateAndGet() {
398 <        AtomicIntegerFieldUpdater a = AtomicIntegerFieldUpdater.
374 <            newUpdater(Atomic8Test.class, "anIntField");
398 >        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
399          a.set(this, 1);
400          assertEquals(18, a.updateAndGet(this, Atomic8Test::addInt17));
401          assertEquals(35, a.updateAndGet(this, Atomic8Test::addInt17));
402 +        assertEquals(35, a.get(this));
403 +        assertEquals(35, anIntField);
404      }
405  
406      /**
# Line 382 | Line 408 | public class Atomic8Test extends JSR166T
408       * and updates with supplied function.
409       */
410      public void testIntegerFieldUpdaterGetAndAccumulate() {
411 <        AtomicIntegerFieldUpdater a = AtomicIntegerFieldUpdater.
386 <            newUpdater(Atomic8Test.class, "anIntField");
411 >        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
412          a.set(this, 1);
413          assertEquals(1, a.getAndAccumulate(this, 2, Integer::sum));
414          assertEquals(3, a.getAndAccumulate(this, 3, Integer::sum));
415          assertEquals(6, a.get(this));
416 +        assertEquals(6, anIntField);
417      }
418  
419      /**
# Line 395 | Line 421 | public class Atomic8Test extends JSR166T
421       * function and returns result.
422       */
423      public void testIntegerFieldUpdaterAccumulateAndGet() {
424 <        AtomicIntegerFieldUpdater a = AtomicIntegerFieldUpdater.
399 <            newUpdater(Atomic8Test.class, "anIntField");
424 >        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
425          a.set(this, 1);
426          assertEquals(7, a.accumulateAndGet(this, 6, Integer::sum));
427          assertEquals(10, a.accumulateAndGet(this, 3, Integer::sum));
428 +        assertEquals(10, a.get(this));
429 +        assertEquals(10, anIntField);
430      }
431  
432  
# Line 408 | Line 435 | public class Atomic8Test extends JSR166T
435       * and updates result of supplied function
436       */
437      public void testReferenceFieldUpdaterGetAndUpdate() {
438 <        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = AtomicReferenceFieldUpdater.
412 <            newUpdater(Atomic8Test.class, Integer.class, "anIntegerField");
438 >        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
439          a.set(this, one);
440          assertEquals(new Integer(1), a.getAndUpdate(this, Atomic8Test::addInteger17));
441          assertEquals(new Integer(18), a.getAndUpdate(this, Atomic8Test::addInteger17));
442          assertEquals(new Integer(35), a.get(this));
443 +        assertEquals(new Integer(35), anIntegerField);
444      }
445  
446      /**
# Line 421 | Line 448 | public class Atomic8Test extends JSR166T
448       * function and returns result.
449       */
450      public void testReferenceFieldUpdaterUpdateAndGet() {
451 <        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = AtomicReferenceFieldUpdater.
425 <            newUpdater(Atomic8Test.class, Integer.class, "anIntegerField");
451 >        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
452          a.set(this, one);
453          assertEquals(new Integer(18), a.updateAndGet(this, Atomic8Test::addInteger17));
454          assertEquals(new Integer(35), a.updateAndGet(this, Atomic8Test::addInteger17));
455 +        assertEquals(new Integer(35), a.get(this));
456 +        assertEquals(new Integer(35), anIntegerField);
457      }
458  
459      /**
# Line 433 | Line 461 | public class Atomic8Test extends JSR166T
461       * with supplied function.
462       */
463      public void testReferenceFieldUpdaterGetAndAccumulate() {
464 <        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = AtomicReferenceFieldUpdater.
437 <            newUpdater(Atomic8Test.class, Integer.class, "anIntegerField");
464 >        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
465          a.set(this, one);
466          assertEquals(new Integer(1), a.getAndAccumulate(this, 2, Atomic8Test::sumInteger));
467          assertEquals(new Integer(3), a.getAndAccumulate(this, 3, Atomic8Test::sumInteger));
468          assertEquals(new Integer(6), a.get(this));
469 +        assertEquals(new Integer(6), anIntegerField);
470      }
471  
472      /**
# Line 446 | Line 474 | public class Atomic8Test extends JSR166T
474       * supplied function and returns result.
475       */
476      public void testReferenceFieldUpdaterAccumulateAndGet() {
477 <        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = AtomicReferenceFieldUpdater.
450 <            newUpdater(Atomic8Test.class, Integer.class, "anIntegerField");
477 >        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
478          a.set(this, one);
479          assertEquals(new Integer(7), a.accumulateAndGet(this, 6, Atomic8Test::sumInteger));
480          assertEquals(new Integer(10), a.accumulateAndGet(this, 3, Atomic8Test::sumInteger));
481 +        assertEquals(new Integer(10), a.get(this));
482 +        assertEquals(new Integer(10), anIntegerField);
483      }
484  
485      /**
486 <     * All Atomic getAndUpdate methods throw npe on null function argument
486 >     * All Atomic getAndUpdate methods throw NullPointerException on
487 >     * null function argument
488       */
489      public void testGetAndUpdateNPE() {
490 <        try { new AtomicLong().getAndUpdate(null); shouldThrow();
491 <        } catch(NullPointerException ok) {}
492 <        try { new AtomicInteger().getAndUpdate(null); shouldThrow();
493 <        } catch(NullPointerException ok) {}
494 <        try { new AtomicReference().getAndUpdate(null); shouldThrow();
495 <        } catch(NullPointerException ok) {}
496 <        try { new AtomicLongArray(1).getAndUpdate(0, null); shouldThrow();
497 <        } catch(NullPointerException ok) {}
498 <        try { new AtomicIntegerArray(1).getAndUpdate(0, null); shouldThrow();
499 <        } catch(NullPointerException ok) {}
500 <        try { new AtomicReferenceArray(1).getAndUpdate(0, null); shouldThrow();
501 <        } catch(NullPointerException ok) {}
502 <        try { AtomicLongFieldUpdater.
503 <                newUpdater(Atomic8Test.class, "aLongField").
504 <                getAndUpdate(this, null);
475 <            shouldThrow();
476 <        } catch(NullPointerException ok) {}
477 <        try { AtomicIntegerFieldUpdater.
478 <                newUpdater(Atomic8Test.class, "anIntField").
479 <                getAndUpdate(this, null);
480 <            shouldThrow();
481 <        } catch(NullPointerException ok) {}
482 <        try {  AtomicReferenceFieldUpdater.
483 <                newUpdater(Atomic8Test.class, Integer.class, "anIntegerField").
484 <                getAndUpdate(this, null);
485 <            shouldThrow();
486 <        } catch(NullPointerException ok) {}
487 <    }
488 <
489 <    /**
490 <     * All Atomic updateAndGet methods throw npe on null function argument
491 <     */
492 <    public void testUpdateGetAndNPE() {
493 <        try { new AtomicLong().updateAndGet(null); shouldThrow();
494 <        } catch(NullPointerException ok) {}
495 <        try { new AtomicInteger().updateAndGet(null); shouldThrow();
496 <        } catch(NullPointerException ok) {}
497 <        try { new AtomicReference().updateAndGet(null); shouldThrow();
498 <        } catch(NullPointerException ok) {}
499 <        try { new AtomicLongArray(1).updateAndGet(0, null); shouldThrow();
500 <        } catch(NullPointerException ok) {}
501 <        try { new AtomicIntegerArray(1).updateAndGet(0, null); shouldThrow();
502 <        } catch(NullPointerException ok) {}
503 <        try { new AtomicReferenceArray(1).updateAndGet(0, null); shouldThrow();
504 <        } catch(NullPointerException ok) {}
505 <        try { AtomicLongFieldUpdater.
506 <                newUpdater(Atomic8Test.class, "aLongField").
507 <                updateAndGet(this, null);
508 <            shouldThrow();
509 <        } catch(NullPointerException ok) {}
510 <        try { AtomicIntegerFieldUpdater.
511 <                newUpdater(Atomic8Test.class, "anIntField").
512 <                updateAndGet(this, null);
513 <            shouldThrow();
514 <        } catch(NullPointerException ok) {}
515 <        try {  AtomicReferenceFieldUpdater.
516 <                newUpdater(Atomic8Test.class, Integer.class, "anIntegerField").
517 <                updateAndGet(this, null);
518 <            shouldThrow();
519 <        } catch(NullPointerException ok) {}
490 >        Runnable[] throwingActions = {
491 >            () -> new AtomicLong().getAndUpdate(null),
492 >            () -> new AtomicInteger().getAndUpdate(null),
493 >            () -> new AtomicReference().getAndUpdate(null),
494 >            () -> new AtomicLongArray(1).getAndUpdate(0, null),
495 >            () -> new AtomicIntegerArray(1).getAndUpdate(0, null),
496 >            () -> new AtomicReferenceArray(1).getAndUpdate(0, null),
497 >            () -> aLongFieldUpdater().getAndUpdate(this, null),
498 >            () -> anIntFieldUpdater().getAndUpdate(this, null),
499 >            () -> anIntegerFieldUpdater().getAndUpdate(this, null),
500 >            ////() -> aLongFieldUpdater().getAndUpdate(null, Atomic8Test::addLong17),
501 >            ////() -> anIntFieldUpdater().getAndUpdate(null, Atomic8Test::addInt17),
502 >            ////() -> anIntegerFieldUpdater().getAndUpdate(null, Atomic8Test::addInteger17),
503 >        };
504 >        assertThrows(NullPointerException.class, throwingActions);
505      }
506  
507      /**
508 <     * All Atomic getAndAccumulate methods throw npe on null function argument
508 >     * All Atomic updateAndGet methods throw NullPointerException on null function argument
509 >     */
510 >    public void testUpdateAndGetNPE() {
511 >        Runnable[] throwingActions = {
512 >            () -> new AtomicLong().updateAndGet(null),
513 >            () -> new AtomicInteger().updateAndGet(null),
514 >            () -> new AtomicReference().updateAndGet(null),
515 >            () -> new AtomicLongArray(1).updateAndGet(0, null),
516 >            () -> new AtomicIntegerArray(1).updateAndGet(0, null),
517 >            () -> new AtomicReferenceArray(1).updateAndGet(0, null),
518 >            () -> aLongFieldUpdater().updateAndGet(this, null),
519 >            () -> anIntFieldUpdater().updateAndGet(this, null),
520 >            () -> anIntegerFieldUpdater().updateAndGet(this, null),
521 >        };
522 >        assertThrows(NullPointerException.class, throwingActions);
523 >    }
524 >
525 >    /**
526 >     * All Atomic getAndAccumulate methods throw NullPointerException
527 >     * on null function argument
528       */
529      public void testGetAndAccumulateNPE() {
530 <        try { new AtomicLong().getAndAccumulate(1L, null); shouldThrow();
531 <        } catch(NullPointerException ok) {}
532 <        try { new AtomicInteger().getAndAccumulate(1, null); shouldThrow();
533 <        } catch(NullPointerException ok) {}
534 <        try { new AtomicReference().getAndAccumulate(one, null); shouldThrow();
535 <        } catch(NullPointerException ok) {}
536 <        try { new AtomicLongArray(1).getAndAccumulate(0, 1L, null); shouldThrow();
537 <        } catch(NullPointerException ok) {}
538 <        try { new AtomicIntegerArray(1).getAndAccumulate(0, 1, null); shouldThrow();
539 <        } catch(NullPointerException ok) {}
540 <        try { new AtomicReferenceArray(1).getAndAccumulate(0, one, null); shouldThrow();
541 <        } catch(NullPointerException ok) {}
538 <        try { AtomicLongFieldUpdater.
539 <                newUpdater(Atomic8Test.class, "aLongField").
540 <                getAndAccumulate(this, 1L, null);
541 <            shouldThrow();
542 <        } catch(NullPointerException ok) {}
543 <        try { AtomicIntegerFieldUpdater.
544 <                newUpdater(Atomic8Test.class, "anIntField").
545 <                getAndAccumulate(this, 1, null);
546 <            shouldThrow();
547 <        } catch(NullPointerException ok) {}
548 <        try {  AtomicReferenceFieldUpdater.
549 <                newUpdater(Atomic8Test.class, Integer.class, "anIntegerField").
550 <                getAndAccumulate(this, one, null);
551 <            shouldThrow();
552 <        } catch(NullPointerException ok) {}
530 >        Runnable[] throwingActions = {
531 >            () -> new AtomicLong().getAndAccumulate(1L, null),
532 >            () -> new AtomicInteger().getAndAccumulate(1, null),
533 >            () -> new AtomicReference().getAndAccumulate(one, null),
534 >            () -> new AtomicLongArray(1).getAndAccumulate(0, 1L, null),
535 >            () -> new AtomicIntegerArray(1).getAndAccumulate(0, 1, null),
536 >            () -> new AtomicReferenceArray(1).getAndAccumulate(0, one, null),
537 >            () -> aLongFieldUpdater().getAndAccumulate(this, 1L, null),
538 >            () -> anIntFieldUpdater().getAndAccumulate(this, 1, null),
539 >            () -> anIntegerFieldUpdater().getAndAccumulate(this, one, null),
540 >        };
541 >        assertThrows(NullPointerException.class, throwingActions);
542      }
543  
544      /**
545 <     * All Atomic accumulateAndGet methods throw npe on null function argument
545 >     * All Atomic accumulateAndGet methods throw NullPointerException
546 >     * on null function argument
547       */
548      public void testAccumulateAndGetNPE() {
549 <        try { new AtomicLong().accumulateAndGet(1L, null); shouldThrow();
550 <        } catch(NullPointerException ok) {}
551 <        try { new AtomicInteger().accumulateAndGet(1, null); shouldThrow();
552 <        } catch(NullPointerException ok) {}
553 <        try { new AtomicReference().accumulateAndGet(one, null); shouldThrow();
554 <        } catch(NullPointerException ok) {}
555 <        try { new AtomicLongArray(1).accumulateAndGet(0, 1L, null); shouldThrow();
556 <        } catch(NullPointerException ok) {}
557 <        try { new AtomicIntegerArray(1).accumulateAndGet(0, 1, null); shouldThrow();
558 <        } catch(NullPointerException ok) {}
559 <        try { new AtomicReferenceArray(1).accumulateAndGet(0, one, null); shouldThrow();
560 <        } catch(NullPointerException ok) {}
571 <        try { AtomicLongFieldUpdater.
572 <                newUpdater(Atomic8Test.class, "aLongField").
573 <                accumulateAndGet(this, 1L, null);
574 <            shouldThrow();
575 <        } catch(NullPointerException ok) {}
576 <        try { AtomicIntegerFieldUpdater.
577 <                newUpdater(Atomic8Test.class, "anIntField").
578 <                accumulateAndGet(this, 1, null);
579 <            shouldThrow();
580 <        } catch(NullPointerException ok) {}
581 <        try {  AtomicReferenceFieldUpdater.
582 <                newUpdater(Atomic8Test.class, Integer.class, "anIntegerField").
583 <                accumulateAndGet(this, one, null);
584 <            shouldThrow();
585 <        } catch(NullPointerException ok) {}
549 >        Runnable[] throwingActions = {
550 >            () -> new AtomicLong().accumulateAndGet(1L, null),
551 >            () -> new AtomicInteger().accumulateAndGet(1, null),
552 >            () -> new AtomicReference().accumulateAndGet(one, null),
553 >            () -> new AtomicLongArray(1).accumulateAndGet(0, 1L, null),
554 >            () -> new AtomicIntegerArray(1).accumulateAndGet(0, 1, null),
555 >            () -> new AtomicReferenceArray(1).accumulateAndGet(0, one, null),
556 >            () -> aLongFieldUpdater().accumulateAndGet(this, 1L, null),
557 >            () -> anIntFieldUpdater().accumulateAndGet(this, 1, null),
558 >            () -> anIntegerFieldUpdater().accumulateAndGet(this, one, null),
559 >        };
560 >        assertThrows(NullPointerException.class, throwingActions);
561      }
562  
563   }
589

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines