Пример #1
0
    def __parse_dishes(menu_html):
        # obtain the names of all dishes in a passed menu
        dish_names = [
            dish.rstrip() for dish in menu_html.xpath(
                "//p[@class='js-schedule-dish-description']/text()")
        ]
        # make duplicates unique by adding (2), (3) etc. to the names
        dish_names = util.make_duplicates_unique(dish_names)
        # obtain the types of the dishes (e.g. 'Tagesgericht 1')
        dish_types = [
            type.text if type.text else ''
            for type in menu_html.xpath("//span[@class='stwm-artname']")
        ]
        # create dictionary out of dish name and dish type
        dishes_dict = {
            dish_name: dish_type
            for dish_name, dish_type in zip(dish_names, dish_types)
        }
        # create Dish objects with correct prices; if price is not available, -1 is used instead

        dishes = []
        for name in dishes_dict:
            if not dishes_dict[name] and dishes:
                # some dishes are multi-row. That means that for the same type the dish is written in multiple rows.
                # From the second row on the type is then just empty. In that case, we just use the price of the
                # previous dish.
                dishes.append(Dish(name, dishes[-1].price))
            else:
                dishes.append(
                    Dish(
                        name,
                        StudentenwerkMenuParser.prices.get(
                            dishes_dict[name], "N/A")))

        return dishes
Пример #2
0
    def __parse_dishes(menu_html, location):
        # obtain the names of all dishes in a passed menu
        dish_names = [
            dish.rstrip() for dish in menu_html.xpath(
                "//p[@class='js-schedule-dish-description']/text()")
        ]
        # make duplicates unique by adding (2), (3) etc. to the names
        dish_names = util.make_duplicates_unique(dish_names)
        # obtain the types of the dishes (e.g. 'Tagesgericht 1')
        dish_types = [
            type.text if type.text else ''
            for type in menu_html.xpath("//span[@class='stwm-artname']")
        ]
        # obtain all ingredients
        dish_markers_additional = menu_html.xpath(
            "//span[contains(@class, 'c-schedule__marker--additional')]/@data-essen"
        )
        dish_markers_allergen = menu_html.xpath(
            "//span[contains(@class, 'c-schedule__marker--allergen')]/@data-essen"
        )
        dish_markers_type = menu_html.xpath(
            "//span[contains(@class, 'c-schedule__marker--type')]/@data-essen")

        # create dictionary out of dish name and dish type
        dishes_dict = {}
        dishes_tup = zip(dish_names, dish_types, dish_markers_additional,
                         dish_markers_allergen, dish_markers_type)
        for dish_name, dish_type, dish_marker_additional, dish_marker_allergen, dish_marker_type in dishes_tup:
            dishes_dict[dish_name] = (dish_type, dish_marker_additional,
                                      dish_marker_allergen, dish_marker_type)

        # create Dish objects with correct prices; if price is not available, -1 is used instead
        dishes = []
        for name in dishes_dict:
            if not dishes_dict[name] and dishes:
                # some dishes are multi-row. That means that for the same type the dish is written in multiple rows.
                # From the second row on the type is then just empty. In that case, we just use the price and
                # ingredients of the previous dish.
                dishes.append(
                    Dish(name, dishes[-1].price, dishes[-1].ingredients,
                         dishes[-1].dish_type))
            else:
                dish_ingredients = Ingredients(location)
                dish_ingredients.parse_ingredients(dishes_dict[name][1])
                dish_ingredients.parse_ingredients(dishes_dict[name][2])
                dish_ingredients.parse_ingredients(dishes_dict[name][3])
                dishes.append(
                    Dish(
                        name,
                        StudentenwerkMenuParser.prices.get(
                            dishes_dict[name][0], "N/A"),
                        dish_ingredients.ingredient_set, dishes_dict[name][0]))

        return dishes
Пример #3
0
    def _parse_dish(location: str, dish_str: str, dish_type: str) -> Dish:
        ingredient_parser: Ingredients = Ingredients(location)
        allergene = StudentenwerkPDFMenuParser.dish_info_regex.findall(
            dish_str)
        prices = {
            key: float(val.replace(',', '.'))
            for key, val in StudentenwerkPDFMenuParser.prices_regex.search(
                dish_str).groupdict().items()
        }
        name = dish_str

        for i in allergene:
            try:
                ingredient_parser.parse_ingredients(i)
                name = name.replace(f'({i})', '')
            except:
                warn(f'Could not parse ingredients: {i}')

        parsed_ingredients = ingredient_parser.ingredient_set
        parsed_prices = StudentenwerkPDFMenuParser._parse_price(prices)
        substituted_name = StudentenwerkPDFMenuParser.prices_regex.sub(
            '', name.strip())
        return Dish(
            name=StudentenwerkPDFMenuParser._demangle_name(substituted_name),
            prices=parsed_prices,
            ingredients=parsed_ingredients,
            dish_type=dish_type)
Пример #4
0
    def parse_dish(self, dish_str):
        # ingredients
        dish_ingredients = Ingredients("mediziner-mensa")
        matches = re.findall(self.ingredients_regex, dish_str)
        while len(matches) > 0:
            for x in matches:
                if len(x) > 0:
                    dish_ingredients.parse_ingredients(x[0])
            dish_str = re.sub(self.ingredients_regex, " ", dish_str)
            matches = re.findall(self.ingredients_regex, dish_str)
        dish_str = re.sub(r"\s+", " ", dish_str).strip()
        dish_str = dish_str.replace(" , ", ", ")

        # price
        dish_price = Prices()
        for x in re.findall(self.price_regex, dish_str):
            if len(x) > 0:
                dish_price = Prices(
                    Price(
                        float(x[0].replace("€", "").replace(",",
                                                            ".").strip())))
        dish_str = re.sub(self.price_regex, "", dish_str)

        return Dish(dish_str, dish_price, dish_ingredients.ingredient_set,
                    "Tagesgericht")
Пример #5
0
    def test_Should_Add_Dish_to_Canteen(self):
        canteen = LazyBuilder()
        dateobj = date(2017, 3, 27)
        dish = Dish("Gulasch vom Schwein", 1.9)

        openmensa.addDishToCanteen(dish, dateobj, canteen)
        meal = canteen._days[dateobj]['Speiseplan'][0]
        self.assertEqual(meal[0], "Gulasch vom Schwein")
        self.assertEqual(meal[2], {'other': 190})
Пример #6
0
    def test_Should_Add_Dish_to_Canteen(self):
        canteen = LazyBuilder()
        dateobj = date(2017, 3, 27)
        dish = Dish("Gulasch vom Schwein", Prices(Price(1.9)),
                    set(["S", "Gl", "GlG", "GlW", "Kn", "Mi"]), "Tagesgericht")

        openmensa.addDishToCanteen(dish, dateobj, canteen)
        meal = canteen._days[dateobj]['Speiseplan'][0]
        self.assertEqual(meal[0], "Gulasch vom Schwein")
        self.assertEqual(meal[2], {'other': 190})
Пример #7
0
    def __parse_dishes(menu_html, location):
        # obtain the names of all dishes in a passed menu
        dish_names: List[str] = [dish.rstrip() for dish in menu_html.xpath("//p[@class='js-schedule-dish-description']/text()")]
        # make duplicates unique by adding (2), (3) etc. to the names
        dish_names = util.make_duplicates_unique(dish_names)
        # obtain the types of the dishes (e.g. 'Tagesgericht 1')
        dish_types: List[str] = [type.text if type.text else '' for type in menu_html.xpath("//span[@class='stwm-artname']")]
        # obtain all ingredients
        dish_markers_additional: List[str] = menu_html.xpath("//li[contains(@class, 'c-schedule__list-item  u-clearfix  clearfix  js-menu__list-item')]/@data-essen-zusatz")
        dish_markers_allergen: List[str] = menu_html.xpath("//li[contains(@class, 'c-schedule__list-item  u-clearfix  clearfix  js-menu__list-item')]/@data-essen-allergene")
        dish_markers_type: List[str] = menu_html.xpath("//li[contains(@class, 'c-schedule__list-item  u-clearfix  clearfix  js-menu__list-item')]/@data-essen-typ")
        dish_markers_meetless: List[str] = menu_html.xpath("//li[contains(@class, 'c-schedule__list-item  u-clearfix  clearfix  js-menu__list-item')]/@data-essen-fleischlos")

        # create dictionary out of dish name and dish type
        dishes_dict: Dict[str, Tuple[str, str, str, str, str]] = dict()
        dishes_tup: zip = zip(dish_names, dish_types, dish_markers_additional, dish_markers_allergen, dish_markers_type, dish_markers_meetless)
        for dish_name, dish_type, dish_marker_additional, dish_marker_allergen, dish_marker_type, dish_marker_meetless in dishes_tup:
            dishes_dict[dish_name] = (dish_type, dish_marker_additional, dish_marker_allergen, dish_marker_type, dish_marker_meetless)

        # create Dish objects with correct prices; if price is not available, -1 is used instead
        dishes: List[Dish] = list()
        for name in dishes_dict:
            if not dishes_dict[name] and dishes:
                # some dishes are multi-row. That means that for the same type the dish is written in multiple rows.
                # From the second row on the type is then just empty. In that case, we just use the price and
                # ingredients of the previous dish.
                dishes.append(Dish(name, dishes[-1].prices, dishes[-1].ingredients, dishes[-1].dish_type))
            else:
                dish_ingredients: Ingredients = Ingredients(location)
                # parse ingredients
                dish_ingredients.parse_ingredients(dishes_dict[name][1])
                dish_ingredients.parse_ingredients(dishes_dict[name][2])
                dish_ingredients.parse_ingredients(dishes_dict[name][3])
                # find price
                price: Price = StudentenwerkMenuParser.__getPrice(location, dishes_dict[name])
                # create dish
                dishes.append(Dish(name, price, dish_ingredients.ingredient_set, dishes_dict[name][0]))

        return dishes
