|
701 | 701 | end |
702 | 702 | end |
703 | 703 | end |
| 704 | + |
| 705 | + describe '#clone' do |
| 706 | + subject(:method_call) { query_builder.clone } |
| 707 | + |
| 708 | + let(:query_clauses_clone) { query_clauses.clone } |
| 709 | + let(:aggregations_clone) { aggregations.clone } |
| 710 | + |
| 711 | + before do |
| 712 | + allow(query_clauses).to receive(:clone).and_return(query_clauses_clone) |
| 713 | + allow(aggregations).to receive(:clone).and_return(aggregations_clone) |
| 714 | + end |
| 715 | + |
| 716 | + shared_examples_for '#clone' do |
| 717 | + it "returns an instance of #{described_class}" do |
| 718 | + expect(method_call).to be_a(described_class) |
| 719 | + end |
| 720 | + |
| 721 | + it 'does not return the same object' do |
| 722 | + expect(method_call).not_to be(query_builder) |
| 723 | + end |
| 724 | + end |
| 725 | + |
| 726 | + context "when the receiver has no 'from' clause" do |
| 727 | + it_behaves_like '#clone' |
| 728 | + |
| 729 | + it "does not have a 'from' clause either" do |
| 730 | + expect(method_call.to_query).not_to have_key(:from) |
| 731 | + end |
| 732 | + end |
| 733 | + |
| 734 | + context "when the receiver has a 'from' clause" do |
| 735 | + before { query_builder.from(100) } |
| 736 | + |
| 737 | + it_behaves_like '#clone' |
| 738 | + |
| 739 | + it "has the expected 'from' clause" do |
| 740 | + expect(method_call.to_query).to include(from: 100) |
| 741 | + end |
| 742 | + end |
| 743 | + |
| 744 | + context "when the receiver has no 'size' clause" do |
| 745 | + it_behaves_like '#clone' |
| 746 | + |
| 747 | + it "does not have a 'size' clause either" do |
| 748 | + expect(method_call.to_query).not_to have_key(:size) |
| 749 | + end |
| 750 | + end |
| 751 | + |
| 752 | + context "when the receiver has a 'size' clause" do |
| 753 | + before { query_builder.size(500) } |
| 754 | + |
| 755 | + it_behaves_like '#clone' |
| 756 | + |
| 757 | + it "has the expected 'size' clause" do |
| 758 | + expect(method_call.to_query).to include(size: 500) |
| 759 | + end |
| 760 | + end |
| 761 | + |
| 762 | + context "when the receiver has no 'source' clause" do |
| 763 | + it_behaves_like '#clone' |
| 764 | + |
| 765 | + it "does not have a 'source' clause either" do |
| 766 | + expect(method_call.to_query).not_to have_key(:_source) |
| 767 | + end |
| 768 | + end |
| 769 | + |
| 770 | + context "when the receiver has a 'source' clause" do |
| 771 | + before { query_builder.source('profile.*') } |
| 772 | + |
| 773 | + it_behaves_like '#clone' |
| 774 | + |
| 775 | + it "has the expected 'source' clause" do |
| 776 | + expect(method_call.to_query).to include(_source: 'profile.*') |
| 777 | + end |
| 778 | + end |
| 779 | + |
| 780 | + context "when the 'source' changes after cloning" do |
| 781 | + let(:source) { %w[profile.* permissions.*] } |
| 782 | + |
| 783 | + before do |
| 784 | + query_builder.source(source) |
| 785 | + end |
| 786 | + |
| 787 | + it_behaves_like '#clone' |
| 788 | + |
| 789 | + it "does not change the 'source' of the clone" do |
| 790 | + clone = method_call |
| 791 | + expect { source << 'pictures.*' }.not_to change(clone, :to_query) |
| 792 | + end |
| 793 | + end |
| 794 | + |
| 795 | + context "when the receiver has no 'collapse' clause" do |
| 796 | + it_behaves_like '#clone' |
| 797 | + |
| 798 | + it "does not have a 'collapse' clause either" do |
| 799 | + expect(method_call.to_query).not_to have_key(:collapse) |
| 800 | + end |
| 801 | + end |
| 802 | + |
| 803 | + context "when the receiver has a 'collapse' clause" do |
| 804 | + before { query_builder.collapse('profile.email') } |
| 805 | + |
| 806 | + it_behaves_like '#clone' |
| 807 | + |
| 808 | + it "has the expected 'collapse' clause" do |
| 809 | + expect(method_call.to_query).to include(collapse: { field: 'profile.email' }) |
| 810 | + end |
| 811 | + end |
| 812 | + |
| 813 | + context "when the receiver has no 'sort' clause" do |
| 814 | + it_behaves_like '#clone' |
| 815 | + |
| 816 | + it "does not have a 'sort' clause either" do |
| 817 | + expect(method_call.to_query).not_to have_key(:sort) |
| 818 | + end |
| 819 | + end |
| 820 | + |
| 821 | + context "when the receiver has a 'sort' clause" do |
| 822 | + before { query_builder.sort(age: :desc) } |
| 823 | + |
| 824 | + it_behaves_like '#clone' |
| 825 | + |
| 826 | + it "has the expected 'sort' clause" do |
| 827 | + expect(method_call.to_query).to include(sort: [{ age: { order: :desc } }]) |
| 828 | + end |
| 829 | + end |
| 830 | + |
| 831 | + context "when the 'sort' changes after cloning" do |
| 832 | + before { query_builder.sort(age: :desc) } |
| 833 | + |
| 834 | + it_behaves_like '#clone' |
| 835 | + |
| 836 | + it "does not change the 'sort' clause of the clone" do |
| 837 | + clone = method_call |
| 838 | + expect { query_builder.sort(name: :asc) }.not_to change(clone, :to_query) |
| 839 | + end |
| 840 | + end |
| 841 | + |
| 842 | + it 'clones the nested QueryClauses object' do |
| 843 | + expect(query_clauses).to receive(:clone) |
| 844 | + method_call |
| 845 | + end |
| 846 | + |
| 847 | + it 'has the cloned QueryClauses object' do |
| 848 | + expect(method_call.query).to be(query_clauses_clone) |
| 849 | + end |
| 850 | + |
| 851 | + it 'clones the nested Aggregations object' do |
| 852 | + expect(aggregations).to receive(:clone) |
| 853 | + method_call |
| 854 | + end |
| 855 | + |
| 856 | + it 'has the cloned Aggregations object' do |
| 857 | + expect(method_call.aggregations).to be(aggregations_clone) |
| 858 | + end |
| 859 | + end |
704 | 860 | end |
0 commit comments