From 94053bfad34ab0b1ff2a4af988509ea407cf597c Mon Sep 17 00:00:00 2001 From: Bruno Date: Mon, 10 Oct 2016 10:18:02 +0200 Subject: [PATCH 1/3] [DEL] del test.php --- test.php | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 test.php diff --git a/test.php b/test.php deleted file mode 100644 index b8eedbe..0000000 --- a/test.php +++ /dev/null @@ -1,16 +0,0 @@ - 'bar', 'bar' => 'baz'); -$data = http_build_query($data); - -$context_options = array ( - 'http' => array ( - 'method' => 'POST', - 'header'=> "Content-type: application/x-www-form-urlencoded\r\n" - . "Content-Length: " . strlen($data) . "\r\n", - 'content' => $data - ) - ); - -$context = context_create_stream($context_options); -$fp = fopen('https://url', 'r', false, $context); -?> From 78a20c1d677d4db2da71570ad948c8cc44a88395 Mon Sep 17 00:00:00 2001 From: Sylvain Jaune Date: Wed, 19 Oct 2016 12:36:22 +0200 Subject: [PATCH 2/3] Refactored classes and fixed tests --- .gitignore | 2 +- composer.json | 8 +- package.json | 31 ----- src/Client.php | 176 ++++++++++++++++++++++++++ src/Conversation.php | 163 ++++++++++++++++++++++++ src/Entity.php | 24 ++++ src/Response.php | 252 +++++++++++++++++++++++++++++++++++++ src/client.php | 165 ------------------------ src/constants.php | 29 ----- src/conversation.php | 151 ---------------------- src/entity.php | 15 --- src/response.php | 176 -------------------------- tests/ClientTest.php | 110 ++++++++++++++++ tests/ConversationTest.php | 47 +++++++ tests/EntityTest.php | 53 ++++++++ tests/ResponseTest.php | 72 +++++++++++ tests/bootstrap.php | 3 - tests/clientTest.php | 114 ----------------- tests/conversationTest.php | 60 --------- tests/data/Converse.json | 36 ++++++ tests/data/Request.json | 52 ++++++++ tests/entityTest.php | 54 -------- tests/responseTest.php | 82 ------------ tests/test.json | 52 -------- tests/testconverse.json | 3 - 25 files changed, 992 insertions(+), 938 deletions(-) delete mode 100644 package.json create mode 100644 src/Client.php create mode 100644 src/Conversation.php create mode 100644 src/Entity.php create mode 100644 src/Response.php delete mode 100644 src/client.php delete mode 100644 src/constants.php delete mode 100644 src/conversation.php delete mode 100644 src/entity.php delete mode 100644 src/response.php create mode 100644 tests/ClientTest.php create mode 100644 tests/ConversationTest.php create mode 100644 tests/EntityTest.php create mode 100644 tests/ResponseTest.php delete mode 100644 tests/bootstrap.php delete mode 100644 tests/clientTest.php delete mode 100644 tests/conversationTest.php create mode 100644 tests/data/Converse.json create mode 100644 tests/data/Request.json delete mode 100644 tests/entityTest.php delete mode 100644 tests/responseTest.php delete mode 100644 tests/test.json delete mode 100644 tests/testconverse.json diff --git a/.gitignore b/.gitignore index 029e2cd..7cc781c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ composer.phar .DS_Store node_modules file.wav -test.php +test.php \ No newline at end of file diff --git a/composer.json b/composer.json index debf41f..301ab84 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,10 @@ { "name": "Bruno", "email": "bruno.gantelmi@recast.ai" + }, + { + "name": "Sylvain Jaune", + "email": "sylvain@hellocare.com" } ], "minimum-stability": "dev", @@ -19,8 +23,8 @@ }, "autoload": { "psr-4": { - "SDK-PHP\\": "src/", - "client\\": "tests/" + "RecastAI\\": "src/", + "Tests\\RecastAI\\": "tests/" } } } diff --git a/package.json b/package.json deleted file mode 100644 index 9b4cf48..0000000 --- a/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "sdkphp", - "version": "1.0.0", - "description": "[logo]: https://github.com/RecastAI/SDK-NodeJs/blob/master/misc/logo-inline.png \"Recast.AI\"", - "main": "index.js", - "directories": { - "test": "tests" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "doc": "./node_modules/apidoc/bin/apidoc -i src/ -o doc/" - }, - "apidoc": { - "name": "php sdk API doc", - "version": "0.1.0", - "description": "apiDoc php sdk recast", - "apidoc": { - "title": "php sdk recast" - } - }, - "repository": { - "type": "git", - "url": "git+https://github.com/bgantelm/SDK-PHP.git" - }, - "author": "", - "license": "ISC", - "bugs": { - "url": "https://github.com/bgantelm/SDK-PHP/issues" - }, - "homepage": "https://github.com/bgantelm/SDK-PHP#readme" -} diff --git a/src/Client.php b/src/Client.php new file mode 100644 index 0000000..db77cd9 --- /dev/null +++ b/src/Client.php @@ -0,0 +1,176 @@ +token = $token; + $this->language = $language; + } + + /** + * Sends a text request to Recast and returns the response. + * + * @param string $text + * + * @return \RecastAI\Response + * + * @throws Token is missing + */ + public function textRequest($text, $options = null) + { + if ($options === null) { + $token = $this->token; + } else if (array_key_exists('token', $options)) { + $token = $options['token']; + } + + if ($this->language) { + $params = array('text' => $text, 'language' => $this->language); + } else { + $params = array('text' => $text); + } + + if (!$token) { + return ('Token is missing'); + } else { + $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); + + $res = $this->requestPrivate(self::API_ENDPOINT, $headers, $params); + return (new Response($res)); + } + } + + /** + * Sends a request to Recast and returns the response. + * + * @param string $url + * @param array $headers + * @param array $params + * + * @return Response $res + */ + protected function requestPrivate($url, $headers, $params) + { + $res = \Requests::post($url, $headers, json_encode($params)); + + return ($res); + } + + /** + * Sends a request to Recast and returns the response. + * + * @param string $url + * @param array $params + * + * @return Response $res + */ + protected function requestFilePrivate($url, $params) + { + $client = new \GuzzleHttp\Client(); + $res = $client->request('POST', $url, $params); + + return ($res); + } + + /** + * Sends a file request to Recast and returns the response. + * + * @param string $file + * + * @return Response + * + * @throws Token is missing + */ + public function fileRequest($file, $options = null) + { + if ($options === null) { + $token = $this->token; + } else if (array_key_exists('token', $options)) { + $token = $options['token']; + } + + if (!$token) { + return ('Token is missing'); + } else { + $url = self::API_ENDPOINT; + + if (!$this->language) { + $params = [ + 'headers' => [ + 'Authorization' => "Token " . $token + ], + 'multipart' => [ + [ + 'Content-Type' => 'multipart/form-data', + 'name' => 'voice', + 'contents' => fopen($file, 'r') + ], + ] + ]; + } else { + $params = [ + 'headers' => [ + 'Authorization' => "Token " . $token + ], + 'multipart' => [ + [ + 'Content-Type' => 'multipart/form-data', + 'name' => 'voice', + 'contents' => fopen($file, 'r') + ], + [ + 'name' => 'language', + 'contents' => $this->language + ], + ] + ]; + } + $res = $this->requestFilePrivate($url, $params); + return (new Response($res)); + } + } + + /** + * @param $text + * @param null $conversation_token + * @param null $options + * @return Conversation|string + */ + public function textConverse($text, $conversation_token = null, $options = null) + { + if ($options === null) { + $token = $this->token; + } else if ($options['token']) { + $token = $options['token']; + } + + if ($this->language) { + $params = array('text' => $text, 'language' => $this->language, 'conversation_token' => $conversation_token); + } else { + $params = array('text' => $text, 'conversation_token' => $conversation_token); + } + + if (!$token) { + return ('Token is missing'); + } else { + $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); + $res = $this->requestPrivate(Conversation::API_ENDPOINT_CONVERSATION, $headers, $params); + + return (new Conversation(($res))); + } + } +} diff --git a/src/Conversation.php b/src/Conversation.php new file mode 100644 index 0000000..eea2b1d --- /dev/null +++ b/src/Conversation.php @@ -0,0 +1,163 @@ +replies = $response->results->replies; + $this->action = $response->results->action; + $this->nextActions = $response->results->next_actions; + $this->memory = $response->results->memory; + $this->conversationToken = $response->results->conversation_token; + } + + /** + * Returns the first reply if there is one + * @return {String}: this first reply or null + */ + public function reply() + { + return (count($this->replies) > 0 ? $this->replies[0] : null); + } + + /** + * Returns a concatenation of the replies + * @return {String}: the concatenation of the replies + */ + public function replies() + { + return ($this->replies); + } + + /** + * Returns a concatenation of the replies + * @return {String}: the concatenation of the replies + */ + public function joinedReplies($separator = ' ') + { + return ($this->replies ? join($separator, $this->replies) : null); + } + + /** + * Returns all the action whose name matches the parameter + * @return {Array}: returns an array of action, or null + */ + public function action() + { + return ($this->action || null); + } + + /** + * Returns the first nextActions whose name matches the parameter + * @return {Array}: returns an array of first nextActions, or null + */ + public function nextAction() + { + return (count($this->nextAction) > 0 ? $this->nextAction[0] : null); + } + + /** + * Returns all nextActions + * @return {Array}: returns an array of nextActions, or [] + */ + public function nextActions() + { + return ($this->nextActions || []); + } + + /** + * Returns the memory matching the alias + * or all the memory if no alias provided + * @return {object}: the memory + */ + public function memory($name = null) + { + if ($name === null) { + return ($this->memory); + } else if (array_key_exists($name, $this->memory)) { + return ($this->memory->$name); + } else { + return (null); + } + } + + /** + * Merge the conversation memory with the one in parameter + * Returns the memory updated + * @return {object}: the memory updated + */ + static public function setMemory($token, $conversation_token, $memory) + { + $params = array('conversation_token' => $conversation_token, 'memory' => $memory); + $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); + + $request = \Requests::put(self::API_ENDPOINT_CONVERSATION, $headers, json_encode($params)); + $res = (json_decode($request->body)); + return ($res->{'results'}->{'memory'}); + } + + /** + * Reset the memory of the conversation + * @return {object}: the updated memory + */ + static public function resetMemory($token, $conversation_token, $alias = null) + { + $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); + if ($alias === null) { + $params = array('conversation_token' => $conversation_token); + } else { + $memory = (object)[ + $alias => null + ]; + $params = array('conversation_token' => $conversation_token, 'memory' => $memory); + } + $request = \Requests::put(self::API_ENDPOINT_CONVERSATION, $headers, json_encode($params)); + return ($request); + } + + /** + * Reset the conversation + * @return {object}: the updated memory + */ + static public function resetConversation($token, $conversation_token) + { + $curl = curl_init(); + + curl_setopt_array($curl, array( + CURLOPT_URL => self::API_ENDPOINT_CONVERSATION, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "DELETE", + CURLOPT_POSTFIELDS => "conversation_token=" . $conversation_token, + CURLOPT_HTTPHEADER => array( + "authorization: Token " . $token, + "cache-control: no-cache", + "content-type: application/x-www-form-urlencoded", + ), + )); + + $response = curl_exec($curl); + $err = curl_error($curl); + + curl_close($curl); + + if ($err) { + echo "cURL Error #:" . $err; + } else { + return ($response); + } + } +} \ No newline at end of file diff --git a/src/Entity.php b/src/Entity.php new file mode 100644 index 0000000..6301b9b --- /dev/null +++ b/src/Entity.php @@ -0,0 +1,24 @@ +name = $name; + foreach ($data as $key => $value) { + $this->$key = $value; + } + } +} \ No newline at end of file diff --git a/src/Response.php b/src/Response.php new file mode 100644 index 0000000..4d9e436 --- /dev/null +++ b/src/Response.php @@ -0,0 +1,252 @@ +entities = []; + + $this->act = $response->results->act; + $this->type = $response->results->type; + $this->source = $response->results->source; + $this->intents = $response->results->intents; + $this->sentiment = $response->results->sentiment; + + foreach ($response->results->entities as $key => $value) { + foreach ($value as $i => $entity) { + $this->entities[] = new Entity($key, $entity); + } + } + + $this->uuid = $response->results->uuid; + $this->language = $response->results->language; + $this->version = $response->results->version; + $this->timestamp = $response->results->timestamp; + $this->status = $response->results->status; + } + + /** + * Returns the first Entity whose name matches the parameter + * @param {String} name: the entity's name + * @return {Entity}: returns the first entity that matches - name - + */ + public function get($name) + { + $count = count($this->entities); + + for ($i = 0; $i <= $count; $i++) { + if ($this->entities[$i]->name == $name) { + return ($this->entities[$i]); + } + } + + return null; + } + + /** + * Returns all the entities whose name matches the parameter + * @param {String} name: the entity's name + * @return {Array}: returns an array of Entity, or null + */ + public function all($name) + { + $count = count($this->entities); + $res = []; + + for ($i = 0; $i < $count; $i++) { + if ($this->entities[$i]->name == $name) { + $res[] = $this->entities[$i]; + } + } + + return ($res); + } + + /** + * Returns the first Intent if there is one + * @return {Sentence}: returns the first Intent or null + */ + public function intent() + { + if ($this->intents[0]) { + return ($this->intents[0]); + } + + return (null); + } + + /** + * ACT HELPERS + * Returns whether or not the response act corresponds to the checked one + * @return {boolean}: true or false + */ + public function isAssert() + { + return ($this->act === self::ACT_ASSERT); + } + + /** + * @return bool + */ + public function isCommand() + { + return ($this->act === self::ACT_COMMAND); + } + + /** + * @return bool + */ + public function isWhQuery() + { + return ($this->act === self::ACT_WH_QUERY); + } + + /** + * @return bool + */ + public function isYnQuery() + { + return ($this->act === self::ACT_YN_QUERY); + } + + /** + * TYPE HELPERS + * Returns whether or not the response type corresponds to the checked one + * @return {boolean}: true or false + */ + public function isAbbreviation() + { + if (strstr($this->type, self::TYPE_ABBREVIATION)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isEntity() + { + if (strstr($this->type, self::TYPE_ENTITY)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isDescription() + { + if (strstr($this->type, self::TYPE_DESCRIPTION)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isHuman() + { + if (strstr($this->type, self::TYPE_HUMAN)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isLocation() + { + if (strstr($this->type, self::TYPE_LOCATION)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isNumber() + { + if (strstr($this->type, self::TYPE_NUMBER)) { + return (true); + } + return (false); + } + + /** + * SENTIMENT HELPERS + * Returns whether or not the response sentiment corresponds to the checked one + * @return {boolean}: true or false + */ + + public function isPositive() + { + return ($this->sentiment === self::SENTIMENT_POSITIVE); + } + + /** + * @return bool + */ + public function isNeutral() + { + return ($this->sentiment === self::SENTIMENT_NEUTRAL); + } + + /** + * @return bool + */ + public function isNegative() + { + return ($this->sentiment === self::SENTIMENT_NEGATIVE); + } + + /** + * @return bool + */ + public function isVPositive() + { + return ($this->sentiment === self::SENTIMENT_VPOSITIVE); + } + + /** + * @return bool + */ + public function isVNegative() + { + return ($this->sentiment === self::SENTIMENT_VNEGATIVE); + } +} diff --git a/src/client.php b/src/client.php deleted file mode 100644 index 158f285..0000000 --- a/src/client.php +++ /dev/null @@ -1,165 +0,0 @@ -token = $token; - $this->language = $language; - } - - /** - * Sends a text request to Recast and returns the response. - * - * @param string $text - * - * @return Response - * - * @throws Token is missing - */ - public function textRequest($text, $options=null) - { - if ($options === null) { - $token = $this->token; - } else if (array_key_exists('token', $options)) { - $token = $options['token']; - } - - if ($this->language) { - $params = array('text' => $text, 'language' => $this->language); - } else { - $params = array('text' => $text); - } - - if (!$token) { - return('Token is missing'); - } else { - $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); - - $res = $this->requestPrivate(constants\Constants::API_ENDPOINT, $headers, $params); - return(new response\Response($res)); - } - } - - /** - * Sends a request to Recast and returns the response. - * - * @param string $url - * @param array $headers - * @param array $params - * - * @return Response $res - */ - protected function requestPrivate($url, $headers, $params) { - $res = Requests::post($url, $headers, json_encode($params)); - - return ($res); - } - - /** - * Sends a request to Recast and returns the response. - * - * @param string $url - * @param array $params - * - * @return Response $res - */ - protected function requestFilePrivate($url, $params) { - $client = new \GuzzleHttp\Client(); - $res = $client->request('POST', $url, $params); - - return ($res); - } - - /** - * Sends a file request to Recast and returns the response. - * - * @param string $file - * - * @return Response - * - * @throws Token is missing - */ - public function fileRequest($file, $options=null) - { - if ($options === null) { - $token = $this->token; - } else if (array_key_exists('token', $options)) { - $token = $options['token']; - } - - if (!$token) { - return('Token is missing'); - } else { - $url = constants\Constants::API_ENDPOINT; - - if (!$this->language) { - $params = [ - 'headers' => [ - 'Authorization' => "Token " . $token - ], - 'multipart' => [ - [ - 'Content-Type' => 'multipart/form-data', - 'name' => 'voice', - 'contents' => fopen($file, 'r') - ], - ] - ]; - } else { - $params = [ - 'headers' => [ - 'Authorization' => "Token " . $token - ], - 'multipart' => [ - [ - 'Content-Type' => 'multipart/form-data', - 'name' => 'voice', - 'contents' => fopen($file, 'r') - ], - [ - 'name' => 'language', - 'contents' => $this->language - ], - ] - ]; - } - $res = $this->requestFilePrivate($url, $params); - return(new response\Response($res)); - } - } - public function textConverse($text, $conversation_token=null, $options=null) { - if ($options === null) { - $token = $this->token; - } else if ($options['token']) { - $token = $options['token']; - } - - if ($this->language) { - $params = array('text' => $text, 'language' => $this->language, 'conversation_token' => $conversation_token); - } else { - $params = array('text' => $text, 'conversation_token' => $conversation_token); - } - - if (!$token) { - return('Token is missing'); - } else { - $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); - $res = $this->requestPrivate(constants\Constants::API_ENDPOINT_CONVERSATION, $headers, $params); - - return(new conversation\Conversation(($res))); - } - } -} diff --git a/src/constants.php b/src/constants.php deleted file mode 100644 index 5b55198..0000000 --- a/src/constants.php +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/src/conversation.php b/src/conversation.php deleted file mode 100644 index 948a9d5..0000000 --- a/src/conversation.php +++ /dev/null @@ -1,151 +0,0 @@ -body); - $this->replies = $res->{'results'}->{'replies'}; - $this->action = $res->{'results'}->{'action'}; - $this->nextActions = $res->{'results'}->{'next_actions'}; - $this->memory = $res->{'results'}->{'memory'}; - $this->conversationToken = $res->{'results'}->{'conversation_token'}; - } - - /** - * Returns the first reply if there is one - * @return {String}: this first reply or null - */ - public function reply() { - return (count($this->replies) > 0 ? $this->replies[0] : null); - } - - /** - * Returns a concatenation of the replies - * @return {String}: the concatenation of the replies - */ - public function replies() { - return ($this->replies); - } - - /** - * Returns a concatenation of the replies - * @return {String}: the concatenation of the replies - */ - public function joinedReplies($separator=' ') { - return ($this->replies ? join($separator, $this->replies) : null); - } - - /** - * Returns all the action whose name matches the parameter - * @return {Array}: returns an array of action, or null - */ - public function action() { - return ($this->action || null); - } - - /** - * Returns the first nextActions whose name matches the parameter - * @return {Array}: returns an array of first nextActions, or null - */ - public function nextAction() { - return (count($this->nextAction) > 0 ? $this->nextAction[0] : null); - } - - /** - * Returns all nextActions - * @return {Array}: returns an array of nextActions, or [] - */ - public function nextActions() { - return ($this->nextActions || []); - } - - /** - * Returns the memory matching the alias - * or all the memory if no alias provided - * @return {object}: the memory - */ - public function memory($name=null) { - if ($name === null) { - return ($this->memory); - } else if (array_key_exists($name, $this->memory)) { - return ($this->memory->$name); - } else { - return (null); - } - } - - /** - * Merge the conversation memory with the one in parameter - * Returns the memory updated - * @return {object}: the memory updated - */ - static public function setMemory($token, $conversation_token, $memory) { - $params = array('conversation_token' => $conversation_token, 'memory' => $memory); - $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); - - $request = Requests::put(constants\Constants::API_ENDPOINT_CONVERSATION, $headers, json_encode($params)); - $res = (json_decode($request->body)); - return ($res->{'results'}->{'memory'}); - } - - /** - * Reset the memory of the conversation - * @return {object}: the updated memory - */ - static public function resetMemory($token, $conversation_token, $alias=null) { - $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); - if ($alias === null) { - $params = array('conversation_token' => $conversation_token); - } else { - $memory = (object) [ - $alias => null - ]; - $params = array('conversation_token' => $conversation_token, 'memory' => $memory); - } - $request = Requests::put(constants\Constants::API_ENDPOINT_CONVERSATION, $headers, json_encode($params)); - return ($request); - } - - /** - * Reset the conversation - * @return {object}: the updated memory - */ - static public function resetConversation($token, $conversation_token) { - $curl = curl_init(); - - curl_setopt_array($curl, array( - CURLOPT_URL => constants\Constants::API_ENDPOINT_CONVERSATION, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "DELETE", - CURLOPT_POSTFIELDS => "conversation_token=" . $conversation_token, - CURLOPT_HTTPHEADER => array( - "authorization: Token " . $token, - "cache-control: no-cache", - "content-type: application/x-www-form-urlencoded", - ), - )); - - $response = curl_exec($curl); - $err = curl_error($curl); - - curl_close($curl); - - if ($err) { - echo "cURL Error #:" . $err; - } else { - return($response); - } - } -} -?> diff --git a/src/entity.php b/src/entity.php deleted file mode 100644 index b65b809..0000000 --- a/src/entity.php +++ /dev/null @@ -1,15 +0,0 @@ -name = $name; - foreach ($data as $key => $value) { - $this->$key = $value; - } - } -} - -?> diff --git a/src/response.php b/src/response.php deleted file mode 100644 index 7778399..0000000 --- a/src/response.php +++ /dev/null @@ -1,176 +0,0 @@ -body); - $this->entities = []; - - $this->act = $res->{'results'}->{'act'}; - $this->type = $res->{'results'}->{'type'}; - $this->source = $res->{'results'}->{'source'}; - $this->intents = $res->{'results'}->{'intents'}; - $this->sentiment = $res->{'results'}->{'sentiment'}; - - foreach ($res->{'results'}->{'entities'} as $key => $value) { - foreach ($value as $i => $entity) { - $this->entities[] = new entity\Entity($key, $entity); - } - } - - $this->uuid = $res->{'results'}->{'uuid'}; - $this->language = $res->{'results'}->{'language'}; - $this->version = $res->{'results'}->{'version'}; - $this->timestamp = $res->{'results'}->{'timestamp'}; - $this->status = $res->{'results'}->{'status'}; - } - - /** - * Returns the first Entity whose name matches the parameter - * @param {String} name: the entity's name - * @return {Entity}: returns the first entity that matches - name - - */ - public function get($name) { - $count = count($this->entities); - - for ($i = 0; $i <= $count; $i++) { - if ($this->entities[$i]->name == $name) { - return ($this->entities[$i]); - } - } - - return null; - } - - /** - * Returns all the entities whose name matches the parameter - * @param {String} name: the entity's name - * @return {Array}: returns an array of Entity, or null - */ - public function all($name) { - $count = count($this->entities); - $res = []; - - for ($i = 0; $i < $count ; $i++) { - if ($this->entities[$i]->name == $name) { - $res[] = $this->entities[$i]; - } - } - - return ($res); - } - - /** - * Returns the first Intent if there is one - * @return {Sentence}: returns the first Intent or null - */ - public function intent() { - if ($this->intents[0]) { - return ($this->intents[0]); - } - - return (null); - } - - /** - * ACT HELPERS - * Returns whether or not the response act corresponds to the checked one - * @return {boolean}: true or false - */ - public function isAssert() { - return ($this->act === constants\Constants::ACT_ASSERT); - } - - public function isCommand() { - return ($this->act === constants\Constants::ACT_COMMAND); - } - - public function isWhQuery() { - return ($this->act === constants\Constants::ACT_WH_QUERY); - } - - public function isYnQuery() { - return ($this->act === constants\Constants::ACT_YN_QUERY); - } - - /** - * TYPE HELPERS - * Returns whether or not the response type corresponds to the checked one - * @return {boolean}: true or false - */ - public function isAbbreviation() { - if (strstr($this->type, constants\Constants::TYPE_ABBREVIATION)) { - return (true); - } - return (false); - } - - public function isEntity() { - if (strstr($this->type, constants\Constants::TYPE_ENTITY)) { - return (true); - } - return (false); - } - - public function isDescription() { - if (strstr($this->type, constants\Constants::TYPE_DESCRIPTION)) { - return (true); - } - return (false); - } - - public function isHuman() { - if (strstr($this->type, constants\Constants::TYPE_HUMAN)) { - return (true); - } - return (false); - } - - public function isLocation() { - if (strstr($this->type, constants\Constants::TYPE_LOCATION)) { - return (true); - } - return (false); - } - - public function isNumber() { - if (strstr($this->type, constants\Constants::TYPE_NUMBER)) { - return (true); - } - return (false); - } - - /** - * SENTIMENT HELPERS - * Returns whether or not the response sentiment corresponds to the checked one - * @return {boolean}: true or false - */ - - public function isPositive() { - return ($this->sentiment === constants\Constants::SENTIMENT_POSITIVE); - } - - public function isNeutral() { - return ($this->sentiment === constants\Constants::SENTIMENT_NEUTRAL); - } - - public function isNegative() { - return ($this->sentiment === constants\Constants::SENTIMENT_NEGATIVE); - } - - public function isVPositive() { - return ($this->sentiment === constants\Constants::SENTIMENT_VPOSITIVE); - } - - public function isVNegative() { - return ($this->sentiment === constants\Constants::SENTIMENT_VNEGATIVE); - } -} diff --git a/tests/ClientTest.php b/tests/ClientTest.php new file mode 100644 index 0000000..f9dac4a --- /dev/null +++ b/tests/ClientTest.php @@ -0,0 +1,110 @@ +assertInstanceOf('RecastAI\Client', new Client($token, null)); + } + + public function testClientClassWithoutToken() + { + $language = 'en'; + $this->assertInstanceOf('RecastAI\Client', new Client(null, $language)); + } + + public function testClientClassWithoutTokenAndLanguage() + { + $this->assertInstanceOf('RecastAI\Client', new Client()); + } + + public function testClientClassWithTokenAndLanguage() + { + $token = 'TestToken'; + $language = 'en'; + + $this->assertInstanceOf('RecastAI\Client', new Client($token, $language)); + } + + public function testClientClassIfAttributesAreOkay() + { + $token = 'TestToken'; + $language = 'en'; + $client = new Client($token, $language); + + $this->assertEquals($client->token, $token); + $this->assertEquals($client->language, $language); + } + + public function testTextRequestIfAllOkay() + { + $callResult = self::jsonResponse(); + $token = 'TestToken'; + $language = 'en'; + + $stub = $this->getMockBuilder('RecastAI\Client') + ->setConstructorArgs(array($token, $language)) + ->setMethods(['requestPrivate']) + ->getMock(); + + $stub->expects($this->once()) + ->method('requestPrivate') + ->will($this->returnValue($callResult)); + + $response = $stub->textRequest($callResult); + + $this->assertEquals('200', $response->status); + } + + public function testTextRequestIfNoToken() + { + $client = new Client(); + $res = $client->textRequest('Hello world'); + $this->assertEquals($res, 'Token is missing'); + } + + public function testFileRequestIfAllOkay() + { + $callResult = self::jsonResponse(); + + $file = __DIR__ . '/data/file.wav'; + + if (!file_exists($file)) { + $this->markTestSkipped('Audio test file not found'); + } + + $token = 'TestToken'; + $language = 'en'; + + $stub = $this->getMockBuilder('RecastAI\Client') + ->setConstructorArgs(array($token, $language)) + ->setMethods(['requestFilePrivate']) + ->getMock(); + + $stub->expects($this->once()) + ->method('requestFilePrivate') + ->will($this->returnValue($callResult)); + + $response = $stub->fileRequest($file); + $this->assertEquals('200', $response->status); + } + + public function testFileRequestIfNoToken() + { + $client = new Client(); + + $res = $client->fileRequest(__DIR__ . '/data/file.wav'); + $this->assertEquals($res, 'Token is missing'); + } +} \ No newline at end of file diff --git a/tests/ConversationTest.php b/tests/ConversationTest.php new file mode 100644 index 0000000..5e6e5bf --- /dev/null +++ b/tests/ConversationTest.php @@ -0,0 +1,47 @@ +assertInstanceOf('RecastAI\Conversation', new Conversation($jsonResult)); + } + + public function testConversationClassAttributes() + { + $jsonResult = self::jsonResponse(); + $result = json_decode($jsonResult); + + $conversation = new Conversation($jsonResult); + + $this->assertEquals($conversation->conversationToken, $result->results->conversation_token); + $this->assertEquals($conversation->replies, $result->results->replies); + $this->assertEquals($conversation->action, $result->results->action); + $this->assertEquals($conversation->nextActions, $result->results->next_actions); + $this->assertEquals($conversation->memory, $result->results->memory); + } + + public function testResponseClassMethods() + { + $jsonResult = self::jsonResponse(); + $result = json_decode($jsonResult); + + $conversation = new Conversation($jsonResult); + + $this->assertEquals($conversation->reply(), $result->results->replies[0]); + $this->assertEquals($conversation->joinedReplies(), join(' ', $result->results->replies)); + $this->assertEquals($conversation->joinedReplies('\n'), join('\n', $result->results->replies)); + $this->assertEquals($conversation->memory(), $result->results->memory); + $this->assertEquals($conversation->memory('loc'), $result->results->memory->loc); + } +} \ No newline at end of file diff --git a/tests/EntityTest.php b/tests/EntityTest.php new file mode 100644 index 0000000..93db246 --- /dev/null +++ b/tests/EntityTest.php @@ -0,0 +1,53 @@ + '1', + 'number' => 'singular', + 'gender' => 'unkown', + 'raw' => 'me', + ]; + + $data2 = (object)[ + 'value' => 'asparagus', + 'raw' => 'asparagus', + ]; + + $this->assertInstanceOf('RecastAI\Entity', new Entity('ingredient', $data2)); + } + + public function testEntityClassShouldHaveAttributes() + { + $data1 = (object)[ + 'person' => '1', + 'number' => 'singular', + 'gender' => 'unkown', + 'raw' => 'me', + ]; + $data2 = (object)[ + 'value' => 'asparagus', + 'raw' => 'asparagus', + ]; + + $testEntity1 = new Entity('person', $data1); + $testEntity2 = new Entity('ingredient', $data2); + + $this->assertEquals($testEntity1->name, 'person'); + $this->assertEquals($testEntity1->person, $data1->person); + $this->assertEquals($testEntity1->number, $data1->number); + $this->assertEquals($testEntity1->gender, $data1->gender); + $this->assertEquals($testEntity1->raw, $data1->raw); + + $this->assertEquals($testEntity2->name, 'ingredient'); + $this->assertEquals($testEntity2->value, $data2->value); + $this->assertEquals($testEntity2->raw, $data2->raw); + } +} diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php new file mode 100644 index 0000000..a65de1c --- /dev/null +++ b/tests/ResponseTest.php @@ -0,0 +1,72 @@ +assertInstanceOf('RecastAI\Response', new Response($jsonResult)); + } + + public function testResponseClassAttributes() + { + $jsonResult = self::jsonResponse(); + $result = json_decode($jsonResult); + + $response = new Response($jsonResult); + + $count = count($response->entities, COUNT_RECURSIVE); + + $this->assertEquals($response->act, $result->results->{'act'}); + $this->assertEquals($response->type, $result->results->{'type'}); + $this->assertEquals($response->source, $result->results->{'source'}); + $this->assertEquals($response->sentiment, $result->results->{'sentiment'}); + $this->assertEquals($response->language, $result->results->{'language'}); + $this->assertEquals($response->version, $result->results->{'version'}); + $this->assertEquals($response->timestamp, $result->results->{'timestamp'}); + $this->assertEquals($count, 4); + $this->assertInstanceOf('RecastAI\Entity', $response->entities[0]); + $this->assertInternalType('array', $response->entities); + $this->assertInternalType('array', $response->intents); + } + + public function testResponseClassMethods() + { + $jsonResult = self::jsonResponse(); + $result = json_decode($jsonResult); + + $response = new Response($jsonResult); + + $all = count($response->all('location')); + $get = $response->get('location'); + + $this->assertEquals($response->intent(), $result->results->{'intents'}[0]); + $this->assertEquals($all, 2); + $this->assertEquals('location', $get->name); + + $this->assertEquals($response->isAssert(), false); + $this->assertEquals($response->isCommand(), false); + $this->assertEquals($response->isWhQuery(), true); + $this->assertEquals($response->isYnQuery(), false); + $this->assertEquals($response->isAbbreviation(), false); + $this->assertEquals($response->isEntity(), false); + $this->assertEquals($response->isDescription(), true); + $this->assertEquals($response->isHuman(), false); + $this->assertEquals($response->isLocation(), false); + $this->assertEquals($response->isNumber(), false); + $this->assertEquals($response->isVPositive(), false); + $this->assertEquals($response->isPositive(), false); + $this->assertEquals($response->isNeutral(), true); + $this->assertEquals($response->isNegative(), false); + $this->assertEquals($response->isVNegative(), false); + } +} \ No newline at end of file diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index 91c51fb..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,3 +0,0 @@ -assertInstanceOf('client\Client', new client\Client($token, null)); - } - - public function testClientClassWithoutToken() { - $token = 'TestToken'; - $language = 'en'; - - $this->assertInstanceOf('client\Client', new client\Client(null, $language)); - } - - public function testClientClassWithoutTokenAndLanguage() { - $token = 'TestToken'; - $language = 'en'; - - $this->assertInstanceOf('client\Client', new client\Client()); - } - - public function testClientClassWithTokenAndLanguage() { - $token = 'TestToken'; - $language = 'en'; - - $this->assertInstanceOf('client\Client', new client\Client($token, $language)); - } - - public function testClientClassIfAttributesAreOkay() { - $token = 'TestToken'; - $language = 'en'; - $client = new client\Client($token, $language); - - $this->assertEquals($client->token, $token); - $this->assertEquals($client->language, $language); - } - - public function testtextRequestIfAllOkay() { - - $fp = fopen ("./tests/test.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/test.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $token = 'TestToken'; - $language = 'en'; - - $stub = $this->getMockBuilder('client\Client') - ->setConstructorArgs(array($token, $language)) - ->setMethods(['requestPrivate']) - ->getMock(); - - $stub->expects($this->once()) - ->method('requestPrivate') - ->will($this->returnValue($res2)); - $res = $stub->textRequest($res2); - $this->assertEquals('200', $res->status); - - } - - public function testtextRequestIfNoToken() { - - $client = new client\Client(); - $res = $client->textRequest('Hello world'); - $this->assertEquals($res, 'Token is missing'); - } - - public function testfileRequestIfAllOkay() { - $fp = fopen ("./tests/test.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/test.json')); - fclose ($fp); - $res2 = json_decode ($contenu_du_fichier); - $file = './file.wav'; - $token = 'TestToken'; - $language = 'en'; - - $stub = $this->getMockBuilder('client\Client') - ->setConstructorArgs(array($token, $language)) - ->setMethods(['requestFilePrivate']) - ->getMock(); - - $stub->expects($this->once()) - ->method('requestFilePrivate') - ->will($this->returnValue($res2)); - - $res = $stub->fileRequest($file); - $this->assertEquals('200', $res->status); - - } - - public function testfileRequestIfNoToken() { - $client = new client\Client(); - - $res = $client->fileRequest('./file.wav'); - $this->assertEquals($res, 'Token is missing'); - } -} - -?> diff --git a/tests/conversationTest.php b/tests/conversationTest.php deleted file mode 100644 index 90f81c5..0000000 --- a/tests/conversationTest.php +++ /dev/null @@ -1,60 +0,0 @@ -assertInstanceOf('conversation\Conversation', new conversation\Conversation($json)); - } - - public function testConversationClassAttributes() { - $fp = fopen ("./tests/testconverse.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/testconverse.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $lol = json_decode($res2->body); - $res = new conversation\Conversation($res2); - - - $this->assertEquals($res->conversationToken, $lol->results->conversation_token); - $this->assertEquals($res->replies, $lol->results->replies); - $this->assertEquals($res->action, $lol->results->action); - $this->assertEquals($res->nextActions, $lol->results->next_actions); - $this->assertEquals($res->memory, $lol->results->memory); - } - - public function testResponseClassMethods() { - $fp = fopen ("./tests/testconverse.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/testconverse.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $lol = json_decode($res2->body); - $res = new conversation\Conversation($res2); - - $this->assertEquals($res->reply(), $lol->results->replies[0]); - $this->assertEquals($res->joinedReplies(), join(' ', $lol->results->replies)); - $this->assertEquals($res->joinedReplies('\n'), join('\n', $lol->results->replies)); - $this->assertEquals($res->memory(), $lol->results->memory); - $this->assertEquals($res->memory('loc'), $lol->results->memory->loc); - - - } -} - - -?> diff --git a/tests/data/Converse.json b/tests/data/Converse.json new file mode 100644 index 0000000..21b5f72 --- /dev/null +++ b/tests/data/Converse.json @@ -0,0 +1,36 @@ +{ + "results": { + "source": "hello", + "replies": [ + "Salut", + "Need location please" + ], + "action": { + "slug": "greetings", + "done": true, + "reply": "Salut" + }, + "next_actions": [ + { + "slug": "capitals", + "done": false, + "reply": "Need location please" + } + ], + "memory": { + "loc": null + }, + "entities": {}, + "intents": [ + { + "slug": "greetings", + "confidence": 0.99 + } + ], + "conversation_token": "f6362f5ded83031d42c2d02d954359f9", + "language": "en", + "timestamp": "2016-10-05T12:07:30.907Z", + "status": 200 + }, + "message": "Converses rendered with success" +} \ No newline at end of file diff --git a/tests/data/Request.json b/tests/data/Request.json new file mode 100644 index 0000000..e3e42d5 --- /dev/null +++ b/tests/data/Request.json @@ -0,0 +1,52 @@ +{ + "results": { + "uuid": "6b356fe1-7aee-4407-8c0f-47ed70675679", + "source": "What is the weather in London tomorrow? And in Paris?", + "intents": [ + { + "name": "weather", + "confidence": 0.67 + } + ], + "act": "wh-query", + "type": "desc:desc", + "sentiment": "neutral", + "entities": { + "action": [ + { + "agent": "the weather in London", + "tense": "present", + "raw": "is", + "confidence": 0.89 + } + ], + "location": [ + { + "formated": "London, London, Greater London, England, United Kingdom", + "lat": 51.5073509, + "lng": -0.1277583, + "raw": "London", + "confidence": 0.97 + }, + { + "formated": "Paris, Paris, Île-de-France, France", + "lat": 48.856614, + "lng": 2.3522219, + "raw": "Paris", + "confidence": 0.83 + } + ], + "datetime": [ + { + "value": "2016-07-11T10:00:00+00:00", + "raw": "tomorrow", + "confidence": 0.95 + } + ] + }, + "language": "en", + "version": "2.0.0", + "timestamp": "2016-07-10T23:17:59+02:00", + "status": 200 + } +} \ No newline at end of file diff --git a/tests/entityTest.php b/tests/entityTest.php deleted file mode 100644 index 689e939..0000000 --- a/tests/entityTest.php +++ /dev/null @@ -1,54 +0,0 @@ - '1', - 'number' => 'singular', - 'gender' => 'unkown', - 'raw' => 'me', - ]; - $data2 = (object) [ - 'value' => 'asparagus', - 'raw' => 'asparagus', - ]; - - $this->assertInstanceOf('entity\Entity', new entity\Entity('ingredient', $data2)); - } - - public function testEntityClassShouldHaveAttributes() { - $data1 = (object) [ - 'person' => '1', - 'number' => 'singular', - 'gender' => 'unkown', - 'raw' => 'me', - ]; - $data2 = (object) [ - 'value' => 'asparagus', - 'raw' => 'asparagus', - ]; - - $testEntity1 = new entity\Entity('person', $data1); - $testEntity2 = new entity\Entity('ingredient', $data2); - - $this->assertEquals($testEntity1->name, 'person'); - $this->assertEquals($testEntity1->person, $data1->person); - $this->assertEquals($testEntity1->number, $data1->number); - $this->assertEquals($testEntity1->gender, $data1->gender); - $this->assertEquals($testEntity1->raw, $data1->raw); - - $this->assertEquals($testEntity2->name, 'ingredient'); - $this->assertEquals($testEntity2->value, $data2->value); - $this->assertEquals($testEntity2->raw, $data2->raw); - } -} diff --git a/tests/responseTest.php b/tests/responseTest.php deleted file mode 100644 index 0ef8374..0000000 --- a/tests/responseTest.php +++ /dev/null @@ -1,82 +0,0 @@ -assertInstanceOf('response\Response', new response\Response($json)); - } - - public function testResponseClassAttributes() { - $fp = fopen ("./tests/test.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/test.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $lol = json_decode($res2->body); - $res = new response\Response($res2); - - $count = count($res->entities, COUNT_RECURSIVE); - - $this->assertEquals($res->act, $lol->results->{'act'}); - $this->assertEquals($res->type, $lol->results->{'type'}); - $this->assertEquals($res->source, $lol->results->{'source'}); - $this->assertEquals($res->sentiment, $lol->results->{'sentiment'}); - $this->assertEquals($res->language, $lol->results->{'language'}); - $this->assertEquals($res->version, $lol->results->{'version'}); - $this->assertEquals($res->timestamp, $lol->results->{'timestamp'}); - $this->assertEquals($count, 4); - $this->assertInstanceOf('entity\Entity', $res->entities[0]); - $this->assertInternalType('array', $res->entities); - $this->assertInternalType('array', $res->intents); - } - - public function testResponseClassMethods() { - - $fp = fopen ("./tests/test.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/test.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $lol = json_decode($res2->body); - $res = new response\Response($res2); - - $all = count($res->all('location')); - $get = $res->get('location'); - - $this->assertEquals($res->intent(), $lol->results->{'intents'}[0]); - $this->assertEquals($all, 2); - $this->assertEquals('location', $get->name); - - $this->assertEquals($res->isAssert(), false); - $this->assertEquals($res->isCommand(), false); - $this->assertEquals($res->isWhQuery(), true); - $this->assertEquals($res->isYnQuery(), false); - $this->assertEquals($res->isAbbreviation(), false); - $this->assertEquals($res->isEntity(), false); - $this->assertEquals($res->isDescription(), true); - $this->assertEquals($res->isHuman(), false); - $this->assertEquals($res->isLocation(), false); - $this->assertEquals($res->isNumber(), false); - $this->assertEquals($res->isVPositive(), false); - $this->assertEquals($res->isPositive(), false); - $this->assertEquals($res->isNeutral(), true); - $this->assertEquals($res->isNegative(), false); - $this->assertEquals($res->isVNegative(), false); - } -} - - -?> diff --git a/tests/test.json b/tests/test.json deleted file mode 100644 index 34bb6a0..0000000 --- a/tests/test.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "body": "{\"results\": { - \"uuid\": \"6b356fe1-7aee-4407-8c0f-47ed70675679\", - \"source\": \"What is the weather in London tomorrow? And in Paris?\", - \"intents\": [ - { - \"name\": \"weather\", - \"confidence\": 0.67 - } - ], - \"act\": \"wh-query\", - \"type\": \"desc:desc\", - \"sentiment\": \"neutral\", - \"entities\": { - \"action\":[ - { - \"agent\": \"the weather in London\", - \"tense\": \"present\", - \"raw\": \"is\", - \"confidence\": 0.89 - } - ], - \"location\": [ - { - \"formated\": \"London, London, Greater London, England, United Kingdom\", - \"lat\": 51.5073509, - \"lng\": -0.1277583, - \"raw\": \"London\", - \"confidence\": 0.97 - }, - { - \"formated\": \"Paris, Paris, Île-de-France, France\", - \"lat\": 48.856614, - \"lng\": 2.3522219, - \"raw\": \"Paris\", - \"confidence\": 0.83 - } - ], - \"datetime\": [ - { - \"value\": \"2016-07-11T10:00:00+00:00\", - \"raw\": \"tomorrow\", - \"confidence\": 0.95 - } - ] - }, - \"language\": \"en\", - \"version\": \"2.0.0\", - \"timestamp\": \"2016-07-10T23:17:59+02:00\", - \"status\": 200 - }}" -} diff --git a/tests/testconverse.json b/tests/testconverse.json deleted file mode 100644 index 63dffe6..0000000 --- a/tests/testconverse.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "body": "{\"results\":{\"source\":\"hello\",\"replies\":[\"Salut\",\"Need location please\"],\"action\":{\"slug\":\"greetings\",\"done\":true,\"reply\":\"Salut\"},\"next_actions\":[{\"slug\":\"capitals\",\"done\":false,\"reply\":\"Need location please\"}],\"memory\":{\"loc\":null},\"entities\":{},\"intents\":[{\"slug\":\"greetings\",\"confidence\":0.99}],\"conversation_token\":\"f6362f5ded83031d42c2d02d954359f9\",\"language\":\"en\",\"timestamp\":\"2016-10-05T12:07:30.907Z\",\"status\":200},\"message\":\"Converses rendered with success\"}" -} From ff650e632104e8aa7d147d4d6aa28d6f1769b9d6 Mon Sep 17 00:00:00 2001 From: Sylvain Jaune Date: Wed, 19 Oct 2016 12:36:22 +0200 Subject: [PATCH 3/3] Refactored classes and fixed tests --- .gitignore | 2 +- composer.json | 8 +- package.json | 31 ----- src/Client.php | 176 ++++++++++++++++++++++++++ src/Conversation.php | 163 ++++++++++++++++++++++++ src/Entity.php | 24 ++++ src/Response.php | 252 +++++++++++++++++++++++++++++++++++++ src/client.php | 165 ------------------------ src/constants.php | 29 ----- src/conversation.php | 151 ---------------------- src/entity.php | 15 --- src/response.php | 176 -------------------------- tests/ClientTest.php | 110 ++++++++++++++++ tests/ConversationTest.php | 47 +++++++ tests/EntityTest.php | 53 ++++++++ tests/ResponseTest.php | 72 +++++++++++ tests/bootstrap.php | 3 - tests/clientTest.php | 114 ----------------- tests/conversationTest.php | 60 --------- tests/data/Converse.json | 36 ++++++ tests/data/Request.json | 52 ++++++++ tests/entityTest.php | 54 -------- tests/responseTest.php | 82 ------------ tests/test.json | 52 -------- tests/testconverse.json | 3 - 25 files changed, 992 insertions(+), 938 deletions(-) delete mode 100644 package.json create mode 100644 src/Client.php create mode 100644 src/Conversation.php create mode 100644 src/Entity.php create mode 100644 src/Response.php delete mode 100644 src/client.php delete mode 100644 src/constants.php delete mode 100644 src/conversation.php delete mode 100644 src/entity.php delete mode 100644 src/response.php create mode 100644 tests/ClientTest.php create mode 100644 tests/ConversationTest.php create mode 100644 tests/EntityTest.php create mode 100644 tests/ResponseTest.php delete mode 100644 tests/bootstrap.php delete mode 100644 tests/clientTest.php delete mode 100644 tests/conversationTest.php create mode 100644 tests/data/Converse.json create mode 100644 tests/data/Request.json delete mode 100644 tests/entityTest.php delete mode 100644 tests/responseTest.php delete mode 100644 tests/test.json delete mode 100644 tests/testconverse.json diff --git a/.gitignore b/.gitignore index 029e2cd..7cc781c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ composer.phar .DS_Store node_modules file.wav -test.php +test.php \ No newline at end of file diff --git a/composer.json b/composer.json index debf41f..301ab84 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,10 @@ { "name": "Bruno", "email": "bruno.gantelmi@recast.ai" + }, + { + "name": "Sylvain Jaune", + "email": "sylvain@hellocare.com" } ], "minimum-stability": "dev", @@ -19,8 +23,8 @@ }, "autoload": { "psr-4": { - "SDK-PHP\\": "src/", - "client\\": "tests/" + "RecastAI\\": "src/", + "Tests\\RecastAI\\": "tests/" } } } diff --git a/package.json b/package.json deleted file mode 100644 index 9b4cf48..0000000 --- a/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "sdkphp", - "version": "1.0.0", - "description": "[logo]: https://github.com/RecastAI/SDK-NodeJs/blob/master/misc/logo-inline.png \"Recast.AI\"", - "main": "index.js", - "directories": { - "test": "tests" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "doc": "./node_modules/apidoc/bin/apidoc -i src/ -o doc/" - }, - "apidoc": { - "name": "php sdk API doc", - "version": "0.1.0", - "description": "apiDoc php sdk recast", - "apidoc": { - "title": "php sdk recast" - } - }, - "repository": { - "type": "git", - "url": "git+https://github.com/bgantelm/SDK-PHP.git" - }, - "author": "", - "license": "ISC", - "bugs": { - "url": "https://github.com/bgantelm/SDK-PHP/issues" - }, - "homepage": "https://github.com/bgantelm/SDK-PHP#readme" -} diff --git a/src/Client.php b/src/Client.php new file mode 100644 index 0000000..db77cd9 --- /dev/null +++ b/src/Client.php @@ -0,0 +1,176 @@ +token = $token; + $this->language = $language; + } + + /** + * Sends a text request to Recast and returns the response. + * + * @param string $text + * + * @return \RecastAI\Response + * + * @throws Token is missing + */ + public function textRequest($text, $options = null) + { + if ($options === null) { + $token = $this->token; + } else if (array_key_exists('token', $options)) { + $token = $options['token']; + } + + if ($this->language) { + $params = array('text' => $text, 'language' => $this->language); + } else { + $params = array('text' => $text); + } + + if (!$token) { + return ('Token is missing'); + } else { + $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); + + $res = $this->requestPrivate(self::API_ENDPOINT, $headers, $params); + return (new Response($res)); + } + } + + /** + * Sends a request to Recast and returns the response. + * + * @param string $url + * @param array $headers + * @param array $params + * + * @return Response $res + */ + protected function requestPrivate($url, $headers, $params) + { + $res = \Requests::post($url, $headers, json_encode($params)); + + return ($res); + } + + /** + * Sends a request to Recast and returns the response. + * + * @param string $url + * @param array $params + * + * @return Response $res + */ + protected function requestFilePrivate($url, $params) + { + $client = new \GuzzleHttp\Client(); + $res = $client->request('POST', $url, $params); + + return ($res); + } + + /** + * Sends a file request to Recast and returns the response. + * + * @param string $file + * + * @return Response + * + * @throws Token is missing + */ + public function fileRequest($file, $options = null) + { + if ($options === null) { + $token = $this->token; + } else if (array_key_exists('token', $options)) { + $token = $options['token']; + } + + if (!$token) { + return ('Token is missing'); + } else { + $url = self::API_ENDPOINT; + + if (!$this->language) { + $params = [ + 'headers' => [ + 'Authorization' => "Token " . $token + ], + 'multipart' => [ + [ + 'Content-Type' => 'multipart/form-data', + 'name' => 'voice', + 'contents' => fopen($file, 'r') + ], + ] + ]; + } else { + $params = [ + 'headers' => [ + 'Authorization' => "Token " . $token + ], + 'multipart' => [ + [ + 'Content-Type' => 'multipart/form-data', + 'name' => 'voice', + 'contents' => fopen($file, 'r') + ], + [ + 'name' => 'language', + 'contents' => $this->language + ], + ] + ]; + } + $res = $this->requestFilePrivate($url, $params); + return (new Response($res)); + } + } + + /** + * @param $text + * @param null $conversation_token + * @param null $options + * @return Conversation|string + */ + public function textConverse($text, $conversation_token = null, $options = null) + { + if ($options === null) { + $token = $this->token; + } else if ($options['token']) { + $token = $options['token']; + } + + if ($this->language) { + $params = array('text' => $text, 'language' => $this->language, 'conversation_token' => $conversation_token); + } else { + $params = array('text' => $text, 'conversation_token' => $conversation_token); + } + + if (!$token) { + return ('Token is missing'); + } else { + $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); + $res = $this->requestPrivate(Conversation::API_ENDPOINT_CONVERSATION, $headers, $params); + + return (new Conversation(($res))); + } + } +} diff --git a/src/Conversation.php b/src/Conversation.php new file mode 100644 index 0000000..eea2b1d --- /dev/null +++ b/src/Conversation.php @@ -0,0 +1,163 @@ +replies = $response->results->replies; + $this->action = $response->results->action; + $this->nextActions = $response->results->next_actions; + $this->memory = $response->results->memory; + $this->conversationToken = $response->results->conversation_token; + } + + /** + * Returns the first reply if there is one + * @return {String}: this first reply or null + */ + public function reply() + { + return (count($this->replies) > 0 ? $this->replies[0] : null); + } + + /** + * Returns a concatenation of the replies + * @return {String}: the concatenation of the replies + */ + public function replies() + { + return ($this->replies); + } + + /** + * Returns a concatenation of the replies + * @return {String}: the concatenation of the replies + */ + public function joinedReplies($separator = ' ') + { + return ($this->replies ? join($separator, $this->replies) : null); + } + + /** + * Returns all the action whose name matches the parameter + * @return {Array}: returns an array of action, or null + */ + public function action() + { + return ($this->action || null); + } + + /** + * Returns the first nextActions whose name matches the parameter + * @return {Array}: returns an array of first nextActions, or null + */ + public function nextAction() + { + return (count($this->nextAction) > 0 ? $this->nextAction[0] : null); + } + + /** + * Returns all nextActions + * @return {Array}: returns an array of nextActions, or [] + */ + public function nextActions() + { + return ($this->nextActions || []); + } + + /** + * Returns the memory matching the alias + * or all the memory if no alias provided + * @return {object}: the memory + */ + public function memory($name = null) + { + if ($name === null) { + return ($this->memory); + } else if (array_key_exists($name, $this->memory)) { + return ($this->memory->$name); + } else { + return (null); + } + } + + /** + * Merge the conversation memory with the one in parameter + * Returns the memory updated + * @return {object}: the memory updated + */ + static public function setMemory($token, $conversation_token, $memory) + { + $params = array('conversation_token' => $conversation_token, 'memory' => $memory); + $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); + + $request = \Requests::put(self::API_ENDPOINT_CONVERSATION, $headers, json_encode($params)); + $res = (json_decode($request->body)); + return ($res->{'results'}->{'memory'}); + } + + /** + * Reset the memory of the conversation + * @return {object}: the updated memory + */ + static public function resetMemory($token, $conversation_token, $alias = null) + { + $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); + if ($alias === null) { + $params = array('conversation_token' => $conversation_token); + } else { + $memory = (object)[ + $alias => null + ]; + $params = array('conversation_token' => $conversation_token, 'memory' => $memory); + } + $request = \Requests::put(self::API_ENDPOINT_CONVERSATION, $headers, json_encode($params)); + return ($request); + } + + /** + * Reset the conversation + * @return {object}: the updated memory + */ + static public function resetConversation($token, $conversation_token) + { + $curl = curl_init(); + + curl_setopt_array($curl, array( + CURLOPT_URL => self::API_ENDPOINT_CONVERSATION, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "DELETE", + CURLOPT_POSTFIELDS => "conversation_token=" . $conversation_token, + CURLOPT_HTTPHEADER => array( + "authorization: Token " . $token, + "cache-control: no-cache", + "content-type: application/x-www-form-urlencoded", + ), + )); + + $response = curl_exec($curl); + $err = curl_error($curl); + + curl_close($curl); + + if ($err) { + echo "cURL Error #:" . $err; + } else { + return ($response); + } + } +} \ No newline at end of file diff --git a/src/Entity.php b/src/Entity.php new file mode 100644 index 0000000..6301b9b --- /dev/null +++ b/src/Entity.php @@ -0,0 +1,24 @@ +name = $name; + foreach ($data as $key => $value) { + $this->$key = $value; + } + } +} \ No newline at end of file diff --git a/src/Response.php b/src/Response.php new file mode 100644 index 0000000..4d9e436 --- /dev/null +++ b/src/Response.php @@ -0,0 +1,252 @@ +entities = []; + + $this->act = $response->results->act; + $this->type = $response->results->type; + $this->source = $response->results->source; + $this->intents = $response->results->intents; + $this->sentiment = $response->results->sentiment; + + foreach ($response->results->entities as $key => $value) { + foreach ($value as $i => $entity) { + $this->entities[] = new Entity($key, $entity); + } + } + + $this->uuid = $response->results->uuid; + $this->language = $response->results->language; + $this->version = $response->results->version; + $this->timestamp = $response->results->timestamp; + $this->status = $response->results->status; + } + + /** + * Returns the first Entity whose name matches the parameter + * @param {String} name: the entity's name + * @return {Entity}: returns the first entity that matches - name - + */ + public function get($name) + { + $count = count($this->entities); + + for ($i = 0; $i <= $count; $i++) { + if ($this->entities[$i]->name == $name) { + return ($this->entities[$i]); + } + } + + return null; + } + + /** + * Returns all the entities whose name matches the parameter + * @param {String} name: the entity's name + * @return {Array}: returns an array of Entity, or null + */ + public function all($name) + { + $count = count($this->entities); + $res = []; + + for ($i = 0; $i < $count; $i++) { + if ($this->entities[$i]->name == $name) { + $res[] = $this->entities[$i]; + } + } + + return ($res); + } + + /** + * Returns the first Intent if there is one + * @return {Sentence}: returns the first Intent or null + */ + public function intent() + { + if ($this->intents[0]) { + return ($this->intents[0]); + } + + return (null); + } + + /** + * ACT HELPERS + * Returns whether or not the response act corresponds to the checked one + * @return {boolean}: true or false + */ + public function isAssert() + { + return ($this->act === self::ACT_ASSERT); + } + + /** + * @return bool + */ + public function isCommand() + { + return ($this->act === self::ACT_COMMAND); + } + + /** + * @return bool + */ + public function isWhQuery() + { + return ($this->act === self::ACT_WH_QUERY); + } + + /** + * @return bool + */ + public function isYnQuery() + { + return ($this->act === self::ACT_YN_QUERY); + } + + /** + * TYPE HELPERS + * Returns whether or not the response type corresponds to the checked one + * @return {boolean}: true or false + */ + public function isAbbreviation() + { + if (strstr($this->type, self::TYPE_ABBREVIATION)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isEntity() + { + if (strstr($this->type, self::TYPE_ENTITY)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isDescription() + { + if (strstr($this->type, self::TYPE_DESCRIPTION)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isHuman() + { + if (strstr($this->type, self::TYPE_HUMAN)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isLocation() + { + if (strstr($this->type, self::TYPE_LOCATION)) { + return (true); + } + return (false); + } + + /** + * @return bool + */ + public function isNumber() + { + if (strstr($this->type, self::TYPE_NUMBER)) { + return (true); + } + return (false); + } + + /** + * SENTIMENT HELPERS + * Returns whether or not the response sentiment corresponds to the checked one + * @return {boolean}: true or false + */ + + public function isPositive() + { + return ($this->sentiment === self::SENTIMENT_POSITIVE); + } + + /** + * @return bool + */ + public function isNeutral() + { + return ($this->sentiment === self::SENTIMENT_NEUTRAL); + } + + /** + * @return bool + */ + public function isNegative() + { + return ($this->sentiment === self::SENTIMENT_NEGATIVE); + } + + /** + * @return bool + */ + public function isVPositive() + { + return ($this->sentiment === self::SENTIMENT_VPOSITIVE); + } + + /** + * @return bool + */ + public function isVNegative() + { + return ($this->sentiment === self::SENTIMENT_VNEGATIVE); + } +} diff --git a/src/client.php b/src/client.php deleted file mode 100644 index 158f285..0000000 --- a/src/client.php +++ /dev/null @@ -1,165 +0,0 @@ -token = $token; - $this->language = $language; - } - - /** - * Sends a text request to Recast and returns the response. - * - * @param string $text - * - * @return Response - * - * @throws Token is missing - */ - public function textRequest($text, $options=null) - { - if ($options === null) { - $token = $this->token; - } else if (array_key_exists('token', $options)) { - $token = $options['token']; - } - - if ($this->language) { - $params = array('text' => $text, 'language' => $this->language); - } else { - $params = array('text' => $text); - } - - if (!$token) { - return('Token is missing'); - } else { - $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); - - $res = $this->requestPrivate(constants\Constants::API_ENDPOINT, $headers, $params); - return(new response\Response($res)); - } - } - - /** - * Sends a request to Recast and returns the response. - * - * @param string $url - * @param array $headers - * @param array $params - * - * @return Response $res - */ - protected function requestPrivate($url, $headers, $params) { - $res = Requests::post($url, $headers, json_encode($params)); - - return ($res); - } - - /** - * Sends a request to Recast and returns the response. - * - * @param string $url - * @param array $params - * - * @return Response $res - */ - protected function requestFilePrivate($url, $params) { - $client = new \GuzzleHttp\Client(); - $res = $client->request('POST', $url, $params); - - return ($res); - } - - /** - * Sends a file request to Recast and returns the response. - * - * @param string $file - * - * @return Response - * - * @throws Token is missing - */ - public function fileRequest($file, $options=null) - { - if ($options === null) { - $token = $this->token; - } else if (array_key_exists('token', $options)) { - $token = $options['token']; - } - - if (!$token) { - return('Token is missing'); - } else { - $url = constants\Constants::API_ENDPOINT; - - if (!$this->language) { - $params = [ - 'headers' => [ - 'Authorization' => "Token " . $token - ], - 'multipart' => [ - [ - 'Content-Type' => 'multipart/form-data', - 'name' => 'voice', - 'contents' => fopen($file, 'r') - ], - ] - ]; - } else { - $params = [ - 'headers' => [ - 'Authorization' => "Token " . $token - ], - 'multipart' => [ - [ - 'Content-Type' => 'multipart/form-data', - 'name' => 'voice', - 'contents' => fopen($file, 'r') - ], - [ - 'name' => 'language', - 'contents' => $this->language - ], - ] - ]; - } - $res = $this->requestFilePrivate($url, $params); - return(new response\Response($res)); - } - } - public function textConverse($text, $conversation_token=null, $options=null) { - if ($options === null) { - $token = $this->token; - } else if ($options['token']) { - $token = $options['token']; - } - - if ($this->language) { - $params = array('text' => $text, 'language' => $this->language, 'conversation_token' => $conversation_token); - } else { - $params = array('text' => $text, 'conversation_token' => $conversation_token); - } - - if (!$token) { - return('Token is missing'); - } else { - $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); - $res = $this->requestPrivate(constants\Constants::API_ENDPOINT_CONVERSATION, $headers, $params); - - return(new conversation\Conversation(($res))); - } - } -} diff --git a/src/constants.php b/src/constants.php deleted file mode 100644 index 5b55198..0000000 --- a/src/constants.php +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/src/conversation.php b/src/conversation.php deleted file mode 100644 index 948a9d5..0000000 --- a/src/conversation.php +++ /dev/null @@ -1,151 +0,0 @@ -body); - $this->replies = $res->{'results'}->{'replies'}; - $this->action = $res->{'results'}->{'action'}; - $this->nextActions = $res->{'results'}->{'next_actions'}; - $this->memory = $res->{'results'}->{'memory'}; - $this->conversationToken = $res->{'results'}->{'conversation_token'}; - } - - /** - * Returns the first reply if there is one - * @return {String}: this first reply or null - */ - public function reply() { - return (count($this->replies) > 0 ? $this->replies[0] : null); - } - - /** - * Returns a concatenation of the replies - * @return {String}: the concatenation of the replies - */ - public function replies() { - return ($this->replies); - } - - /** - * Returns a concatenation of the replies - * @return {String}: the concatenation of the replies - */ - public function joinedReplies($separator=' ') { - return ($this->replies ? join($separator, $this->replies) : null); - } - - /** - * Returns all the action whose name matches the parameter - * @return {Array}: returns an array of action, or null - */ - public function action() { - return ($this->action || null); - } - - /** - * Returns the first nextActions whose name matches the parameter - * @return {Array}: returns an array of first nextActions, or null - */ - public function nextAction() { - return (count($this->nextAction) > 0 ? $this->nextAction[0] : null); - } - - /** - * Returns all nextActions - * @return {Array}: returns an array of nextActions, or [] - */ - public function nextActions() { - return ($this->nextActions || []); - } - - /** - * Returns the memory matching the alias - * or all the memory if no alias provided - * @return {object}: the memory - */ - public function memory($name=null) { - if ($name === null) { - return ($this->memory); - } else if (array_key_exists($name, $this->memory)) { - return ($this->memory->$name); - } else { - return (null); - } - } - - /** - * Merge the conversation memory with the one in parameter - * Returns the memory updated - * @return {object}: the memory updated - */ - static public function setMemory($token, $conversation_token, $memory) { - $params = array('conversation_token' => $conversation_token, 'memory' => $memory); - $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); - - $request = Requests::put(constants\Constants::API_ENDPOINT_CONVERSATION, $headers, json_encode($params)); - $res = (json_decode($request->body)); - return ($res->{'results'}->{'memory'}); - } - - /** - * Reset the memory of the conversation - * @return {object}: the updated memory - */ - static public function resetMemory($token, $conversation_token, $alias=null) { - $headers = array('Content-Type' => 'application/json', 'Authorization' => "Token " . $token); - if ($alias === null) { - $params = array('conversation_token' => $conversation_token); - } else { - $memory = (object) [ - $alias => null - ]; - $params = array('conversation_token' => $conversation_token, 'memory' => $memory); - } - $request = Requests::put(constants\Constants::API_ENDPOINT_CONVERSATION, $headers, json_encode($params)); - return ($request); - } - - /** - * Reset the conversation - * @return {object}: the updated memory - */ - static public function resetConversation($token, $conversation_token) { - $curl = curl_init(); - - curl_setopt_array($curl, array( - CURLOPT_URL => constants\Constants::API_ENDPOINT_CONVERSATION, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "DELETE", - CURLOPT_POSTFIELDS => "conversation_token=" . $conversation_token, - CURLOPT_HTTPHEADER => array( - "authorization: Token " . $token, - "cache-control: no-cache", - "content-type: application/x-www-form-urlencoded", - ), - )); - - $response = curl_exec($curl); - $err = curl_error($curl); - - curl_close($curl); - - if ($err) { - echo "cURL Error #:" . $err; - } else { - return($response); - } - } -} -?> diff --git a/src/entity.php b/src/entity.php deleted file mode 100644 index b65b809..0000000 --- a/src/entity.php +++ /dev/null @@ -1,15 +0,0 @@ -name = $name; - foreach ($data as $key => $value) { - $this->$key = $value; - } - } -} - -?> diff --git a/src/response.php b/src/response.php deleted file mode 100644 index 7778399..0000000 --- a/src/response.php +++ /dev/null @@ -1,176 +0,0 @@ -body); - $this->entities = []; - - $this->act = $res->{'results'}->{'act'}; - $this->type = $res->{'results'}->{'type'}; - $this->source = $res->{'results'}->{'source'}; - $this->intents = $res->{'results'}->{'intents'}; - $this->sentiment = $res->{'results'}->{'sentiment'}; - - foreach ($res->{'results'}->{'entities'} as $key => $value) { - foreach ($value as $i => $entity) { - $this->entities[] = new entity\Entity($key, $entity); - } - } - - $this->uuid = $res->{'results'}->{'uuid'}; - $this->language = $res->{'results'}->{'language'}; - $this->version = $res->{'results'}->{'version'}; - $this->timestamp = $res->{'results'}->{'timestamp'}; - $this->status = $res->{'results'}->{'status'}; - } - - /** - * Returns the first Entity whose name matches the parameter - * @param {String} name: the entity's name - * @return {Entity}: returns the first entity that matches - name - - */ - public function get($name) { - $count = count($this->entities); - - for ($i = 0; $i <= $count; $i++) { - if ($this->entities[$i]->name == $name) { - return ($this->entities[$i]); - } - } - - return null; - } - - /** - * Returns all the entities whose name matches the parameter - * @param {String} name: the entity's name - * @return {Array}: returns an array of Entity, or null - */ - public function all($name) { - $count = count($this->entities); - $res = []; - - for ($i = 0; $i < $count ; $i++) { - if ($this->entities[$i]->name == $name) { - $res[] = $this->entities[$i]; - } - } - - return ($res); - } - - /** - * Returns the first Intent if there is one - * @return {Sentence}: returns the first Intent or null - */ - public function intent() { - if ($this->intents[0]) { - return ($this->intents[0]); - } - - return (null); - } - - /** - * ACT HELPERS - * Returns whether or not the response act corresponds to the checked one - * @return {boolean}: true or false - */ - public function isAssert() { - return ($this->act === constants\Constants::ACT_ASSERT); - } - - public function isCommand() { - return ($this->act === constants\Constants::ACT_COMMAND); - } - - public function isWhQuery() { - return ($this->act === constants\Constants::ACT_WH_QUERY); - } - - public function isYnQuery() { - return ($this->act === constants\Constants::ACT_YN_QUERY); - } - - /** - * TYPE HELPERS - * Returns whether or not the response type corresponds to the checked one - * @return {boolean}: true or false - */ - public function isAbbreviation() { - if (strstr($this->type, constants\Constants::TYPE_ABBREVIATION)) { - return (true); - } - return (false); - } - - public function isEntity() { - if (strstr($this->type, constants\Constants::TYPE_ENTITY)) { - return (true); - } - return (false); - } - - public function isDescription() { - if (strstr($this->type, constants\Constants::TYPE_DESCRIPTION)) { - return (true); - } - return (false); - } - - public function isHuman() { - if (strstr($this->type, constants\Constants::TYPE_HUMAN)) { - return (true); - } - return (false); - } - - public function isLocation() { - if (strstr($this->type, constants\Constants::TYPE_LOCATION)) { - return (true); - } - return (false); - } - - public function isNumber() { - if (strstr($this->type, constants\Constants::TYPE_NUMBER)) { - return (true); - } - return (false); - } - - /** - * SENTIMENT HELPERS - * Returns whether or not the response sentiment corresponds to the checked one - * @return {boolean}: true or false - */ - - public function isPositive() { - return ($this->sentiment === constants\Constants::SENTIMENT_POSITIVE); - } - - public function isNeutral() { - return ($this->sentiment === constants\Constants::SENTIMENT_NEUTRAL); - } - - public function isNegative() { - return ($this->sentiment === constants\Constants::SENTIMENT_NEGATIVE); - } - - public function isVPositive() { - return ($this->sentiment === constants\Constants::SENTIMENT_VPOSITIVE); - } - - public function isVNegative() { - return ($this->sentiment === constants\Constants::SENTIMENT_VNEGATIVE); - } -} diff --git a/tests/ClientTest.php b/tests/ClientTest.php new file mode 100644 index 0000000..f9dac4a --- /dev/null +++ b/tests/ClientTest.php @@ -0,0 +1,110 @@ +assertInstanceOf('RecastAI\Client', new Client($token, null)); + } + + public function testClientClassWithoutToken() + { + $language = 'en'; + $this->assertInstanceOf('RecastAI\Client', new Client(null, $language)); + } + + public function testClientClassWithoutTokenAndLanguage() + { + $this->assertInstanceOf('RecastAI\Client', new Client()); + } + + public function testClientClassWithTokenAndLanguage() + { + $token = 'TestToken'; + $language = 'en'; + + $this->assertInstanceOf('RecastAI\Client', new Client($token, $language)); + } + + public function testClientClassIfAttributesAreOkay() + { + $token = 'TestToken'; + $language = 'en'; + $client = new Client($token, $language); + + $this->assertEquals($client->token, $token); + $this->assertEquals($client->language, $language); + } + + public function testTextRequestIfAllOkay() + { + $callResult = self::jsonResponse(); + $token = 'TestToken'; + $language = 'en'; + + $stub = $this->getMockBuilder('RecastAI\Client') + ->setConstructorArgs(array($token, $language)) + ->setMethods(['requestPrivate']) + ->getMock(); + + $stub->expects($this->once()) + ->method('requestPrivate') + ->will($this->returnValue($callResult)); + + $response = $stub->textRequest($callResult); + + $this->assertEquals('200', $response->status); + } + + public function testTextRequestIfNoToken() + { + $client = new Client(); + $res = $client->textRequest('Hello world'); + $this->assertEquals($res, 'Token is missing'); + } + + public function testFileRequestIfAllOkay() + { + $callResult = self::jsonResponse(); + + $file = __DIR__ . '/data/file.wav'; + + if (!file_exists($file)) { + $this->markTestSkipped('Audio test file not found'); + } + + $token = 'TestToken'; + $language = 'en'; + + $stub = $this->getMockBuilder('RecastAI\Client') + ->setConstructorArgs(array($token, $language)) + ->setMethods(['requestFilePrivate']) + ->getMock(); + + $stub->expects($this->once()) + ->method('requestFilePrivate') + ->will($this->returnValue($callResult)); + + $response = $stub->fileRequest($file); + $this->assertEquals('200', $response->status); + } + + public function testFileRequestIfNoToken() + { + $client = new Client(); + + $res = $client->fileRequest(__DIR__ . '/data/file.wav'); + $this->assertEquals($res, 'Token is missing'); + } +} \ No newline at end of file diff --git a/tests/ConversationTest.php b/tests/ConversationTest.php new file mode 100644 index 0000000..5e6e5bf --- /dev/null +++ b/tests/ConversationTest.php @@ -0,0 +1,47 @@ +assertInstanceOf('RecastAI\Conversation', new Conversation($jsonResult)); + } + + public function testConversationClassAttributes() + { + $jsonResult = self::jsonResponse(); + $result = json_decode($jsonResult); + + $conversation = new Conversation($jsonResult); + + $this->assertEquals($conversation->conversationToken, $result->results->conversation_token); + $this->assertEquals($conversation->replies, $result->results->replies); + $this->assertEquals($conversation->action, $result->results->action); + $this->assertEquals($conversation->nextActions, $result->results->next_actions); + $this->assertEquals($conversation->memory, $result->results->memory); + } + + public function testResponseClassMethods() + { + $jsonResult = self::jsonResponse(); + $result = json_decode($jsonResult); + + $conversation = new Conversation($jsonResult); + + $this->assertEquals($conversation->reply(), $result->results->replies[0]); + $this->assertEquals($conversation->joinedReplies(), join(' ', $result->results->replies)); + $this->assertEquals($conversation->joinedReplies('\n'), join('\n', $result->results->replies)); + $this->assertEquals($conversation->memory(), $result->results->memory); + $this->assertEquals($conversation->memory('loc'), $result->results->memory->loc); + } +} \ No newline at end of file diff --git a/tests/EntityTest.php b/tests/EntityTest.php new file mode 100644 index 0000000..93db246 --- /dev/null +++ b/tests/EntityTest.php @@ -0,0 +1,53 @@ + '1', + 'number' => 'singular', + 'gender' => 'unkown', + 'raw' => 'me', + ]; + + $data2 = (object)[ + 'value' => 'asparagus', + 'raw' => 'asparagus', + ]; + + $this->assertInstanceOf('RecastAI\Entity', new Entity('ingredient', $data2)); + } + + public function testEntityClassShouldHaveAttributes() + { + $data1 = (object)[ + 'person' => '1', + 'number' => 'singular', + 'gender' => 'unkown', + 'raw' => 'me', + ]; + $data2 = (object)[ + 'value' => 'asparagus', + 'raw' => 'asparagus', + ]; + + $testEntity1 = new Entity('person', $data1); + $testEntity2 = new Entity('ingredient', $data2); + + $this->assertEquals($testEntity1->name, 'person'); + $this->assertEquals($testEntity1->person, $data1->person); + $this->assertEquals($testEntity1->number, $data1->number); + $this->assertEquals($testEntity1->gender, $data1->gender); + $this->assertEquals($testEntity1->raw, $data1->raw); + + $this->assertEquals($testEntity2->name, 'ingredient'); + $this->assertEquals($testEntity2->value, $data2->value); + $this->assertEquals($testEntity2->raw, $data2->raw); + } +} diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php new file mode 100644 index 0000000..a65de1c --- /dev/null +++ b/tests/ResponseTest.php @@ -0,0 +1,72 @@ +assertInstanceOf('RecastAI\Response', new Response($jsonResult)); + } + + public function testResponseClassAttributes() + { + $jsonResult = self::jsonResponse(); + $result = json_decode($jsonResult); + + $response = new Response($jsonResult); + + $count = count($response->entities, COUNT_RECURSIVE); + + $this->assertEquals($response->act, $result->results->{'act'}); + $this->assertEquals($response->type, $result->results->{'type'}); + $this->assertEquals($response->source, $result->results->{'source'}); + $this->assertEquals($response->sentiment, $result->results->{'sentiment'}); + $this->assertEquals($response->language, $result->results->{'language'}); + $this->assertEquals($response->version, $result->results->{'version'}); + $this->assertEquals($response->timestamp, $result->results->{'timestamp'}); + $this->assertEquals($count, 4); + $this->assertInstanceOf('RecastAI\Entity', $response->entities[0]); + $this->assertInternalType('array', $response->entities); + $this->assertInternalType('array', $response->intents); + } + + public function testResponseClassMethods() + { + $jsonResult = self::jsonResponse(); + $result = json_decode($jsonResult); + + $response = new Response($jsonResult); + + $all = count($response->all('location')); + $get = $response->get('location'); + + $this->assertEquals($response->intent(), $result->results->{'intents'}[0]); + $this->assertEquals($all, 2); + $this->assertEquals('location', $get->name); + + $this->assertEquals($response->isAssert(), false); + $this->assertEquals($response->isCommand(), false); + $this->assertEquals($response->isWhQuery(), true); + $this->assertEquals($response->isYnQuery(), false); + $this->assertEquals($response->isAbbreviation(), false); + $this->assertEquals($response->isEntity(), false); + $this->assertEquals($response->isDescription(), true); + $this->assertEquals($response->isHuman(), false); + $this->assertEquals($response->isLocation(), false); + $this->assertEquals($response->isNumber(), false); + $this->assertEquals($response->isVPositive(), false); + $this->assertEquals($response->isPositive(), false); + $this->assertEquals($response->isNeutral(), true); + $this->assertEquals($response->isNegative(), false); + $this->assertEquals($response->isVNegative(), false); + } +} \ No newline at end of file diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index 91c51fb..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,3 +0,0 @@ -assertInstanceOf('client\Client', new client\Client($token, null)); - } - - public function testClientClassWithoutToken() { - $token = 'TestToken'; - $language = 'en'; - - $this->assertInstanceOf('client\Client', new client\Client(null, $language)); - } - - public function testClientClassWithoutTokenAndLanguage() { - $token = 'TestToken'; - $language = 'en'; - - $this->assertInstanceOf('client\Client', new client\Client()); - } - - public function testClientClassWithTokenAndLanguage() { - $token = 'TestToken'; - $language = 'en'; - - $this->assertInstanceOf('client\Client', new client\Client($token, $language)); - } - - public function testClientClassIfAttributesAreOkay() { - $token = 'TestToken'; - $language = 'en'; - $client = new client\Client($token, $language); - - $this->assertEquals($client->token, $token); - $this->assertEquals($client->language, $language); - } - - public function testtextRequestIfAllOkay() { - - $fp = fopen ("./tests/test.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/test.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $token = 'TestToken'; - $language = 'en'; - - $stub = $this->getMockBuilder('client\Client') - ->setConstructorArgs(array($token, $language)) - ->setMethods(['requestPrivate']) - ->getMock(); - - $stub->expects($this->once()) - ->method('requestPrivate') - ->will($this->returnValue($res2)); - $res = $stub->textRequest($res2); - $this->assertEquals('200', $res->status); - - } - - public function testtextRequestIfNoToken() { - - $client = new client\Client(); - $res = $client->textRequest('Hello world'); - $this->assertEquals($res, 'Token is missing'); - } - - public function testfileRequestIfAllOkay() { - $fp = fopen ("./tests/test.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/test.json')); - fclose ($fp); - $res2 = json_decode ($contenu_du_fichier); - $file = './file.wav'; - $token = 'TestToken'; - $language = 'en'; - - $stub = $this->getMockBuilder('client\Client') - ->setConstructorArgs(array($token, $language)) - ->setMethods(['requestFilePrivate']) - ->getMock(); - - $stub->expects($this->once()) - ->method('requestFilePrivate') - ->will($this->returnValue($res2)); - - $res = $stub->fileRequest($file); - $this->assertEquals('200', $res->status); - - } - - public function testfileRequestIfNoToken() { - $client = new client\Client(); - - $res = $client->fileRequest('./file.wav'); - $this->assertEquals($res, 'Token is missing'); - } -} - -?> diff --git a/tests/conversationTest.php b/tests/conversationTest.php deleted file mode 100644 index 90f81c5..0000000 --- a/tests/conversationTest.php +++ /dev/null @@ -1,60 +0,0 @@ -assertInstanceOf('conversation\Conversation', new conversation\Conversation($json)); - } - - public function testConversationClassAttributes() { - $fp = fopen ("./tests/testconverse.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/testconverse.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $lol = json_decode($res2->body); - $res = new conversation\Conversation($res2); - - - $this->assertEquals($res->conversationToken, $lol->results->conversation_token); - $this->assertEquals($res->replies, $lol->results->replies); - $this->assertEquals($res->action, $lol->results->action); - $this->assertEquals($res->nextActions, $lol->results->next_actions); - $this->assertEquals($res->memory, $lol->results->memory); - } - - public function testResponseClassMethods() { - $fp = fopen ("./tests/testconverse.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/testconverse.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $lol = json_decode($res2->body); - $res = new conversation\Conversation($res2); - - $this->assertEquals($res->reply(), $lol->results->replies[0]); - $this->assertEquals($res->joinedReplies(), join(' ', $lol->results->replies)); - $this->assertEquals($res->joinedReplies('\n'), join('\n', $lol->results->replies)); - $this->assertEquals($res->memory(), $lol->results->memory); - $this->assertEquals($res->memory('loc'), $lol->results->memory->loc); - - - } -} - - -?> diff --git a/tests/data/Converse.json b/tests/data/Converse.json new file mode 100644 index 0000000..21b5f72 --- /dev/null +++ b/tests/data/Converse.json @@ -0,0 +1,36 @@ +{ + "results": { + "source": "hello", + "replies": [ + "Salut", + "Need location please" + ], + "action": { + "slug": "greetings", + "done": true, + "reply": "Salut" + }, + "next_actions": [ + { + "slug": "capitals", + "done": false, + "reply": "Need location please" + } + ], + "memory": { + "loc": null + }, + "entities": {}, + "intents": [ + { + "slug": "greetings", + "confidence": 0.99 + } + ], + "conversation_token": "f6362f5ded83031d42c2d02d954359f9", + "language": "en", + "timestamp": "2016-10-05T12:07:30.907Z", + "status": 200 + }, + "message": "Converses rendered with success" +} \ No newline at end of file diff --git a/tests/data/Request.json b/tests/data/Request.json new file mode 100644 index 0000000..e3e42d5 --- /dev/null +++ b/tests/data/Request.json @@ -0,0 +1,52 @@ +{ + "results": { + "uuid": "6b356fe1-7aee-4407-8c0f-47ed70675679", + "source": "What is the weather in London tomorrow? And in Paris?", + "intents": [ + { + "name": "weather", + "confidence": 0.67 + } + ], + "act": "wh-query", + "type": "desc:desc", + "sentiment": "neutral", + "entities": { + "action": [ + { + "agent": "the weather in London", + "tense": "present", + "raw": "is", + "confidence": 0.89 + } + ], + "location": [ + { + "formated": "London, London, Greater London, England, United Kingdom", + "lat": 51.5073509, + "lng": -0.1277583, + "raw": "London", + "confidence": 0.97 + }, + { + "formated": "Paris, Paris, Île-de-France, France", + "lat": 48.856614, + "lng": 2.3522219, + "raw": "Paris", + "confidence": 0.83 + } + ], + "datetime": [ + { + "value": "2016-07-11T10:00:00+00:00", + "raw": "tomorrow", + "confidence": 0.95 + } + ] + }, + "language": "en", + "version": "2.0.0", + "timestamp": "2016-07-10T23:17:59+02:00", + "status": 200 + } +} \ No newline at end of file diff --git a/tests/entityTest.php b/tests/entityTest.php deleted file mode 100644 index 689e939..0000000 --- a/tests/entityTest.php +++ /dev/null @@ -1,54 +0,0 @@ - '1', - 'number' => 'singular', - 'gender' => 'unkown', - 'raw' => 'me', - ]; - $data2 = (object) [ - 'value' => 'asparagus', - 'raw' => 'asparagus', - ]; - - $this->assertInstanceOf('entity\Entity', new entity\Entity('ingredient', $data2)); - } - - public function testEntityClassShouldHaveAttributes() { - $data1 = (object) [ - 'person' => '1', - 'number' => 'singular', - 'gender' => 'unkown', - 'raw' => 'me', - ]; - $data2 = (object) [ - 'value' => 'asparagus', - 'raw' => 'asparagus', - ]; - - $testEntity1 = new entity\Entity('person', $data1); - $testEntity2 = new entity\Entity('ingredient', $data2); - - $this->assertEquals($testEntity1->name, 'person'); - $this->assertEquals($testEntity1->person, $data1->person); - $this->assertEquals($testEntity1->number, $data1->number); - $this->assertEquals($testEntity1->gender, $data1->gender); - $this->assertEquals($testEntity1->raw, $data1->raw); - - $this->assertEquals($testEntity2->name, 'ingredient'); - $this->assertEquals($testEntity2->value, $data2->value); - $this->assertEquals($testEntity2->raw, $data2->raw); - } -} diff --git a/tests/responseTest.php b/tests/responseTest.php deleted file mode 100644 index 0ef8374..0000000 --- a/tests/responseTest.php +++ /dev/null @@ -1,82 +0,0 @@ -assertInstanceOf('response\Response', new response\Response($json)); - } - - public function testResponseClassAttributes() { - $fp = fopen ("./tests/test.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/test.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $lol = json_decode($res2->body); - $res = new response\Response($res2); - - $count = count($res->entities, COUNT_RECURSIVE); - - $this->assertEquals($res->act, $lol->results->{'act'}); - $this->assertEquals($res->type, $lol->results->{'type'}); - $this->assertEquals($res->source, $lol->results->{'source'}); - $this->assertEquals($res->sentiment, $lol->results->{'sentiment'}); - $this->assertEquals($res->language, $lol->results->{'language'}); - $this->assertEquals($res->version, $lol->results->{'version'}); - $this->assertEquals($res->timestamp, $lol->results->{'timestamp'}); - $this->assertEquals($count, 4); - $this->assertInstanceOf('entity\Entity', $res->entities[0]); - $this->assertInternalType('array', $res->entities); - $this->assertInternalType('array', $res->intents); - } - - public function testResponseClassMethods() { - - $fp = fopen ("./tests/test.json", "r"); - $contenu_du_fichier = fread ($fp, filesize('./tests/test.json')); - fclose ($fp); - - $res2 = json_decode ($contenu_du_fichier); - $lol = json_decode($res2->body); - $res = new response\Response($res2); - - $all = count($res->all('location')); - $get = $res->get('location'); - - $this->assertEquals($res->intent(), $lol->results->{'intents'}[0]); - $this->assertEquals($all, 2); - $this->assertEquals('location', $get->name); - - $this->assertEquals($res->isAssert(), false); - $this->assertEquals($res->isCommand(), false); - $this->assertEquals($res->isWhQuery(), true); - $this->assertEquals($res->isYnQuery(), false); - $this->assertEquals($res->isAbbreviation(), false); - $this->assertEquals($res->isEntity(), false); - $this->assertEquals($res->isDescription(), true); - $this->assertEquals($res->isHuman(), false); - $this->assertEquals($res->isLocation(), false); - $this->assertEquals($res->isNumber(), false); - $this->assertEquals($res->isVPositive(), false); - $this->assertEquals($res->isPositive(), false); - $this->assertEquals($res->isNeutral(), true); - $this->assertEquals($res->isNegative(), false); - $this->assertEquals($res->isVNegative(), false); - } -} - - -?> diff --git a/tests/test.json b/tests/test.json deleted file mode 100644 index 34bb6a0..0000000 --- a/tests/test.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "body": "{\"results\": { - \"uuid\": \"6b356fe1-7aee-4407-8c0f-47ed70675679\", - \"source\": \"What is the weather in London tomorrow? And in Paris?\", - \"intents\": [ - { - \"name\": \"weather\", - \"confidence\": 0.67 - } - ], - \"act\": \"wh-query\", - \"type\": \"desc:desc\", - \"sentiment\": \"neutral\", - \"entities\": { - \"action\":[ - { - \"agent\": \"the weather in London\", - \"tense\": \"present\", - \"raw\": \"is\", - \"confidence\": 0.89 - } - ], - \"location\": [ - { - \"formated\": \"London, London, Greater London, England, United Kingdom\", - \"lat\": 51.5073509, - \"lng\": -0.1277583, - \"raw\": \"London\", - \"confidence\": 0.97 - }, - { - \"formated\": \"Paris, Paris, Île-de-France, France\", - \"lat\": 48.856614, - \"lng\": 2.3522219, - \"raw\": \"Paris\", - \"confidence\": 0.83 - } - ], - \"datetime\": [ - { - \"value\": \"2016-07-11T10:00:00+00:00\", - \"raw\": \"tomorrow\", - \"confidence\": 0.95 - } - ] - }, - \"language\": \"en\", - \"version\": \"2.0.0\", - \"timestamp\": \"2016-07-10T23:17:59+02:00\", - \"status\": 200 - }}" -} diff --git a/tests/testconverse.json b/tests/testconverse.json deleted file mode 100644 index 63dffe6..0000000 --- a/tests/testconverse.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "body": "{\"results\":{\"source\":\"hello\",\"replies\":[\"Salut\",\"Need location please\"],\"action\":{\"slug\":\"greetings\",\"done\":true,\"reply\":\"Salut\"},\"next_actions\":[{\"slug\":\"capitals\",\"done\":false,\"reply\":\"Need location please\"}],\"memory\":{\"loc\":null},\"entities\":{},\"intents\":[{\"slug\":\"greetings\",\"confidence\":0.99}],\"conversation_token\":\"f6362f5ded83031d42c2d02d954359f9\",\"language\":\"en\",\"timestamp\":\"2016-10-05T12:07:30.907Z\",\"status\":200},\"message\":\"Converses rendered with success\"}" -}