mongoid 7.4.3 → 7.5.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.
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