emeals 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/lib/emeals/dish.rb +6 -6
- data/lib/emeals/meal.rb +107 -85
- data/lib/emeals/menu.rb +27 -15
- data/lib/emeals/version.rb +1 -1
- data/spec/client_spec.rb +1 -76
- data/spec/fixtures/meal.erb +31 -0
- data/spec/meal_parser_spec.rb +103 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/templates.rb +29 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88f64929d0e17e3a429aef954e2508bf354afb6c
|
4
|
+
data.tar.gz: 7811beff315cd7d5b8a06720f1b696611f4a1658
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba0a4c7c3ea79ba9a535569d33b97ac40429341d4fa219f908e02a35dd068c8852469486d0537e87e2845f521abf33a14b15e0127da7a0dd75849bea44083e1f
|
7
|
+
data.tar.gz: 9056e857a31afc51ad2ac0429a26c6f70a3ed51566c7d0097b2dc560c36c3426632a4a0054546d63f949b7e2ac090223d3e3557cd691c9fbebac3729eae1f547
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.0
|
1
|
+
2.0.0-p0
|
data/lib/emeals/dish.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
class Emeals::Dish
|
4
|
-
|
4
|
+
attr_reader :name, :ingredients, :instructions
|
5
5
|
|
6
|
-
def initialize(name)
|
6
|
+
def initialize(name, ingredients = [], instructions = [])
|
7
7
|
@name = name
|
8
|
-
@ingredients =
|
9
|
-
@instructions =
|
8
|
+
@ingredients = ingredients
|
9
|
+
@instructions = instructions
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -37,7 +37,7 @@ class Emeals::Quantity
|
|
37
37
|
end
|
38
38
|
|
39
39
|
class Emeals::Ingredient
|
40
|
-
|
40
|
+
attr_reader :quantity, :description
|
41
41
|
|
42
42
|
def initialize(amount, unit, description)
|
43
43
|
@quantity = Emeals::Quantity.new(amount, unit)
|
@@ -58,4 +58,4 @@ class Emeals::Ingredient
|
|
58
58
|
def ==(other)
|
59
59
|
other.quantity == @quantity && other.description == @description
|
60
60
|
end
|
61
|
-
end
|
61
|
+
end
|
data/lib/emeals/meal.rb
CHANGED
@@ -5,98 +5,81 @@ require 'emeals/dish'
|
|
5
5
|
class Emeals::Meal
|
6
6
|
attr_reader :entree, :side, :flags, :times
|
7
7
|
|
8
|
-
def initialize(entree = nil, side = nil)
|
8
|
+
def initialize(entree = nil, side = nil, flags = [], times = {})
|
9
9
|
@entree = entree
|
10
10
|
@side = side
|
11
|
-
@flags =
|
12
|
-
@times =
|
11
|
+
@flags = flags
|
12
|
+
@times = times
|
13
13
|
end
|
14
14
|
|
15
|
-
def parse
|
16
|
-
|
17
|
-
names = []
|
18
|
-
entree_instructions = []
|
19
|
-
side_instructions = []
|
20
|
-
meal_text.split("\n").each do |line|
|
21
|
-
case parse_state
|
22
|
-
when :header
|
23
|
-
parse_flags(line)
|
24
|
-
parse_state = :names
|
25
|
-
when :names
|
26
|
-
if line =~ /Prep Cook Total/
|
27
|
-
entree_name, side_name = separate_entree_and_side_names(names)
|
28
|
-
@entree = Emeals::Dish.new(entree_name)
|
29
|
-
@side = Emeals::Dish.new(side_name)
|
30
|
-
parse_state = :times
|
31
|
-
else
|
32
|
-
names << line
|
33
|
-
end
|
34
|
-
when :times
|
35
|
-
parse_times(line)
|
36
|
-
parse_state = :entree_ingredients
|
37
|
-
when :entree_ingredients
|
38
|
-
if line.include? "-------"
|
39
|
-
parse_state = :side_ingredients
|
40
|
-
else
|
41
|
-
add_ingredients_to_dish(line, @entree)
|
42
|
-
end
|
43
|
-
when :side_ingredients
|
44
|
-
if line =~ /^[A-Z]/
|
45
|
-
entree_instructions << line
|
46
|
-
parse_state = :entree_instructions
|
47
|
-
else
|
48
|
-
add_ingredients_to_dish(line, @side)
|
49
|
-
end
|
50
|
-
when :entree_instructions
|
51
|
-
if line.include? "-------"
|
52
|
-
add_instructions_to_dish(entree_instructions, @entree)
|
53
|
-
parse_state = :side_instructions
|
54
|
-
else
|
55
|
-
entree_instructions << line
|
56
|
-
end
|
57
|
-
when :side_instructions
|
58
|
-
if line =~ /^Copyright/
|
59
|
-
side_instructions = side_instructions[0..-3]
|
60
|
-
break
|
61
|
-
else
|
62
|
-
side_instructions << line
|
63
|
-
end
|
64
|
-
else
|
65
|
-
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
add_instructions_to_dish(side_instructions, @side)
|
70
|
-
self
|
15
|
+
def self.parse(meal_text)
|
16
|
+
Emeals::MealParser.new(meal_text).parse
|
71
17
|
end
|
72
18
|
|
73
19
|
FLAGS = {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
20
|
+
"Slow Cooker" => :slow_cooker,
|
21
|
+
"On the Grill" => :on_the_grill,
|
22
|
+
"Super Fast" => :super_fast,
|
23
|
+
"Marinate Ahead" => :marinate_ahead
|
78
24
|
}
|
79
25
|
|
80
|
-
|
26
|
+
FLAGS.values.each do |flag|
|
81
27
|
define_method "#{flag}?" do
|
82
|
-
@flags.include? flag
|
28
|
+
@flags.include? flag
|
83
29
|
end
|
84
30
|
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Emeals::MealParser
|
34
|
+
def initialize(meal_text)
|
35
|
+
@meal_text = meal_text
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse
|
39
|
+
entree_name = side_name = flags = times = nil
|
40
|
+
names = entree_ingredients = side_ingredients = []
|
41
|
+
parse_state = :header
|
42
|
+
entree_instructions = []
|
43
|
+
side_instructions = []
|
44
|
+
@meal_text.split("\n").each do |line|
|
45
|
+
case parse_state
|
46
|
+
when :header
|
47
|
+
flags, parse_state = parse_flags(line)
|
48
|
+
when :names
|
49
|
+
entree_name, side_name, names, parse_state = parse_names(line, names)
|
50
|
+
when :times
|
51
|
+
times, parse_state = parse_times(line)
|
52
|
+
when :entree_ingredients
|
53
|
+
entree_ingredients, parse_state = parse_entree_ingredients(line, entree_ingredients)
|
54
|
+
when :side_ingredients
|
55
|
+
side_ingredients, entree_instructions, parse_state = parse_side_ingredients(line, side_ingredients)
|
56
|
+
when :entree_instructions
|
57
|
+
entree_instructions, parse_state = parse_entree_instructions(line, entree_instructions)
|
58
|
+
when :side_instructions
|
59
|
+
side_instructions, parse_state = parse_side_instructions(line, side_instructions)
|
60
|
+
else
|
61
|
+
break
|
62
|
+
end
|
63
|
+
end
|
64
|
+
entree = Emeals::Dish.new(entree_name, entree_ingredients, format_instructions(entree_instructions))
|
65
|
+
side = Emeals::Dish.new(side_name, side_ingredients, format_instructions(side_instructions))
|
66
|
+
Emeals::Meal.new(entree, side, flags, times)
|
67
|
+
end
|
85
68
|
|
86
69
|
private
|
87
70
|
|
88
71
|
def separate_entree_and_side_names(names)
|
89
72
|
case names.size
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
else
|
96
|
-
[names[0], join_names(names[1..2])]
|
97
|
-
end
|
73
|
+
when 2
|
74
|
+
names
|
75
|
+
when 3
|
76
|
+
if names[1].length < names[0].length
|
77
|
+
[join_names(names[0..1]), names[2]]
|
98
78
|
else
|
99
|
-
[
|
79
|
+
[names[0], join_names(names[1..2])]
|
80
|
+
end
|
81
|
+
else
|
82
|
+
[join_names(names[0..1]), join_names(names[2..-1])]
|
100
83
|
end
|
101
84
|
end
|
102
85
|
|
@@ -105,31 +88,70 @@ class Emeals::Meal
|
|
105
88
|
end
|
106
89
|
|
107
90
|
def parse_flags(line)
|
108
|
-
FLAGS.
|
109
|
-
|
91
|
+
[Emeals::Meal::FLAGS.select {|flag, sym| line.include? flag }.values, :names]
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse_names(line, names)
|
95
|
+
if line =~ /Prep Cook Total/
|
96
|
+
entree_name, side_name = separate_entree_and_side_names(names)
|
97
|
+
[entree_name, side_name, nil, :times]
|
98
|
+
else
|
99
|
+
[nil, nil, names + [line], :names]
|
110
100
|
end
|
111
101
|
end
|
112
102
|
|
113
103
|
def parse_times(line)
|
114
104
|
times = line.split(" ")
|
115
|
-
|
116
|
-
|
117
|
-
|
105
|
+
[{prep: times.first, cook: times[1], total: times[2..-1].join(" ")}, :entree_ingredients]
|
106
|
+
end
|
107
|
+
|
108
|
+
def parse_entree_ingredients(line, ingredients)
|
109
|
+
if line.include? "-------"
|
110
|
+
[ingredients, :side_ingredients]
|
111
|
+
else
|
112
|
+
[find_ingredients(ingredients, line), :entree_ingredients]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def parse_side_ingredients(line, ingredients)
|
117
|
+
if line =~ /^[A-Z]/
|
118
|
+
[ingredients, [line], :entree_instructions]
|
119
|
+
else
|
120
|
+
[find_ingredients(ingredients, line), nil, :side_ingredients]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def parse_entree_instructions(line, instructions)
|
125
|
+
if line.include? "-------"
|
126
|
+
[instructions, :side_instructions]
|
127
|
+
else
|
128
|
+
[instructions + [line], :entree_instructions]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def parse_side_instructions(line, instructions)
|
133
|
+
if line =~ /^Copyright/
|
134
|
+
[instructions[0..-3], nil]
|
135
|
+
else
|
136
|
+
[instructions + [line], :side_instructions]
|
137
|
+
end
|
118
138
|
end
|
119
139
|
|
120
140
|
INGREDIENT_REGEX = /(?:\d|\xC2\xBC|\xC2\xBD)+ .+?(?=, (?:\d|\xC2\xBC|\xC2\xBD)+|$)/
|
121
141
|
|
122
|
-
def
|
142
|
+
def find_ingredients(ingredients, line)
|
123
143
|
if line =~ /^\d|\xC2\xBC|\xC2\xBD/
|
124
|
-
line.scan(INGREDIENT_REGEX).
|
125
|
-
|
144
|
+
ingredients + line.scan(INGREDIENT_REGEX).map do |match|
|
145
|
+
Emeals::Ingredient.parse(match)
|
126
146
|
end
|
127
147
|
else
|
128
|
-
|
148
|
+
# TODO we shouldn't be modifying this in-place
|
149
|
+
ingredients.last.description << " #{line}"
|
150
|
+
ingredients
|
129
151
|
end
|
130
152
|
end
|
131
153
|
|
132
|
-
def
|
133
|
-
|
154
|
+
def format_instructions(instructions)
|
155
|
+
instructions.join(" ").split(/\. ?/)
|
134
156
|
end
|
135
157
|
end
|
data/lib/emeals/menu.rb
CHANGED
@@ -1,34 +1,46 @@
|
|
1
1
|
require 'emeals/meal'
|
2
2
|
|
3
3
|
class Emeals::Menu
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :meals
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
@
|
8
|
-
@meals = []
|
6
|
+
def initialize(meals)
|
7
|
+
@meals = meals
|
9
8
|
end
|
10
9
|
|
11
|
-
def
|
10
|
+
def count
|
11
|
+
@meals.size
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parse(menu_text)
|
15
|
+
Emeals::MenuParser.new(menu_text).parse
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Emeals::MenuParser
|
20
|
+
def initialize(menu_text)
|
21
|
+
@menu_text = menu_text
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse
|
12
25
|
buffer = []
|
26
|
+
meals = []
|
13
27
|
add_to_buffer = false
|
14
|
-
|
28
|
+
|
29
|
+
@menu_text.split("\n").each do |line|
|
15
30
|
if line =~ /Meal (\d+)/
|
16
|
-
|
17
|
-
|
18
|
-
@meals << Emeals::Meal.new.parse!(buffer.join("\n"))
|
31
|
+
if add_to_buffer and !buffer.empty?
|
32
|
+
meals << Emeals::Meal.parse(buffer.join("\n"))
|
19
33
|
end
|
20
34
|
|
21
|
-
add_to_buffer =
|
35
|
+
add_to_buffer = meals.size < $1.to_i
|
22
36
|
buffer = add_to_buffer ? [line] : []
|
23
37
|
next unless add_to_buffer
|
24
38
|
else
|
25
39
|
buffer << line if add_to_buffer
|
26
40
|
end
|
27
41
|
end
|
28
|
-
self
|
29
|
-
end
|
30
42
|
|
31
|
-
|
32
|
-
new.parse!(menu_text)
|
43
|
+
Emeals::Menu.new(meals)
|
33
44
|
end
|
34
|
-
end
|
45
|
+
end
|
46
|
+
|
data/lib/emeals/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -22,80 +22,7 @@ describe Emeals::Client do
|
|
22
22
|
expect(@menu.count).to eq 7
|
23
23
|
end
|
24
24
|
|
25
|
-
describe "entree names" do
|
26
|
-
it "reads the names of entrees when the side wraps to two lines" do
|
27
|
-
expect(@meals[5].entree.name).to eq "Baked Cod Provencal"
|
28
|
-
end
|
29
|
-
|
30
|
-
it "reads the names of entrees which wrap to two lines" do
|
31
|
-
expect(@meals.first.entree.name).to eq "Spicy Sausage and Egg Scramble"
|
32
|
-
end
|
33
|
-
|
34
|
-
it "reads the names of entrees when both the side and entree wrap to two lines" do
|
35
|
-
expect(@meals.last.entree.name).to eq "Peppery Grilled Ribeye Steaks"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe "side names" do
|
40
|
-
it "reads the names of sides that are a single line" do
|
41
|
-
expect(@meals.first.side.name).to eq "Oregano Roasted Zucchini"
|
42
|
-
end
|
43
|
-
|
44
|
-
it "reads the names of sides that wrap to two lines" do
|
45
|
-
expect(@meals[5].side.name).to eq "Roasted Asparagus with Sun-Dried Tomatoes"
|
46
|
-
end
|
47
|
-
|
48
|
-
it "reads the names of sides when both the side and entree wrap to two lines" do
|
49
|
-
expect(@meals.last.side.name).to eq "Heirloom Tomato and Spinach Salad"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "flags" do
|
54
|
-
it "reads a meal with no flags correctly" do
|
55
|
-
expect(@meals.first.flags).to be_empty
|
56
|
-
end
|
57
|
-
|
58
|
-
it "reads the slow cooker flag correctly" do
|
59
|
-
expect(@meals[1].flags).to eq [:slow_cooker]
|
60
|
-
expect(@meals[1]).to be_slow_cooker
|
61
|
-
end
|
62
|
-
|
63
|
-
it "reads the on the grill flag correctly" do
|
64
|
-
expect(@meals[3].flags).to eq [:on_the_grill]
|
65
|
-
expect(@meals[3]).to be_on_the_grill
|
66
|
-
end
|
67
|
-
|
68
|
-
it "reads the super fast flag correctly" do
|
69
|
-
expect(@meals[5].flags).to eq [:super_fast]
|
70
|
-
expect(@meals[5]).to be_super_fast
|
71
|
-
end
|
72
|
-
|
73
|
-
it "reads the marinate ahead flag correctly" do
|
74
|
-
expect(@meals[6].flags).to eq [:marinate_ahead]
|
75
|
-
expect(@meals[6]).to be_marinate_ahead
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe "times" do
|
80
|
-
it "reads prep times correctly" do
|
81
|
-
expect(@meals.first.times[:prep]).to eq "10m"
|
82
|
-
expect(@meals[5].times[:prep]).to eq "15m"
|
83
|
-
end
|
84
|
-
|
85
|
-
it "reads cook times correctly" do
|
86
|
-
expect(@meals.first.times[:cook]).to eq "20m"
|
87
|
-
expect(@meals[1].times[:cook]).to eq "4h"
|
88
|
-
end
|
89
|
-
|
90
|
-
it "reads total times correctly" do
|
91
|
-
expect(@meals.first.times[:total]).to eq "30m"
|
92
|
-
expect(@meals[1].times[:total]).to eq "4h 10m"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
25
|
describe "entree ingredients" do
|
97
|
-
include Emeals
|
98
|
-
|
99
26
|
let(:dish) { @meals.first.entree }
|
100
27
|
|
101
28
|
it "reads the correct number of ingredients" do
|
@@ -116,8 +43,6 @@ describe Emeals::Client do
|
|
116
43
|
end
|
117
44
|
|
118
45
|
describe "side ingredients" do
|
119
|
-
include Emeals
|
120
|
-
|
121
46
|
let(:dish) { @meals[3].side }
|
122
47
|
|
123
48
|
it "reads the correct number of ingredients" do
|
@@ -176,4 +101,4 @@ describe Emeals::Client do
|
|
176
101
|
end
|
177
102
|
end
|
178
103
|
end
|
179
|
-
end
|
104
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Meal 1 <%= @flags %>
|
2
|
+
<%= @entree %>
|
3
|
+
<%= @side %>
|
4
|
+
Prep Cook Total
|
5
|
+
<%= [@prep_time, @cook_time, @total_time].join(" ") %>
|
6
|
+
¼ lb ground pork sausage
|
7
|
+
½ small onion, minced
|
8
|
+
<%= "#{@entree_ingredients}\n" unless @entree_ingredients == "" -%>
|
9
|
+
4 large eggs, lightly beaten
|
10
|
+
¼ teaspoon kosher salt, ¼ teaspoon pepper
|
11
|
+
---------------------------------------------------------------
|
12
|
+
1 lb fresh zucchini, trimmed and thinly sliced
|
13
|
+
1 tablespoon chopped fresh oregano
|
14
|
+
<%= "#{@side_ingredients}\n" unless @side_ingredients == "" -%>
|
15
|
+
1 tablespoon olive oil
|
16
|
+
¼ teaspoon kosher salt, ¼ teaspoon pepper
|
17
|
+
Heat a nonstick skillet over medium-high heat.
|
18
|
+
Add sausage to pan; cook 6 minutes or until
|
19
|
+
done. Drain on a paper towel-lined plate,
|
20
|
+
reserving 1 tablespoon drippings in pan. <%= "#{@entree_instructions} " unless @entree_instructions == "" %>Add
|
21
|
+
onion to pan over medium heat. Cook 3
|
22
|
+
minutes or until lightly browned. Add eggs; cook
|
23
|
+
2 minutes, stirring constantly. Stir in sausage,
|
24
|
+
salt and pepper; cook until eggs are thickened
|
25
|
+
and set. Note: Remaining pork sausage can be
|
26
|
+
frozen for up to 2 months.
|
27
|
+
---------------------------------------------------------------
|
28
|
+
Preheat oven to 425 degrees. Toss zucchini,
|
29
|
+
oregano, oil, salt and pepper in a large roasting
|
30
|
+
pan. <%= "#{@side_instructions} " unless @side_instructions == "" %>Bake 20 minutes or until just tender.
|
31
|
+
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'emeals/meal'
|
4
|
+
|
5
|
+
describe Emeals::MealParser do
|
6
|
+
describe "entree names" do
|
7
|
+
let(:entree1) { make_meal(entree: 'Baked Cod Provencal').entree.name }
|
8
|
+
let(:entree2) { make_meal(entree: 'Baked Cod Provencal',
|
9
|
+
side: "A Side That Wraps Onto\nTwo Lines").entree.name }
|
10
|
+
let(:entree3) { make_meal.entree.name }
|
11
|
+
let(:entree4) { make_meal(side: "A Side That Wraps Onto\nTwo Lines").entree.name }
|
12
|
+
|
13
|
+
it "reads the names of entrees when entree and side are single-line" do
|
14
|
+
expect(entree1).to eq "Baked Cod Provencal"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "reads the names of entrees when the side wraps to two lines" do
|
18
|
+
expect(entree2).to eq "Baked Cod Provencal"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "reads the names of entrees which wrap to two lines" do
|
22
|
+
expect(entree3).to eq "Spicy Sausage and Egg Scramble"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "reads the names of entrees when both the side and entree wrap to two lines" do
|
26
|
+
expect(entree4).to eq "Spicy Sausage and Egg Scramble"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "side names" do
|
31
|
+
let(:side1) { make_meal(entree: 'Baked Cod Provencal').side.name }
|
32
|
+
let(:side2) { make_meal.side.name }
|
33
|
+
let(:side3) { make_meal(entree: 'Baked Cod Provencal',
|
34
|
+
side: "A Side That Wraps Onto\nTwo Lines").side.name }
|
35
|
+
let(:side4) { make_meal(side: "A Side That Wraps Onto\nTwo Lines").side.name }
|
36
|
+
|
37
|
+
it "reads the names of sides when entree and side are single-line" do
|
38
|
+
expect(side1).to eq "Oregano Roasted Zucchini"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "reads the names of sides when the side wraps to two lines" do
|
42
|
+
expect(side2).to eq "Oregano Roasted Zucchini"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "reads the names of sides which wrap to two lines" do
|
46
|
+
expect(side3).to eq "A Side That Wraps Onto Two Lines"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "reads the names of sides when both the side and entree wrap to two lines" do
|
50
|
+
expect(side4).to eq "A Side That Wraps Onto Two Lines"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "flags" do
|
55
|
+
let(:slow_cooker) { make_meal flags: "Slow Cooker" }
|
56
|
+
let(:on_the_grill) { make_meal flags: "On the Grill" }
|
57
|
+
let(:super_fast) { make_meal flags: "Super Fast" }
|
58
|
+
let(:marinate_ahead) { make_meal flags: "Marinate Ahead" }
|
59
|
+
|
60
|
+
it "reads the slow cooker flag correctly" do
|
61
|
+
expect(slow_cooker.flags).to eq [:slow_cooker]
|
62
|
+
expect(slow_cooker).to be_slow_cooker
|
63
|
+
end
|
64
|
+
|
65
|
+
it "reads the on the grill flag correctly" do
|
66
|
+
expect(on_the_grill.flags).to eq [:on_the_grill]
|
67
|
+
expect(on_the_grill).to be_on_the_grill
|
68
|
+
end
|
69
|
+
|
70
|
+
it "reads the super fast flag correctly" do
|
71
|
+
expect(super_fast.flags).to eq [:super_fast]
|
72
|
+
expect(super_fast).to be_super_fast
|
73
|
+
end
|
74
|
+
|
75
|
+
it "reads the marinate ahead flag correctly" do
|
76
|
+
expect(marinate_ahead.flags).to eq [:marinate_ahead]
|
77
|
+
expect(marinate_ahead).to be_marinate_ahead
|
78
|
+
end
|
79
|
+
|
80
|
+
it "reads a meal with no flags correctly" do
|
81
|
+
expect(make_meal.flags).to eq []
|
82
|
+
expect(make_meal).to_not be_slow_cooker
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "times" do
|
87
|
+
it "reads prep times correctly" do
|
88
|
+
expect(make_meal.times[:prep]).to eq "10m"
|
89
|
+
expect(make_meal(prep_time: "15m").times[:prep]).to eq "15m"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "reads cook times correctly" do
|
93
|
+
expect(make_meal.times[:cook]).to eq "20m"
|
94
|
+
expect(make_meal(cook_time: "4h").times[:cook]).to eq "4h"
|
95
|
+
end
|
96
|
+
|
97
|
+
it "reads total times correctly" do
|
98
|
+
expect(make_meal.times[:total]).to eq "30m"
|
99
|
+
expect(make_meal(total_time: "4h 10m").times[:total]).to eq "4h 10m"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -4,6 +4,9 @@
|
|
4
4
|
# loaded once.
|
5
5
|
#
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each {|f| require f}
|
9
|
+
|
7
10
|
RSpec.configure do |config|
|
8
11
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
12
|
config.run_all_when_everything_filtered = true
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'emeals'
|
2
|
+
|
3
|
+
TEMPLATE_DIR = File.join(File.dirname(__FILE__), '..', 'fixtures')
|
4
|
+
|
5
|
+
DEFAULT_MEAL_OPTIONS = {
|
6
|
+
entree: "Spicy Sausage and Egg\nScramble",
|
7
|
+
side: "Oregano Roasted Zucchini",
|
8
|
+
flags: "",
|
9
|
+
prep_time: '10m',
|
10
|
+
cook_time: '20m',
|
11
|
+
total_time: '30m',
|
12
|
+
entree_ingredients: "",
|
13
|
+
side_ingredients: "",
|
14
|
+
entree_instructions: "",
|
15
|
+
side_instructions: "",
|
16
|
+
before: "",
|
17
|
+
after: ""
|
18
|
+
}
|
19
|
+
|
20
|
+
def make_meal(options = {})
|
21
|
+
options = DEFAULT_MEAL_OPTIONS.merge(options)
|
22
|
+
|
23
|
+
ctx = Object.new
|
24
|
+
def ctx.evaluate(options)
|
25
|
+
options.each {|k,v| instance_variable_set("@#{k}", v) }
|
26
|
+
ERB.new(File.read(File.join(TEMPLATE_DIR, 'meal.erb')), nil, '-').result(binding)
|
27
|
+
end
|
28
|
+
Emeals::MealParser.new(ctx.evaluate(options)).parse
|
29
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emeals
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Moriarity
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A client for interpreting eMeals menus.
|
14
14
|
email:
|
@@ -33,10 +33,13 @@ files:
|
|
33
33
|
- lib/emeals/menu.rb
|
34
34
|
- lib/emeals/version.rb
|
35
35
|
- spec/client_spec.rb
|
36
|
+
- spec/fixtures/meal.erb
|
36
37
|
- spec/fixtures/menu.pdf
|
37
38
|
- spec/fixtures/menu.txt
|
38
39
|
- spec/ingredient_spec.rb
|
40
|
+
- spec/meal_parser_spec.rb
|
39
41
|
- spec/spec_helper.rb
|
42
|
+
- spec/support/templates.rb
|
40
43
|
homepage: ''
|
41
44
|
licenses: []
|
42
45
|
metadata: {}
|
@@ -56,13 +59,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
59
|
version: '0'
|
57
60
|
requirements: []
|
58
61
|
rubyforge_project:
|
59
|
-
rubygems_version: 2.0.
|
62
|
+
rubygems_version: 2.0.0
|
60
63
|
signing_key:
|
61
64
|
specification_version: 4
|
62
65
|
summary: eMeals Client
|
63
66
|
test_files:
|
64
67
|
- spec/client_spec.rb
|
68
|
+
- spec/fixtures/meal.erb
|
65
69
|
- spec/fixtures/menu.pdf
|
66
70
|
- spec/fixtures/menu.txt
|
67
71
|
- spec/ingredient_spec.rb
|
72
|
+
- spec/meal_parser_spec.rb
|
68
73
|
- spec/spec_helper.rb
|
74
|
+
- spec/support/templates.rb
|