emeals 0.0.1 → 0.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/.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
|