Пример #8
0
    def get_menus(self, text, year, week_number):
        menus = {}
        lines = text.splitlines()
        count = 0
        # remove headline etc.
        for line in lines:
            # Find the line which is the header of the table and includes the day of week
            line_shrink = line.replace(" ", "").replace("\n", "").lower()
            # Note we do not include 'montag' und 'freitag' since they are also used in the line before the table
            # header to indicate the range of the week “Monday … until Friday _”
            if any(x in line_shrink
                   for x in ('dienstag', 'mittwoch', 'donnerstag')):
                break

            count += 1

        else:
            warn(
                "NotImplemented: IPP parsing failed. Menu text is not a weekly menu. First line: '{}'"
                .format(lines[0]))
            return None

        lines = lines[count:]
        weekdays = lines[0]

        # The column detection is done through the string "Tagessuppe siehe Aushang" which is at the beginning of
        # every column. However, due to center alignment the column do not begin at the 'T' character and broader
        # text in the column might be left of this character, which then gets truncated. But the gap between the 'T'
        # and the '€' character of the previous column¹ — the real beginning of the current column — is always three,
        # which will be subtracted here. Monday is the second column, so the value should never become negative
        # although it is handled here.
        # ¹or 'e' of "Internationale Küche" if it is the monday column

        # find lines which match the regex
        # lines[1:] == exclude the weekday line which also can contain `Geschlossen`
        soup_lines_iter = (x for x in lines[1:]
                           if self.split_days_regex.search(x))

        soup_line1 = next(soup_lines_iter)
        soup_line2 = next(soup_lines_iter, '')

        # Sometimes on closed days, the keywords are written instead of the week of day instead of the soup line
        positions1 = [
            (max(a.start() - 3, 0), a.end())
            for a in list(re.finditer(self.split_days_regex_closed, weekdays))
        ]

        positions2 = [(max(a.start() - 3, 0), a.end()) for a in list(
            re.finditer(self.split_days_regex_soup_one_line, soup_line1))]
        # In the second line there is just 'Aushang' (two lines "Tagessuppe siehe Aushang" or
        # closed days ("Geschlossen", "Feiertag")
        positions3 = [(max(a.start() - 14, 0), a.end() + 3) for a in list(
            re.finditer(self.split_days_regex_soup_two_line, soup_line2))]
        # closed days ("Geschlossen", "Feiertag", …) can be in first line and second line
        positions4 = [
            (max(a.start() - 3, 0), a.end()) for a in
            list(re.finditer(self.split_days_regex_closed, soup_line1)) +
            list(re.finditer(self.split_days_regex_closed, soup_line2))
        ]

        if positions3:  # Two lines "Tagessuppe siehe Aushang"
            soup_line_index = lines.index(soup_line2)
        else:
            soup_line_index = lines.index(soup_line1)

        positions = sorted(positions1 + positions2 + positions3 + positions4)

        if len(positions) != 5:
            warn(
                "IPP PDF parsing of week {} in year {} failed. Only {} of 5 columns detected."
                .format(week_number, year, len(positions)))
            return None

        pos_mon = positions[0][0]
        pos_tue = positions[1][0]
        pos_wed = positions[2][0]
        pos_thu = positions[3][0]
        pos_fri = positions[4][0]

        lines_weekdays = {
            "mon": "",
            "tue": "",
            "wed": "",
            "thu": "",
            "fri": ""
        }
        # it must be lines[3:] instead of lines[2:] or else the menus would start with "Preis ab 0,90€" (from the
        # soups) instead of the first menu, if there is a day where the bistro is closed.
        for line in lines[soup_line_index + 3:]:
            lines_weekdays["mon"] += " " + line[pos_mon:pos_tue].replace(
                "\n", " ")
            lines_weekdays["tue"] += " " + line[pos_tue:pos_wed].replace(
                "\n", " ")
            lines_weekdays["wed"] += " " + line[pos_wed:pos_thu].replace(
                "\n", " ")
            lines_weekdays["thu"] += " " + line[pos_thu:pos_fri].replace(
                "\n", " ")
            lines_weekdays["fri"] += " " + line[pos_fri:].replace("\n", " ")

        for key in lines_weekdays:
            # Appends `?€` to „Überraschungsmenü“ if it do not have a price. The second '€' is a separator for the
            # later split
            lines_weekdays[key] = self.surprise_without_price_regex.sub(
                r"\g<1>?€ € \g<2>", lines_weekdays[key])
            # get rid of two-character umlauts (e.g. SMALL_LETTER_A+COMBINING_DIACRITICAL_MARK_UMLAUT)
            lines_weekdays[key] = unicodedata.normalize(
                "NFKC", lines_weekdays[key])
            # remove multi-whitespaces
            lines_weekdays[key] = ' '.join(lines_weekdays[key].split())
            # get all dish including name and price
            dish_names_price = re.findall(self.dish_regex,
                                          lines_weekdays[key] + ' ')
            # create dish types
            # since we have the same dish types every day we can use them if there are 4 dishes available
            if len(dish_names_price) == 4:
                dish_types = [
                    "Veggie", "Traditionelle Küche", "Internationale Küche",
                    "Specials"
                ]
            else:
                dish_types = ["Tagesgericht"] * len(dish_names_price)

            # create ingredients
            # all dishes have the same ingridients
            ingredients = Ingredients("ipp-bistro")
            ingredients.parse_ingredients("Mi,Gl,Sf,Sl,Ei,Se,4")
            # create list of Dish objects
            counter = 0
            dishes = []
            for (dish_name, price) in dish_names_price:
                dishes.append(
                    Dish(dish_name.strip(),
                         Prices(Price(price.replace(',', '.').strip())),
                         ingredients.ingredient_set, dish_types[counter]))
                counter += 1
            date = self.get_date(year, week_number,
                                 self.weekday_positions[key])
            # create new Menu object and add it to dict
            menu = Menu(date, dishes)
            # remove duplicates
            menu.remove_duplicates()
            menus[date] = menu

        return menus
Пример #9
0
    def get_menus(self, text, year, week_number):
        menus = {}
        lines = text.splitlines()
        count = 0
        # remove headline etc.
        for line in lines:
            if line.replace(" ", "").replace(
                    "\n",
                    "").lower() == "montagdienstagmittwochdonnerstagfreitag":
                break

            count += 1

        lines = lines[count:]
        # we assume that the weeksdays are now all in the first line
        pos_mon = lines[0].find("Montag")
        pos_tue = lines[0].find("Dienstag")
        pos_wed = lines[0].find("Mittwoch")
        pos_thu = lines[0].find("Donnerstag")
        pos_fri = lines[0].find("Freitag")

        # The text is formatted as table using whitespaces. Hence, we need to get those parts of each line that refer
        #  to the respective week day
        lines_weekdays = {
            "mon": "",
            "tue": "",
            "wed": "",
            "thu": "",
            "fri": ""
        }
        for line in lines:
            lines_weekdays["mon"] += " " + line[pos_mon:pos_tue].replace(
                "\n", " ").replace("Montag", "")
            lines_weekdays["tue"] += " " + line[pos_tue:pos_wed].replace(
                "\n", " ").replace("Dienstag", "")
            lines_weekdays["wed"] += " " + line[pos_wed:pos_thu].replace(
                "\n", " ").replace("Mittwoch", "")
            lines_weekdays["thu"] += " " + line[pos_thu:pos_fri].replace(
                "\n", " ").replace("Donnerstag", "")
            lines_weekdays["fri"] += " " + line[pos_fri:].replace(
                "\n", " ").replace("Freitag", "")

        # currently, up to 5 dishes are on the menu
        num_dishes = 5
        line_aktion = []
        if year < 2018:
            # in older versions of the FMI Bistro menu, the Aktionsgericht was the same for the whole week
            num_dishes = 3
            line_aktion = [s for s in lines if "Aktion" in s]
            if len(line_aktion) == 1:
                line_aktion_pos = lines.index(line_aktion[0]) - 2
                aktionsgericht = ' '.join(
                    lines[line_aktion_pos:line_aktion_pos + 3])
                aktionsgericht = aktionsgericht \
                    .replace("Montag – Freitag", "") \
                    .replace("Tagessuppe täglich wechselndes Angebot", "") \
                    .replace("ab € 1,00", "") \
                    .replace("Aktion", "")
                num_dishes += aktionsgericht.count('€')
                for key in lines_weekdays:
                    lines_weekdays[
                        key] = aktionsgericht + ", " + lines_weekdays[key]

        # Process menus for each day
        for key in lines_weekdays:
            # stop parsing day when bistro is closed at that day
            if "geschlossen" in lines_weekdays[key].lower():
                continue

            # extract all allergens
            dish_allergens = []
            for x in re.findall(self.allergens_regex, lines_weekdays[key]):
                if len(x) > 0:
                    dish_allergens.append(
                        re.sub(r"((Allergene:)|\s|\n)*", "", x[0]))
                else:
                    dish_allergens.append("")
            lines_weekdays[key] = re.sub(self.allergens_regex, "",
                                         lines_weekdays[key])
            # get rid of two-character umlauts (e.g. SMALL_LETTER_A+COMBINING_DIACRITICAL_MARK_UMLAUT)
            lines_weekdays[key] = unicodedata.normalize(
                "NFKC", lines_weekdays[key])
            # remove multi-whitespaces
            lines_weekdays[key] = ' '.join(lines_weekdays[key].split())

            # remove no allergens indicator
            lines_weekdays[key] = lines_weekdays[key].replace("./.", "")
            # get all dish including name and price
            dish_names = re.findall(self.dish_regex, lines_weekdays[key])
            # get dish prices
            prices = re.findall(self.price_regex, ' '.join(dish_names))
            # convert prices to float
            prices = [
                Prices(
                    Price(
                        float(
                            price.replace("€", "").replace(",", ".").strip())))
                for price in prices
            ]
            # remove price and commas from dish names
            dish_names = [
                re.sub(self.price_regex, "", dish).replace(",", "").strip()
                for dish in dish_names
            ]
            # create list of Dish objects; only take first 3/4 as the following dishes are corrupt and not necessary
            dishes = []
            for (dish_name, price,
                 dish_allergen) in list(zip(dish_names, prices,
                                            dish_allergens)):
                # filter empty dishes
                if dish_name:
                    ingredients = Ingredients("fmi-bistro")
                    ingredients.parse_ingredients(dish_allergen)
                    dishes.append(
                        Dish(dish_name, price, ingredients.ingredient_set,
                             "Tagesgericht"))
            dishes = dishes[:num_dishes]
            date = self.get_date(year, week_number,
                                 self.weekday_positions[key])
            # create new Menu object and add it to dict
            menu = Menu(date, dishes)
            # remove duplicates
            menu.remove_duplicates()
            menus[date] = menu

        return menus
