mongoid 7.4.3 → 7.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/config/locales/en.yml +7 -0
  4. data/lib/mongoid/association/embedded/batchable.rb +3 -20
  5. data/lib/mongoid/association/macros.rb +20 -0
  6. data/lib/mongoid/association/referenced/has_many/enumerable.rb +12 -8
  7. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  8. data/lib/mongoid/atomic/paths/embedded/many.rb +0 -19
  9. data/lib/mongoid/config.rb +6 -1
  10. data/lib/mongoid/contextual/memory.rb +144 -12
  11. data/lib/mongoid/contextual/mongo.rb +118 -26
  12. data/lib/mongoid/contextual/none.rb +45 -1
  13. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -0
  14. data/lib/mongoid/criteria/queryable/extensions/hash.rb +2 -0
  15. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  16. data/lib/mongoid/criteria/queryable/selectable.rb +26 -10
  17. data/lib/mongoid/criteria.rb +2 -0
  18. data/lib/mongoid/document.rb +2 -0
  19. data/lib/mongoid/equality.rb +4 -4
  20. data/lib/mongoid/errors/document_not_found.rb +23 -6
  21. data/lib/mongoid/fields.rb +145 -21
  22. data/lib/mongoid/findable.rb +20 -5
  23. data/lib/mongoid/version.rb +1 -1
  24. data/lib/mongoid/warnings.rb +29 -0
  25. data/lib/mongoid.rb +1 -0
  26. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -3
  27. data/spec/integration/i18n_fallbacks_spec.rb +15 -1
  28. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +0 -21
  29. data/spec/mongoid/association/embedded/embeds_many_models.rb +0 -121
  30. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +0 -8
  31. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +54 -0
  32. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +8 -24
  33. data/spec/mongoid/clients/options_spec.rb +1 -0
  34. data/spec/mongoid/config_spec.rb +10 -4
  35. data/spec/mongoid/contextual/memory_spec.rb +826 -65
  36. data/spec/mongoid/contextual/mongo_spec.rb +781 -18
  37. data/spec/mongoid/contextual/none_spec.rb +46 -0
  38. data/spec/mongoid/criteria/queryable/selectable_spec.rb +212 -39
  39. data/spec/mongoid/criteria_spec.rb +8 -0
  40. data/spec/mongoid/equality_spec.rb +12 -12
  41. data/spec/mongoid/errors/document_not_found_spec.rb +49 -0
  42. data/spec/mongoid/findable_spec.rb +30 -0
  43. data/spec/support/models/code.rb +2 -0
  44. data.tar.gz.sig +0 -0
  45. metadata +3 -2
  46. metadata.gz.sig +0 -0
@@ -584,6 +584,10 @@ describe Mongoid::Contextual::Mongo do
584
584
  d.save!
585
585
  end
586
586
 
587
+ after do
588
+ I18n.locale = :en
589
+ end
590
+
587
591
  let(:criteria) do
588
592
  Dictionary.criteria
589
593
  end
@@ -684,6 +688,10 @@ describe Mongoid::Contextual::Mongo do
684
688
  I18n.fallbacks = prev_fallbacks
685
689
  end
686
690
 
691
+ after do
692
+ I18n.locale = :en
693
+ end
694
+
687
695
  let(:distinct) do
688
696
  context.distinct(:description).first
689
697
  end
@@ -719,6 +727,10 @@ describe Mongoid::Contextual::Mongo do
719
727
  Person.create!(passport: p, employer_id: 12345)
720
728
  end
721
729
 
730
+ after do
731
+ I18n.locale = :en
732
+ end
733
+
722
734
  let(:criteria) do
723
735
  Person.where(employer_id: 12345)
724
736
  end
@@ -1470,6 +1482,10 @@ describe Mongoid::Contextual::Mongo do
1470
1482
  Band.create!(name: "New Order")
1471
1483
  end
1472
1484
 
