From: Cake Date: Sun, 20 Feb 2011 03:55:10 +0000 (+0900) Subject: Collectionableプラグイン導入 X-Git-Url: http://git.osdn.net/view?p=trpgtools-onweb%2Fcake-frame.git;a=commitdiff_plain;h=61f7f05ff0470c2f8ade62e7bed88a76d5fc06e4 Collectionableプラグイン導入 --- diff --git a/app/app_model.php b/app/app_model.php index 4e9ff9e..c691b52 100644 --- a/app/app_model.php +++ b/app/app_model.php @@ -14,6 +14,7 @@ app::import('Sanitize'); class AppModel extends Model { var $actsAs = array( + 'Collectionable.options', 'Cakeplus.ValidationErrorI18n', 'Cakeplus.AddValidationRule', 'SanitizePlus', diff --git a/app/plugins/collectionable/README.md b/app/plugins/collectionable/README.md new file mode 100644 index 0000000..2a4a911 --- /dev/null +++ b/app/plugins/collectionable/README.md @@ -0,0 +1,276 @@ +# Collectionable Plugin # + +## Introduction ## +This is a utility plugin for CakePHP. This helps managing find options, virtualFields and validations. + +## Setup ## +- Define $options(such a property name can be modified by configure) for Options Behavior +- Define $virtualFieldsCollection(such a property name can be modified by configure) for VirtualFields Behavior +- Define 'Validation'(such a config name can be modified by configure) section into Configure for ConfigValidationBehavior +- Define $validate{PatternName}, like $validateAdd, same structure with $validate, for MultiValidationBehavior + +## Sample code ## + +### OptionsBehavior ### + +Here is a simple Post Model. + class Post extends AppModel { + var $hasMany = array('Comment'); + var $hasOne = array('Status'); + + var $acsAs = array('Collectionable.options'); + var $defaultOption = true; // or string like 'default' + + var $options =array( + 'default' => array( + 'contain' => array( + 'Comment', + 'Status', + ), + 'limit' => 10, + ), + 'published' => array( + 'condtiions' => array('Status.published' => true), + ), + 'recent' => array( + 'order' => ('Post.updated DESC'), + ), + 'rss' => array( + 'limit' => 15, + ), + 'unlimited' => array( + 'limit' => null, + ), + 'index' => array( + // You can do sub merging + 'options' => array( + 'published', + 'recent', + ), + ), + ); + } + +You can use them by like: + class PostsController extends AppController { + function index() { + $this->paginate = $this->Post->options('index'); + $this->set('posts', $this->paginate()); + } + + function rss() { + $this->paginate = $this->Post->options('index', 'rss'); // multiple merging at run time; + $this->set('posts', $this->paginate()); + } + + function all_in_one_page() { + // you can use "options" attribute wihtin finding options + $posts = $this->Post->find('all', array('options' => array('index', 'unlimited'))); + $this->set(compact('posts')); + } + } + +To see more syntax, you would look at [the test case](http://github.com/hiromi2424/Collectionable/blob/master/tests/cases/behaviors/options.test.php) or [the code](http://github.com/hiromi2424/Collectionable/blob/master/models/behaviors/options.php). + +### VirtualFieldsBehavior ### + +This sample uses [MatchableBehavior](http://github.com/hiromi2424/MatchableBehavior). + + class User extends AppModel { + var $hasMany = array('Post'); + var $actsAs = array('Collectionable.VirtualFields', 'Matchable'); + + var $virtualFields = array( + 'full_name' => "CONCAT(User.first_name, ' ', User.last_name)", + ); + var $virtualFieldsCollection = array( + 'posts_count' => 'COUNT(Post.id)', + 'amount_used' => 'SUM(Post.volume)', + ); + } + +You can use them by like: + + + class UsersController extends AppController { + function admin_index() { + // Hey, you may feel like using OptionsBehavior :P + $jointo = array('Post'); + $group = 'User.id'; + $virtualFields = array('posts_count', 'amount_used'); // key of collections + $this->paginate = compact('jointo', 'group', 'virtualFields'); + $this->set('users', $this->paginate()); + } + + function profile() { + $virtualFields = array('full_name' => false); // disable virtualFields + $user = $this->User->find('first', compact('virtualFields')); + $this->set(compact('user')); + } + } + +### ConfigValidationBehavior ### + + + class User extends AppModel { + var $actsAs = array('Collectionable.ConfigValidation'); + + var $validate = array( + 'nickname' => array( + 'required' => array( + 'rule' => array('notempty'), + ), + 'min' => array( + 'rule' => array('minlength'), + 'message' => 'I said more than %s!!', + ), + ), + 'email' => array( + 'required' => array( + 'rule' => array('notempty'), + ), + 'among' => array( + 'rule' => array('between'), + ), + ), + ); + } + +You can set validation parameters, messages from Configuration: + + + Configure::write('Validation', array( + 'parameters' => array( + 'User' => array( + 'nickname' => array( + 'min' => 3, + ), + 'email' => array( + 'among' => array(16, 256) + ), + ), + ), + 'messages' => array( + 'default' => array( + 'required' => 'you need to enter.', + 'min' => '%s characters needed', + ), + 'User' => array( + 'email' => array( + 'required' => 'are you kidding me or misreading?', + ), + ), + ), + )); + + +Note that priority is "hard coded on your model" > "specifying Model and field" > "default". +But if you turn $overwrite property on, "specifying Model and field" forces to overwrite("default" does not). + + +### MultiValidationBehavior ### + + + class User extends AppModel { + + var $actsAs = array('Collectionable.MultiValidation'); + + var $validate = array( + 'password_raw' => array( + 'required' => array( + 'rule' => array('notempty'), + ), + 'minlength' => array( + 'rule' => array('minlength', 6), + ), + ), + ); + + // note that $validateprofile is invalid with 'profile' + var $validateProfile = array( + 'nickname' => array( + 'required' => array( + 'rule' => array('notempty'), + ), + 'maxlength' => array( + 'rule' => array('maxlength', 40), + ), + ), + ); + + var $validateRequireEmail = array( + 'email' => array( + 'required' => array( + 'rule' => array('notempty'), + ), + 'email' => array( + 'rule' => array('email'), + ), + ), + ); + + var $validatePasswordConfirm = array( + 'password_confirm' => array( + 'required' => array( + 'rule' => array('notempty'), + ), + 'confirm_password' => array( + 'rule' => array('confirm_password'), + ), + ), + ); + + // You can set validation pattern on demand: + function add($data, $validate = true, $options = array()) { + $this->useValidationSet('requireEmail'); + $this->create(); + return $this->save($data, $validate, $options); + } + + // You can dsiable default $validate with second argument as false: + function edit($data, $validate = true, $options = array()) { + $this->useValidationSet('profile', false); + return $this->save($data, $validate, $options); + } + + // You can specify two and more rule sets. these will be merged + function resetEmail($data) { + $this->useValidationSet(array('requireEmail', 'passwordConfirm')); + } + + function confirm_password() { + // confirm password + } + + } + + +## Thanks ## +- [nojimage](http://github.com/nojimage) created [base of this plugin](http://github.com/nojimage/paging) + + +## License + +Licensed under The MIT License. +Redistributions of files must retain the above copyright notice. + + +Copyright 2010 hiromi, https://github.com/hiromi2424 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/app/plugins/collectionable/locale/collectionable.pot b/app/plugins/collectionable/locale/collectionable.pot new file mode 100644 index 0000000..889acca --- /dev/null +++ b/app/plugins/collectionable/locale/collectionable.pot @@ -0,0 +1,29 @@ +# LANGUAGE translation of CakePHP Application +# Copyright hiromi +# +msgid "" +msgstr "" +"Project-Id-Version: Collectionable Plugin for CakePHP v1.0\n" +"POT-Creation-Date: 2011-02-10 06:00+0900\n" +"PO-Revision-Date: 2011-02-10 06:11+0900\n" +"Last-Translator: hiromi \n" +"Language-Team: hiromi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: models\behaviors\config_validation.php:118 +#: tests\cases\behaviors\config_validation.test.php:358 +msgid "getValidationParameter() requires 2 arguments as $field and $rule" +msgstr "" + +#: models\behaviors\config_validation.php:143 +#: tests\cases\behaviors\config_validation.test.php:376 +msgid "getValidationMessage() requires a argument as $rule" +msgstr "" + +#: models\behaviors\multi_validation.php:97 +msgid "Unexpected property name: Model::$%s was not found." +msgstr "" + diff --git a/app/plugins/collectionable/locale/eng/LC_MESSAGES/collectionable.mo b/app/plugins/collectionable/locale/eng/LC_MESSAGES/collectionable.mo new file mode 100644 index 0000000..c821a1d Binary files /dev/null and b/app/plugins/collectionable/locale/eng/LC_MESSAGES/collectionable.mo differ diff --git a/app/plugins/collectionable/locale/eng/LC_MESSAGES/collectionable.po b/app/plugins/collectionable/locale/eng/LC_MESSAGES/collectionable.po new file mode 100644 index 0000000..652e04d --- /dev/null +++ b/app/plugins/collectionable/locale/eng/LC_MESSAGES/collectionable.po @@ -0,0 +1,29 @@ +# LANGUAGE translation of CakePHP Application +# Copyright hiromi +# +msgid "" +msgstr "" +"Project-Id-Version: Collectionable Plugin for CakePHP v1.0\n" +"POT-Creation-Date: 2011-02-10 06:00+0900\n" +"PO-Revision-Date: 2011-02-10 06:11+0900\n" +"Last-Translator: hiromi \n" +"Language-Team: hiromi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: models\behaviors\config_validation.php:118 +#: tests\cases\behaviors\config_validation.test.php:358 +msgid "getValidationParameter() requires 2 arguments as $field and $rule" +msgstr "getValidationParameter() requires 2 arguments as $field and $rule" + +#: models\behaviors\config_validation.php:143 +#: tests\cases\behaviors\config_validation.test.php:376 +msgid "getValidationMessage() requires a argument as $rule" +msgstr "getValidationMessage() requires a argument as $rule" + +#: models\behaviors\multi_validation.php:97 +msgid "Unexpected property name: Model::$%s was not found." +msgstr "Unexpected property name: Model::$%s was not found." + diff --git a/app/plugins/collectionable/locale/jpn/LC_MESSAGES/collectionable.mo b/app/plugins/collectionable/locale/jpn/LC_MESSAGES/collectionable.mo new file mode 100644 index 0000000..5b00124 Binary files /dev/null and b/app/plugins/collectionable/locale/jpn/LC_MESSAGES/collectionable.mo differ diff --git a/app/plugins/collectionable/locale/jpn/LC_MESSAGES/collectionable.po b/app/plugins/collectionable/locale/jpn/LC_MESSAGES/collectionable.po new file mode 100644 index 0000000..dd9d005 --- /dev/null +++ b/app/plugins/collectionable/locale/jpn/LC_MESSAGES/collectionable.po @@ -0,0 +1,29 @@ +# LANGUAGE translation of CakePHP Application +# Copyright hiromi +# +msgid "" +msgstr "" +"Project-Id-Version: Collectionable Plugin for CakePHP v1.0\n" +"POT-Creation-Date: 2011-02-10 06:00+0900\n" +"PO-Revision-Date: 2011-02-10 06:11+0900\n" +"Last-Translator: hiromi \n" +"Language-Team: hiromi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: models\behaviors\config_validation.php:118 +#: tests\cases\behaviors\config_validation.test.php:358 +msgid "getValidationParameter() requires 2 arguments as $field and $rule" +msgstr "getValidationParameter() は$fieldと$ruleの二つの引数が必要です" + +#: models\behaviors\config_validation.php:143 +#: tests\cases\behaviors\config_validation.test.php:376 +msgid "getValidationMessage() requires a argument as $rule" +msgstr "getValidationParameter() は$rule引数が必要です" + +#: models\behaviors\multi_validation.php:97 +msgid "Unexpected property name: Model::$%s was not found." +msgstr "予期しないプロパティ名:Model::$%sが見つかりませんでした。" + diff --git a/app/plugins/collectionable/models/behaviors/config_validation.php b/app/plugins/collectionable/models/behaviors/config_validation.php new file mode 100644 index 0000000..ed640f4 --- /dev/null +++ b/app/plugins/collectionable/models/behaviors/config_validation.php @@ -0,0 +1,130 @@ +validate || !is_array($model->validate)) { + return true; + } + + $this->_setParameters($model); + $this->_setMessages($model); + $this->_convertFormat($model); + return true; + } + + function _setParameters(&$model) { + $overwrite = $this->overwrite === true || $this->overwrite == $this->parametersName; + foreach ($model->validate as $field => $elements) { + foreach ($elements as $name => $element) { + $parameters = $this->_config($this->parametersName, $model->name, $field, $name); + if ($parameters === null || !isset($element['rule'])) { + continue; + } + + if (count($element['rule']) > 1 && !$overwrite) { + continue; + } + + $model->validate[$field][$name]['rule'] = array_merge(array(current($element['rule'])), (array)$parameters); + } + } + } + + function _setMessages(&$model) { + $overwrite = $this->overwrite === true || $this->overwrite == $this->messagesName; + foreach ($model->validate as $field => $elements) { + foreach ($elements as $name => $element) { + $default = $this->_config($this->messagesName, 'default', $name); + $desire = $this->_config($this->messagesName, $model->name, $field, $name); + if ($default === null && $desire === null) { + continue; + } + + if (isset($element['message']) && !$overwrite) { + continue; + } + if ($desire !== null) { + $model->validate[$field][$name]['message'] = $desire; + continue; + } + if (!isset($element['message'])) { + $model->validate[$field][$name]['message'] = $default; + } + } + } + } + + function _convertFormat(&$model) { + if (!$this->convertFormat) { + return; + } + foreach ($model->validate as $field => $elements) { + foreach ($elements as $name => $element) { + if (!isset($element['message']) || !isset($element['rule']) || !is_array($element['rule'])) { + continue; + } + if (count($element['rule']) > 1) { + array_shift($element['rule']); + array_unshift($element['rule'], $element['message']); + $model->validate[$field][$name]['message'] = call_user_func_array('sprintf', $element['rule']); + } + } + } + } + + function _config() { + $args = func_get_args(); + array_unshift($args, $this->configName); + return Configure::read(implode('.', $args)); + } + + function getValidationParameter(&$model, $field, $rule) { + if (is_array($field) || is_array($rule) || $field === null || $rule === null) { + trigger_error(__d('collectionable', 'getValidationParameter() requires 2 arguments as $field and $rule', true)); + return null; + } + + $this->beforeValidate($model); + if (empty($model->validate[$field][$rule]['rule'])) { + return null; + } + $rule = $model->validate[$field][$rule]['rule']; + array_shift($rule); + if (empty($rule)) { + return null; + } + $parameters = count($rule) === 1 ? current($rule) : $rule; + return $parameters; + } + + function getValidationMessage(&$model, $rule, $field = null) { + if (is_array($rule) || $rule === null) { + trigger_error(__d('collectionable', 'getValidationMessage() requires a argument as $rule', true)); + return null; + } + if (is_array($field)) { + $field = null; + } + if ($field !== null) { + $swap = $rule; + $rule = $field; + $field = $swap; + } + if ($field === null) { + $default = $this->_config($this->messagesName, 'default', $rule); + return $default; + } + + $this->beforeValidate($model); + if (empty($model->validate[$field][$rule]['message'])) { + return null; + } + return $model->validate[$field][$rule]['message']; + } +} \ No newline at end of file diff --git a/app/plugins/collectionable/models/behaviors/multi_validation.php b/app/plugins/collectionable/models/behaviors/multi_validation.php new file mode 100644 index 0000000..fa48cfe --- /dev/null +++ b/app/plugins/collectionable/models/behaviors/multi_validation.php @@ -0,0 +1,87 @@ + true, + ); + + var $_backupValidate = array(); + + function setup($Model, $settings = array()) { + + $this->settings[$Model->alias] = array_merge($this->defaultSettings, (array)$settings); + return true; + + } + + function restoreValidate($Model) { + + if (isset($this->_backupValidate[$Model->alias])) { + $Model->validate = $this->_backupValidate[$Model->alias]; + unset($this->_backupValidate[$Model->alias]); + } + + } + + function afterSave($Model, $created = true, $options = array()) { + + if ($this->settings[$Model->alias]['restore']) { + $this->restoreValidate($Model); + } + + return true; + + } + + function useValidationSet($Model, $method, $useBase = true) { + + $validates = array_map('ucfirst', (array)$method); + + $result = array(); + foreach ($validates as $validate) { + + $property = 'validate' . $validate; + if (!isset($Model->{$property})) { + trigger_error(sprintf(__d('collectionable', 'Unexpected property name: Model::$%s was not found.', true), $property)); + return false; + } + $result = $this->mergeValidationSet($Model, $result, $Model->{$property}); + + } + + if ($useBase) { + $result = $this->mergeValidationSet($Model, $Model->validate, $result); + } + + $this->_backupValidate[$Model->alias] = $Model->validate; + $Model->validate = $result; + + return true; + + } + + function mergeValidationSet($Model) { + + $validationSets = func_get_args(); + /* $Model = */ array_shift($validationSets); + + $result = array(); + foreach ($validationSets as $validationSet) { + foreach ($validationSet as $field => $ruleSet) { + foreach ($ruleSet as $name => $rules) { + if (isset($result[$field][$name])) { + $result[$field][$name] = array_merge($result[$field][$name], $rules); + } else { + $result[$field][$name] = $rules; + } + } + } + } + + return $result; + + } + +} diff --git a/app/plugins/collectionable/models/behaviors/options.php b/app/plugins/collectionable/models/behaviors/options.php new file mode 100644 index 0000000..89557b2 --- /dev/null +++ b/app/plugins/collectionable/models/behaviors/options.php @@ -0,0 +1,100 @@ + true, + 'defaultOption' => false, + 'optionName' => 'options', + ); + + var $defaultQuery = array( + 'conditions' => null, 'fields' => null, 'joins' => array(), 'limit' => null, + 'offset' => null, 'order' => null, 'page' => null, 'group' => null, 'callbacks' => true + ); + + function setup(&$Model, $settings = array()) { + $this->settings = array_merge($this->defaultSettings, (array)$settings); + $optionName = $this->settings['optionName']; + if ($this->settings['setupProperty']) { + if (empty($Model->{$optionName})) { + $Model->{$optionName} = array(); + } + if (empty($Model->defaultOption)) { + $Model->defaultOption = $this->settings['defaultOption']; + } + } + return true; + } + + function beforeFind(&$Model, $query = array()) { + if (isset($query['options'])) { + $options = $query['options']; + unset($query['options']); + + $query = Set::merge($this->defaultQuery, $this->options($Model, $options), Set::filter($query)); + } + return $query; + } + + function options(&$Model, $type = null){ + $args = func_get_args(); + if (func_num_args() > 2) { + array_shift($args); + $type = $args; + } + + $option = array(); + if (is_array($type)) { + foreach ($type as $t) { + $option = Set::merge($option, $this->options($Model, $t)); + } + } else { + $optionName = $this->settings['optionName']; + $option = isset($Model->{$optionName}[$type]) ? $Model->{$optionName}[$type] : array(); + $default = array(); + if ($Model->defaultOption) { + $default = $this->_getDefault($Model->defaultOption, $Model->{$optionName}); + } + $options = array(); + if (isset($option[$optionName]) && !empty($option[$optionName])) { + $options = $this->_intelligentlyMerge(array(), $option[$optionName], $Model->{$optionName}); + unset($option['options']); + } + $option = Set::merge($default, $options, $option); + } + return $option; + } + + function _getDefault($defaultOption, $options) { + $default = array(); + if ($defaultOption === true && !empty($options['default'])) { + $default = $options['default']; + } elseif (is_array($defaultOption)) { + $default = $this->_intelligentlyMerge($default, $defaultOption, $options); + } elseif (!empty($options[$defaultOption])) { + $default = $this->_intelligentlyMerge($default, $options[$defaultOption], $options); + } + return $default; + } + + function _intelligentlyMerge($data, $merges, $options) { + $merges = (array)$merges; + if (Set::numeric(array_keys($merges))) { + foreach($merges as $merge) { + if (!empty($options[$merge])) { + $data = $this->_intelligentlyMerge($data, $options[$merge], $options); + } + } + } else { + $optionName = $this->settings['optionName']; + if (array_key_exists($optionName, $merges)) { + $data = $this->_intelligentlyMerge($data, $merges[$optionName], $options); + unset($merges[$optionName]); + } + $data = Set::merge($data, $merges); + } + return $data; + } +} \ No newline at end of file diff --git a/app/plugins/collectionable/models/behaviors/virtual_fields.php b/app/plugins/collectionable/models/behaviors/virtual_fields.php new file mode 100644 index 0000000..d121d3e --- /dev/null +++ b/app/plugins/collectionable/models/behaviors/virtual_fields.php @@ -0,0 +1,63 @@ + true, + 'collectionName' => 'virtualFieldsCollection', + ); + var $__virtualFieldsBackup = array(); + + function setup(&$Model, $settings = array()) { + $this->settings = Set::merge($this->defaultSettings, $settings); + extract($this->settings); + if (!isset($Model->{$collectionName}) && $this->settings['setupProperty']) { + $Model->{$collectionName} = array(); + } + return true; + } + + function beforeFind(&$Model, $query = array()){ + extract($this->settings); + if (!isset($query['virtualFields'])) { + return true; + } + $virtualFields = Set::normalize($query['virtualFields']); + unset($query['virtualFields']); + + $blackList = array(); + foreach ($virtualFields as $key => $sql) { + if (($sql !== false && empty($sql)) || $sql === true) { + if (isset($Model->{$collectionName}[$key])) { + $virtualFields[$key] = $Model->{$collectionName}[$key]; + } else { + unset($virtualFields[$key]); + } + } else { + $blackList[] = $key; + unset($virtualFields[$key]); + } + } + + if (!empty($virtualFields) || !empty($blackList)){ + $this->__virtualFieldsBackup[$Model->alias] = $Model->virtualFields; + $Model->virtualFields = array_merge($Model->virtualFields, $virtualFields); + if (!empty($blackList)) { + foreach ($blackList as $key) { + if (isset($Model->virtualFields[$key])) { + unset($Model->virtualFields[$key]); + } + } + } + } + return $query; + } + + function afterFind(&$Model, $results = array(), $primary = false) { + if (isset($this->__virtualFieldsBackup[$Model->alias])) { + $Model->virtualFields = $this->__virtualFieldsBackup[$Model->alias]; + unset($this->__virtualFieldsBackup[$Model->alias]); + } + return true; + } +} \ No newline at end of file diff --git a/app/plugins/collectionable/tests/cases/models/behaviors/config_validation.test.php b/app/plugins/collectionable/tests/cases/models/behaviors/config_validation.test.php new file mode 100644 index 0000000..e202078 --- /dev/null +++ b/app/plugins/collectionable/tests/cases/models/behaviors/config_validation.test.php @@ -0,0 +1,344 @@ + array( + 'required' => array( + 'rule' => array('notempty'), + ), + 'min' => array( + 'rule' => array('minlength'), + 'message' => '%s文字ください', + ), + 'max' => array( + 'rule' => array('maxlength', 32), + 'message' => '32文字', + ), + 'hoge' => array( + 'rule' => array('userdefined', 2000), + ), + 'piyo' => array( + 'rule' => array('userdefined'), + ), + 'fuga' => array( + 'rule' => array('userdefined'), + 'message' => 'ふがー', + ), + 'moge' => array( + 'rule' => array('userdefined', 5000, 'hoge'), + 'message' => '%s %s', + ), + 'multi' => array( + 'rule' => array('userdefined'), + ), + ), + ); +} + +class ConfigValidationBehaviorTestCase extends CakeTestCase { + var $data = array( + 'ConfigValidaitonMockModel' => array( + 'nickname' => '0123456789012', + ), + ); + + function start() { + Configure::write('TestValidation', array( + 'parameters' => array( + 'ConfigValidaitonMockModel' => array( + 'nickname' => array( + 'min' => 10, + 'max' => 100, + 'multi' => array(-100, 900), + ), + ), + ), + 'messages' => array( + 'default' => array( + 'required' => '必須項目です', + 'max' => '%s文字以内で入力してください。', + 'hoge' => '%sです', + 'fuga' => 'でふぉると', + ), + 'ConfigValidaitonMockModel' => array( + 'nickname' => array( + 'required' => '必ず入力してください。', + 'piyo' => 'うりりりー', + 'fuga' => 'してい', + ), + ), + ), + )); + parent::start(); + } + + function startTest() { + $this->_attach(); + } + + function endTest() { + $this->_clear(); + } + + function _attach() { + $this->Behavior = new ConfigValidationBehavior; + $this->Behavior->configName = 'TestValidation'; + $this->Behavior->convertFormat = false; + $this->Model =& ClassRegistry::init('ConfigValidaitonMockModel'); + } + + function _clear() { + unset($this->Behavior); + unset($this->Model); + ClassRegistry::flush(); + } + + function _reattach() { + $this->_clear(); + $this->_attach(); + } + + function testAll() { + $this->Behavior->convertFormat = true; + $this->Behavior->beforeValidate($this->Model); + + $result = $this->Model->validate; + $expects = array( + 'nickname' => array( + 'required' => array( + 'rule' => array('notempty'), + 'message' => '必ず入力してください。', + ), + 'min' => array( + 'rule' => array('minlength', 10), + 'message' => '10文字ください', + ), + 'max' => array( + 'rule' => array('maxlength', 32), + 'message' => '32文字', + ), + 'hoge' => array( + 'rule' => array('userdefined', 2000), + 'message' => '2000です', + ), + 'piyo' => array( + 'rule' => array('userdefined'), + 'message' => 'うりりりー', + ), + 'fuga' => array( + 'rule' => array('userdefined'), + 'message' => 'ふがー', + ), + 'moge' => array( + 'rule' => array('userdefined', 5000, 'hoge'), + 'message' => '5000 hoge', + ), + 'multi' => array( + 'rule' => array('userdefined', -100, 900), + ), + ), + ); + + $this->_reattach(); + $this->Behavior->convertFormat = true; + $this->Behavior->overwrite = 'parameters'; + $this->Behavior->beforeValidate($this->Model); + + $result = $this->Model->validate; + $expects = array( + 'nickname' => array( + 'required' => array( + 'rule' => array('notempty'), + 'message' => '必ず入力してください。', + ), + 'min' => array( + 'rule' => array('minlength', 10), + 'message' => '10文字ください', + ), + 'max' => array( + 'rule' => array('maxlength', 100), + 'message' => '32文字', + ), + 'hoge' => array( + 'rule' => array('userdefined', 2000), + 'message' => '2000です', + ), + 'piyo' => array( + 'rule' => array('userdefined'), + 'message' => 'うりりりー', + ), + 'fuga' => array( + 'rule' => array('userdefined'), + 'message' => 'ふがー', + ), + 'moge' => array( + 'rule' => array('userdefined', 5000, 'hoge'), + 'message' => '5000 hoge', + ), + 'multi' => array( + 'rule' => array('userdefined', -100, 900), + ), + ), + ); + + $this->_reattach(); + $this->Behavior->convertFormat = true; + $this->Behavior->overwrite = 'messages'; + $this->Behavior->beforeValidate($this->Model); + + $result = $this->Model->validate; + $expected = array( + 'nickname' => array( + 'required' => array( + 'rule' => array('notempty'), + 'message' => '必ず入力してください。', + ), + 'min' => array( + 'rule' => array('minlength', 10), + 'message' => '10文字ください', + ), + 'max' => array( + 'rule' => array('maxlength', 32), + 'message' => '32文字', + ), + 'hoge' => array( + 'rule' => array('userdefined', 2000), + 'message' => '2000です', + ), + 'piyo' => array( + 'rule' => array('userdefined'), + 'message' => 'うりりりー', + ), + 'fuga' => array( + 'rule' => array('userdefined'), + 'message' => 'してい', + ), + 'moge' => array( + 'rule' => array('userdefined', 5000, 'hoge'), + 'message' => '5000 hoge', + ), + 'multi' => array( + 'rule' => array('userdefined', -100, 900), + ), + ), + ); + $this->assertEqual($result, $expected); + + $this->_reattach(); + $this->Behavior->convertFormat = true; + $this->Behavior->overwrite = true; + $this->Behavior->beforeValidate($this->Model); + + $result = $this->Model->validate; + $expected = array( + 'nickname' => array( + 'required' => array( + 'rule' => array('notempty'), + 'message' => '必ず入力してください。', + ), + 'min' => array( + 'rule' => array('minlength', 10), + 'message' => '10文字ください', + ), + 'max' => array( + 'rule' => array('maxlength', 100), + 'message' => '32文字', + ), + 'hoge' => array( + 'rule' => array('userdefined', 2000), + 'message' => '2000です', + ), + 'piyo' => array( + 'rule' => array('userdefined'), + 'message' => 'うりりりー', + ), + 'fuga' => array( + 'rule' => array('userdefined'), + 'message' => 'してい', + ), + 'moge' => array( + 'rule' => array('userdefined', 5000, 'hoge'), + 'message' => '5000 hoge', + ), + 'multi' => array( + 'rule' => array('userdefined', -100, 900), + ), + ), + ); + $this->assertEqual($result, $expected); + + $this->_reattach(); + $this->Model->validate = true; + $this->assertTrue($this->Behavior->beforeValidate($this->Model)); + $this->assertTrue($this->Model->validate); + + $this->_reattach(); + $this->Model->validate = array(); + $this->assertTrue($this->Behavior->beforeValidate($this->Model)); + $this->assertEqual($this->Model->validate, array()); + + $this->_reattach(); + $this->Model->validate = array('hoge' => array('monyomonyo' => array('hoge' => '%s'))); + $this->assertTrue($this->Behavior->beforeValidate($this->Model)); + $this->assertEqual($this->Model->validate, array('hoge' => array('monyomonyo' => array('hoge' => '%s')))); + } + + function testSetParameters() { + $this->Behavior->_setParameters($this->Model); + + $this->assertEqual($this->Model->validate['nickname']['min']['rule'], array('minlength', 10)); + $this->assertEqual($this->Model->validate['nickname']['max']['rule'], array('maxlength', 32)); + $this->assertEqual($this->Model->validate['nickname']['multi']['rule'], array('userdefined', -100, 900)); + + $this->_reattach(); + $this->Behavior->overwrite = true; + $this->Behavior->_setParameters($this->Model); + + $this->assertEqual($this->Model->validate['nickname']['min']['rule'], array('minlength', 10)); + $this->assertEqual($this->Model->validate['nickname']['max']['rule'], array('maxlength', 100)); + $this->assertEqual($this->Model->validate['nickname']['multi']['rule'], array('userdefined', -100, 900)); + } + + function testSetMessages() { + $this->Behavior->_setMessages($this->Model); + $this->assertEqual($this->Model->validate['nickname']['required']['message'], '必ず入力してください。'); + $this->assertEqual($this->Model->validate['nickname']['max']['message'], '32文字'); + $this->assertEqual($this->Model->validate['nickname']['hoge']['message'], '%sです'); + $this->assertEqual($this->Model->validate['nickname']['piyo']['message'], 'うりりりー'); + $this->assertEqual($this->Model->validate['nickname']['fuga']['message'], 'ふがー'); + + $this->_reattach(); + $this->Behavior->overwrite = true; + $this->Behavior->_setMessages($this->Model); + + $this->assertEqual($this->Model->validate['nickname']['fuga']['message'], 'してい'); + } + + function testConvertFormat() { + $this->Behavior->convertFormat = true; + $this->Behavior->_convertFormat($this->Model); + + $this->assertEqual($this->Model->validate['nickname']['moge']['message'], '5000 hoge'); + } + + function testGetValidationParameter() { + $this->expectError(); + $this->assertNull($this->Behavior->getValidationParameter($this->Model, 'nickname', null)); + $this->assertNull($this->Behavior->getValidationParameter($this->Model, 'nickname', 'undefined')); + $this->assertEqual($this->Behavior->getValidationParameter($this->Model, 'nickname', 'max'), 32); + $this->assertEqual($this->Behavior->getValidationParameter($this->Model, 'nickname', 'multi'), array(-100, 900)); + } + + function testGetConfigMessage() { + $this->Behavior->convertFormat = true; + + $this->expectError(); + $this->assertNull($this->Behavior->getValidationMessage($this->Model, null)); + $this->assertNull($this->Behavior->getValidationMessage($this->Model, 'not defined')); + $this->assertEqual($this->Behavior->getValidationMessage($this->Model, 'fuga'), 'でふぉると'); + $this->assertEqual($this->Behavior->getValidationMessage($this->Model, 'max'), '%s文字以内で入力してください。'); + $this->assertEqual($this->Behavior->getValidationMessage($this->Model, 'nickname', 'min'), '10文字ください'); + } +} diff --git a/app/plugins/collectionable/tests/cases/models/behaviors/multi_validation.test.php b/app/plugins/collectionable/tests/cases/models/behaviors/multi_validation.test.php new file mode 100644 index 0000000..def8ae6 --- /dev/null +++ b/app/plugins/collectionable/tests/cases/models/behaviors/multi_validation.test.php @@ -0,0 +1,175 @@ + array( + 'email' => array( + 'rule' => array('email'), + ), + ), + 'title' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + ); + + var $validateBestAnswer = array( + 'best_answer_id' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + ); + + var $validateEdit = array( + 'email' => array( + 'email' => array( + 'rule' => array('email', true), + ), + ), + ); + +} + +class MultiValidationBehaviorTestCase extends CakeTestCase { + + var $data = array( + 'MultiValidaitonMockModel' => array( + 'nickname' => '0123456789012', + ), + ); + + function startTest() { + $this->_attach(); + } + + function endTest() { + $this->_clear(); + } + + function _attach($settings = array()) { + + $this->Model = ClassRegistry::init('MultiValidaitonMockModel'); + $this->Model->Behaviors->detach('Collectionable.MultiValidation'); + $this->Model->Behaviors->attach('Collectionable.MultiValidation', $settings); + + } + + function _clear() { + + unset($this->Model); + ClassRegistry::flush(); + + } + + function _reattach($settings = array()) { + + $this->_clear(); + $this->_attach($settings); + + } + + function testUseValidationSet() { + + $this->Model->useValidationSet('BestAnswer'); + $result = $this->Model->validate; + $expected = array( + 'email' => array( + 'email' => array( + 'rule' => array('email'), + ), + ), + 'title' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + 'best_answer_id' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + ); + $this->assertIdentical($result, $expected); + + $this->Model->restoreValidate(); + $this->Model->useValidationSet('bestAnswer'); + $result = $this->Model->validate; + $this->assertIdentical($result, $expected); + + $this->Model->restoreValidate(); + $this->Model->useValidationSet('BestAnswer', false); + $result = $this->Model->validate; + $expected = array( + 'best_answer_id' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + ); + $this->assertIdentical($result, $expected); + + $this->Model->restoreValidate(); + $this->Model->useValidationSet(array('bestAnswer', 'edit')); + $result = $this->Model->validate; + $expected = array( + 'email' => array( + 'email' => array( + 'rule' => array('email', true), + ), + ), + 'title' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + 'best_answer_id' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + ); + $this->assertIdentical($result, $expected); + + $this->expectError(); + $this->assertFalse($this->Model->useValidationSet('invalidPropertyName')); + + } + + function testAfterSave() { + + $this->Model->useValidationSet('bestAnswer', false); + $this->Model->Behaviors->MultiValidation->afterSave($this->Model); + $expected = array( + 'email' => array( + 'email' => array( + 'rule' => array('email'), + ), + ), + 'title' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + ); + $this->assertIdentical($this->Model->validate, $expected); + + $this->_reattach(array('restore' => false)); + + $this->Model->useValidationSet('bestAnswer', false); + $this->Model->Behaviors->MultiValidation->afterSave($this->Model); + $expected = array( + 'best_answer_id' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + ); + $this->assertIdentical($this->Model->validate, $expected); + + } + +} diff --git a/app/plugins/collectionable/tests/cases/models/behaviors/options.test.php b/app/plugins/collectionable/tests/cases/models/behaviors/options.test.php new file mode 100644 index 0000000..63ebfc5 --- /dev/null +++ b/app/plugins/collectionable/tests/cases/models/behaviors/options.test.php @@ -0,0 +1,213 @@ + array( + 'className' => 'VirtualFieldsPost', + 'table' => 'Virtual_fields_posts', + 'foreignKey' => 'user_id', + ), + ); + } +} + +class OptionsBehaviorTest extends CakeTestCase { + var $Model; + var $fixtures = array('plugin.collectionable.virtual_fields_user', 'plugin.collectionable.virtual_fields_post'); + var $autoFixtures = false; + + function startCase() { + $this->Model =& ClassRegistry::init('OptionsBehaviorMockModel'); + $this->_reset(); + } + + function _reset($settings = array()) { + unset($this->Model->defaultOption); + unset($this->Model->options); + $this->Model->Behaviors->attach('Collectionable.Options', $settings); + } + + function startTest($method) { + $this->_reset(false); + } + + function testArguments() { + $result = $this->Model->options(); + $expects = array(); + $this->assertIdentical($result, $expects); + + $result = $this->Model->options('no sence'); + $expects = array(); + $this->assertIdentical($result, $expects); + + $result = $this->Model->options(array('one', 'two', 'three')); + $expects = array(); + $this->assertIdentical($result, $expects); + + $this->_reset(array('defaultOption' => true)); + $result = $this->Model->defaultOption; + $expects = true; + $this->assertIdentical($result, $expects); + } + + function testDefaults() { + $this->Model->options = array( + 'default' => array('order' => 'default'), + 'one' => array('conditions' => array('one')), + 'two' => array('order' => 'two'), + 'three' => array('order' => 'three'), + ); + + $result = $this->Model->options('one'); + $expects = array('conditions' => array('one')); + $this->assertEqual($result, $expects); + + $this->Model->defaultOption = true; + $result = $this->Model->options('one'); + $expects = array('conditions' => array('one'), 'order' => 'default'); + $this->assertEqual($result, $expects); + + $this->Model->defaultOption = 'three'; + + $result = $this->Model->options('one'); + $expects = array('conditions' => array('one'), 'order' => 'three'); + $this->assertEqual($result, $expects); + + $result = $this->Model->options('two'); + $expects = array('order' => 'two'); + $this->assertEqual($result, $expects); + + $this->Model->defaultOption = array('one', 'three'); + + $result = $this->Model->options('two'); + $expects = array('conditions' => array('one'), 'order' => 'two'); + $this->assertEqual($result, $expects); + + } + + function testMerge() { + $this->Model->options = array( + 'one' => array('conditions' => array('one')), + 'two' => array('order' => 'two', 'group' => 'two'), + 'three' => array('order' => 'three'), + 'four' => array('conditions' => array('four'), 'group' => 'four'), + ); + + $result = $this->Model->options('one', 'two', 'three'); + $expects = array('conditions' => array('one'), 'group' => 'two', 'order' => 'three'); + $this->assertEqual($result, $expects); + + $result = $this->Model->options('three', 'four', 'one'); + $expects = array('conditions' => array('four', 'one'), 'order' => 'three', 'group' => 'four'); + $this->assertEqual($result, $expects); + + $result = $this->Model->options('one', 'two', 'four'); + $expects = array('conditions' => array('one', 'four'), 'order' => 'two', 'group' => 'four'); + $this->assertEqual($result, $expects); + } + + function testOptions() { + $this->Model->options = array( + 'one' => array('conditions' => array('one')), + 'two' => array('order' => 'two', 'group' => 'two'), + 'three' => array('order' => 'three'), + 'four' => array('conditions' => array('four'), 'group' => 'four'), + 'string' => array( + 'conditions' => array('merging'), + 'order' => 'merging', + 'options' => 'one', + ), + 'single_array' => array( + 'conditions' => array('merging'), + 'order' => 'merging', + 'options' => array('one'), + ), + 'multi_array' => array( + 'conditions' => array('merging'), + 'order' => 'merging', + 'options' => array('one', 'two'), + ), + 'extra_options' => array( + 'conditions' => array('merging'), + 'order' => 'merging', + 'options' => array( + 'conditions' => array('extra'), + ), + ), + 'chaos' => array( + 'conditions' => array('merging'), + 'order' => 'merging', + 'options' => array( + 'one', + 'four', + 'conditions' => array('chaos'), + ), + ), + ); + + $result = $this->Model->options('string'); + $expects = array('conditions' => array('one', 'merging'), 'order' => 'merging'); + $this->assertEqual($result, $expects); + + $result = $this->Model->options('single_array'); + $expects = array('conditions' => array('one', 'merging'), 'order' => 'merging'); + $this->assertEqual($result, $expects); + + $result = $this->Model->options('multi_array'); + $expects = array('conditions' => array('one', 'merging'), 'order' => 'merging', 'group' => 'two'); + $this->assertEqual($result, $expects); + + $result = $this->Model->options('extra_options'); + $expects = array('conditions' => array('extra', 'merging'), 'order' => 'merging'); + $this->assertEqual($result, $expects); + + $result = $this->Model->options('chaos'); + $expects = array('one', 'four', 'conditions' => array('chaos', 'merging'), 'order' => 'merging'); + $this->assertEqual($result, $expects); + } + + function testFindOptions() { + $this->loadFixtures('VirtualFieldsUser'); + $User =& ClassRegistry::init(array('alias' => 'User', 'class' => 'VirtualFieldsUser')); + $User->recursive = -1; + $User->options = array( + 'limitation' => array( + 'limit' => 1, + 'fields' => array('User.id', 'User.first_name') + ), + ); + $User->Behaviors->attach('Collectionable.options'); + + $result = $User->find('all', array('options' => 'limitation', 'limit' => 2, 'order' => 'User.id')); + $expects = array( + array('User' => array('id' => 1, 'first_name' => 'yamada')), + array('User' => array('id' => 2, 'first_name' => 'tanaka')), + ); + $this->assertEqual($result, $expects); + } + + function testRecursiveMerge() { + $this->Model->options = array( + 'one' => array('conditions' => array('one')), + 'two' => array('conditions' => array('two'), 'options' => 'one'), + 'three' => array('conditions' => array('three'), 'options' => 'two'), + 'four' => array('conditions' => array('four')), + ); + + $result = $this->Model->options('three'); + $expects = array('one', 'two', 'three'); + $this->assertEqual($result['conditions'], $expects); + + $this->Model->defaultOption = 'three'; + $result = $this->Model->options('four'); + $expects = array('one', 'two', 'three', 'four'); + $this->assertEqual($result['conditions'], $expects); + } +} \ No newline at end of file diff --git a/app/plugins/collectionable/tests/cases/models/behaviors/virtual_fields.test.php b/app/plugins/collectionable/tests/cases/models/behaviors/virtual_fields.test.php new file mode 100644 index 0000000..52ac608 --- /dev/null +++ b/app/plugins/collectionable/tests/cases/models/behaviors/virtual_fields.test.php @@ -0,0 +1,145 @@ + array( + 'className' => 'VirtualFieldsPost', + 'table' => 'Virtual_fields_posts', + 'foreignKey' => 'user_id', + ), + ); + } +} + +class VirualFieldsBehaviorTest extends CakeTestCase { + var $Behavior; + var $Model; + var $db; + + var $fixtures = array( + 'plugin.collectionable.virtual_fields_post', + 'plugin.collectionable.virtual_fields_user', + ); + + function startCase() { + parent::startCase(); + $this->_reset(); + } + + function _reset($settings = array(), $model = null) { + $model = $model === null ? 'VirtualFieldsBehaviorMockModel' : $model; + $this->Model = ClassRegistry::init($model); + $this->Model->Behaviors->attach('Collectionable.VirtualFields', $settings); + $this->Behavior =& ClassRegistry::getObject('VirtualFieldsBehavior'); + } + + function testUndefined() { + $virtualFields = array('not_be_defined'); + $this->Behavior->beforeFind($this->Model, compact('virtualFields')); + $result = $this->Model->virtualFields; + $expects = array(); + $this->assertEqual($result, $expects); + + $this->Behavior->afterFind($this->Model); + $this->Model->virtualFields = array( + 'full_name' => "CONCAT(User.first_name, ' ', User.last_name)", + ); + $virtualFields = array('not_be_defined'); + $this->Behavior->beforeFind($this->Model, compact('virtualFields')); + $result = $this->Model->virtualFields; + $expects = array('full_name' => "CONCAT(User.first_name, ' ', User.last_name)"); + $this->assertEqual($result, $expects); + + $this->Behavior->afterFind($this->Model); + $this->Model->virtualFields = array(); + $this->Model->virtualFieldsCollection = array( + 'posts_count' => 'COUNT(Post.id)', + ); + $virtualFields = array('not_be_defined'); + $this->Behavior->beforeFind($this->Model, compact('virtualFields')); + $result = $this->Model->virtualFields; + $expects = array(); + $this->assertEqual($result, $expects); + } + + function testFind() { + $this->_reset(false, 'VirtualFieldsUser'); + $this->skipIf($this->db->config['driver'] !== 'mysql', "%s This tests belonges to MySQL('s SQL expression)"); + + $this->Model->virtualFields = array( + 'full_name' => "CONCAT(User.first_name, ' ', User.last_name)", + ); + $this->Model->virtualFieldsCollection = array( + 'posts_count' => 'COUNT(Post.id)', + ); + $this->Model->recursive = -1; + + $result = $this->Model->find('first', array('fields' => array('User.full_name'))); + $expected = array('User' => array('full_name' => 'yamada ichirou')); + $this->assertEqual($result, $expected); + + $virtualFields = array('posts_count'); + $joins = array( + array( + 'table' => $this->Model->Post->table, + 'alias' => 'Post', + 'type' => 'LEFT', + 'conditions' => array('User.id = Post.user_id') + ) + ); + $group = 'User.id'; + $fields = array('User.full_name', 'User.posts_count'); + $result = $this->Model->find('first', compact('fields', 'virtualFields', 'joins', 'group')); + $expected = array('User' => array('full_name' => 'yamada ichirou', 'posts_count' => 2)); + $this->assertEqual($result, $expected); + + // ensure virtualFields of model was reset + $result = $this->Model->find('first', array('fields' => array('User.full_name'))); + $expected = array('User' => array('full_name' => 'yamada ichirou')); + $this->assertEqual($result, $expected); + + $this->Model->virtualFieldsCollection['full_name'] = "CONCAT(User.first_name, '.', User.last_name)"; + $result = $this->Model->find('first', array('fields' => array('User.full_name'), 'virtualFields' => 'full_name')); + $expected = array('User' => array('full_name' => 'yamada.ichirou')); + $this->assertEqual($result, $expected); + + $result = $this->Model->find('first', array('fields' => array('User.full_name'))); + $expected = array('User' => array('full_name' => 'yamada ichirou')); + $this->assertEqual($result, $expected); + } + + function testBlackList() { + $this->Model->virtualFields = array( + 'full_name' => "CONCAT(User.first_name, ' ', User.last_name)", + 'posts_count' => 'COUNT(Post.id)', + ); + + $this->Behavior->beforeFind($this->Model); + $result = $this->Model->virtualFields; + $expected = array('full_name' => "CONCAT(User.first_name, ' ', User.last_name)", 'posts_count' => 'COUNT(Post.id)'); + $this->assertEqual($result, $expected); + + $this->Behavior->afterFind($this->Model); + $virtualFields = array('posts_count' => false); + $this->Behavior->beforeFind($this->Model, compact('virtualFields')); + $result = $this->Model->virtualFields; + $expected = array('full_name' => "CONCAT(User.first_name, ' ', User.last_name)"); + $this->assertEqual($result, $expected); + + $this->Behavior->afterFind($this->Model); + $result = $this->Model->virtualFields; + $expected = array('full_name' => "CONCAT(User.first_name, ' ', User.last_name)", 'posts_count' => 'COUNT(Post.id)'); + $this->assertEqual($result, $expected); + } + + function testSettings() { + + } +} \ No newline at end of file diff --git a/app/plugins/collectionable/tests/fixtures/virtual_fields_post_fixture.php b/app/plugins/collectionable/tests/fixtures/virtual_fields_post_fixture.php new file mode 100644 index 0000000..e4e2f67 --- /dev/null +++ b/app/plugins/collectionable/tests/fixtures/virtual_fields_post_fixture.php @@ -0,0 +1,19 @@ + array('type' => 'integer', 'key' => 'primary'), + 'user_id' => array('type' => 'integer', 'key' => 'index'), + 'title' => array('type' => 'string', 'length' => 255, 'null' => false), + 'body' => 'text', + ); + + var $records = array( + array('id' => 1, 'title' => 'title1', 'body' => 'article 1', 'user_id' => 1), + array('id' => 2, 'title' => 'title2', 'body' => 'article 2', 'user_id' => 2), + array('id' => 3, 'title' => 'title3', 'body' => 'article 3', 'user_id' => 1), + array('id' => 4, 'title' => 'title4', 'body' => 'article 4', 'user_id' => 3), + ); +} \ No newline at end of file diff --git a/app/plugins/collectionable/tests/fixtures/virtual_fields_user_fixture.php b/app/plugins/collectionable/tests/fixtures/virtual_fields_user_fixture.php new file mode 100644 index 0000000..126c30a --- /dev/null +++ b/app/plugins/collectionable/tests/fixtures/virtual_fields_user_fixture.php @@ -0,0 +1,18 @@ + array('type' => 'integer', 'key' => 'primary'), + 'first_name' => array('type' => 'string', 'length' => 255, 'null' => false), + 'last_name' => array('type' => 'string', 'length' => 255, 'null' => false), + ); + + var $records = array( + array('id' => 1, 'first_name' => 'yamada', 'last_name' => 'ichirou'), + array('id' => 2, 'first_name' => 'tanaka', 'last_name' => 'jirou'), + array('id' => 3, 'first_name' => 'kaneda', 'last_name' => 'saburou'), + array('id' => 4, 'first_name' => 'shimizu', 'last_name' => 'shinou'), + ); +} \ No newline at end of file