Пример #10
0
class MedizinerMensaParserTest(unittest.TestCase):
    mediziner_mensa_parser = MedizinerMensaMenuParser()
    test_menu1 = open(
        'src/test/assets/mediziner-mensa/KW_44_Herbst_4_Mensa_2018.txt',
        'r').read()
    year1 = 2018
    week_number1 = 44

    date_mon1 = date(2018, 10, 29)
    date_tue1 = date(2018, 10, 30)
    date_wed1 = date(2018, 10, 31)
    date_thu1 = date(2018, 11, 1)
    date_fri1 = date(2018, 11, 2)
    date_sat1 = date(2018, 11, 3)
    date_sun1 = date(2018, 11, 4)

    dish1_mon1 = Dish("Spinatcremesuppe", "N/A", set(["Mi", "Gl"]))
    dish2_mon1 = Dish("Gekochtes Ochsenfleisch mit Meerrettich", "N/A",
                      set(["Sw", "Mi", "R", "3", "5"]))
    dish3_mon1 = Dish("Kürbisauflauf", "N/A", set(["1", "2", "Ei", "Mi",
                                                   "Gl"]))
    dish4_mon1 = Dish("Asiatische Gemüse-Puten-Pfanne mit Reisnudeln", 3.8,
                      set(["G", "Se", "Gl", "Fi", "So", "G"]))

    dish1_tue1 = Dish("Selleriecremesuppe", "N/A", set(["Mi", "Gl"]))
    dish2_tue1 = Dish("Oldenburger Grünkohl mit Mettenden", "N/A",
                      set(["Gl", "Mi", "Sf", "2", "3", "4", "S", "8"]))
    dish3_tue1 = Dish("Kaschmir Kohlrabi und Brokkoli", "N/A", set(["Mi"]))
    dish4_tue1 = Dish("Conchiglioni Nudeln mit mit mediterranem Gemüse", 3.15,
                      set(["1", "2", "Ei", "Gl", "Mi"]))

    dish1_wed1 = Dish("Französische Zwiebelsuppe", "N/A", set())
    dish2_wed1 = Dish("Germknödel mit Vanillesoße", "N/A",
                      set(["1", "9", "Ei", "Mi", "Gl"]))
    dish3_wed1 = Dish("Herzhaftes Kartoffelgratin", "N/A",
                      set(["Gl", "Ei", "Mi", "Sl", "1", "2"]))
    dish4_wed1 = Dish("Holzfällersteak mit Bratkartoffeln und Weißkrautsalat",
                      3.7, set(["Sw", "Gl", "S"]))

    dish1_thu1 = Dish("Süßkartoffelcremesuppe", "N/A", set(["Mi", "Gl"]))
    dish2_thu1 = Dish("Hähnchenbrust gegrillt", "N/A", set(["G"]))
    dish3_thu1 = Dish("In Sesamöl gebratenes Wokgemüse", "N/A",
                      set(["2", "Se", "Gl", "So"]))

    dish1_fri1 = Dish("Brokkolicremesuppe", "N/A", set(["Mi", "Gl"]))
    dish2_fri1 = Dish("Forelle \"Müllerin Art \"", "N/A", set(["Gl", "Fi"]))
    dish3_fri1 = Dish("Quarkklößchen", "N/A",
                      set(["Gl", "Ei", "Mi", "Sw", "2", "3", "5"]))
    dish4_fri1 = Dish("Chili con Cous Cous mit Kürbis-Apfel-Salat", 2.15,
                      set(["3", "9", "Sw", "Gl"]))

    dish1_sat1 = Dish("Bratspätzlesuppe", "N/A",
                      set(["Ei", "Sl", "R", "Gl", "S"]))
    dish2_sat1 = Dish("Geflügelpflanzerl", "N/A",
                      set(["Gl", "Ei", "Mi", "So", "G"]))
    dish3_sat1 = Dish("Krauttopf mit einer Vollkornsemmel", "N/A", set(["Gl"]))

    dish1_sun1 = Dish("Käsecremesuppe", "N/A", set(["1", "2", "Mi", "Gl"]))
    dish2_sun1 = Dish("Geschmortes Kalbfleisch", "N/A", set(["K"]))
    dish3_sun1 = Dish("Vegetarische Moussaka", "N/A",
                      set(["1", "2", "Mi", "Gl"]))

    menu_mon1 = Menu(date_mon1,
                     [dish1_mon1, dish2_mon1, dish3_mon1, dish4_mon1])
    menu_tue1 = Menu(date_tue1,
                     [dish1_tue1, dish2_tue1, dish3_tue1, dish4_tue1])
    menu_wed1 = Menu(date_wed1,
                     [dish1_wed1, dish2_wed1, dish3_wed1, dish4_wed1])
    menu_thu1 = Menu(date_thu1, [dish1_thu1, dish2_thu1, dish3_thu1])
    menu_fri1 = Menu(date_fri1,
                     [dish1_fri1, dish2_fri1, dish3_fri1, dish4_fri1])
    menu_sat1 = Menu(date_sat1, [dish1_sat1, dish2_sat1, dish3_sat1])
    menu_sun1 = Menu(date_sun1, [dish1_sun1, dish2_sun1, dish3_sun1])

    test_menu2 = open(
        'src/test/assets/mediziner-mensa/KW_47_Herbst_3_Mensa_2018.txt',
        'r').read()
    year2 = 2018
    week_number2 = 47

    date_mon2 = date(2018, 11, 19)
    date_tue2 = date(2018, 11, 20)
    date_wed2 = date(2018, 11, 21)
    date_thu2 = date(2018, 11, 22)
    date_fri2 = date(2018, 11, 23)
    date_sat2 = date(2018, 11, 24)
    date_sun2 = date(2018, 11, 25)

    dish1_mon2 = Dish("Blumenkohlcremesuppe", "N/A", set(["Gl", "Mi"]))
    dish2_mon2 = Dish("Pfannengyros mit Tzaziki", "N/A", set(["S", "Mi"]))
    dish3_mon2 = Dish("Spaghetti \" Gemüsebolognese \"", "N/A",
                      set(["Sl", "Gl"]))
    dish4_mon2 = Dish(
        "Thai-Curry aus Blumenkohl und Kartoffeln mit Gemüsreis und Salat",
        2.2, set(["Sw", "So", "Gl", "Mi"]))

    dish1_tue2 = Dish("Gelbe Erbsensuppe", "N/A", set(["Gl", "Mi"]))
    dish2_tue2 = Dish("Grüner Bohneneintopf mit Rindfleisch", "N/A",
                      set(["Sl", "R"]))
    dish3_tue2 = Dish("Veggi-Gulasch", "N/A", set(["Sl", "Gl"]))
    dish4_tue2 = Dish(
        "Rotbarschfischfilet in Dillsoße mit Kürbisgemüse und Wacholderreis",
        3.65, set(["Mi", "Gl", "Fi"]))

    dish1_wed2 = Dish("Rinderbrühe \" Gärtnerin \"", "N/A", set(["Sl", "R"]))
    dish2_wed2 = Dish("Schweinegulasch", "N/A", set(["Gl", "S"]))
    dish3_wed2 = Dish("Gemüsekuchen mit Mozzarella überbacken", "N/A",
                      set(["Sl", "Ei", "Gl", "Mi"]))
    dish4_wed2 = Dish("Schinkennudeln mit Tomatensoße, dazu gemischter Salat",
                      2.1, set(["Gl", "Mi", "Sf", "Sw", "2", "3", "8", "G"]))

    dish1_thu2 = Dish("Kürbiscremesuppe", "N/A", set(["Gl", "Mi"]))
    dish2_thu2 = Dish("Rinderhackbraten", "N/A",
                      set(["Gl", "Ei", "Mi", "Sf", "So", "R"]))
    dish3_thu2 = Dish("Dinkel-Kräuterbratling", "N/A", set(["Ei", "Gl", "Mi"]))
    dish4_thu2 = Dish(
        "Pikantes Risotto mit buntem Gemüse und Tomatensalat mit Basilikum",
        2.15, set(["Mi", "1", "2", "Sw"]))

    dish1_fri2 = Dish("Minestrone", "N/A", set(["Sl", "Ei", "Gl"]))
    dish2_fri2 = Dish("Gebratene Hähnchenbrust", "N/A", set(["G"]))
    dish3_fri2 = Dish("Scheiterhaufen mit Apfel-Vanille-Ragout", "N/A",
                      set(["Ei", "Gl", "Mi", "So", "9", "3"]))
    dish4_fri2 = Dish(
        "Paniertes Schnitzel vom Schwein und Pute mit Kartoffelmayosalat und Zitronenecke",
        3.6, set(["Gl", "Ei", "Sf", "4", "3", "G", "S"]))

    dish1_sat2 = Dish("Tomatencremesuppe", "N/A", set(["Gl", "Mi"]))
    dish2_sat2 = Dish("Pichelsteiner Gemüseeintopf mit Rindfleisch", "N/A",
                      set(["Sl", "R"]))
    dish3_sat2 = Dish("Ofenkartoffel mit herzhaftem Gemüseragout", "N/A",
                      set(["Sl", "Gl", "Mi"]))

    dish1_sun2 = Dish("Grießnockerlsuppe", "N/A", set(["Ei", "Gl"]))
    dish2_sun2 = Dish("Glasierter Putenbraten in Kräuterrahmsoße", "N/A",
                      set(["G", "Gl", "Mi"]))
    dish3_sun2 = Dish("Eieromelett", "N/A", set(["Ei", "Gl", "Mi"]))

    menu_mon2 = Menu(date_mon2,
                     [dish1_mon2, dish2_mon2, dish3_mon2, dish4_mon2])
    menu_tue2 = Menu(date_tue2,
                     [dish1_tue2, dish2_tue2, dish3_tue2, dish4_tue2])
    menu_wed2 = Menu(date_wed2,
                     [dish1_wed2, dish2_wed2, dish3_wed2, dish4_wed2])
    menu_thu2 = Menu(date_thu2,
                     [dish1_thu2, dish2_thu2, dish3_thu2, dish4_thu2])
    menu_fri2 = Menu(date_fri2,
                     [dish1_fri2, dish2_fri2, dish3_fri2, dish4_fri2])
    menu_sat2 = Menu(date_sat2, [dish1_sat2, dish2_sat2, dish3_sat2])
    menu_sun2 = Menu(date_sun2, [dish1_sun2, dish2_sun2, dish3_sun2])

    def test_Should_Return_Menu1(self):
        menus_actual1 = self.mediziner_mensa_parser.get_menus(
            self.test_menu1, self.year1, self.week_number1)
        self.assertEqual(7, len(menus_actual1))
        self.assertEqual(self.menu_mon1, menus_actual1[self.date_mon1])
        self.assertEqual(self.menu_tue1, menus_actual1[self.date_tue1])
        self.assertEqual(self.menu_wed1, menus_actual1[self.date_wed1])
        self.assertEqual(self.menu_thu1, menus_actual1[self.date_thu1])
        self.assertEqual(self.menu_fri1, menus_actual1[self.date_fri1])
        self.assertEqual(self.menu_sat1, menus_actual1[self.date_sat1])
        self.assertEqual(self.menu_sun1, menus_actual1[self.date_sun1])

        menus_actual2 = self.mediziner_mensa_parser.get_menus(
            self.test_menu2, self.year2, self.week_number2)
        self.assertEqual(7, len(menus_actual2))
        self.assertEqual(self.menu_mon2, menus_actual2[self.date_mon2])
        self.assertEqual(self.menu_tue2, menus_actual2[self.date_tue2])
        self.assertEqual(self.menu_wed2, menus_actual2[self.date_wed2])
        self.assertEqual(self.menu_thu2, menus_actual2[self.date_thu2])
        self.assertEqual(self.menu_fri2, menus_actual2[self.date_fri2])
        self.assertEqual(self.menu_sat2, menus_actual2[self.date_sat2])
        self.assertEqual(self.menu_sun2, menus_actual2[self.date_sun2])