1485
+ let!(:rolling_stones) do
1486
+ Band.create!(name: "The Rolling Stones")
1487
+ end
1488
+
1473
1489
  context "when the context is not cached" do
1474
1490
 
1475
1491
  let(:criteria) do
@@ -1510,14 +1526,14 @@ describe Mongoid::Contextual::Mongo do
1510
1526
  context "when there is sort on the context" do
1511
1527
 
1512
1528
  it "follows the main sort" do
1513
- expect(context.send(method)).to eq(new_order)
1529
+ expect(context.send(method)).to eq(rolling_stones)
1514
1530
  end
1515
1531
  end
1516
1532
 
1517
1533
  context "when subsequently calling #last" do
1518
1534
 
1519
1535
  it "returns the correct document" do
1520
- expect(context.send(method)).to eq(new_order)
1536
+ expect(context.send(method)).to eq(rolling_stones)
1521
1537
  expect(context.last).to eq(depeche_mode)
1522
1538
  end
1523
1539
  end
@@ -1542,23 +1558,22 @@ describe Mongoid::Contextual::Mongo do
1542
1558
 
1543
1559
  it 'returns the last document, sorted by _id' do
1544
1560
  expect(context.send(method)).to eq(depeche_mode)
1545
- expect(context.last).to eq(new_order)
1561
+ expect(context.last).to eq(rolling_stones)
1546
1562
  end
1547
1563
  end
1548
1564
 
1549
- context 'with option { sort: :none }' do
1550
-
1565
+ context 'with option { id_sort: :none }' do
1551
1566
  let(:opts) do
1552
1567
  { id_sort: :none }
1553
1568
  end
1554
1569
 
1555
- it 'does not apply the sort on _id' do
1570
+ it 'applies the sort on _id' do
1556
1571
  expect(context.send(method, opts)).to eq(depeche_mode)
1557
1572
  end
1558
1573
 
1559
1574
  context 'when calling #last' do
1560
1575
 
1561
- it 'does not apply a sort on _id' do
1576
+ it 'doesn\'t apply a sort on _id' do
1562
1577
  expect(context.send(method, opts)).to eq(depeche_mode)
1563
1578
  expect(context.last(opts)).to eq(depeche_mode)
1564
1579
  end
@@ -1576,33 +1591,32 @@ describe Mongoid::Contextual::Mongo do
1576
1591
  described_class.new(criteria)
1577
1592
  end
1578
1593
 
1579
-
1580
1594
  it 'applies the criteria sort' do
1581
- expect(context.send(method)).to eq(new_order)
1595
+ expect(context.send(method)).to eq(rolling_stones)
1582
1596
  end
1583
1597
 
1584
1598
  context 'when calling #last' do
1585
1599
 
1586
1600
  it 'applies the criteria sort' do
1587
- expect(context.send(method)).to eq(new_order)
1601
+ expect(context.send(method)).to eq(rolling_stones)
1588
1602
  expect(context.last).to eq(depeche_mode)
1589
1603
  end
1590
1604
  end
1591
1605
 
1592
- context 'with option { sort: :none }' do
1606
+ context 'with option { id_sort: :none }' do
1593
1607
 
1594
1608
  let(:opts) do
1595
1609
  { id_sort: :none }
1596
1610
  end
1597
1611
 
1598
- it 'applies the criteria sort' do
1599
- expect(context.send(method, opts)).to eq(new_order)
1612
+ it 'uses the preexisting sort' do
1613
+ expect(context.send(method, opts)).to eq(rolling_stones)
1600
1614
  end
1601
1615
 
1602
1616
  context 'when calling #last' do
1603
1617
 
1604
- it 'applies the criteria sort' do
1605
- expect(context.send(method, opts)).to eq(new_order)
1618
+ it 'uses the preexisting sort' do
1619
+ expect(context.send(method, opts)).to eq(rolling_stones)
1606
1620
  expect(context.last(opts)).to eq(depeche_mode)
1607
1621
  end
1608
1622
  end
