def test_should_raise_when_missing_model_file(self): # Given self.tmp_file_path.mkdir() # When / Then with self.assertRaises(LoadingError): SnipsNLUEngine.from_path(self.tmp_file_path)
def test_should_raise_with_incompatible_model(self): # Given self.tmp_file_path.mkdir() engine_model_path = self.tmp_file_path / "nlu_engine.json" self.writeJsonContent(engine_model_path, {"model_version": "0.1.0"}) # When / Then with self.assertRaises(IncompatibleModelError): SnipsNLUEngine.from_path(self.tmp_file_path)
def test_train(self): # Given / When train(self.beverage_dataset_path, str(self.tmp_file_path)) # Then if not self.tmp_file_path.exists(): self.fail("No trained engine generated") msg = "Failed to create an engine from engine dict." with self.fail_if_exception(msg): SnipsNLUEngine.from_path(self.tmp_file_path)
def test_should_persist_resources_from_memory(self): # Given dataset_stream = io.StringIO(""" --- type: intent name: MakeTea utterances: - make me a [beverage_temperature:Temperature](hot) cup of tea - make me [number_of_cups:snips/number](five) tea cups --- type: intent name: MakeCoffee utterances: - make me [number_of_cups:snips/number](one) cup of coffee please - brew [number_of_cups] cups of coffee""") dataset = Dataset.from_yaml_files("en", [dataset_stream]).json shared = self.get_shared_data(dataset) engine = SnipsNLUEngine(**shared).fit(dataset) dir_temp_engine = self.fixture_dir / "temp_engine" engine.persist(dir_temp_engine) # When loaded_engine = SnipsNLUEngine.from_path(dir_temp_engine) shutil.rmtree(str(dir_temp_engine)) # Then loaded_engine.to_byte_array()
def test_should_parse_after_deserialization_from_dir(self): # Given dataset = BEVERAGE_DATASET engine = SnipsNLUEngine().fit(dataset) input_ = "Give me 3 cups of hot tea please" # When engine.persist(self.tmp_file_path) deserialized_engine = SnipsNLUEngine.from_path(self.tmp_file_path) result = deserialized_engine.parse(input_) # Then expected_slots = [ resolved_slot({ START: 8, END: 9 }, "3", { "kind": "Number", "value": 3.0 }, "snips/number", "number_of_cups"), custom_slot( unresolved_slot({ START: 18, END: 21 }, "hot", "Temperature", "beverage_temperature")) ] self.assertEqual(result[RES_INPUT], input_) self.assertEqual(result[RES_INTENT][RES_INTENT_NAME], "MakeTea") self.assertListEqual(result[RES_SLOTS], expected_slots)
def test_should_bypass_model_version_check_when_specified(self): # Given dataset_stream = io.StringIO(""" --- type: intent name: Greeting utterances: - hello world""") dataset = Dataset.from_yaml_files("en", [dataset_stream]).json with patch("snips_nlu.nlu_engine.nlu_engine.__model_version__", "0.1.0"): engine = SnipsNLUEngine().fit(dataset) engine.persist(self.tmp_file_path) # When / Then SnipsNLUEngine.from_path(self.tmp_file_path, bypass_version_check=True)
def test_should_be_deserializable_from_dir_when_empty(self): # Given engine = SnipsNLUEngine() engine.persist(self.tmp_file_path) # When engine = SnipsNLUEngine.from_path(self.tmp_file_path) # Then self.assertFalse(engine.fitted)
def test_should_parse_after_deserialization_from_dir(self): # Given dataset_stream = io.StringIO(""" --- type: intent name: MakeTea utterances: - make me a [beverage_temperature:Temperature](hot) cup of tea - make me [number_of_cups:snips/number](five) tea cups - i want [number_of_cups] cups of [beverage_temperature](boiling hot) tea pls - can you prepare [number_of_cups] cup of [beverage_temperature](cold) tea ? --- type: intent name: MakeCoffee utterances: - make me [number_of_cups:snips/number](one) cup of coffee please - brew [number_of_cups] cups of coffee - can you prepare [number_of_cups] cup of coffee""") dataset = Dataset.from_yaml_files("en", [dataset_stream]).json shared = self.get_shared_data(dataset) engine = SnipsNLUEngine(**shared).fit(dataset) text = "Give me 3 cups of hot tea please" # When engine.persist(self.tmp_file_path) deserialized_engine = SnipsNLUEngine.from_path(self.tmp_file_path) result = deserialized_engine.parse(text) # Then expected_slots = [ resolved_slot({ START: 8, END: 9 }, "3", { "kind": "Number", "value": 3.0 }, "snips/number", "number_of_cups"), custom_slot( unresolved_slot({ START: 18, END: 21 }, "hot", "Temperature", "beverage_temperature")) ] self.assertEqual(result[RES_INPUT], text) self.assertEqual(result[RES_INTENT][RES_INTENT_NAME], "MakeTea") self.assertListEqual(result[RES_SLOTS], expected_slots)
def test_should_be_deserializable( self, mocked_builtin_entity_parser, mocked_custom_entity_parser): # Given mocked_builtin_entity_parser.from_path = MagicMock() mocked_custom_entity_parser.from_path = MagicMock() @IntentParser.register("test_intent_parser1", True) class TestIntentParser1(MockIntentParser): pass @IntentParser.register("test_intent_parser2", True) class TestIntentParser2(MockIntentParser): pass dataset_metadata = { "language_code": "en", "entities": { "Temperature": { "automatically_extensible": True, "utterances": { "boiling": "hot", "cold": "cold", "hot": "hot", "iced": "cold" } } }, "slot_name_mappings": { "MakeCoffee": { "number_of_cups": "snips/number" }, "MakeTea": { "beverage_temperature": "Temperature", "number_of_cups": "snips/number" } }, } engine_dict = { "unit_name": "nlu_engine", "dataset_metadata": dataset_metadata, "config": { "unit_name": "nlu_engine", "intent_parsers_configs": [ { "unit_name": "test_intent_parser1" }, { "unit_name": "test_intent_parser2" } ] }, "intent_parsers": [ "test_intent_parser1", "test_intent_parser2", ], "builtin_entity_parser": "builtin_entity_parser", "custom_entity_parser": "custom_entity_parser", "model_version": snips_nlu.__model_version__, "training_package_version": snips_nlu.__version__ } self.tmp_file_path.mkdir() parser1_path = self.tmp_file_path / "test_intent_parser1" parser1_path.mkdir() parser2_path = self.tmp_file_path / "test_intent_parser2" parser2_path.mkdir() (self.tmp_file_path / "resources").mkdir() self.writeJsonContent(self.tmp_file_path / "nlu_engine.json", engine_dict) self.writeJsonContent( parser1_path / "metadata.json", {"unit_name": "test_intent_parser1", "fitted": True}) self.writeJsonContent( parser2_path / "metadata.json", {"unit_name": "test_intent_parser2", "fitted": True}) # When engine = SnipsNLUEngine.from_path(self.tmp_file_path) # Then expected_engine_config = { "unit_name": "nlu_engine", "intent_parsers_configs": [ { "unit_name": "test_intent_parser1" }, { "unit_name": "test_intent_parser2" } ] } self.assertDictEqual(dataset_metadata, engine.dataset_metadata) self.assertDictEqual(expected_engine_config, engine.config.to_dict()) self.assertIsInstance(engine.intent_parsers[0], TestIntentParser1) self.assertIsInstance(engine.intent_parsers[1], TestIntentParser2) mocked_custom_entity_parser.from_path.assert_called_once_with( self.tmp_file_path / "custom_entity_parser") mocked_builtin_entity_parser.from_path.assert_called_once_with( self.tmp_file_path / "builtin_entity_parser")
def test_should_be_deserializable_from_dir(self): # Given register_processing_unit(TestIntentParser1) register_processing_unit(TestIntentParser2) dataset_metadata = { "language_code": "en", "entities": { "Temperature": { "automatically_extensible": True, "utterances": { "boiling": "hot", "cold": "cold", "hot": "hot", "iced": "cold" } } }, "slot_name_mappings": { "MakeCoffee": { "number_of_cups": "snips/number" }, "MakeTea": { "beverage_temperature": "Temperature", "number_of_cups": "snips/number" } }, } parser1_config = TestIntentParser1Config() parser2_config = TestIntentParser2Config() engine_config = NLUEngineConfig([parser1_config, parser2_config]) engine_dict = { "unit_name": "nlu_engine", "dataset_metadata": dataset_metadata, "config": engine_config.to_dict(), "intent_parsers": [ "test_intent_parser1", "test_intent_parser2", ], "model_version": snips_nlu.__model_version__, "training_package_version": snips_nlu.__version__ } self.tmp_file_path.mkdir() parser1_path = self.tmp_file_path / "test_intent_parser1" parser1_path.mkdir() parser2_path = self.tmp_file_path / "test_intent_parser2" parser2_path.mkdir() (self.tmp_file_path / "resources").mkdir() self.writeJsonContent(self.tmp_file_path / "nlu_engine.json", engine_dict) self.writeJsonContent(parser1_path / "metadata.json", {"unit_name": "test_intent_parser1"}) self.writeJsonContent(parser2_path / "metadata.json", {"unit_name": "test_intent_parser2"}) # When engine = SnipsNLUEngine.from_path(self.tmp_file_path) # Then parser1_config = TestIntentParser1Config() parser2_config = TestIntentParser2Config() expected_engine_config = NLUEngineConfig( [parser1_config, parser2_config]).to_dict() # pylint:disable=protected-access self.assertDictEqual(engine._dataset_metadata, dataset_metadata) # pylint:enable=protected-access self.assertDictEqual(engine.config.to_dict(), expected_engine_config)