Пример #11
0
class IPPBistroParserTest(unittest.TestCase):
    ipp_parser = IPPBistroMenuParser()
    test_menu1 = open('src/test/assets/ipp/KW-47_20.11-24.11.2017-1.txt',
                      'r').read()
    year1 = 2017
    week_number1 = 47
    test_menu2 = open('src/test/assets/ipp/KW-48_27.11-01.12.10.2017-3.txt',
                      'r').read()
    year2 = 2017
    week_number2 = 48

    date_mon1 = date(2017, 11, 20)
    date_tue1 = date(2017, 11, 21)
    date_wed1 = date(2017, 11, 22)
    date_thu1 = date(2017, 11, 23)
    date_fri1 = date(2017, 11, 24)
    dish1_mon1 = Dish("Gefüllter Germknödel mit Vanillesauce", 3.5,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_mon1 = Dish(
        "Ofengulasch vom Rind mit Kürbis und Pflaumen, dazu Rigatoni", 5.5,
        {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_mon1 = Dish(
        "\"Palek Tofu\" Gebratener Tofu mit Spinat, Ingwer, Curry-Sahnesauce und Basmatireis",
        5.2, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_mon1 = Dish(
        "Gebratene Hähnchenbrust auf Fenchelgemüse, dazu Kräuterreis und Orangensauce",
        6.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish1_tue1 = Dish(
        "Gebratene Weißkohl-Kartoffelpfanne mit gerösteten Sonnenblumenkernen",
        3.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_tue1 = Dish("Jägerschnitzel mit Spätzle oder Reis", 4.8,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_tue1 = Dish(
        "Vegetarisch gefüllte Tortelli mit leichter Zitronen-Buttersauce und gehobeltem Parmesan",
        4.8, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_tue1 = Dish("\"Bami Goreng\" indonesische Bratnudeln mit Gemüse, Huhn, Schweinefleisch und Pilzen, " \
                      "dazu Honig-Chili- Dip", 6.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish1_wed1 = Dish("Erbseneintopf (mit Wienerle 4,20 €)", 3.5,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_wed1 = Dish("Hackbraten mit Zigeunersauce und Reis", 4.8,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_wed1 = Dish(
        "\"Farfalle Rustico\" mit Champignons, Schinken Tomaten und Peperoni (auf Wunsch mit "
        "Reibekäse)", 4.6, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_wed1 = Dish("Rumpsteak mit Balsamico Pilzen und Wedges", 7.9,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish1_thu1 = Dish(
        "Mediterrane Frittata mit Zucchini, Kartoffeln, Paprika, kleiner Salatbeilage und "
        "Joghurt-Limetten Dip", 3.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_thu1 = Dish(
        "Frischer Bayrischer Schweinenackenbraten vom Brett geschnitten dazu Kartoffel- Gurkensalat",
        4.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_thu1 = Dish(
        "\"Enchilada Verdura\", überbackene Weizentortilla, gefüllt mit Hähnchenfleisch, Sauerrahm, "
        "Kidneybohnen, Mais, dazu", 5.9,
        {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_thu1 = Dish(
        "\"Lamm Palak\" mit Spinat und Curry (mittelscharf), dazu Reis", 6.9,
        {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish1_fri1 = Dish("Nudelpfanne mit Gemüsesauce (auf Wunsch mit Reibekäse)",
                      3.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_fri1 = Dish("Matjes \"Hausfrauen Art\" mit Salzkartoffeln", 5.2,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_fri1 = Dish("Currygeschnetzeltes von der Pute mit Früchten und Reis",
                      4.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_fri1 = Dish("Honig-Kassler mit Apfel-Spitzkohl und Kartoffelspalten",
                      6.2, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    menu_mon1 = Menu(date_mon1,
                     [dish1_mon1, dish2_mon1, dish3_mon1, dish4_mon1])
    menu_tue1 = Menu(date_tue1,
                     [dish1_tue1, dish2_tue1, dish3_tue1, dish4_tue1])
    menu_wed1 = Menu(date_wed1,
                     [dish1_wed1, dish2_wed1, dish3_wed1, dish4_wed1])
    menu_thu1 = Menu(date_thu1,
                     [dish1_thu1, dish2_thu1, dish3_thu1, dish4_thu1])
    menu_fri1 = Menu(date_fri1,
                     [dish1_fri1, dish2_fri1, dish3_fri1, dish4_fri1])

    date_mon2 = date(2017, 11, 27)
    date_tue2 = date(2017, 11, 28)
    date_wed2 = date(2017, 11, 29)
    date_thu2 = date(2017, 11, 30)
    date_fri2 = date(2017, 12, 1)
    dish1_mon2 = Dish("Wirsing-Kartoffelauflauf mit Bechamel und Käse", 3.5,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_mon2 = Dish("Paprikarahm Geschnetzeltes mit Paprikamix und Nudeln",
                      4.8, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_mon2 = Dish(
        "\"Dal Curry\" mit Kartoffeln, Kokosmilch, Ingwer, Koriander, Reis und scharfem Chutney",
        4.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_mon2 = Dish(
        "Deftiger Hüttenschmaus, Rinderrostbraten mit Zwiebeln, Semmelknödel und gebratenem Gemüse",
        7.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish1_tue2 = Dish("Herbstliche Gemüse-Reis Pfanne mit pikantem Mango Dip",
                      3.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_tue2 = Dish("Krautwickerl mit Speck-Zwieblsauce und Püree", 4.5,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_tue2 = Dish("Rigatoni mit Rosenkohl und Schnittlauch", 4.6,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_tue2 = Dish("Spanferkelrücken mit Knödel und Bayerisch Kraut", 6.8,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish1_wed2 = Dish(
        "Weißwurst Gröst ́l mit Knödel, Lauchzwiebeln, Karotten und Kräuter auf Wunsch mit "
        "Bratenjus", 3.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_wed2 = Dish("Estragonrahmschnitzel mit Pommes frites oder Reis", 4.6,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_wed2 = Dish("Gemüse Lasagne", 4.9,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_wed2 = Dish(
        "\"Tandoori Chicken\" mit Auberginen, Tomaten, Zucchini, Zitronenschale Minze und Reis",
        6.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish1_thu2 = Dish("Rote Beete Eintopf mit Kartoffeln, Nudeln und Dill",
                      3.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_thu2 = Dish(
        "Sauerbraten \"Nepal\" mit weißen Bohnen, getrockneten Tomaten und Pasta",
        5.8, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_thu2 = Dish(
        "\"Kaku Chicken\" mit geröstetem Curry, Kokosraspel, Tomaten und Reis",
        6.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_thu2 = Dish(
        "Leberkäs Burger special mit Pommes frites und Cole slaw", 4.8,
        {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish1_fri2 = Dish("Exotische Linsen-Spätzle Pfanne", 3.5,
                      {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish2_fri2 = Dish(
        "Seelachsfilet gebacken mit Sardellenmayonnaise und Pommes frites",
        4.6, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish3_fri2 = Dish("Gemüse-Linguini mit Pesto-Rahmsauce und Parmesankäse",
                      4.4, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    dish4_fri2 = Dish(
        "Schweinefilet Medaillons in grüner Pfefferrahmsauce mit Kroketten und karamellisierten "
        "Möhren", 7.2, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})

    menu_mon2 = Menu(date_mon2,
                     [dish1_mon2, dish2_mon2, dish3_mon2, dish4_mon2])
    menu_tue2 = Menu(date_tue2,
                     [dish1_tue2, dish2_tue2, dish3_tue2, dish4_tue2])
    menu_wed2 = Menu(date_wed2,
                     [dish1_wed2, dish2_wed2, dish3_wed2, dish4_wed2])
    menu_thu2 = Menu(date_thu2,
                     [dish1_thu2, dish2_thu2, dish3_thu2, dish4_thu2])
    menu_fri2 = Menu(date_fri2,
                     [dish1_fri2, dish2_fri2, dish3_fri2, dish4_fri2])

    def test_Should_Return_Menu1(self):
        menus_actual1 = self.ipp_parser.get_menus(self.test_menu1, self.year1,
                                                  self.week_number1)
        self.assertEqual(5, len(menus_actual1))
        self.assertEqual(self.menu_mon1, menus_actual1[self.date_mon1])
        self.assertEqual(self.menu_tue1, menus_actual1[self.date_tue1])
        self.assertEqual(self.menu_wed1, menus_actual1[self.date_wed1])
        self.assertEqual(self.menu_thu1, menus_actual1[self.date_thu1])
        self.assertEqual(self.menu_fri1, menus_actual1[self.date_fri1])

    def test_Should_Return_Menu2(self):
        menus_actual2 = self.ipp_parser.get_menus(self.test_menu2, self.year2,
                                                  self.week_number2)
        self.assertEqual(5, len(menus_actual2))
        self.assertEqual(self.menu_mon2, menus_actual2[self.date_mon2])
        self.assertEqual(self.menu_tue2, menus_actual2[self.date_tue2])
        self.assertEqual(self.menu_wed2, menus_actual2[self.date_wed2])
        self.assertEqual(self.menu_thu2, menus_actual2[self.date_thu2])
        self.assertEqual(self.menu_fri2, menus_actual2[self.date_fri2])

    ## Test Cases with holidays

    ## Two holidays (Mon & Tue)

    y18w18_date_mon = date(2018, 4, 30)
    y18w18_date_tue = date(2018, 5, 1)
    y18w18_date_wed = date(2018, 5, 2)
    y18w18_date_thu = date(2018, 5, 3)
    y18w18_date_fri = date(2018, 5, 4)

    y18w18_dishes_wed = [
        Dish("Kirschmichel mit Vanillesauce", 3.5,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "Fitnessteak vom Grill, dazu Zitrone oder Kräuterbutter, Grilltomate und Ofenkartoffel mit "
            "Sauerrahmdip oder bunter Salatauswahl", 8.2,
            {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "\"Chana Dal\" Kichererbsen, Kartoffeln, Kokosmilch, Curryblätter und Reis",
            4.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "Calamari alla Romana, gebackene Tintenfischringe mit Knoblauchmayonnaise und "
            "gemischtem Blattsalat mit Tomate und Gurke", 6.2,
            {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    ]

    y18w18_dishes_thu = [
        Dish(
            "Grenaillekartoffeln mit Apfel-Möhren-Quark, auf Wunsch mit gerösteten Sonnenblumenkernen",
            3.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "Böfflamott, gebeizter Rinderschmorbraten mit Rotwein, dazu Frühlingsgemüse und Semmelknödel",
            6.8, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("Fussili mit Lauch, Ricotta, Meerrettich und frischem Basilikum",
             4.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "Aus dem Wok Putengeschnetzeltes mit Mangold, Möhren, Frühlings- zwiebeln und Basmatireis",
            6.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    ]

    y18w18_dishes_fri = [
        Dish(
            "Curryreispfanne mit Gemüse, Ananas, Kreuzkümmel, Koriander und Chili-Dip",
            3.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "Zitronen Seelachs auf Paprika-Champignon Gemüse, Petersilien- Kartoffeln und leichter Buttersauce",
            5.90, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("Paprikarahmgeschnetzeltes mit Hörnchennudeln", 5.2,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "\"Pasta Arora\" italienische Nudeln mit Tomatensahne, Mozzarella und Basilikum",
            4.5, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    ]

    y18w18_menu_mon = Menu(y18w18_date_mon, set())
    y18w18_menu_tue = Menu(y18w18_date_tue, set())
    y18w18_menu_wed = Menu(y18w18_date_wed, y18w18_dishes_wed)
    y18w18_menu_thu = Menu(y18w18_date_thu, y18w18_dishes_thu)
    y18w18_menu_fri = Menu(y18w18_date_fri, y18w18_dishes_fri)

    y18w18_test_menu = open('src/test/assets/ipp/KW-18_30.04.-04.05.18.txt',
                            'r').read()

    def test_Holiday_Should_Return_Menu_y18w18(self):
        menus_actual = self.ipp_parser.get_menus(self.y18w18_test_menu,
                                                 year=2018,
                                                 week_number=18)
        self.assertEqual(5, len(menus_actual))

        self.assertEqual(self.y18w18_menu_mon,
                         menus_actual[self.y18w18_date_mon])
        self.assertEqual(self.y18w18_menu_tue,
                         menus_actual[self.y18w18_date_tue])
        self.assertEqual(self.y18w18_menu_wed,
                         menus_actual[self.y18w18_date_wed])
        self.assertEqual(self.y18w18_menu_thu,
                         menus_actual[self.y18w18_date_thu])
        self.assertEqual(self.y18w18_menu_fri,
                         menus_actual[self.y18w18_date_fri])

    ## One holiday (Thu)

    y18w19_date_mon = date(2018, 5, 7)
    y18w19_date_tue = date(2018, 5, 8)
    y18w19_date_wed = date(2018, 5, 9)
    y18w19_date_thu = date(2018, 5, 10)
    y18w19_date_fri = date(2018, 5, 11)

    y18w19_dishes_mon = [
        Dish("Gemüse-Schupfnudeln dazu Sauerrahm-Dip", 3.5,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("Würziger Putenbrustbraten mit Frühlingsgemüse und Kroketten",
             7.2, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("Gnocchi-Lauch Gratin mit Käse überbacken", 4.8,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("Schweinefleisch süß-sauer mit Ananas, Paprika, Tomaten und Reis",
             6.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    ]

    y18w19_dishes_tue = [
        Dish("Gebackener Edamer mit Rohkostsalat und Preiselbeeren", 4.9,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "Köttbullar (Hackfleischbällchen) mit Rahmsauce, Preiselbeeren und Petersilienkartoffeln",
            4.8, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("Burgunderbraten vom Rind mit Knödel und Blaukraut", 6.2,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("Quarkknödel auf Erdbeer-Rhabarber Kompott", 3.5,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    ]

    y18w19_dishes_wed = [
        Dish("Italienische Minestrone mit Reis", 3.5,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("Gebackenes Schweineschnitzel mit Zitrone und Pommes frites", 5.9,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "\"Vegetarian Vindaloo\" Kartoffeln und Tomaten in Currysauce, dazu Reis und frischer Koriander",
            4.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        # Note the " after the Basilikum is correct since it is part of the PDF
        Dish(
            "Farfalle \"al Tonno\" mit Thunfisch, Kapern, Oliven, Tomaten und Basilikum\"",
            4.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    ]

    y18w19_dishes_fri = [
        Dish("Spaghetti mit Tomatensauce und Reibekäse", 3.5,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish("2 Paar Schweinswürst ́l auf Sauerkraut und Püree", 4.8,
             {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "\"Chicken Padam Pasanda\" mit Nusssauce, Kokos- flocken und indischen Gewürzen, dazu Basmatireis",
            6.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"}),
        Dish(
            "Kartoffeltasche, gefüllt mit Kräuterfrischkäse auf Paprikagemüse",
            4.9, {"Mi", "Gl", "Sf", "Sl", "Ei", "Se", "4"})
    ]

    y18w19_menu_mon = Menu(y18w19_date_mon, y18w19_dishes_mon)
    y18w19_menu_tue = Menu(y18w19_date_tue, y18w19_dishes_tue)
    y18w19_menu_wed = Menu(y18w19_date_wed, y18w19_dishes_wed)
    y18w19_menu_thu = Menu(y18w19_date_thu, set())
    y18w19_menu_fri = Menu(y18w19_date_fri, y18w19_dishes_fri)

    y18w19_test_menu = open('src/test/assets/ipp/KW-19_07.05.-11.05.18.txt',
                            'r').read()

    def test_Holiday_Should_Return_Menu_y18w19(self):
        menus_actual = self.ipp_parser.get_menus(self.y18w19_test_menu,
                                                 year=2018,
                                                 week_number=19)
        self.assertEqual(5, len(menus_actual))

        self.assertEqual(self.y18w19_menu_mon,
                         menus_actual[self.y18w19_date_mon])
        self.assertEqual(self.y18w19_menu_tue,
                         menus_actual[self.y18w19_date_tue])
        self.assertEqual(self.y18w19_menu_wed,
                         menus_actual[self.y18w19_date_wed])
        self.assertEqual(self.y18w19_menu_thu,
                         menus_actual[self.y18w19_date_thu])
        self.assertEqual(self.y18w19_menu_fri,
                         menus_actual[self.y18w19_date_fri])

    ## "Überraschungsmenü" and "Geschlossen" in first line of table

    y19w22_dishes_mon = [
        Dish("Kohlrabieintopf mit Kartoffeln (mit Wiener 4,50 €)", 3.5,
             {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish("Pfefferrahmgeschnetzeltes von der Pute mit Reis", 5.9,
             {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish("Überraschungsmenü", "?€",
             {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish(
            "Luganer Schweinesteak mit Senf, Schinken, Käse und Tomatenragout gratiniert, dazu Pommes frites",
            6.9, {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'})
    ]
    y19w22_dishes_tue = [
        Dish("Überraschungsmenü", 3.7,
             {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish("Gnocchi Aurora, dazu Pesto und Grana", 4.8,
             {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish(
            "Wokgericht Gemüse-Couscous mit mariniertem Harissa-Honig- Hühnchen (leicht scharf)",
            6.9, {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish(
            "\"Kentucky-fried-Schnitzel\", Schweineschnitzel in Paprika- Oregano-Panade, dazu Pommes frites",
            6.2, {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'})
    ]
    y19w22_dishes_wed = [
        Dish("Puddingmilchreis mit Himbeersauce", 3.5,
             {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish(
            "Putenschnitzel in Zitronen- Kapernsauce mit Petersilienkartoffeln",
            6.9, {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish(
            "Penne \"Diabolo\" mit Cabanossi, Peperoni,Paprika, Zucchini, Chilipulver und Mais, dazu Grana",
            4.9, {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'}),
        Dish(
            "\"Battala Curry\", süße Kartoffeln, Erbsen, Kokosmilch, Senfkörner und Reis",
            4.9, {'Sf', 'Mi', 'Sl', 'Ei', '4', 'Se', 'Gl'})
    ]

    y19w22_date_mon = date(2019, 5, 27)
    y19w22_date_tue = date(2019, 5, 28)
    y19w22_date_wed = date(2019, 5, 29)
    y19w22_date_thu = date(2019, 5, 30)
    y19w22_date_fri = date(2019, 5, 30)

    y19w22_menu_mon = Menu(y19w22_date_mon, y19w22_dishes_mon)
    y19w22_menu_tue = Menu(y19w22_date_tue, y19w22_dishes_tue)
    y19w22_menu_wed = Menu(y19w22_date_wed, y19w22_dishes_wed)

    y19w22_test_menu = open('src/test/assets/ipp/KW_22-27.05.-31.05.19.txt',
                            'r').read()

    def test_surprise_holiday_first_line_y19w22(self):
        menus_actual = self.ipp_parser.get_menus(self.y19w22_test_menu,
                                                 year=2019,
                                                 week_number=22)

        self.assertEqual(self.y19w22_menu_mon,
                         menus_actual[self.y19w22_date_mon])
        self.assertEqual(self.y19w22_menu_tue,
                         menus_actual[self.y19w22_date_tue])
        self.assertEqual(self.y19w22_menu_wed,
                         menus_actual[self.y19w22_date_wed])
        self.assertEqual(Menu(self.y19w22_date_thu, []),
                         menus_actual[self.y19w22_date_thu])
        self.assertEqual(Menu(self.y19w22_date_fri, []),
                         menus_actual[self.y19w22_date_fri])
Пример #12
0
class StudentenwerkMenuParserTest(unittest.TestCase):
    studentenwerk_menu_parser = StudentenwerkMenuParser()

    menu_html_garching = html.fromstring(
        open("src/test/assets/speiseplan_garching.html").read())
    menu_html_arcisstrasse = html.fromstring(
        open("src/test/assets/speiseplan_arcisstrasse.html").read())
    menu_html_großhadern = html.fromstring(
        open("src/test/assets/speiseplan_großhadern.html").read())
    menu_html_wrong_date_format = html.fromstring(
        open("src/test/assets/speiseplan_garching_wrong_date_format.html").
        read())

    menu1_date = date(2017, 3, 27)
    menu2_date = date(2017, 4, 3)
    menu3_date = date(2017, 4, 4)

    # dishes in Garching
    dish1_1_garching = Dish("Kartoffelgulasch mit Paprika", 1, set())
    dish1_2_garching = Dish("Hackfleischbällchen mit Champignonrahmsauce", 1.9,
                            set(["R", "S", "Ei", "Gl", "GlW", "Kn", "Mi"]))
    dish1_3_garching = Dish(
        "Seelachsfilet (MSC) im Sesammantel mit Remouladensauce", 2.4,
        set(["1", "2", "3", "9", "Ei", "Fi", "Gl", "GlW", "Mi", "Se", "Sf"]))
    dish1_4_garching = Dish(
        "Gebackene Calamari-Ringe mit Remouladensauce", 2.6,
        set(["1", "2", "3", "9", "Ei", "Gl", "GlW", "Mi", "Sf", "Wt"]))

    dish2_1_garching = Dish("Kartoffeleintopf mit Majoran", 1, set(["Sl"]))
    dish2_2_garching = Dish("Gulasch vom Schwein", 1.9,
                            set(["S", "Gl", "GlG", "GlW", "Kn", "Mi"]))
    dish2_3_garching = Dish("Paniertes Hähnchenschnitzel", 2.4,
                            set(["Gl", "GlW", "GlG", "Kn", "Mi", "Sl"]))

    menu1_garching = Menu(menu1_date, [
        dish1_1_garching, dish1_2_garching, dish1_3_garching, dish1_4_garching
    ])
    menu2_garching = Menu(
        menu2_date, [dish2_1_garching, dish2_2_garching, dish2_3_garching])

    # dishes in Arcisstrasse
    dish1_1_arcisstrasse = Dish("Kartoffelgulasch mit Paprika", 1, set())
    dish1_2_arcisstrasse = Dish("Hackfleischbällchen mit Champignonrahmsauce",
                                1.55,
                                set(["R", "S", "Ei", "Gl", "GlW", "Kn", "Mi"]))
    dish1_3_arcisstrasse = Dish(
        "Hackfleischbällchen mit Champignonrahmsauce (2)", 1.9,
        set(["R", "S", "Ei", "Gl", "GlW", "Kn", "Mi"]))
    dish1_4_arcisstrasse = Dish("Pasta Pomodori", 1.9, set(["Gl", "GlW",
                                                            "Kn"]))
    dish1_5_arcisstrasse = Dish(
        "Gebackene Calamari-Ringe mit Zitronen-Knoblauch-Dip", 2.6,
        set(["1", "2", "3", "9", "Ei", "Gl", "GlW", "Kn", "Mi", "Sf", "Wt"]))
    dish1_6_arcisstrasse = Dish(
        "Seelachsfilet (MSC) im Sesammantel mit Zitronen-Knoblauch-Dip", 2.6,
        set(["1", "3", "9", "Ei", "Fi", "Gl", "GlW", "Kn", "Mi", "Se", "Sf"]))
    dish1_7_arcisstrasse = Dish("Pasta Pomodori (2)", "0.68€ / 100g",
                                set(["Gl", "GlW", "Kn"]))
    dish1_8_arcisstrasse = Dish("Kartoffelgulasch mit Paprika (2)",
                                "0.68€ / 100g", set())
    dish1_9_arcisstrasse = Dish("Pasta mit Sojabolognese", "0.68€ / 100g",
                                set(["Sl", "So"]))
    menu1_arcisstrasse = Menu(menu1_date, [
        dish1_1_arcisstrasse, dish1_2_arcisstrasse, dish1_3_arcisstrasse,
        dish1_4_arcisstrasse, dish1_5_arcisstrasse, dish1_6_arcisstrasse,
        dish1_7_arcisstrasse, dish1_8_arcisstrasse, dish1_9_arcisstrasse
    ])

    # dishes in Großhadern
    dish1_1_großhadern = Dish("Pasta-Gemüse-Auflauf mit Tomatensauce", 1.9,
                              set(["1", "Ei", "Gl", "GlW", "Kn", "Mi"]))
    dish1_2_großhadern = Dish(
        "Rinderroulade nach Hausfrauenart mit Senf-Gemüse-Sauce", 3,
        set([
            "R", "S", "2", "3", "99", "Gl", "GlG", "GlW", "Kn", "Mi", "Sf",
            "Sl", "Sw"
        ]))
    menu1_großhadern = Menu(menu3_date,
                            [dish1_1_großhadern, dish1_2_großhadern])

    def test_Should_ReturnMenu_When_PassedDateIsCorrect(self):
        self.assertEqual(
            self.menu1_garching,
            self.studentenwerk_menu_parser.get_menus(
                self.menu_html_garching, "mensa-garching")[self.menu1_date])
        self.assertEqual(
            self.menu2_garching,
            self.studentenwerk_menu_parser.get_menus(
                self.menu_html_garching, "mensa-garching")[self.menu2_date])

        self.assertEqual(
            self.menu1_arcisstrasse,
            self.studentenwerk_menu_parser.get_menus(
                self.menu_html_arcisstrasse,
                "mensa-arcisstrasse")[self.menu1_date])

        self.assertEqual(
            self.menu1_großhadern,
            self.studentenwerk_menu_parser.get_menus(
                self.menu_html_großhadern,
                "stubistro-grosshadern")[self.menu3_date])

    def test_Should_IgnoreDay_When_DateOfTheDayIsInAWrongFormat(self):
        self.assertEqual(
            22,
            len(
                self.studentenwerk_menu_parser.get_menus(
                    self.menu_html_wrong_date_format, "mensa-garching")))

    def test_Should_ReturnWeeks_When_ConvertingMenuToWeekObjects(self):
        menus = self.studentenwerk_menu_parser.get_menus(
            self.menu_html_garching, "mensa-garching")
        weeks_actual = Week.to_weeks(menus)
        length_weeks_actual = len(weeks_actual)

        self.assertEqual(5, length_weeks_actual)
        for calendar_week in weeks_actual:
            week = weeks_actual[calendar_week]
            week_length = len(week.days)
            # calendar weeks 15 and 16 have one day less, because of a holiday
            if calendar_week == 15 or calendar_week == 16:
                self.assertEqual(4, week_length)
            else:
                self.assertEqual(5, week_length)

    def order_json_objects(self, obj):
        """
        Recusively orders all elemts in a Json object.
        Source: https://stackoverflow.com/questions/25851183/how-to-compare-two-json-objects-with-the-same-elements-in-a-different-order-equa
        """
        if isinstance(obj, dict):
            return sorted(
                (k, self.order_json_objects(v)) for k, v in obj.items())
        if isinstance(obj, list):
            return sorted(self.order_json_objects(x) for x in obj)
        else:
            return obj

    def test_Should_ConvertWeekToJSON(self):
        with open('src/test/assets/speiseplan_garching_kw2017-13.json'
                  ) as data_file:
            week_2017_13 = json.load(data_file)
        with open('src/test/assets/speiseplan_garching_kw2017-14.json'
                  ) as data_file:
            week_2017_14 = json.load(data_file)
        with open('src/test/assets/speiseplan_garching_kw2017-15.json'
                  ) as data_file:
            week_2017_15 = json.load(data_file)
        with open('src/test/assets/speiseplan_garching_kw2017-16.json'
                  ) as data_file:
            week_2017_16 = json.load(data_file)
        with open('src/test/assets/speiseplan_garching_kw2017-17.json'
                  ) as data_file:
            week_2017_17 = json.load(data_file)

        menus = self.studentenwerk_menu_parser.get_menus(
            self.menu_html_garching, "mensa-garching")
        weeks = Week.to_weeks(menus)
        week_2017_13_actual = json.loads(weeks[13].to_json())
        week_2017_14_actual = json.loads(weeks[14].to_json())
        week_2017_15_actual = json.loads(weeks[15].to_json())
        week_2017_16_actual = json.loads(weeks[16].to_json())
        week_2017_17_actual = json.loads(weeks[17].to_json())

        a = self.order_json_objects(week_2017_13_actual)
        b = self.order_json_objects(week_2017_13)

        self.assertEqual(self.order_json_objects(week_2017_13_actual),
                         self.order_json_objects(week_2017_13))
        self.assertEqual(self.order_json_objects(week_2017_14_actual),
                         self.order_json_objects(week_2017_14))
        self.assertEqual(self.order_json_objects(week_2017_15_actual),
                         self.order_json_objects(week_2017_15))
        self.assertEqual(self.order_json_objects(week_2017_16_actual),
                         self.order_json_objects(week_2017_16))
        self.assertEqual(self.order_json_objects(week_2017_17_actual),
                         self.order_json_objects(week_2017_17))

    def test_Should_CreateCorrectDirectoriesAndJSONFiles(self):
        # parse menu
        menus = self.studentenwerk_menu_parser.get_menus(
            self.menu_html_garching, "mensa-garching")
        # get weeks
        weeks = Week.to_weeks(menus)

        # create temp dir for testing
        with tempfile.TemporaryDirectory() as temp_dir:
            # store output in the tempdir
            # location can be an empty string because combination won't get tested (combine_dishes is False) here
            main.jsonify(weeks, temp_dir, "", False)

            # check if two directories are created (one for 2016 and 2017)
            created_dirs = [
                name for name in os.listdir(temp_dir)
                if os.path.isdir(os.path.join(temp_dir, name))
            ]
            created_dirs.sort()
            self.assertEqual(1, len(created_dirs))
            self.assertEqual("2017", created_dirs[0])

            # check if the created directories contain the JSON files
            dir_2017 = "%s/2017" % temp_dir
            files_in_2017 = [
                name for name in os.listdir(dir_2017)
                if os.path.isfile(os.path.join(dir_2017, name))
            ]
            files_in_2017.sort()
            self.assertEqual(
                ["13.json", "14.json", "15.json", "16.json", "17.json"],
                files_in_2017)
Пример #13
0
class StudentenwerkMenuParserTest(unittest.TestCase):
    studentenwerk_menu_parser = StudentenwerkMenuParser()

    menu_html_garching = html.fromstring(
        open("src/test/assets/speiseplan_garching.html").read())
    menu_html_arcisstrasse = html.fromstring(
        open("src/test/assets/speiseplan_arcisstrasse.html").read())
    menu_html_großhadern = html.fromstring(
        open("src/test/assets/speiseplan_großhadern.html").read())
    menu_html_wrong_date_format = html.fromstring(
        open("src/test/assets/speiseplan_garching_wrong_date_format.html").
        read())

    menu1_date = date(2017, 3, 27)
    menu2_date = date(2017, 4, 3)
    menu3_date = date(2017, 4, 4)

    # dishes in Garching
    dish1_1_garching = Dish("Kartoffelgulasch mit Paprika", 1)
    dish1_2_garching = Dish("Hackfleischbällchen mit Champignonrahmsauce", 1.9)
    dish1_3_garching = Dish(
        "Seelachsfilet (MSC) im Sesammantel mit Remouladensauce", 2.4)
    dish1_4_garching = Dish("Gebackene Calamari-Ringe mit Remouladensauce",
                            2.6)

    dish2_1_garching = Dish("Kartoffeleintopf mit Majoran", 1)
    dish2_2_garching = Dish("Gulasch vom Schwein", 1.9)
    dish2_3_garching = Dish("Paniertes Hähnchenschnitzel", 2.4)

    menu1_garching = Menu(menu1_date, [
        dish1_1_garching, dish1_2_garching, dish1_3_garching, dish1_4_garching
    ])
    menu2_garching = Menu(
        menu2_date, [dish2_1_garching, dish2_2_garching, dish2_3_garching])

    # dishes in Arcisstrasse
    dish1_1_arcisstrasse = Dish("Kartoffelgulasch mit Paprika", 1)
    dish1_2_arcisstrasse = Dish("Hackfleischbällchen mit Champignonrahmsauce",
                                1.55)
    dish1_3_arcisstrasse = Dish(
        "Hackfleischbällchen mit Champignonrahmsauce (2)", 1.9)
    dish1_4_arcisstrasse = Dish("Pasta Pomodori", 1.9)
    dish1_5_arcisstrasse = Dish(
        "Gebackene Calamari-Ringe mit Zitronen-Knoblauch-Dip", 2.6)
    dish1_6_arcisstrasse = Dish(
        "Seelachsfilet (MSC) im Sesammantel mit Zitronen-Knoblauch-Dip", 2.6)
    dish1_7_arcisstrasse = Dish("Pasta Pomodori (2)", "0.68€ / 100g")
    dish1_8_arcisstrasse = Dish("Kartoffelgulasch mit Paprika (2)",
                                "0.68€ / 100g")
    dish1_9_arcisstrasse = Dish("Pasta mit Sojabolognese", "0.68€ / 100g")
    menu1_arcisstrasse = Menu(menu1_date, [
        dish1_1_arcisstrasse, dish1_2_arcisstrasse, dish1_3_arcisstrasse,
        dish1_4_arcisstrasse, dish1_5_arcisstrasse, dish1_6_arcisstrasse,
        dish1_7_arcisstrasse, dish1_8_arcisstrasse, dish1_9_arcisstrasse
    ])

    # dishes in Großhadern
    dish1_1_großhadern = Dish("Pasta-Gemüse-Auflauf mit Tomatensauce", 1.9)
    dish1_2_großhadern = Dish(
        "Rinderroulade nach Hausfrauenart mit Senf-Gemüse-Sauce", 3)
    menu1_großhadern = Menu(menu3_date,
                            [dish1_1_großhadern, dish1_2_großhadern])

    def test_Should_ReturnMenu_When_PassedDateIsCorrect(self):
        self.assertEqual(
            self.menu1_garching,
            self.studentenwerk_menu_parser.get_menus(
                self.menu_html_garching)[self.menu1_date])
        self.assertEqual(
            self.menu2_garching,
            self.studentenwerk_menu_parser.get_menus(
                self.menu_html_garching)[self.menu2_date])

        self.assertEqual(
            self.menu1_arcisstrasse,
            self.studentenwerk_menu_parser.get_menus(
                self.menu_html_arcisstrasse)[self.menu1_date])

        self.assertEqual(
            self.menu1_großhadern,
            self.studentenwerk_menu_parser.get_menus(
                self.menu_html_großhadern)[self.menu3_date])

    def test_Should_IgnoreDay_When_DateOfTheDayIsInAWrongFormat(self):
        self.assertEqual(
            22,
            len(
                self.studentenwerk_menu_parser.get_menus(
                    self.menu_html_wrong_date_format)))

    def test_Should_ReturnWeeks_When_ConvertingMenuToWeekObjects(self):
        menus = self.studentenwerk_menu_parser.get_menus(
            self.menu_html_garching)
        weeks_actual = Week.to_weeks(menus)
        length_weeks_actual = len(weeks_actual)

        self.assertEqual(5, length_weeks_actual)
        for calendar_week in weeks_actual:
            week = weeks_actual[calendar_week]
            week_length = len(week.days)
            # calendar weeks 15 and 16 have one day less, because of a holiday
            if calendar_week == 15 or calendar_week == 16:
                self.assertEqual(4, week_length)
            else:
                self.assertEqual(5, week_length)

    def test_Should_ConvertWeekToJSON(self):
        with open('src/test/assets/speiseplan_garching_kw2017-13.json'
                  ) as data_file:
            week_2017_13 = json.load(data_file)
        with open('src/test/assets/speiseplan_garching_kw2017-14.json'
                  ) as data_file:
            week_2017_14 = json.load(data_file)
        with open('src/test/assets/speiseplan_garching_kw2017-15.json'
                  ) as data_file:
            week_2017_15 = json.load(data_file)
        with open('src/test/assets/speiseplan_garching_kw2017-16.json'
                  ) as data_file:
            week_2017_16 = json.load(data_file)
        with open('src/test/assets/speiseplan_garching_kw2017-17.json'
                  ) as data_file:
            week_2017_17 = json.load(data_file)

        menus = self.studentenwerk_menu_parser.get_menus(
            self.menu_html_garching)
        weeks = Week.to_weeks(menus)
        week_2017_13_actual = json.loads(weeks[13].to_json())
        week_2017_14_actual = json.loads(weeks[14].to_json())
        week_2017_15_actual = json.loads(weeks[15].to_json())
        week_2017_16_actual = json.loads(weeks[16].to_json())
        week_2017_17_actual = json.loads(weeks[17].to_json())

        self.assertEqual(sorted(week_2017_13_actual.items()),
                         sorted(week_2017_13.items()))
        self.assertEqual(sorted(week_2017_14_actual.items()),
                         sorted(week_2017_14.items()))
        self.assertEqual(sorted(week_2017_15_actual.items()),
                         sorted(week_2017_15.items()))
        self.assertEqual(sorted(week_2017_16_actual.items()),
                         sorted(week_2017_16.items()))
        self.assertEqual(sorted(week_2017_17_actual.items()),
                         sorted(week_2017_17.items()))

    def test_Should_CreateCorrectDirectoriesAndJSONFiles(self):
        # parse menu
        menus = self.studentenwerk_menu_parser.get_menus(
            self.menu_html_garching)
        # get weeks
        weeks = Week.to_weeks(menus)

        # create temp dir for testing
        with tempfile.TemporaryDirectory() as temp_dir:
            # store output in the tempdir
            # location can be an empty string because combination won't get tested (combine_dishes is False) here
            main.jsonify(weeks, temp_dir, "", False)

            # check if two directories are created (one for 2016 and 2017)
            created_dirs = [
                name for name in os.listdir(temp_dir)
                if os.path.isdir(os.path.join(temp_dir, name))
            ]
            created_dirs.sort()
            self.assertEqual(1, len(created_dirs))
            self.assertEqual("2017", created_dirs[0])

            # check if the created directories contain the JSON files
            dir_2017 = "%s/2017" % temp_dir
            files_in_2017 = [
                name for name in os.listdir(dir_2017)
                if os.path.isfile(os.path.join(dir_2017, name))
            ]
            files_in_2017.sort()
            self.assertEqual(
                ["13.json", "14.json", "15.json", "16.json", "17.json"],
                files_in_2017)
Пример #14
0
class IPPBistroParserTest(unittest.TestCase):
    ipp_parser = IPPBistroMenuParser()
    test_menu1 = open('src/test/assets/ipp/KW-47_20.11-24.11.2017-1.txt',
                      'r').read()
    year1 = 2017
    week_number1 = 47
    test_menu2 = open('src/test/assets/ipp/KW-48_27.11-01.12.10.2017-3.txt',
                      'r').read()
    year2 = 2017
    week_number2 = 48

    date_mon1 = date(2017, 11, 20)
    date_tue1 = date(2017, 11, 21)
    date_wed1 = date(2017, 11, 22)
    date_thu1 = date(2017, 11, 23)
    date_fri1 = date(2017, 11, 24)
    dish1_mon1 = Dish("Gefüllter Germknödel mit Vanillesauce", 3.5)
    dish2_mon1 = Dish(
        "Ofengulasch vom Rind mit Kürbis und Pflaumen, dazu Rigatoni", 5.5)
    dish3_mon1 = Dish(
        "\"Palek Tofu\" Gebratener Tofu mit Spinat, Ingwer, Curry-Sahnesauce und Basmatireis",
        5.2)
    dish4_mon1 = Dish(
        "Gebratene Hähnchenbrust auf Fenchelgemüse, dazu Kräuterreis und Orangensauce",
        6.9)
    dish1_tue1 = Dish(
        "Gebratene Weißkohl-Kartoffelpfanne mit gerösteten Sonnenblumenkernen",
        3.5)
    dish2_tue1 = Dish("Jägerschnitzel mit Spätzle oder Reis", 4.8)
    dish3_tue1 = Dish(
        "Vegetarisch gefüllte Tortelli mit leichter Zitronen-Buttersauce und gehobeltem Parmesan",
        4.8)
    dish4_tue1 = Dish("\"Bami Goreng\" indonesische Bratnudeln mit Gemüse, Huhn, Schweinefleisch und Pilzen, " \
                                   "dazu Honig-Chili- Dip", 6.9)
    dish1_wed1 = Dish("Erbseneintopf (mit Wienerle 4,20 €)", 3.5)
    # TODO fix "B"
    dish2_wed1 = Dish("Hackbraten mit Zigeunersauce und Reis B", 4.8)
    dish3_wed1 = Dish(
        "\"Farfalle Rustico\" mit Champignons, Schinken Tomaten und Peperoni (auf Wunsch mit "
        "Reibekäse)", 4.6)
    dish4_wed1 = Dish("Rumpsteak mit Balsamico Pilzen und Wedges", 7.9)
    dish1_thu1 = Dish(
        "Mediterrane Frittata mit Zucchini, Kartoffeln, Paprika, kleiner Salatbeilage und "
        "Joghurt-Limetten Dip", 3.5)
    # TODO fix bug that B of Brett is missing -> rett
    dish2_thu1 = Dish(
        "Frischer Bayrischer Schweinenackenbraten vom rett geschnitten dazu Kartoffel- Gurkensalat",
        4.5)
    dish3_thu1 = Dish(
        "\"Enchilada Verdura\", überbackene Weizentortilla, gefüllt mit Hähnchenfleisch, Sauerrahm, "
        "Kidneybohnen, Mais, dazu", 5.9)
    dish4_thu1 = Dish(
        "\"Lamm Palak\" mit Spinat und Curry (mittelscharf), dazu Reis", 6.9)
    dish1_fri1 = Dish("Nudelpfanne mit Gemüsesauce (auf Wunsch mit Reibekäse)",
                      3.5)
    dish2_fri1 = Dish("Matjes \"Hausfrauen Art\" mit Salzkartoffeln", 5.2)
    dish3_fri1 = Dish("Currygeschnetzeltes von der Pute mit Früchten und Reis",
                      4.9)
    dish4_fri1 = Dish("Honig-Kassler mit Apfel-Spitzkohl und Kartoffelspalten",
                      6.2)
    menu_mon1 = Menu(date_mon1,
                     [dish1_mon1, dish2_mon1, dish3_mon1, dish4_mon1])
    menu_tue1 = Menu(date_tue1,
                     [dish1_tue1, dish2_tue1, dish3_tue1, dish4_tue1])
    menu_wed1 = Menu(date_wed1,
                     [dish1_wed1, dish2_wed1, dish3_wed1, dish4_wed1])
    menu_thu1 = Menu(date_thu1,
                     [dish1_thu1, dish2_thu1, dish3_thu1, dish4_thu1])
    menu_fri1 = Menu(date_fri1,
                     [dish1_fri1, dish2_fri1, dish3_fri1, dish4_fri1])

    date_mon2 = date(2017, 11, 27)
    date_tue2 = date(2017, 11, 28)
    date_wed2 = date(2017, 11, 29)
    date_thu2 = date(2017, 11, 30)
    date_fri2 = date(2017, 12, 1)
    dish1_mon2 = Dish("Wirsing-Kartoffelauflauf mit Bechamel und Käse", 3.5)
    dish2_mon2 = Dish("Paprikarahm Geschnetzeltes mit Paprikamix und Nudeln",
                      4.8)
    dish3_mon2 = Dish(
        "\"Dal Curry\" mit Kartoffeln, Kokosmilch, Ingwer, Koriander, Reis und scharfem Chutney",
        4.9)
    # TODO fix missing "R" of "Rinderbraten"
    dish4_mon2 = Dish(
        "Deftiger Hüttenschmaus, inderrostbraten mit Zwiebeln, Semmelknödel und gebratenem Gemüse",
        7.9)
    dish1_tue2 = Dish("Herbstliche Gemüse-Reis Pfanne mit pikantem Mango Dip",
                      3.5)
    dish2_tue2 = Dish("Krautwickerl mit Speck-Zwieblsauce und Püree", 4.5)
    dish3_tue2 = Dish("Rigatoni mit Rosenkohl und Schnittlauch", 4.6)
    dish4_tue2 = Dish("Spanferkelrücken mit Knödel und Bayerisch Kraut", 6.8)
    dish1_wed2 = Dish(
        "Weißwurst Gröst ́l mit Knödel, Lauchzwiebeln, Karotten und Kräuter auf Wunsch mit "
        "Bratenjus", 3.5)
    dish2_wed2 = Dish("Estragonrahmschnitzel mit Pommes frites oder Reis", 4.6)
    dish3_wed2 = Dish("Gemüse Lasagne", 4.9)
    dish4_wed2 = Dish(
        "\"Tandoori Chicken\" mit Auberginen, Tomaten, Zucchini, Zitronenschale Minze und Reis",
        6.9)
    dish1_thu2 = Dish("Rote Beete Eintopf mit Kartoffeln, Nudeln und Dill",
                      3.5)
    dish2_thu2 = Dish(
        "Sauerbraten \"Nepal\" mit weißen Bohnen, getrockneten Tomaten und Pasta",
        5.8)
    dish3_thu2 = Dish(
        "\"Kaku Chicken\" mit geröstetem Curry, Kokosraspel, Tomaten und Reis",
        6.9)
    dish4_thu2 = Dish(
        "Leberkäs Burger special mit Pommes frites und Cole slaw", 4.8)
    dish1_fri2 = Dish("Exotische Linsen-Spätzle Pfanne", 3.5)
    dish2_fri2 = Dish(
        "Seelachsfilet gebacken mit Sardellenmayonnaise und Pommes frites",
        4.6)
    dish3_fri2 = Dish("Gemüse-Linguini mit Pesto-Rahmsauce und Parmesankäse",
                      4.4)
    dish4_fri2 = Dish(
        "Schweinefilet Medaillons in grüner Pfefferrahmsauce mit Kroketten und karamellisierten "
        "Möhren", 7.2)

    menu_mon2 = Menu(date_mon2,
                     [dish1_mon2, dish2_mon2, dish3_mon2, dish4_mon2])
    menu_tue2 = Menu(date_tue2,
                     [dish1_tue2, dish2_tue2, dish3_tue2, dish4_tue2])
    menu_wed2 = Menu(date_wed2,
                     [dish1_wed2, dish2_wed2, dish3_wed2, dish4_wed2])
    menu_thu2 = Menu(date_thu2,
                     [dish1_thu2, dish2_thu2, dish3_thu2, dish4_thu2])
    menu_fri2 = Menu(date_fri2,
                     [dish1_fri2, dish2_fri2, dish3_fri2, dish4_fri2])

    def test_Should_Return_Menu1(self):
        menus_actual1 = self.ipp_parser.get_menus(self.test_menu1, self.year1,
                                                  self.week_number1)
        self.assertEqual(5, len(menus_actual1))
        self.assertEqual(self.menu_mon1, menus_actual1[self.date_mon1])
        self.assertEqual(self.menu_tue1, menus_actual1[self.date_tue1])
        self.assertEqual(self.menu_wed1, menus_actual1[self.date_wed1])
        self.assertEqual(self.menu_thu1, menus_actual1[self.date_thu1])
        self.assertEqual(self.menu_fri1, menus_actual1[self.date_fri1])

    def test_Should_Return_Menu2(self):
        menus_actual2 = self.ipp_parser.get_menus(self.test_menu2, self.year2,
                                                  self.week_number2)
        self.assertEqual(5, len(menus_actual2))
        self.assertEqual(self.menu_mon2, menus_actual2[self.date_mon2])
        self.assertEqual(self.menu_tue2, menus_actual2[self.date_tue2])
        self.assertEqual(self.menu_wed2, menus_actual2[self.date_wed2])
        self.assertEqual(self.menu_thu2, menus_actual2[self.date_thu2])
        self.assertEqual(self.menu_fri2, menus_actual2[self.date_fri2])
Пример #15
0
    def get_menus(self, text, year, week_number):
        menus = {}
        count = 0
        lines = text.replace("Extraessen", "").splitlines()
        for line in lines:
            if "Montag" in line:
                break

            count += 1

        lines = lines[count:]

        # get rid of Zusatzstoffe and Allergene: everything below the last ***-delimiter is irrelevant
        last_relevant_line = len(lines)
        for index, line in enumerate(lines):
            if "***" in line:
                last_relevant_line = index
        lines = lines[:last_relevant_line]

        days_list = [
            d for d in re.split(
                r"(Montag|Dienstag|Mittwoch|Donnerstag|Freitag|Samstag|Sonntag),\s\d{1,2}.\d{1,2}.\d{4}",
                "\n".join(lines).replace("*", "").strip()) if d not in [
                    "", "Montag", "Dienstag", "Mittwoch", "Donnerstag",
                    "Freitag", "Samstag", "Sonntag"
                ]
        ]
        if len(days_list) != 7:
            # as the Mediziner Mensa is part of hospital, it should serve food on each day
            return None
        days = {
            "mon": days_list[0],
            "tue": days_list[1],
            "wed": days_list[2],
            "thu": days_list[3],
            "fri": days_list[4],
            "sat": days_list[5],
            "sun": days_list[6]
        }

        for key in days:
            day_lines = unicodedata.normalize("NFKC",
                                              days[key]).splitlines(True)
            soup_str = ""
            mains_str = ""
            for day_line in day_lines:
                soup_str += day_line[:36].strip() + "\n"
                mains_str += day_line[40:100].strip() + "\n"

            soup = soup_str.replace("-\n", "").strip().replace("\n", " ")
            mains = [soup] + [
                m.strip().replace("\n", " ")
                # https://regex101.com/r/MDFu1Z/1
                for m in re.split(r"(\n{2,}|(?<!mit)\n(?=[A-Z]))", mains_str)
                if m is not ""
            ]
            mains = [
                re.sub(r"\s(([A-Z]|\d),?)+\s?(?!(\w|\d))", "",
                       m.replace("€", "")).strip() for m in mains
                if m not in ["", "Feiertag"]
            ]
            # TODO prices
            dishes = [Dish(dish_name, "N/A") for dish_name in mains]
            date = self.get_date(year, week_number,
                                 self.weekday_positions[key])
            menu = Menu(date, dishes)
            # remove duplicates
            menu.remove_duplicates()
            menus[date] = menu

        return menus
Пример #16
0
    def get_menus(self, text, year, week_number):
        menus = {}
        lines = text.splitlines()
        count = 0
        # remove headline etc.
        for line in lines:
            if line.replace(" ", "").replace(
                    "\n",
                    "").lower() == "montagdienstagmittwochdonnerstagfreitag":
                break

            count += 1

        lines = lines[count:]
        weekdays = lines[0]

        # The column detection is done through the string "Tagessuppe siehe Aushang" which is at the beginning of
        # every column. However, due to center alignment the column do not begin at the 'T' character and broader
        # text in the column might be left of this character, which then gets truncated. But the gap between the 'T'
        # and the '€' character of the previous column¹ — the real beginning of the current column — is always three,
        # which will be subtracted here. Monday is the second column, so the value should never become negative
        # although it is handled here.
        # ¹or 'e' of "Internationale Küche" if it is the monday column

        # find lines which match the regex
        soup_lines_iter = (x for x in lines if self.split_days_regex.search(x))

        soup_line1 = next(soup_lines_iter)
        soup_line2 = next(soup_lines_iter, '')

        positions1 = [(max(a.start() - 3, 0), a.end()) for a in list(
            re.finditer(self.split_days_regex_soup_one_line, soup_line1))]
        # In the second line there is just 'Aushang' (two lines "Tagessuppe siehe Aushang" or
        # closed days ("Geschlossen", "Feiertag")
        positions2 = [(max(a.start() - 14, 0), a.end() + 3) for a in list(
            re.finditer(self.split_days_regex_soup_two_line, soup_line2))]
        positions3 = [(max(a.start() - 3, 0), a.end()) for a in list(
            re.finditer(self.split_days_regex_closed, soup_line2))]

        if positions2:  # Two lines "Tagessuppe siehe Aushang"
            soup_line_index = lines.index(soup_line2)
        else:
            soup_line_index = lines.index(soup_line1)

        positions = sorted(positions1 + positions2 + positions3)

        if len(positions) != 5:
            warn(
                "IPP PDF parsing of week {} in year {} failed. Only {} of 5 columns detected."
                .format(week_number, year, len(positions)))
            return None

        pos_mon = positions[0][0]
        pos_tue = positions[1][0]
        pos_wed = positions[2][0]
        pos_thu = positions[3][0]
        pos_fri = positions[4][0]

        lines_weekdays = {
            "mon": "",
            "tue": "",
            "wed": "",
            "thu": "",
            "fri": ""
        }
        # it must be lines[3:] instead of lines[2:] or else the menus would start with "Preis ab 0,90€" (from the
        # soups) instead of the first menu, if there is a day where the bistro is closed.
        for line in lines[soup_line_index + 3:]:
            lines_weekdays["mon"] += " " + line[pos_mon:pos_tue].replace(
                "\n", " ")
            lines_weekdays["tue"] += " " + line[pos_tue:pos_wed].replace(
                "\n", " ")
            lines_weekdays["wed"] += " " + line[pos_wed:pos_thu].replace(
                "\n", " ")
            lines_weekdays["thu"] += " " + line[pos_thu:pos_fri].replace(
                "\n", " ")
            lines_weekdays["fri"] += " " + line[pos_fri:].replace("\n", " ")

        for key in lines_weekdays:
            # get rid of two-character umlauts (e.g. SMALL_LETTER_A+COMBINING_DIACRITICAL_MARK_UMLAUT)
            lines_weekdays[key] = unicodedata.normalize(
                "NFKC", lines_weekdays[key])
            # remove multi-whitespaces
            lines_weekdays[key] = ' '.join(lines_weekdays[key].split())
            # get all dish including name and price
            dish_names = re.findall(self.dish_regex, lines_weekdays[key] + " ")
            # get dish prices
            prices = re.findall(self.price_regex, ' '.join(dish_names))
            # convert prices to float
            prices = [
                float(price.replace("€", "").replace(",", ".").strip())
                for price in prices
            ]
            # remove price and commas from dish names
            dish_names = [
                re.sub(self.price_regex, "", dish).strip()
                for dish in dish_names
            ]
            # create list of Dish objects
            dishes = [
                Dish(dish_name, price)
                for (dish_name, price) in list(zip(dish_names, prices))
            ]
            date = self.get_date(year, week_number,
                                 self.weekday_positions[key])
            # create new Menu object and add it to dict
            menu = Menu(date, dishes)
            # remove duplicates
            menu.remove_duplicates()
            menus[date] = menu

        return menus
Пример #17
0
    def test_Should_Add_Week_to_Canteen(self):
        date_mon2 = date(2017, 11, 6)
        date_tue2 = date(2017, 11, 7)
        date_wed2 = date(2017, 11, 8)
        date_thu2 = date(2017, 11, 9)
        date_fri2 = date(2017, 11, 10)
        dish_aktion2 = Dish(
            "Pochiertes Lachsfilet mit Dillsoße dazu Minze-Reis", 6.5,
            set(["Sl", "Mi"]), "Tagesgericht")
        dish1_mon2 = Dish("Dampfkartoffeln mit Zucchinigemüse", 3.6,
                          set(["Sl"]), "Tagesgericht")
        dish2_mon2 = Dish("Valess-Schnitzel mit Tomaten-Couscous", 4.3,
                          set(["Sl", "Gl", "Ei", "Mi"]), "Tagesgericht")
        dish3_mon2 = Dish("Kasslerpfanne mit frischen Champignons und Spätzle",
                          4.9, set(["Sl", "Mi"]), "Tagesgericht")
        dish1_tue2 = Dish("Gemüsereispfanne mit geräuchertem Tofu", 3.6,
                          set(["Sl"]), "Tagesgericht")
        dish2_tue2 = Dish(
            "Schweineschnitzel in Karottenpanade mit Rosmarin- Risoleekartoffeln",
            5.3, set(["Sl", "Gl", "Ei"]), "Tagesgericht")
        dish1_wed2 = Dish("Spaghetti al Pomodoro", 3.6, set(["Sl", "Gl"]),
                          "Tagesgericht")
        dish2_wed2 = Dish(
            "Krustenbraten vom Schwein mit Kartoffelknödel und Krautsalat",
            5.3, set(["Sl", "Gl"]), "Tagesgericht")
        dish1_thu2 = Dish("Red-Thaicurrysuppe mit Gemüse und Kokosmilch", 2.9,
                          set(["Sl"]), "Tagesgericht")
        dish2_thu2 = Dish("Senf-Eier mit Salzkartoffeln", 3.8,
                          set(["Sl", "Sf", "Mi"]), "Tagesgericht")
        dish3_thu2 = Dish("Putengyros mit Zaziki und Tomatenreis", 5.3,
                          set(["Sl", "Mi"]), "Tagesgericht")
        dish1_fri2 = Dish("Spiralnudeln mit Ratatouillegemüse", 3.6,
                          set(["Gl"]), "Tagesgericht")
        dish2_fri2 = Dish("Milchreis mit warmen Sauerkirschen", 3, set(["Mi"]),
                          "Tagesgericht")
        dish3_fri2 = Dish("Lasagne aus Seelachs und Blattspinat", 5.3,
                          set(["Sl", "Gl", "Mi"]), "Tagesgericht")
        menu_mon2 = Menu(date_mon2,
                         [dish_aktion2, dish1_mon2, dish2_mon2, dish3_mon2])
        menu_tue2 = Menu(date_tue2, [dish_aktion2, dish1_tue2, dish2_tue2])
        menu_wed2 = Menu(date_wed2, [dish_aktion2, dish1_wed2, dish2_wed2])
        menu_thu2 = Menu(date_thu2,
                         [dish_aktion2, dish1_thu2, dish2_thu2, dish3_thu2])
        menu_fri2 = Menu(date_fri2,
                         [dish_aktion2, dish1_fri2, dish2_fri2, dish3_fri2])
        week = Week(45, 2017,
                    [menu_mon2, menu_tue2, menu_wed2, menu_thu2, menu_fri2])
        week = {}
        week[date_mon2] = menu_mon2
        week[date_tue2] = menu_tue2
        week[date_wed2] = menu_wed2
        week[date_thu2] = menu_thu2
        week[date_fri2] = menu_fri2
        weeks = Week.to_weeks(week)

        canteen = openmensa.weeksToCanteenFeed(weeks)
        self.assertEqual(canteen.hasMealsFor(date_mon2), True)
        self.assertEqual(canteen.hasMealsFor(date_tue2), True)
        self.assertEqual(canteen.hasMealsFor(date_wed2), True)
        self.assertEqual(canteen.hasMealsFor(date_thu2), True)
        self.assertEqual(canteen.hasMealsFor(date_fri2), True)

        canteen_wed2 = canteen._days[date_wed2]['Speiseplan']
        self.assertEqual(
            canteen_wed2[0],
            ("Pochiertes Lachsfilet mit Dillsoße dazu Minze-Reis", [], {
                'other': 650
            }))
        self.assertEqual(canteen_wed2[1], ("Spaghetti al Pomodoro", [], {
            'other': 360
        }))
        self.assertEqual(
            canteen_wed2[2],
            ("Krustenbraten vom Schwein mit Kartoffelknödel und Krautsalat",
             [], {
                 'other': 530
             }))
Пример #18
0
class FMIBistroParserTest(unittest.TestCase):
    bistro_parser = FMIBistroMenuParser()
    test_menu1 = open('src/test/assets/fmi/Garching-Speiseplan_KW44_2017.txt',
                      'r').read()
    year1 = 2017
    week_number1 = 44
    test_menu2 = open('src/test/assets/fmi/Garching-Speiseplan_KW45_2017.txt',
                      'r').read()
    year2 = 2017
    week_number2 = 45

    date_mon1 = date(2017, 10, 30)
    date_thu1 = date(2017, 11, 2)
    date_fri1 = date(2017, 11, 3)

    dish_aktion1 = Dish(
        "Tellerfleisch mit Bouillonkartoffeln und Sahnemeerrettich Kaiserschmarrn mit Zwetschenröster",
        3.0, set(["Sl", "Mi"]))
    dish1_mon1 = Dish("Kurkumareis mit Asia Wokgemüse", 3.6, set(["Sl"]))
    dish2_mon1 = Dish(
        "Kartoffel „Cordon Bleu“ mit Frischkäse gefüllt dazu Blattsalate", 4.3,
        set(["Sl", "Ei", "Mi"]))
    dish3_mon1 = Dish(
        "Putenschnitzel natur mit Paprikarahmsoße dazu Ebly Gemüseweizen", 5.3,
        set(["Sl", "Mi"]))
    dish1_thu1 = Dish("Süßkartoffel Gemüsepfanne", 3.6, set(["Sl"]))
    dish2_thu1 = Dish("Gemüse Nudelauflauf", 4.3, set(["Sl", "Gl", "Mi"]))
    dish3_thu1 = Dish("Hähnchenspieß in Kokos Currysoße dazu Früchtereis", 5.3,
                      set(["Sl", "Mi"]))
    dish1_fri1 = Dish("Antipasti Rosmarinkartoffeln", 3.6, set(["Sl"]))
    dish2_fri1 = Dish("Schlemmerfilet auf Antipasti Rosmarinkartoffeln", 4.5,
                      set(["Sl"]))
    dish3_fri1 = Dish("Kaiserschmarrn mit Zwetschenröster", 3,
                      set(["Gl", "Ei", "Mi"]))
    menu_mon1 = Menu(date_mon1,
                     [dish_aktion1, dish1_mon1, dish2_mon1, dish3_mon1])
    menu_thu1 = Menu(date_thu1,
                     [dish_aktion1, dish1_thu1, dish2_thu1, dish3_thu1])
    menu_fri1 = Menu(date_fri1,
                     [dish_aktion1, dish1_fri1, dish2_fri1, dish3_fri1])

    date_mon2 = date(2017, 11, 6)
    date_tue2 = date(2017, 11, 7)
    date_wed2 = date(2017, 11, 8)
    date_thu2 = date(2017, 11, 9)
    date_fri2 = date(2017, 11, 10)
    dish_aktion2 = Dish("Pochiertes Lachsfilet mit Dillsoße dazu Minze-Reis",
                        6.5, set(["Sl", "Mi"]))
    dish1_mon2 = Dish("Dampfkartoffeln mit Zucchinigemüse", 3.6, set(["Sl"]))
    dish2_mon2 = Dish("Valess-Schnitzel mit Tomaten-Couscous", 4.3,
                      set(["Sl", "Gl", "Ei", "Mi"]))
    dish3_mon2 = Dish("Kasslerpfanne mit frischen Champignons und Spätzle",
                      4.9, set(["Sl", "Mi"]))
    dish1_tue2 = Dish("Gemüsereispfanne mit geräuchertem Tofu", 3.6,
                      set(["Sl"]))
    dish2_tue2 = Dish(
        "Schweineschnitzel in Karottenpanade mit Rosmarin- Risoleekartoffeln",
        5.3, set(["Sl", "Gl", "Ei"]))
    dish1_wed2 = Dish("Spaghetti al Pomodoro", 3.6, set(["Sl", "Gl"]))
    dish2_wed2 = Dish(
        "Krustenbraten vom Schwein mit Kartoffelknödel und Krautsalat", 5.3,
        set(["Sl", "Gl"]))
    dish1_thu2 = Dish("Red-Thaicurrysuppe mit Gemüse und Kokosmilch", 2.9,
                      set(["Sl"]))
    dish2_thu2 = Dish("Senf-Eier mit Salzkartoffeln", 3.8,
                      set(["Sl", "Sf", "Mi"]))
    dish3_thu2 = Dish("Putengyros mit Zaziki und Tomatenreis", 5.3,
                      set(["Sl", "Mi"]))
    dish1_fri2 = Dish("Spiralnudeln mit Ratatouillegemüse", 3.6, set(["Gl"]))
    dish2_fri2 = Dish("Milchreis mit warmen Sauerkirschen", 3, set(["Mi"]))
    dish3_fri2 = Dish("Lasagne aus Seelachs und Blattspinat", 5.3,
                      set(["Sl", "Gl", "Mi"]))
    menu_mon2 = Menu(date_mon2,
                     [dish_aktion2, dish1_mon2, dish2_mon2, dish3_mon2])
    menu_tue2 = Menu(date_tue2, [dish_aktion2, dish1_tue2, dish2_tue2])
    menu_wed2 = Menu(date_wed2, [dish_aktion2, dish1_wed2, dish2_wed2])
    menu_thu2 = Menu(date_thu2,
                     [dish_aktion2, dish1_thu2, dish2_thu2, dish3_thu2])
    menu_fri2 = Menu(date_fri2,
                     [dish_aktion2, dish1_fri2, dish2_fri2, dish3_fri2])

    def test_Should_Return_Menu(self):
        menus_actual1 = self.bistro_parser.get_menus(self.test_menu1,
                                                     self.year1,
                                                     self.week_number1)
        menus_actual2 = self.bistro_parser.get_menus(self.test_menu2,
                                                     self.year2,
                                                     self.week_number2)

        self.assertEqual(3, len(menus_actual1))
        self.assertEqual(self.menu_mon1, menus_actual1[self.date_mon1])
        self.assertEqual(self.menu_thu1, menus_actual1[self.date_thu1])
        self.assertEqual(self.menu_fri1, menus_actual1[self.date_fri1])

        self.assertEqual(5, len(menus_actual2))
        self.assertEqual(self.menu_mon2, menus_actual2[self.date_mon2])
        self.assertEqual(self.menu_tue2, menus_actual2[self.date_tue2])
        self.assertEqual(self.menu_wed2, menus_actual2[self.date_wed2])
        self.assertEqual(self.menu_thu2, menus_actual2[self.date_thu2])
        self.assertEqual(self.menu_fri2, menus_actual2[self.date_fri2])