@@ -1622,14 +1636,14 @@ describe Mongoid::Contextual::Mongo do
1622
1636
  context "when there is sort on the context" do
1623
1637
 
1624
1638
  it "follows the main sort" do
1625
- expect(context.send(method)).to eq(new_order)
1639
+ expect(context.send(method)).to eq(rolling_stones)
1626
1640
  end
1627
1641
  end
1628
1642
 
1629
1643
  context "when subsequently calling #last" do
1630
1644
 
1631
1645
  it "returns the correct document" do
1632
- expect(context.send(method)).to eq(new_order)
1646
+ expect(context.send(method)).to eq(rolling_stones)
1633
1647
  expect(context.last).to eq(depeche_mode)
1634
1648
  end
1635
1649
  end
@@ -1669,6 +1683,680 @@ describe Mongoid::Contextual::Mongo do
1669
1683
  end
1670
1684
  end
1671
1685
  end
1686
+
1687
+ context "when including a limit" do
1688
+
1689
+ context "when the context is not cached" do
1690
+
1691
+ let(:context) do
1692
+ described_class.new(criteria)
1693
+ end
1694
+
1695
+ context "when the limit is 1" do
1696
+ let(:criteria) do
1697
+ Band.criteria
1698
+ end
1699
+
1700
+ let(:docs) do
1701
+ context.send(method, 1)
1702
+ end
1703
+
1704
+ it "returns an array of documents" do
1705
+ expect(docs).to eq([ depeche_mode ])
1706
+ end
1707
+ end
1708
+
1709
+ context "when the limit is >1" do
1710
+ let(:criteria) do
1711
+ Band.criteria
1712
+ end
1713
+
1714
+ let(:docs) do
1715
+ context.send(method, 2)
1716
+ end
1717
+
1718
+ it "returns the number of documents in order" do
1719
+ expect(docs).to eq([ depeche_mode, new_order ])
1720
+ end
1721
+ end
1722
+
1723
+ context 'when the criteria has a collation' do
1724
+ min_server_version '3.4'
1725
+
1726
+ let(:criteria) do
1727
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
1728
+ end
1729
+
1730
+ it "returns the first matching document" do
1731
+ expect(context.send(method, 1)).to eq([ depeche_mode ])
1732
+ end
1733
+ end
1734
+ end
1735
+
1736
+ context "when the context is cached" do
1737
+
1738
+ let(:context) do
1739
+ described_class.new(criteria)
1740
+ end
1741
+
1742
+ context "when the whole context is loaded" do
1743
+
1744
+ before do
1745
+ context.to_a
1746
+ end
1747
+
1748
+ context "when all of the documents are cached" do
1749
+
1750
+ let(:criteria) do
1751
+ Band.all.cache
1752
+ end
1753
+
1754
+ context "when requesting all of the documents" do
1755
+
1756
+ let(:docs) do
1757
+ context.send(method, 3)
1758
+ end
1759
+
1760
+ it "returns all of the documents without touching the database" do
1761
+ expect(context).to receive(:view).never
1762
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
1763
+ end
1764
+ end
1765
+
1766
+ context "when requesting fewer than all of the documents" do
1767
+
1768
+ let(:docs) do
1769
+ context.send(method, 2)
1770
+ end
1771
+
1772
+ it "returns all of the documents without touching the database" do
1773
+ expect(context).to receive(:view).never
1774
+ expect(docs).to eq([ depeche_mode, new_order ])
1775
+ end
1776
+ end
1777
+ end
1778
+
1779
+ context "when only one document is cached" do
1780
+
1781
+ let(:criteria) do
1782
+ Band.where(name: "Depeche Mode").cache
1783
+ end
1784
+
1785
+ context "when requesting one document" do
1786
+
1787
+ let(:docs) do
1788
+ context.send(method, 1)
1789
+ end
1790
+
1791
+ it "returns one document without touching the database" do
1792
+ expect(context).to receive(:view).never
1793
+ expect(docs).to eq([ depeche_mode ])
1794
+ end
1795
+ end
1796
+ end
1797
+ end
1798
+
1799
+ context "when the first method was called before" do
1800
+
1801
+ let(:context) do
1802
+ described_class.new(criteria)
1803
+ end
1804
+
1805
+ let(:criteria) do
1806
+ Band.all.cache
1807
+ end
1808
+
1809
+ before do
1810
+ context.first(before_limit)
1811
+ end
1812
+
1813
+ let(:docs) do
1814
+ context.send(method, limit)
1815
+ end
1816
+
1817
+ context "when getting all of the documents before" do
1818
+ let(:before_limit) { 3 }
1819
+
1820
+ context "when getting all of the documents" do
1821
+ let(:limit) { 3 }
1822
+
1823
+ it "returns all documents without touching the database" do
1824
+ expect(context).to receive(:view).never
1825
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
1826
+ end
1827
+ end
1828
+
1829
+ context "when getting fewer documents" do
1830
+ let(:limit) { 2 }
1831
+
1832
+ it "returns the correct documents without touching the database" do
1833
+ expect(context).to receive(:view).never
1834
+ expect(docs).to eq([ depeche_mode, new_order ])
1835
+ end
1836
+ end
1837
+ end
1838
+
1839
+ context "when getting fewer documents before" do
1840
+ let(:before_limit) { 2 }
1841
+
1842
+ context "when getting the same number of documents" do
1843
+ let(:limit) { 2 }
1844
+
1845
+ it "returns the correct documents without touching the database" do
1846
+ expect(context).to receive(:view).never
1847
+ expect(docs).to eq([ depeche_mode, new_order ])
1848
+ end
1849
+ end
1850
+
1851
+ context "when getting more documents" do
1852
+ let(:limit) { 3 }
1853
+
1854
+ it "returns the correct documents and touches the database" do
1855
+ expect(context).to receive(:view).exactly(3).times.and_call_original
1856
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
1857
+ end
1858
+ end
1859
+ end
1860
+
1861
+ context "when getting one document before" do
1862
+ let(:before_limit) { 1 }
1863
+
1864
+ context "when getting one document" do
1865
+ let(:limit) { 1 }
1866
+
1867
+ it "returns the correct documents without touching the database" do
1868
+ expect(context).to receive(:view).never
1869
+ expect(docs).to eq([ depeche_mode ])
1870
+ end
1871
+ end
1872
+
1873
+ context "when getting more than one document" do
1874
+ let(:limit) { 3 }
1875
+
1876
+ it "returns the correct documents and touches the database" do
1877
+ expect(context).to receive(:view).exactly(3).times.and_call_original
1878
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
1879
+ end
1880
+ end
1881
+ end
1882
+ end
1883
+ end
1884
+ end
1885
+
1886
+ context "when calling #first then #last" do
1887
+
1888
+ let(:context) do
1889
+ described_class.new(criteria)
1890
+ end
1891
+
1892
+ let(:criteria) do
1893
+ Band.all.cache
1894
+ end
1895
+
1896
+ before do
1897
+ context.first(before_limit)
1898
+ end
1899
+
1900
+ let(:docs) do
1901
+ context.last(limit)
1902
+ end
1903
+
1904
+ context "when getting one from the beginning and one from the end" do
1905
+ let(:before_limit) { 2 }
1906
+ let(:limit) { 1 }
1907
+
1908
+ it "gets the correct document" do
1909
+ expect(docs).to eq([rolling_stones])
1910
+ end
1911
+ end
1912
+ end
1913
+ end
1914
+ end
1915
+
1916
+ describe "#last" do
1917
+ let!(:depeche_mode) do
1918
+ Band.create!(name: "Depeche Mode")
1919
+ end
1920
+
1921
+ let!(:new_order) do
1922
+ Band.create!(name: "New Order")
1923
+ end
1924
+
1925
+ let!(:rolling_stones) do
1926
+ Band.create!(name: "The Rolling Stones")
1927
+ end
1928
+
1929
+ context "when the context is not cached" do
1930
+
1931
+ let(:criteria) do
1932
+ Band.where(name: "Depeche Mode")
1933
+ end
1934
+
1935
+ let(:context) do
1936
+ described_class.new(criteria)
1937
+ end
1938
+
1939
+ it "returns the last matching document" do
1940
+ expect(context.last).to eq(depeche_mode)
1941
+ end
1942
+
1943
+ context 'when the criteria has a collation' do
1944
+ min_server_version '3.4'
1945
+
1946
+ let(:criteria) do
1947
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
1948
+ end
1949
+
1950
+ it "returns the last matching document" do
1951
+ expect(context.last).to eq(depeche_mode)
1952
+ end
1953
+ end
1954
+ end
1955
+
1956
+ context "when using .desc" do
1957
+
1958
+ let(:criteria) do
1959
+ Band.desc(:name)
1960
+ end
1961
+
1962
+ let(:context) do
1963
+ described_class.new(criteria)
1964
+ end
1965
+
1966
+ context "when there is sort on the context" do
1967
+
1968
+ it "follows the main sort" do
1969
+ expect(context.last).to eq(depeche_mode)
1970
+ end
1971
+ end
1972
+
1973
+ context "when subsequently calling #first" do
1974
+
1975
+ it "returns the correct document" do
1976
+ expect(context.last).to eq(depeche_mode)
1977
+ expect(context.first).to eq(rolling_stones)
1978
+ end
1979
+ end
1980
+ end
1981
+
1982
+ context 'when the criteria has no sort' do
1983
+
1984
+ let(:criteria) do
1985
+ Band.all
1986
+ end
1987
+
1988
+ let(:context) do
1989
+ described_class.new(criteria)
1990
+ end
1991
+
1992
+ it 'applies a sort on _id' do
1993
+ expect(context.last).to eq(rolling_stones)
1994
+ end
1995
+
1996
+ context 'when calling #first' do
1997
+
1998
+ it 'returns the first document, sorted by _id' do
1999
+ pending "MONGOID-5416"
2000
+ expect(context.last).to eq(rolling_stones)
2001
+ expect(context.first).to eq(depeche_mode)
2002
+ end
2003
+ end
2004
+
2005
+ context 'with option { id_sort: :none }' do
2006
+ let(:opts) do
2007
+ { id_sort: :none }
2008
+ end
2009
+
2010
+ it 'doesn\'t apply the sort on _id' do
2011
+ expect(context.last(opts)).to eq(depeche_mode)
2012
+ end
2013
+
2014
+ context 'when calling #first' do
2015
+
2016
+ it 'doesn\'t apply the sort on _id' do
2017
+ pending "MONGOID-5416"
2018
+ expect(context.last(opts)).to eq(rolling_stones)
2019
+ expect(context.first(opts)).to eq(depeche_mode)
2020
+ end
2021
+ end
2022
+ end
2023
+ end
2024
+
2025
+ context 'when the criteria has a sort' do
2026
+
2027
+ let(:criteria) do
2028
+ Band.desc(:name)
2029
+ end
2030
+
2031
+ let(:context) do
2032
+ described_class.new(criteria)
2033
+ end
2034
+
2035
+
2036
+ it 'applies the criteria sort' do
2037
+ expect(context.last).to eq(depeche_mode)
2038
+ end
2039
+
2040
+ context 'when calling #first' do
2041
+
2042
+ it 'applies the criteria sort' do
2043
+ expect(context.last).to eq(depeche_mode)
2044
+ expect(context.first).to eq(rolling_stones)
2045
+ end
2046
+ end
2047
+
2048
+ context 'with option { id_sort: :none }' do
2049
+
2050
+ let(:opts) do
2051
+ { id_sort: :none }
2052
+ end
2053
+
2054
+ it 'uses the preexisting sort' do
2055
+ expect(context.last(opts)).to eq(depeche_mode)
2056
+ end
2057
+
2058
+ context 'when calling #first' do
2059
+
2060
+ it 'uses the preexisting sort' do
2061
+ expect(context.last(opts)).to eq(depeche_mode)
2062
+ expect(context.first(opts)).to eq(rolling_stones)
2063
+ end
2064
+ end
2065
+ end
2066
+ end
2067
+
2068
+ context "when using .sort" do
2069
+
2070
+ let(:criteria) do
2071
+ Band.all.sort(:name => -1).criteria
2072
+ end
2073
+
2074
+ let(:context) do
2075
+ described_class.new(criteria)
2076
+ end
2077
+
2078
+ context "when there is sort on the context" do
2079
+
2080
+ it "follows the main sort" do
2081
+ expect(context.last).to eq(depeche_mode)
2082
+ end
2083
+ end
2084
+
2085
+ context "when subsequently calling #first" do
2086
+
2087
+ it "returns the correct document" do
2088
+ expect(context.last).to eq(depeche_mode)
2089
+ expect(context.first).to eq(rolling_stones)
2090
+ end
2091
+ end
2092
+ end
2093
+
2094
+ context "when the context is cached" do
2095
+
2096
+ let(:criteria) do
2097
+ Band.where(name: "Depeche Mode").cache
2098
+ end
2099
+
2100
+ let(:context) do
2101
+ described_class.new(criteria)
2102
+ end
2103
+
2104
+ context "when the cache is loaded" do
2105
+
2106
+ before do
2107
+ context.to_a
2108
+ end
2109
+
2110
+ it "returns the last document without touching the database" do
2111
+ expect(context).to receive(:view).never
2112
+ expect(context.last).to eq(depeche_mode)
2113
+ end
2114
+ end
2115
+
2116
+ context "when last method was called before" do
2117
+
2118
+ before do
2119
+ context.last
2120
+ end
2121
+
2122
+ it "returns the last document without touching the database" do
2123
+ expect(context).to receive(:view).never
2124
+ expect(context.last).to eq(depeche_mode)
2125
+ end
2126
+ end
2127
+ end
2128
+
2129
+ context "when including a limit" do
2130
+
2131
+ context "when the context is not cached" do
2132
+
2133
+ let(:context) do
2134
+ described_class.new(criteria)
2135
+ end
2136
+
2137
+ context "when the limit is 1" do
2138
+ let(:criteria) do
2139
+ Band.criteria
2140
+ end
2141
+
2142
+ let(:docs) do
2143
+ context.last(1)
2144
+ end
2145
+
2146
+ it "returns an array of documents" do
2147
+ expect(docs).to eq([ rolling_stones ])
2148
+ end
2149
+ end
2150
+
2151
+ context "when the limit is >1" do
2152
+ let(:criteria) do
2153
+ Band.criteria
2154
+ end
2155
+
2156
+ let(:docs) do
2157
+ context.last(2)
2158
+ end
2159
+
2160
+ it "returns the number of documents in order" do
2161
+ expect(docs).to eq([ new_order, rolling_stones ])
2162
+ end
2163
+ end
2164
+
2165
+ context 'when the criteria has a collation' do
2166
+ min_server_version '3.4'
2167
+
2168
+ let(:criteria) do
2169
+ Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
2170
+ end
2171
+
2172
+ it "returns the first matching document" do
2173
+ expect(context.last(1)).to eq([ depeche_mode ])
2174
+ end
2175
+ end
2176
+ end
2177
+
2178
+ context "when the context is cached" do
2179
+
2180
+ let(:context) do
2181
+ described_class.new(criteria)
2182
+ end
2183
+
2184
+ context "when the whole context is loaded" do
2185
+
2186
+ before do
2187
+ context.to_a
2188
+ end
2189
+
2190
+ context "when all of the documents are cached" do
2191
+
2192
+ let(:criteria) do
2193
+ Band.all.cache
2194
+ end
2195
+
2196
+ context "when requesting all of the documents" do
2197
+
2198
+ let(:docs) do
2199
+ context.last(3)
2200
+ end
2201
+
2202
+ it "returns all of the documents without touching the database" do
2203
+ expect(context).to receive(:view).never
2204
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2205
+ end
2206
+ end
2207
+
2208
+ context "when requesting fewer than all of the documents" do
2209
+
2210
+ let(:docs) do
2211
+ context.last(2)
2212
+ end
2213
+
2214
+ it "returns all of the documents without touching the database" do
2215
+ expect(context).to receive(:view).never
2216
+ expect(docs).to eq([ new_order, rolling_stones ])
2217
+ end
2218
+ end
2219
+ end
2220
+
2221
+ context "when only one document is cached" do
2222
+
2223
+ let(:criteria) do
2224
+ Band.where(name: "Depeche Mode").cache
2225
+ end
2226
+
2227
+ context "when requesting one document" do
2228
+
2229
+ let(:docs) do
2230
+ context.last(1)
2231
+ end
2232
+
2233
+ it "returns one document without touching the database" do
2234
+ expect(context).to receive(:view).never
2235
+ expect(docs).to eq([ depeche_mode ])
2236
+ end
2237
+ end
2238
+ end
2239
+ end
2240
+
2241
+ context "when the last method was called before" do
2242
+
2243
+ let(:context) do
2244
+ described_class.new(criteria)
2245
+ end
2246
+
2247
+ let(:criteria) do
2248
+ Band.all.cache
2249
+ end
2250
+
2251
+ before do
2252
+ context.last(before_limit)
2253
+ end
2254
+
2255
+ let(:docs) do
2256
+ context.last(limit)
2257
+ end
2258
+
2259
+ context "when getting all of the documents before" do
2260
+ let(:before_limit) { 3 }
2261
+
2262
+ context "when getting all of the documents" do
2263
+ let(:limit) { 3 }
2264
+
2265
+ it "returns all documents without touching the database" do
2266
+ expect(context).to receive(:view).never
2267
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2268
+ end
2269
+ end
2270
+
2271
+ context "when getting fewer documents" do
2272
+ let(:limit) { 2 }
2273
+
2274
+ it "returns the correct documents without touching the database" do
2275
+ expect(context).to receive(:view).never
2276
+ expect(docs).to eq([ new_order, rolling_stones ])
2277
+ end
2278
+ end
2279
+ end
2280
+
2281
+ context "when getting fewer documents before" do
2282
+ let(:before_limit) { 2 }
2283
+
2284
+ context "when getting the same number of documents" do
2285
+ let(:limit) { 2 }
2286
+
2287
+ it "returns the correct documents without touching the database" do
2288
+ expect(context).to receive(:view).never
2289
+ expect(docs).to eq([ new_order, rolling_stones ])
2290
+ end
2291
+ end
2292
+
2293
+ context "when getting more documents" do
2294
+ let(:limit) { 3 }
2295
+
2296
+ it "returns the correct documents and touches the database" do
2297
+ expect(context).to receive(:view).twice.and_call_original
2298
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2299
+ end
2300
+ end
2301
+ end
2302
+
2303
+ context "when getting one document before" do
2304
+ let(:before_limit) { 1 }
2305
+
2306
+ context "when getting one document" do
2307
+ let(:limit) { 1 }
2308
+
2309
+ it "returns the correct documents without touching the database" do
2310
+ expect(context).to receive(:view).never
2311
+ expect(docs).to eq([ rolling_stones ])
2312
+ end
2313
+ end
2314
+
2315
+ context "when getting more than one document" do
2316
+ let(:limit) { 3 }
2317
+
2318
+ it "returns the correct documents and touches the database" do
2319
+ expect(context).to receive(:view).twice.and_call_original
2320
+ expect(docs).to eq([ depeche_mode, new_order, rolling_stones ])
2321
+ end
2322
+ end
2323
+ end
2324
+ end
2325
+ end
2326
+ end
2327
+
2328
+ context "when calling #last then #first" do
2329
+
2330
+ let(:context) do
2331
+ described_class.new(criteria)
2332
+ end
2333
+
2334
+ let(:criteria) do
2335
+ Band.all.cache
2336
+ end
2337
+
2338
+ before do
2339
+ context.last(before_limit)
2340
+ end
2341
+
2342
+ let(:docs) do
2343
+ context.first(limit)
2344
+ end
2345
+
2346
+ context "when getting one from the beginning and one from the end" do
2347
+ let(:before_limit) { 2 }
2348
+ let(:limit) { 1 }
2349
+
2350
+ it "hits the database" do
2351
+ expect(context).to receive(:view).exactly(3).times.and_call_original
2352
+ docs
2353
+ end
2354
+
2355
+ it "gets the correct document" do
2356
+ pending "MONGOID-5416"
2357
+ expect(docs).to eq([ depeche_mode ])
2358
+ end
2359
+ end
1672
2360
  end
