allrecipes 1.0.0 → 1.1.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 +4 -4
- data/.travis.yml +12 -0
- data/Gemfile +3 -0
- data/README.md +54 -10
- data/Rakefile +1 -0
- data/lib/allrecipes/main.rb +24 -11
- data/lib/allrecipes/page_parser.rb +1 -1
- data/lib/allrecipes/recipe_parser.rb +59 -9
- data/lib/allrecipes/url_helper.rb +78 -84
- data/lib/allrecipes/version.rb +1 -1
- data/spec/allrecipes_spec.rb +70 -2
- data/spec/recipe_filter_spec.rb +3 -3
- data/spec/recipe_parser_spec.rb +17 -2
- data/spec/spec_helper.rb +4 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcd90231bb99a50a29edd0c32105b20b4bf8820a
|
4
|
+
data.tar.gz: 1136762e02a2363375f6fb2038dd7a729d63549d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15de609534ffec45437568f31901a1b84bfc7f3829bbd5a9ddf7a659197a6161fa59116093e6f3f2af91dbdee9265fb8ac803fa9205c385ded435d141733e933
|
7
|
+
data.tar.gz: c606406a5bc8a57b3eaa37f45240c9989612695ee6cb4ed290e8fe2e712c74eab4844d47622b2038a8df870cd3cac5da105b2165b609382667d0f3d3664f4b86
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
# Allrecipes
|
1
|
+
# The Allrecipes Ruby Gem
|
2
|
+
[](http://badge.fury.io/rb/allrecipes)
|
3
|
+
[](https://travis-ci.org/shivamd/allrecipes)
|
4
|
+
[](https://gemnasium.com/shivamd/allrecipes)
|
5
|
+
[](https://codeclimate.com/github/shivamd/allrecipes)
|
6
|
+
[](https://coveralls.io/r/shivamd/allrecipes)
|
7
|
+
|
2
8
|
|
3
9
|
A Ruby interface to the Allrecipes API.
|
4
10
|
Allrecipes doesn't have an API, the requests are done using mechanize.
|
@@ -110,6 +116,44 @@ List of regions available:
|
|
110
116
|
recipes.ingredient("apples") #default sorted by relevance, limit 21.
|
111
117
|
```
|
112
118
|
|
119
|
+
**Passing options to search**
|
120
|
+
|
121
|
+
```#all, #region, #course, #ingredient``` all accept an options hash with the following paramters: limit, page & sort_by.
|
122
|
+
|
123
|
+
**Limit**
|
124
|
+
|
125
|
+
Default & max limit is 20 for ```#all, #region & #course```.
|
126
|
+
Defaut & max limit is 21 for ```#ingredient```.
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
recipes.all({ limit: 10 })
|
130
|
+
recipes.ingredient("apples", { limit: 10 })
|
131
|
+
```
|
132
|
+
**Page**
|
133
|
+
|
134
|
+
For pagination it's as simple as passing the page number.
|
135
|
+
If there are no results specified for that page, a blank array will be returned.
|
136
|
+
```ruby
|
137
|
+
recipes.all({ limit: 5, page: 3 }) #first 5 results from the 3rd page.
|
138
|
+
recipes.course("dessert", { page: 2 }) #20 results from page 2.
|
139
|
+
```
|
140
|
+
|
141
|
+
**Sort_By**
|
142
|
+
|
143
|
+
```#all, #region, #course``` are default sorted by popularity. Options available are popularity, date(newest first) and title(ascending).
|
144
|
+
If mentioned outside of this scope, will resort to default(popularity).
|
145
|
+
```ruby
|
146
|
+
recipes.all({ page: 5, sort_by: "date" })
|
147
|
+
recipes.region("german", { sort_by: "title", limit: 10 })
|
148
|
+
```
|
149
|
+
|
150
|
+
```#ingredient``` search is default sorted by relevance. Options available are relevance, popularity and rating.
|
151
|
+
If mentioned outside of this scope, will resort to default(relevance).
|
152
|
+
```ruby
|
153
|
+
recipes.ingredient("apples", { sort_by: "rating", page: 3 })
|
154
|
+
```
|
155
|
+
|
156
|
+
|
113
157
|
**Sample response**
|
114
158
|
```ruby
|
115
159
|
[
|
@@ -137,12 +181,12 @@ recipes.ingredient("apples") #default sorted by relevance, limit 21.
|
|
137
181
|
|
138
182
|
## Todo
|
139
183
|
|
140
|
-
1.
|
141
|
-
2.
|
142
|
-
3. Add
|
143
|
-
4. Add
|
144
|
-
5. Add
|
145
|
-
6.
|
146
|
-
7. Able to
|
147
|
-
8. Able to
|
148
|
-
9.
|
184
|
+
1. Complex search with queries such as multiple ingredients, course, time etc.
|
185
|
+
2. Add prep time & cook time to results
|
186
|
+
3. Add nutrional info to results.
|
187
|
+
4. Add rating to results
|
188
|
+
5. Add user photos for recipe to results
|
189
|
+
6. Able to get popular recipes of the day.
|
190
|
+
7. Able to request with recipe URL.
|
191
|
+
8. Able to request with page URL.
|
192
|
+
9. Option for selecting what keys to return.
|
data/Rakefile
CHANGED
data/lib/allrecipes/main.rb
CHANGED
@@ -7,27 +7,25 @@ class Allrecipes
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def all(options={})
|
10
|
-
page = @agent.get $URL + "/recipes" +
|
10
|
+
page = @agent.get $URL + "/recipes" + recipe_filters(options)
|
11
11
|
PageParser.new(page, options).recipes
|
12
12
|
end
|
13
13
|
|
14
14
|
def course(course_type, options={})
|
15
|
-
|
16
|
-
course_url = get_course_url(course_type) + "?page=#{options[:page]}&st=#{search_sort_parameter(options[:sort_by])}"
|
17
|
-
page = @agent.get(course_url)
|
18
|
-
PageParser.new(page, options).recipes
|
19
|
-
rescue Exception
|
20
|
-
raise "Course type doesn't exist"
|
21
|
-
end
|
15
|
+
recipe_search(course_type, options.merge({ url_type: "course" }))
|
22
16
|
end
|
23
17
|
|
24
18
|
def region(region_type, options={})
|
19
|
+
recipe_search(region_type, options.merge({ url_type: "region" }))
|
20
|
+
end
|
21
|
+
|
22
|
+
def recipe_search(type, options)
|
25
23
|
begin
|
26
|
-
|
27
|
-
page = @agent.get(
|
24
|
+
url = recipes_url(type, options)
|
25
|
+
page = @agent.get(url)
|
28
26
|
PageParser.new(page, options).recipes
|
29
27
|
rescue Exception
|
30
|
-
raise "
|
28
|
+
raise "#{options[:url_type].capitalize} doesn't exist"
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
@@ -42,6 +40,21 @@ class Allrecipes
|
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
43
|
+
def recipe_url(url)
|
44
|
+
begin
|
45
|
+
RecipeParser.new(url).recipe
|
46
|
+
rescue Exception
|
47
|
+
raise "This page does not contain a recipe"
|
48
|
+
end
|
49
|
+
end
|
45
50
|
|
51
|
+
def page_url(url)
|
52
|
+
begin
|
53
|
+
page = @agent.get(url)
|
54
|
+
PageParser.new(page).recipes
|
55
|
+
rescue Exception
|
56
|
+
raise "This page does not contain recipes"
|
57
|
+
end
|
58
|
+
end
|
46
59
|
end
|
47
60
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
class RecipeParser
|
2
|
-
$BASE_URL = "http://allrecipes.com"
|
3
2
|
|
4
3
|
def initialize(page)
|
5
|
-
@page =
|
4
|
+
@page = request_page(page)
|
6
5
|
@directions = []
|
7
6
|
@ingredients = []
|
8
7
|
get_ingredients
|
@@ -13,6 +12,14 @@ class RecipeParser
|
|
13
12
|
Mechanize.new
|
14
13
|
end
|
15
14
|
|
15
|
+
def request_page(page)
|
16
|
+
if page.match(/allrecipes\.com/)
|
17
|
+
agent.get page
|
18
|
+
else
|
19
|
+
raise "Invalid URL"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
16
23
|
def name
|
17
24
|
@page.search(name_id).inner_text
|
18
25
|
end
|
@@ -37,6 +44,42 @@ class RecipeParser
|
|
37
44
|
"#lblYield"
|
38
45
|
end
|
39
46
|
|
47
|
+
def rating
|
48
|
+
rating_html = @page.search(rating_class)
|
49
|
+
if rating_html.length > 0
|
50
|
+
float_value = rating_html.attr("content").inner_text.to_f
|
51
|
+
(float_value * 2).round / 2.0 #to convert to nearest 0.5
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def rating_class
|
56
|
+
".detail-right meta[itemprop='ratingValue']"
|
57
|
+
end
|
58
|
+
|
59
|
+
def time(type)
|
60
|
+
minutes = minutes(type)
|
61
|
+
hours = hours(type)
|
62
|
+
time = 0
|
63
|
+
time += minutes ? minutes.inner_text.to_i : 0
|
64
|
+
time += hours ? hours.inner_text.to_i * 60 : 0 #hours to minutes
|
65
|
+
end
|
66
|
+
|
67
|
+
def minutes(type)
|
68
|
+
@page.search("##{type}MinsSpan em")
|
69
|
+
end
|
70
|
+
|
71
|
+
def hours(type)
|
72
|
+
@page.search("##{type}HoursSpan em")
|
73
|
+
end
|
74
|
+
|
75
|
+
def preparation_time
|
76
|
+
time("prep")
|
77
|
+
end
|
78
|
+
|
79
|
+
def cooking_time
|
80
|
+
time("cook")
|
81
|
+
end
|
82
|
+
|
40
83
|
def directions_class
|
41
84
|
".directions ol li span"
|
42
85
|
end
|
@@ -91,13 +134,20 @@ class RecipeParser
|
|
91
134
|
end
|
92
135
|
|
93
136
|
def recipe
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
137
|
+
begin
|
138
|
+
{
|
139
|
+
name: name,
|
140
|
+
image: image,
|
141
|
+
servings: servings,
|
142
|
+
ingredients: @ingredients,
|
143
|
+
directions: @directions,
|
144
|
+
rating: rating,
|
145
|
+
prep_time: preparation_time,
|
146
|
+
cook_time: cooking_time
|
147
|
+
}
|
148
|
+
rescue
|
149
|
+
raise "Error getting recipe"
|
150
|
+
end
|
101
151
|
end
|
102
152
|
|
103
153
|
end
|
@@ -1,99 +1,93 @@
|
|
1
1
|
module URLHelper
|
2
|
+
COURSES = {
|
3
|
+
"bread"=> "bread",
|
4
|
+
"appetizer"=> "appetizers-and-snacks",
|
5
|
+
"breakfast"=> "breakfast-and-brunch",
|
6
|
+
"dessert"=> "desserts",
|
7
|
+
"drink"=> "drinks",
|
8
|
+
"main"=> "main-dish",
|
9
|
+
"salad"=> "salad",
|
10
|
+
"side"=> "side-dish",
|
11
|
+
"soup"=> "soups-stews-and-chili",
|
12
|
+
"fruit"=> "fruits-and-vegetables",
|
13
|
+
"herbs"=> "herbs-and-spices",
|
14
|
+
"meat"=> "meat-and-poultry",
|
15
|
+
"pasta"=> "pasta",
|
16
|
+
"seafood"=> "seafood",
|
17
|
+
"wholegrains"=> "whole-grains"
|
18
|
+
}
|
2
19
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
20
|
+
REGIONS = {
|
21
|
+
"asian"=> "asian",
|
22
|
+
"chinese" => "asian/chinese",
|
23
|
+
"thai" => "asian/thai",
|
24
|
+
"japanese" => "asian/japanese",
|
25
|
+
"filipino" => "asian/filipino",
|
26
|
+
"korean" => "asian/korean",
|
27
|
+
"vietnamese" => "asian/vietnamese",
|
28
|
+
"malaysian" => "asian/malaysian",
|
29
|
+
"pakistani" => "asian/pakistani",
|
30
|
+
"indonesian" => "asian/indonesian",
|
31
|
+
"iranian" => "asian/iranian",
|
32
|
+
"bangladeshi" => "asian/bangladeshi",
|
33
|
+
"indian" => "asian/indian",
|
11
34
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
"breakfast"=> "breakfast-and-brunch",
|
18
|
-
"dessert"=> "desserts",
|
19
|
-
"drink"=> "drinks",
|
20
|
-
"main"=> "main-dish",
|
21
|
-
"salad"=> "salad",
|
22
|
-
"side"=> "side-dish",
|
23
|
-
"soup"=> "soups-stews-and-chili",
|
24
|
-
"fruit"=> "fruits-and-vegetables",
|
25
|
-
"herbs"=> "herbs-and-spices",
|
26
|
-
"meat"=> "meat-and-poultry",
|
27
|
-
"pasta"=> "pasta",
|
28
|
-
"seafood"=> "seafood",
|
29
|
-
"wholegrains"=> "whole-grains"
|
30
|
-
}
|
31
|
-
end
|
35
|
+
"african"=> "african",
|
36
|
+
"african_main"=> "african/main-dishes",
|
37
|
+
"moroccan"=> "african/moroccan",
|
38
|
+
"south_african"=> "african/south-african",
|
39
|
+
"egyptian"=> "african/egyptian",
|
32
40
|
|
33
|
-
|
34
|
-
begin
|
35
|
-
"http://allrecipes.com/recipes/world-cuisine/" + regions[region_type]
|
36
|
-
rescue Exception => e
|
37
|
-
puts e.message
|
38
|
-
puts e.backtrace.inspect
|
39
|
-
end
|
40
|
-
end
|
41
|
+
"australian"=> "australian-and-new-zealander",
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
"thai" => "asian/thai",
|
47
|
-
"japanese" => "asian/japanese",
|
48
|
-
"filipino" => "asian/filipino",
|
49
|
-
"korean" => "asian/korean",
|
50
|
-
"vietnamese" => "asian/vietnamese",
|
51
|
-
"malaysian" => "asian/malaysian",
|
52
|
-
"pakistani" => "asian/pakistani",
|
53
|
-
"indonesian" => "asian/indonesian",
|
54
|
-
"iranian" => "asian/iranian",
|
55
|
-
"bangladeshi" => "asian/bangladeshi",
|
56
|
-
"indian" => "asian/indian",
|
43
|
+
"canadian"=> "canadian",
|
44
|
+
"vancouver" => "canadian/vancouver",
|
45
|
+
"toronto" => "canadian/toronto",
|
46
|
+
"quebec" => "canadian/quebec-recipes",
|
57
47
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
48
|
+
"european"=> "european",
|
49
|
+
"italian"=> "european/italian",
|
50
|
+
"uk"=> "european/uk-and-ireland",
|
51
|
+
"french"=> "european/french",
|
52
|
+
"greek"=> "european/greek",
|
53
|
+
"eastern_european"=> "european/eastern-european",
|
54
|
+
"german"=> "european/german",
|
55
|
+
"scandinavian"=> "european/scandinavian",
|
56
|
+
"spanish"=> "european/spanish",
|
57
|
+
"portuguese"=> "european/portuguese",
|
58
|
+
"dutch"=> "european/dutch",
|
59
|
+
"austrian"=> "european/austrian",
|
60
|
+
"swiss"=> "european/swiss",
|
61
|
+
"belgian"=> "european/belgian",
|
63
62
|
|
64
|
-
|
63
|
+
"latin_american"=> "latin-american",
|
64
|
+
"mexican" => "latin-american/mexican",
|
65
|
+
"caribbean" => "latin-american/caribbean",
|
66
|
+
"south_american" => "latin-american/south-american",
|
65
67
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
"middle_eastern"=> "middle-eastern",
|
69
|
+
"lebanese" => "middle-eastern/lebanese",
|
70
|
+
"turkish" => "middle-eastern/turkish",
|
71
|
+
"israeli" => "middle-eastern/israeli",
|
70
72
|
|
71
|
-
|
72
|
-
"italian"=> "european/italian",
|
73
|
-
"uk"=> "european/uk-and-ireland",
|
74
|
-
"french"=> "european/french",
|
75
|
-
"greek"=> "european/greek",
|
76
|
-
"eastern_european"=> "european/eastern-european",
|
77
|
-
"german"=> "european/german",
|
78
|
-
"scandinavian"=> "european/scandinavian",
|
79
|
-
"spanish"=> "european/spanish",
|
80
|
-
"portuguese"=> "european/portuguese",
|
81
|
-
"dutch"=> "european/dutch",
|
82
|
-
"austrian"=> "european/austrian",
|
83
|
-
"swiss"=> "european/swiss",
|
84
|
-
"belgian"=> "european/belgian",
|
73
|
+
}
|
85
74
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
75
|
+
def course_base_url(course_type)
|
76
|
+
"http://allrecipes.com/recipes/" + COURSES[course_type]
|
77
|
+
end
|
78
|
+
|
79
|
+
def region_base_url(region_type)
|
80
|
+
"http://allrecipes.com/recipes/world-cuisine/" + REGIONS[region_type]
|
81
|
+
end
|
90
82
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
83
|
+
def recipes_url(type, options)
|
84
|
+
base = send("#{options[:url_type]}_base_url", type)
|
85
|
+
filters = recipe_filters(options)
|
86
|
+
[base, filters].join
|
87
|
+
end
|
95
88
|
|
96
|
-
|
89
|
+
def recipe_filters(options)
|
90
|
+
"?page=#{options[:page]}&st=#{search_sort_parameter(options[:sort_by])}"
|
97
91
|
end
|
98
92
|
|
99
93
|
def search_sort_parameter(sort_type)
|
data/lib/allrecipes/version.rb
CHANGED
data/spec/allrecipes_spec.rb
CHANGED
@@ -41,7 +41,7 @@ describe Allrecipes do
|
|
41
41
|
context "non existent course" do
|
42
42
|
let(:nonexistent_course) { -> { subject.course("nonexistent") } }
|
43
43
|
it "should give appropriate error message" do
|
44
|
-
expect(nonexistent_course).to raise_error("Course
|
44
|
+
expect(nonexistent_course).to raise_error("Course doesn't exist")
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -107,7 +107,7 @@ describe Allrecipes do
|
|
107
107
|
expect(@recipes.count).to eq 21
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
it "should include a recipe with specified ingredient" do
|
111
111
|
expect(@recipes.first[:ingredients].select{ |ingredient| ingredient["name"].include?("apples") }.count).to eq 1
|
112
112
|
end
|
113
113
|
|
@@ -121,4 +121,72 @@ describe Allrecipes do
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
+
describe "#recipe_url" do
|
125
|
+
context "correct url" do
|
126
|
+
before do
|
127
|
+
VCR.use_cassette "recipe_url" do
|
128
|
+
@recipe = subject.recipe_url("http://allrecipes.com/Recipe/Mushrooms-with-a-Soy-Sauce-Glaze")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it "requests the correct url" do
|
133
|
+
expect(a_request(:get, "http://allrecipes.com/Recipe/Mushrooms-with-a-Soy-Sauce-Glaze")).to have_been_made
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should return a formatted recipe" do
|
137
|
+
expected_output = {
|
138
|
+
name: @recipe[:name],
|
139
|
+
image: @recipe[:image],
|
140
|
+
servings: @recipe[:servings],
|
141
|
+
ingredients: @recipe[:ingredients],
|
142
|
+
directions: @recipe[:directions],
|
143
|
+
rating: @recipe[:rating],
|
144
|
+
prep_time: @recipe[:prep_time],
|
145
|
+
cook_time: @recipe[:cook_time]
|
146
|
+
}
|
147
|
+
expect(@recipe).to eq expected_output
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "invalid url" do
|
152
|
+
let(:invalid_allrecipes_url) { -> { subject.recipe_url("http://allrecipes.com") } }
|
153
|
+
it "should give appropriate error message" do
|
154
|
+
expect(invalid_allrecipes_url).to raise_error("This page does not contain a recipe")
|
155
|
+
end
|
156
|
+
|
157
|
+
let(:invalid_url) { -> { subject.recipe_url("invalid") } }
|
158
|
+
it "should give appropriate error message" do
|
159
|
+
expect(invalid_url).to raise_error("This page does not contain a recipe")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "#page_url" do
|
165
|
+
context "correct url" do
|
166
|
+
before do
|
167
|
+
VCR.use_cassette "recipes_from_page" do
|
168
|
+
@recipes = subject.page_url("http://allrecipes.com/recipes?st=n&Page=7")
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
it "requests the correct URL" do
|
173
|
+
expect(a_request(:get, "http://allrecipes.com/recipes?st=n&Page=7")).to have_been_made
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should have the right count of recipes" do
|
177
|
+
expect(@recipes.count).to eq 20
|
178
|
+
end
|
179
|
+
end
|
180
|
+
context "invalid url" do
|
181
|
+
let(:invalid_allrecipes_url) { -> { subject.page_url("http://allrecipes.com") } }
|
182
|
+
it "should give appropriate error message" do
|
183
|
+
expect(invalid_allrecipes_url).to raise_error("This page does not contain recipes")
|
184
|
+
end
|
185
|
+
|
186
|
+
let(:invalid_url) { -> { subject.page_url("invalid") } }
|
187
|
+
it "should give appropriate error message" do
|
188
|
+
expect(invalid_url).to raise_error("This page does not contain recipes")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
124
192
|
end
|
data/spec/recipe_filter_spec.rb
CHANGED
@@ -47,7 +47,7 @@ describe Allrecipes do
|
|
47
47
|
expect(a_request(:get, "http://allrecipes.com/search/?wt=apples&page=5&sb=re")).to have_been_made
|
48
48
|
end
|
49
49
|
|
50
|
-
|
50
|
+
it "should be different from the initial page" do
|
51
51
|
expect(@all_recipes).to_not eq @all_recipes_initial
|
52
52
|
expect(@region_recipes).to_not eq @region_recipes_initial
|
53
53
|
expect(@course_recipes).to_not eq @course_recipes_initial
|
@@ -117,7 +117,7 @@ describe Allrecipes do
|
|
117
117
|
expect(@ingredient_recipes.count).to eq 21
|
118
118
|
end
|
119
119
|
|
120
|
-
|
120
|
+
it "should have default search sorted bsorted by popularity" do
|
121
121
|
expect(@all_recipes).to eq @all_recipes_initial
|
122
122
|
expect(@region_recipes).to eq @region_recipes_initial
|
123
123
|
expect(@course_recipes).to eq @course_recipes_initial
|
@@ -202,7 +202,7 @@ describe Allrecipes do
|
|
202
202
|
it "should be the same as default search" do
|
203
203
|
recipe_names = @ingredient_recipes.map{ |ing| ing[:name] }.sort
|
204
204
|
initial_recipe_names = @ingredient_recipes_initial.map{ |ing| ing[:name] }.sort
|
205
|
-
expect(recipe_names).to eq initial_recipe_names
|
205
|
+
expect(recipe_names).to eq initial_recipe_names
|
206
206
|
end
|
207
207
|
end
|
208
208
|
context "Rating sort for ingredient search" do
|
data/spec/recipe_parser_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
describe RecipeParser do
|
3
3
|
before do
|
4
4
|
VCR.use_cassette "recipe" do
|
5
|
-
url = "/Recipe/Worlds-Best-Lasagna/"
|
5
|
+
url = "http://allrecipes.com/Recipe/Worlds-Best-Lasagna/"
|
6
6
|
@recipe = RecipeParser.new(url).recipe
|
7
7
|
end
|
8
8
|
end
|
@@ -19,6 +19,18 @@ describe RecipeParser do
|
|
19
19
|
expect(@recipe[:servings]).to eq 12
|
20
20
|
end
|
21
21
|
|
22
|
+
it "should have the right rating" do
|
23
|
+
expect(@recipe[:rating]).to eq 5
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should have the right prep time" do
|
27
|
+
expect(@recipe[:prep_time]).to eq 30
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have the right cook time" do
|
31
|
+
expect(@recipe[:cook_time]).to eq 150
|
32
|
+
end
|
33
|
+
|
22
34
|
context "ingredients" do
|
23
35
|
|
24
36
|
it "should have the right amount of ingredients" do
|
@@ -46,7 +58,10 @@ describe RecipeParser do
|
|
46
58
|
image: @recipe[:image],
|
47
59
|
servings: @recipe[:servings],
|
48
60
|
ingredients: @recipe[:ingredients],
|
49
|
-
directions: @recipe[:directions]
|
61
|
+
directions: @recipe[:directions],
|
62
|
+
rating: @recipe[:rating],
|
63
|
+
prep_time: @recipe[:prep_time],
|
64
|
+
cook_time: @recipe[:cook_time]
|
50
65
|
}
|
51
66
|
expect(@recipe).to eq expected_output
|
52
67
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: allrecipes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- shivamd
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|
@@ -117,6 +117,7 @@ extensions: []
|
|
117
117
|
extra_rdoc_files: []
|
118
118
|
files:
|
119
119
|
- .gitignore
|
120
|
+
- .travis.yml
|
120
121
|
- Gemfile
|
121
122
|
- LICENSE.txt
|
122
123
|
- README.md
|