rspec-expectations 2.14.5 → 2.99.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -7
- data/Changelog.md +114 -31
- data/features/README.md +2 -1
- data/features/built_in_matchers/be.feature +40 -40
- data/features/step_definitions/additional_cli_steps.rb +10 -0
- data/features/test_frameworks/test_unit.feature +40 -0
- data/lib/rspec/expectations/caller_filter.rb +60 -0
- data/lib/rspec/{matchers → expectations}/configuration.rb +5 -3
- data/lib/rspec/expectations/deprecation.rb +11 -15
- data/lib/rspec/expectations/expectation_target.rb +75 -8
- data/lib/rspec/expectations/handler.rb +5 -1
- data/lib/rspec/expectations/syntax.rb +3 -5
- data/lib/rspec/expectations/version.rb +1 -2
- data/lib/rspec/expectations.rb +1 -1
- data/lib/rspec/matchers/be_close.rb +4 -1
- data/lib/rspec/matchers/built_in/base_matcher.rb +10 -5
- data/lib/rspec/matchers/built_in/be.rb +38 -9
- data/lib/rspec/matchers/built_in/be_within.rb +8 -2
- data/lib/rspec/matchers/built_in/change.rb +39 -1
- data/lib/rspec/matchers/built_in/has.rb +40 -7
- data/lib/rspec/matchers/built_in/have.rb +151 -2
- data/lib/rspec/matchers/built_in/include.rb +1 -1
- data/lib/rspec/matchers/built_in/match_array.rb +1 -1
- data/lib/rspec/matchers/built_in/raise_error.rb +7 -1
- data/lib/rspec/matchers/built_in/respond_to.rb +7 -1
- data/lib/rspec/matchers/built_in/satisfy.rb +7 -1
- data/lib/rspec/matchers/built_in/throw_symbol.rb +10 -2
- data/lib/rspec/matchers/built_in/yield.rb +25 -3
- data/lib/rspec/matchers/built_in.rb +2 -2
- data/lib/rspec/matchers/differentiate_block_method_types.rb +55 -0
- data/lib/rspec/matchers/dsl.rb +2 -1
- data/lib/rspec/matchers/match_aliases.rb +22 -0
- data/lib/rspec/matchers/matcher.rb +131 -10
- data/lib/rspec/matchers/operator_matcher.rb +70 -70
- data/lib/rspec/matchers/pretty.rb +4 -0
- data/lib/rspec/matchers/test_unit_integration.rb +22 -5
- data/lib/rspec/matchers.rb +41 -7
- data/lib/rspec-expectations.rb +5 -0
- data/spec/rspec/{matchers → expectations}/configuration_spec.rb +21 -2
- data/spec/rspec/expectations/expectation_target_spec.rb +62 -0
- data/spec/rspec/expectations/extensions/kernel_spec.rb +4 -0
- data/spec/rspec/expectations/handler_spec.rb +1 -1
- data/spec/rspec/expectations/syntax_spec.rb +6 -6
- data/spec/rspec/expectations_spec.rb +22 -1
- data/spec/rspec/matchers/base_matcher_spec.rb +15 -21
- data/spec/rspec/matchers/be_close_spec.rb +4 -1
- data/spec/rspec/matchers/be_spec.rb +105 -10
- data/spec/rspec/matchers/change_spec.rb +76 -1
- data/spec/rspec/matchers/description_generation_spec.rb +22 -18
- data/spec/rspec/matchers/differentiate_block_method_types_spec.rb +39 -0
- data/spec/rspec/matchers/eq_spec.rb +1 -1
- data/spec/rspec/matchers/has_spec.rb +24 -0
- data/spec/rspec/matchers/have_spec.rb +399 -1
- data/spec/rspec/matchers/matcher_spec.rb +213 -24
- data/spec/rspec/matchers/operator_matcher_spec.rb +28 -9
- data/spec/rspec/matchers/pretty_spec.rb +23 -0
- data/spec/rspec/matchers/raise_error_spec.rb +3 -3
- data/spec/rspec/matchers/throw_symbol_spec.rb +14 -14
- data/spec/spec_helper.rb +4 -2
- data/spec/support/helper_methods.rb +42 -0
- data/spec/support/shared_examples.rb +42 -0
- metadata +85 -64
- data/spec/rspec/matchers/matchers_spec.rb +0 -37
|
@@ -10,7 +10,18 @@ describe "have matcher" do
|
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
before(:each)
|
|
13
|
+
before(:each) do
|
|
14
|
+
stub_const("ActiveSupport::Inflector", inflector)
|
|
15
|
+
allow_deprecation
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def expect_have_deprecation(expression, message)
|
|
19
|
+
expect_deprecation_with_type(
|
|
20
|
+
"`#{expression}`",
|
|
21
|
+
message,
|
|
22
|
+
'the have matcher'
|
|
23
|
+
)
|
|
24
|
+
end
|
|
14
25
|
|
|
15
26
|
def create_collection_owner_with(n)
|
|
16
27
|
owner = RSpec::Expectations::Helper::CollectionOwner.new
|
|
@@ -452,4 +463,391 @@ EOF
|
|
|
452
463
|
end
|
|
453
464
|
end
|
|
454
465
|
end
|
|
466
|
+
|
|
467
|
+
context "deprecations for the have matcher" do
|
|
468
|
+
it "has the correct call site in the deprecation message" do
|
|
469
|
+
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
|
470
|
+
expect([1, 2, 3]).to have(3).items
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
context "when the target is a collection" do
|
|
474
|
+
it "prints a specific message for the positive expectation format" do
|
|
475
|
+
expectation_expression = "expect(collection).to have(3).items"
|
|
476
|
+
|
|
477
|
+
message = "the rspec-collection_matchers gem " +
|
|
478
|
+
"or replace your expectation with something like " +
|
|
479
|
+
"`expect(collection.size).to eq(3)`"
|
|
480
|
+
|
|
481
|
+
expect_have_deprecation(expectation_expression, message)
|
|
482
|
+
|
|
483
|
+
expect([1, 2, 3]).to have(3).items
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
it "prints a specific message for the negative expectation format" do
|
|
487
|
+
expectation_expression = "expect(collection).not_to have(4).items"
|
|
488
|
+
|
|
489
|
+
message = "the rspec-collection_matchers gem " +
|
|
490
|
+
"or replace your expectation with something like " +
|
|
491
|
+
"`expect(collection.size).to_not eq(4)`"
|
|
492
|
+
|
|
493
|
+
expect_have_deprecation(expectation_expression, message)
|
|
494
|
+
|
|
495
|
+
expect([1, 2, 3]).to_not have(4).items
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
context "when the target owns a collection" do
|
|
500
|
+
class self::BagOfWords
|
|
501
|
+
attr_reader :words
|
|
502
|
+
|
|
503
|
+
def initialize(words)
|
|
504
|
+
@words = words
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
it "prints a specific message for the positive expectation format" do
|
|
509
|
+
expectation_expression = "expect(collection_owner).to have(3).words"
|
|
510
|
+
|
|
511
|
+
message = "the rspec-collection_matchers gem " +
|
|
512
|
+
"or replace your expectation with something like " +
|
|
513
|
+
"`expect(collection_owner.words.size).to eq(3)`"
|
|
514
|
+
|
|
515
|
+
expect_have_deprecation(expectation_expression, message)
|
|
516
|
+
|
|
517
|
+
target = BagOfWords.new(%w[foo bar baz])
|
|
518
|
+
expect(target).to have(3).words
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
it "prints a specific message for the negative expectation format" do
|
|
522
|
+
expectation_expression = "expect(collection_owner).not_to have(4).words"
|
|
523
|
+
|
|
524
|
+
message = "the rspec-collection_matchers gem " +
|
|
525
|
+
"or replace your expectation with something like " +
|
|
526
|
+
"`expect(collection_owner.words.size).to_not eq(4)`"
|
|
527
|
+
|
|
528
|
+
expect_have_deprecation(expectation_expression, message)
|
|
529
|
+
|
|
530
|
+
target = BagOfWords.new(%w[foo bar baz])
|
|
531
|
+
expect(target).to_not have(4).words
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
context "when the target is a Rails record" do
|
|
536
|
+
class TheModel
|
|
537
|
+
attr_reader :errors
|
|
538
|
+
|
|
539
|
+
def initialize(errors)
|
|
540
|
+
@errors = {}
|
|
541
|
+
@errors[:attr] = Array(errors)
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def errors_on(attr, _ignore_opts = {})
|
|
545
|
+
Array(@errors[attr]).flatten.compact
|
|
546
|
+
end
|
|
547
|
+
alias_method :error_on, :errors_on
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
let(:message_preamble) do
|
|
551
|
+
"the rspec-collection_matchers gem " +
|
|
552
|
+
"or replace your expectation with something like "
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
before do
|
|
556
|
+
stub_const "RSpec::Rails", Module.new
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
it "prints a specific message for the positive expectation format" do
|
|
560
|
+
expectation_expression = "expect(record).to have(2).errors_on(:attr)"
|
|
561
|
+
message = message_preamble + <<-EOS.gsub(/^\s+\|/, '')
|
|
562
|
+
|
|
|
563
|
+
|
|
|
564
|
+
| record.valid?
|
|
565
|
+
| expect(record.errors[:attr].size).to eq(2)
|
|
566
|
+
|
|
|
567
|
+
EOS
|
|
568
|
+
|
|
569
|
+
expect_have_deprecation(expectation_expression, message)
|
|
570
|
+
|
|
571
|
+
target = TheModel.new(%w(foo bar))
|
|
572
|
+
expect(target).to have(2).errors_on(:attr)
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
it "prints a specific message for the negative expectation format" do
|
|
576
|
+
expectation_expression = "expect(record).not_to have(2).errors_on(:attr)"
|
|
577
|
+
message = message_preamble + <<-EOS.gsub(/^\s+\|/, '')
|
|
578
|
+
|
|
|
579
|
+
|
|
|
580
|
+
| record.valid?
|
|
581
|
+
| expect(record.errors[:attr].size).to_not eq(2)
|
|
582
|
+
|
|
|
583
|
+
EOS
|
|
584
|
+
|
|
585
|
+
expect_have_deprecation(expectation_expression, message)
|
|
586
|
+
|
|
587
|
+
target = TheModel.new('foo')
|
|
588
|
+
expect(target).not_to have(2).errors_on(:attr)
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
it "prints message for singular form: `error_on`" do
|
|
592
|
+
expectation_expression = "expect(record).to have(1).error_on(:attr)"
|
|
593
|
+
message = message_preamble + <<-EOS.gsub(/^\s+\|/, '')
|
|
594
|
+
|
|
|
595
|
+
|
|
|
596
|
+
| record.valid?
|
|
597
|
+
| expect(record.errors[:attr].size).to eq(1)
|
|
598
|
+
|
|
|
599
|
+
EOS
|
|
600
|
+
|
|
601
|
+
expect_have_deprecation(expectation_expression, message)
|
|
602
|
+
|
|
603
|
+
target = TheModel.new('foo')
|
|
604
|
+
expect(target).to have(1).error_on(:attr)
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
it "includes a validation context when provided" do
|
|
608
|
+
expectation_expression = "expect(record).to have(2).errors_on(:attr, :context => :spec)"
|
|
609
|
+
message = message_preamble + <<-EOS.gsub(/^\s+\|/, '')
|
|
610
|
+
|
|
|
611
|
+
|
|
|
612
|
+
| record.valid?(:spec)
|
|
613
|
+
| expect(record.errors[:attr].size).to eq(2)
|
|
614
|
+
|
|
|
615
|
+
EOS
|
|
616
|
+
|
|
617
|
+
expect_have_deprecation(expectation_expression, message)
|
|
618
|
+
|
|
619
|
+
target = TheModel.new(%w(foo bar))
|
|
620
|
+
options = {:context => :spec, :should_be_ignored => true}
|
|
621
|
+
expect(target).to have(2).errors_on(:attr, options)
|
|
622
|
+
end
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
context "when the target is an enumerator" do
|
|
626
|
+
it "prints a specific message for the positive expectation format" do
|
|
627
|
+
target = %w[a b c].to_enum(:each)
|
|
628
|
+
|
|
629
|
+
expectation_expression = "expect(collection).to have(3).letters"
|
|
630
|
+
|
|
631
|
+
message = "the rspec-collection_matchers gem " +
|
|
632
|
+
"or replace your expectation with something like " +
|
|
633
|
+
"`expect(collection.count).to eq(3)`"
|
|
634
|
+
|
|
635
|
+
expect_have_deprecation(expectation_expression, message)
|
|
636
|
+
|
|
637
|
+
expect(target).to have(3).letters
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
it "prints a specific message for the negative expectation format" do
|
|
641
|
+
target = %w[a b c].to_enum(:each)
|
|
642
|
+
|
|
643
|
+
expectation_expression = "expect(collection).not_to have(4).letters"
|
|
644
|
+
|
|
645
|
+
message = "the rspec-collection_matchers gem " +
|
|
646
|
+
"or replace your expectation with something like " +
|
|
647
|
+
"`expect(collection.count).to_not eq(4)`"
|
|
648
|
+
|
|
649
|
+
expect_have_deprecation(expectation_expression, message)
|
|
650
|
+
|
|
651
|
+
expect(target).to_not have(4).letters
|
|
652
|
+
end
|
|
653
|
+
end
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
context "deprecations for the have_at_most matcher" do
|
|
657
|
+
it "has the correct call site in the deprecation message" do
|
|
658
|
+
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
|
659
|
+
expect([1, 2, 3]).to have_at_most(3).items
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
context "when the target is a collection" do
|
|
663
|
+
it "prints a specific message for the positive expectation format" do
|
|
664
|
+
expectation_expression = "expect(collection).to have_at_most(3).items"
|
|
665
|
+
|
|
666
|
+
message = "the rspec-collection_matchers gem " +
|
|
667
|
+
"or replace your expectation with something like " +
|
|
668
|
+
"`expect(collection.size).to be <= 3`"
|
|
669
|
+
|
|
670
|
+
expect_have_deprecation(expectation_expression, message)
|
|
671
|
+
|
|
672
|
+
expect([1, 2, 3]).to have_at_most(3).items
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
it "prints a specific message for the negative expectation format" do
|
|
676
|
+
expectation_expression = "expect(collection).not_to have_at_most(2).items"
|
|
677
|
+
|
|
678
|
+
message = "the rspec-collection_matchers gem " +
|
|
679
|
+
"or replace your expectation with something like " +
|
|
680
|
+
"`expect(collection.size).to be > 2`"
|
|
681
|
+
|
|
682
|
+
expect_have_deprecation(expectation_expression, message)
|
|
683
|
+
|
|
684
|
+
expect([1, 2, 3]).to_not have_at_most(2).items
|
|
685
|
+
end
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
context "when the target owns a collection" do
|
|
689
|
+
class self::BagOfWords
|
|
690
|
+
attr_reader :words
|
|
691
|
+
|
|
692
|
+
def initialize(words)
|
|
693
|
+
@words = words
|
|
694
|
+
end
|
|
695
|
+
end
|
|
696
|
+
|
|
697
|
+
it "prints a specific message for the positive expectation format" do
|
|
698
|
+
expectation_expression = "expect(collection_owner).to have_at_most(3).words"
|
|
699
|
+
|
|
700
|
+
message = "the rspec-collection_matchers gem " +
|
|
701
|
+
"or replace your expectation with something like " +
|
|
702
|
+
"`expect(collection_owner.words.size).to be <= 3`"
|
|
703
|
+
|
|
704
|
+
expect_have_deprecation(expectation_expression, message)
|
|
705
|
+
|
|
706
|
+
target = BagOfWords.new(%w[foo bar baz])
|
|
707
|
+
expect(target).to have_at_most(3).words
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
it "prints a specific message for the negative expectation format" do
|
|
711
|
+
expectation_expression = "expect(collection_owner).not_to have_at_most(2).words"
|
|
712
|
+
|
|
713
|
+
message = "the rspec-collection_matchers gem " +
|
|
714
|
+
"or replace your expectation with something like " +
|
|
715
|
+
"`expect(collection_owner.words.size).to be > 2`"
|
|
716
|
+
|
|
717
|
+
expect_have_deprecation(expectation_expression, message)
|
|
718
|
+
|
|
719
|
+
target = BagOfWords.new(%w[foo bar baz])
|
|
720
|
+
expect(target).to_not have_at_most(2).words
|
|
721
|
+
end
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
context "when the target is an enumerator" do
|
|
725
|
+
it "prints a specific message for the positive expectation format" do
|
|
726
|
+
target = %w[a b c].to_enum(:each)
|
|
727
|
+
|
|
728
|
+
expectation_expression = "expect(collection).to have_at_most(3).letters"
|
|
729
|
+
|
|
730
|
+
message = "the rspec-collection_matchers gem " +
|
|
731
|
+
"or replace your expectation with something like " +
|
|
732
|
+
"`expect(collection.count).to be <= 3`"
|
|
733
|
+
|
|
734
|
+
expect_have_deprecation(expectation_expression, message)
|
|
735
|
+
|
|
736
|
+
expect(target).to have_at_most(3).letters
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
it "prints a specific message for the negative expectation format" do
|
|
740
|
+
target = %w[a b c].to_enum(:each)
|
|
741
|
+
|
|
742
|
+
expectation_expression = "expect(collection).not_to have_at_most(2).letters"
|
|
743
|
+
|
|
744
|
+
message = "the rspec-collection_matchers gem " +
|
|
745
|
+
"or replace your expectation with something like " +
|
|
746
|
+
"`expect(collection.count).to be > 2`"
|
|
747
|
+
|
|
748
|
+
expect_have_deprecation(expectation_expression, message)
|
|
749
|
+
|
|
750
|
+
expect(target).to_not have_at_most(2).letters
|
|
751
|
+
end
|
|
752
|
+
end
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
context "deprecations for the have_at_least matcher" do
|
|
756
|
+
it "has the correct call site in the deprecation message" do
|
|
757
|
+
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
|
758
|
+
expect([1, 2, 3]).to have_at_least(3).items
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
context "when the target is a collection" do
|
|
762
|
+
it "prints a specific message for the positive expectation format" do
|
|
763
|
+
expectation_expression = "expect(collection).to have_at_least(3).items"
|
|
764
|
+
|
|
765
|
+
message = "the rspec-collection_matchers gem " +
|
|
766
|
+
"or replace your expectation with something like " +
|
|
767
|
+
"`expect(collection.size).to be >= 3`"
|
|
768
|
+
|
|
769
|
+
expect_have_deprecation(expectation_expression, message)
|
|
770
|
+
|
|
771
|
+
expect([1, 2, 3]).to have_at_least(3).items
|
|
772
|
+
end
|
|
773
|
+
|
|
774
|
+
it "prints a specific message for the negative expectation format" do
|
|
775
|
+
expectation_expression = "expect(collection).not_to have_at_least(4).items"
|
|
776
|
+
|
|
777
|
+
message = "the rspec-collection_matchers gem " +
|
|
778
|
+
"or replace your expectation with something like " +
|
|
779
|
+
"`expect(collection.size).to be < 4`"
|
|
780
|
+
|
|
781
|
+
expect_have_deprecation(expectation_expression, message)
|
|
782
|
+
|
|
783
|
+
expect([1, 2, 3]).to_not have_at_least(4).items
|
|
784
|
+
end
|
|
785
|
+
end
|
|
786
|
+
|
|
787
|
+
context "when the target owns a collection" do
|
|
788
|
+
class BagOfWords
|
|
789
|
+
attr_reader :words
|
|
790
|
+
|
|
791
|
+
def initialize(words)
|
|
792
|
+
@words = words
|
|
793
|
+
end
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
it "prints a specific message for the positive expectation format" do
|
|
797
|
+
expectation_expression = "expect(collection_owner).to have_at_least(3).words"
|
|
798
|
+
|
|
799
|
+
message = "the rspec-collection_matchers gem " +
|
|
800
|
+
"or replace your expectation with something like " +
|
|
801
|
+
"`expect(collection_owner.words.size).to be >= 3`"
|
|
802
|
+
|
|
803
|
+
expect_have_deprecation(expectation_expression, message)
|
|
804
|
+
|
|
805
|
+
target = BagOfWords.new(%w[foo bar baz])
|
|
806
|
+
expect(target).to have_at_least(3).words
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
it "prints a specific message for the negative expectation format" do
|
|
810
|
+
expectation_expression = "expect(collection_owner).not_to have_at_least(4).words"
|
|
811
|
+
|
|
812
|
+
message = "the rspec-collection_matchers gem " +
|
|
813
|
+
"or replace your expectation with something like " +
|
|
814
|
+
"`expect(collection_owner.words.size).to be < 4`"
|
|
815
|
+
|
|
816
|
+
expect_have_deprecation(expectation_expression, message)
|
|
817
|
+
|
|
818
|
+
target = BagOfWords.new(%w[foo bar baz])
|
|
819
|
+
expect(target).to_not have_at_least(4).words
|
|
820
|
+
end
|
|
821
|
+
end
|
|
822
|
+
|
|
823
|
+
context "when the target is an enumerator" do
|
|
824
|
+
it "prints a specific message for the positive expectation format" do
|
|
825
|
+
target = %w[a b c].to_enum(:each)
|
|
826
|
+
|
|
827
|
+
expectation_expression = "expect(collection).to have_at_least(3).letters"
|
|
828
|
+
|
|
829
|
+
message = "the rspec-collection_matchers gem " +
|
|
830
|
+
"or replace your expectation with something like " +
|
|
831
|
+
"`expect(collection.count).to be >= 3`"
|
|
832
|
+
|
|
833
|
+
expect_have_deprecation(expectation_expression, message)
|
|
834
|
+
|
|
835
|
+
expect(target).to have_at_least(3).letters
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
it "prints a specific message for the negative expectation format" do
|
|
839
|
+
target = %w[a b c].to_enum(:each)
|
|
840
|
+
|
|
841
|
+
expectation_expression = "expect(collection).not_to have_at_least(4).letters"
|
|
842
|
+
|
|
843
|
+
message = "the rspec-collection_matchers gem " +
|
|
844
|
+
"or replace your expectation with something like " +
|
|
845
|
+
"`expect(collection.count).to be < 4`"
|
|
846
|
+
|
|
847
|
+
expect_have_deprecation(expectation_expression, message)
|
|
848
|
+
|
|
849
|
+
expect(target).to_not have_at_least(4).letters
|
|
850
|
+
end
|
|
851
|
+
end
|
|
852
|
+
end
|
|
455
853
|
end
|