1673
2361
  end
1674
2362
 
@@ -1823,6 +2511,80 @@ describe Mongoid::Contextual::Mongo do
1823
2511
  end
1824
2512
  end
1825
2513
 
2514
+ describe "#take" do
2515
+
2516
+ let!(:depeche_mode) do
2517
+ Band.create!(name: "Depeche Mode")
2518
+ end
2519
+
2520
+ let!(:new_order) do
2521
+ Band.create!(name: "New Order")
2522
+ end
2523
+
2524
+ let!(:rolling_stones) do
2525
+ Band.create!(name: "The Rolling Stones")
2526
+ end
2527
+
2528
+ let(:criteria) do
2529
+ Band.all
2530
+ end
2531
+
2532
+ let(:context) do
2533
+ described_class.new(criteria)
2534
+ end
2535
+
2536
+ it "takes the correct number results" do
2537
+ expect(context.take(2)).to eq([ depeche_mode, new_order ])
2538
+ end
2539
+
2540
+ it "returns an array when passing 1" do
2541
+ expect(context.take(1)).to eq([ depeche_mode ])
2542
+ end
2543
+
2544
+ it "does not return an array when not passing an argument" do
2545
+ expect(context.take).to eq(depeche_mode)
2546
+ end
2547
+
2548
+ it "returns all the documents taking more than whats in the db" do
2549
+ expect(context.take(5)).to eq([ depeche_mode, new_order, rolling_stones ])
2550
+ end
2551
+ end
2552
+
2553
+ describe "#take!" do
2554
+
2555
+ let!(:depeche_mode) do
2556
+ Band.create!(name: "Depeche Mode")
2557
+ end
2558
+
2559
+ let!(:new_order) do
2560
+ Band.create!(name: "New Order")
2561
+ end
2562
+
2563
+ let!(:rolling_stones) do
2564
+ Band.create!(name: "The Rolling Stones")
2565
+ end
2566
+
2567
+ let(:criteria) do
2568
+ Band.all
2569
+ end
2570
+
2571
+ let(:context) do
2572
+ described_class.new(criteria)
2573
+ end
2574
+
2575
+ it "takes the first document" do
2576
+ expect(context.take!).to eq(depeche_mode)
2577
+ end
2578
+
2579
+ context "when there are no documents" do
2580
+ it "raises an error" do
2581
+ expect do
2582
+ Person.take!
2583
+ end.to raise_error(Mongoid::Errors::DocumentNotFound)
2584
+ end
2585
+ end
2586
+ end
2587
+
1826
2588
  describe "#map" do
1827
2589
 
1828
2590
  before do
@@ -1840,7 +2602,8 @@ describe Mongoid::Contextual::Mongo do
1840
2602
 
1841
2603
  context "when passed the symbol field name" do
1842
2604
 
1843
- it "performs mapping" do
2605
+ it "performs mapping and warns" do
2606
+ expect(Mongoid::Warnings).to receive(:warn_map_field_deprecated)
1844
2607
  expect(context.map(:name)).to eq ["Depeche Mode", "New Order"]
1845
2608
  end
1846
2609
  end