Browse Source

Merge branch 'master' into master

tags/2.0.16
jakharbek 6 years ago committed by GitHub
parent
commit
56de079108
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 205
      docs/guide-ar/README.md
  2. 57
      docs/guide-ar/intro-yii.md
  3. 25
      docs/guide-ar/start-prerequisites.md
  4. 20
      docs/guide-es/test-acceptance.md
  5. 58
      docs/guide-es/test-environment-setup.md
  6. 26
      docs/guide-es/test-functional.md
  7. 80
      docs/guide-es/test-overview.md
  8. 34
      docs/guide-es/test-unit.md
  9. 2
      docs/guide-ru/tutorial-core-validators.md
  10. 2
      docs/guide-zh-CN/rest-authentication.md
  11. 37
      docs/guide/structure-widgets.md
  12. 3
      framework/CHANGELOG.md
  13. 6
      framework/assets/yii.activeForm.js
  14. 2
      framework/assets/yii.js
  15. 4
      framework/assets/yii.validation.js
  16. 2
      framework/db/QueryTrait.php
  17. 2
      framework/helpers/BaseArrayHelper.php
  18. 34
      tests/js/data/yii.activeForm.html
  19. 26
      tests/js/tests/yii.activeForm.test.js
  20. 27
      tests/js/tests/yii.test.js
  21. 35
      tests/js/tests/yii.validation.test.js
  22. 2
      tests/mssql/docker-compose.yml

205
docs/guide-ar/README.md

@ -0,0 +1,205 @@
Yii 2.0 الدليل التقني الخاص ببيئة العمل
===============================
تم تحرير هذا الملف اعتمادا على [الشروط الخاصة بتوثيف ال Yii](http://www.yiiframework.com/doc/terms/).
جميع الحقوق محفوظة
2014 (c) Yii Software LLC.
المقدمة
------------
* [عن بيئة العمل Yii](intro-yii.md)
* [التحديث من الإصدار 1.1](../guide/intro-upgrade-from-v1.md)
البداية من هنا
---------------
* [ماذا يجب أن تعرف عن بيئة العمل](start-prerequisites.md)
* [تنصيب ال Yii](../guide/start-installation.md)
* [تشغيل وتطبيق بيئة العمل](../guide/start-workflow.md)
* [قل مرحبا - المشروع الأول](../guide/start-hello.md)
* [العمل مع ال forms](../guide/start-forms.md)
* [العمل مع قواعد البيانات](../guide/start-databases.md)
* [إنشاء الشيفرة البرمجية من خلال ال gii](../guide/start-gii.md)
* [ماذا الآن - الخطوة القادمة](../guide/start-looking-ahead.md)
الهيكلية الخاصة بالتطبيق (Application Structure)
---------------------
* [نظرة عامة عن الهيكلية الخاصة بالتطبيق](../guide/structure-overview.md)
* [Entry Scripts](../guide/structure-entry-scripts.md)
* [التطبيقات](../guide/structure-applications.md)
* [مكونات التطبيقات](../guide/structure-application-components.md)
* [Controllers](../guide/structure-controllers.md)
* [Models](../guide/structure-models.md)
* [Views](../guide/structure-views.md)
* [Modules](../guide/structure-modules.md)
* [Filters](../guide/structure-filters.md)
* [Widgets](../guide/structure-widgets.md)
* [Assets](../guide/structure-assets.md)
* [Extensions](../guide/structure-extensions.md)
التعامل مع ال requests
-----------------
* [نظرة عامة عن التعامل مع ال requests](../guide/runtime-overview.md)
* [Bootstrapping](../guide/runtime-bootstrapping.md)
* [Routing and URL Creation](../guide/runtime-routing.md)
* [Requests](../guide/runtime-requests.md)
* [Responses](../guide/runtime-responses.md)
* [Sessions and Cookies](../guide/runtime-sessions-cookies.md)
* [Handling Errors - التحكم بالأخطاء](../guide/runtime-handling-errors.md)
* [Logging - تسجيل الحركات](../guide/runtime-logging.md)
المفاهيم الرئيسية (Key Concepts)
------------
* [Components](../guide/concept-components.md)
* [Properties](../guide/concept-properties.md)
* [Events](../guide/concept-events.md)
* [Behaviors](../guide/concept-behaviors.md)
* [Configurations](../guide/concept-configurations.md)
* [Aliases](../guide/concept-aliases.md)
* [Class Autoloading](../guide/concept-autoloading.md)
* [Service Locator](../guide/concept-service-locator.md)
* [Dependency Injection Container](../guide/concept-di-container.md)
التعامل مع قواعد البيانات
----------------------
* [Database Access Objects](../guide/db-dao.md): Connecting to a database, basic queries, transactions, and schema manipulation
* [Query Builder](../guide/db-query-builder.md): Querying the database using a simple abstraction layer
* [Active Record](../guide/db-active-record.md): The Active Record ORM, retrieving and manipulating records, and defining relations
* [Migrations](../guide/db-migrations.md): Apply version control to your databases in a team development environment
* [Sphinx](https://www.yiiframework.com/extension/yiisoft/yii2-sphinx/doc/guide)
* [Redis](https://www.yiiframework.com/extension/yiisoft/yii2-redis/doc/guide)
* [MongoDB](https://www.yiiframework.com/extension/yiisoft/yii2-mongodb/doc/guide)
* [ElasticSearch](https://www.yiiframework.com/extension/yiisoft/yii2-elasticsearch/doc/guide)
الحصول على البيانات من خلال المستخدمين
-----------------------
* [Creating Forms](../guide/input-forms.md)
* [Validating Input](../guide/input-validation.md)
* [Uploading Files](../guide/input-file-upload.md)
* [Collecting Tabular Input](../guide/input-tabular-input.md)
* [Getting Data for Multiple Models](../guide/input-multiple-models.md)
* [Extending ActiveForm on the Client Side](../guide/input-form-javascript.md)
عرض البيانات
---------------
* [Data Formatting](../guide/output-formatting.md)
* [Pagination](../guide/output-pagination.md)
* [Sorting](../guide/output-sorting.md)
* [Data Providers](../guide/output-data-providers.md)
* [Data Widgets](../guide/output-data-widgets.md)
* [Working with Client Scripts](../guide/output-client-scripts.md)
* [Theming](../guide/output-theming.md)
الامان والحماية
--------
* [Security Overview](../guide/security-overview.md)
* [Authentication](../guide/security-authentication.md)
* [Authorization](../guide/security-authorization.md)
* [Working with Passwords](../guide/security-passwords.md)
* [Cryptography](../guide/security-cryptography.md)
* [Auth Clients](https://www.yiiframework.com/extension/yiisoft/yii2-authclient/doc/guide)
* [Best Practices](../guide/security-best-practices.md)
Caching التخزين المؤقت
-------
* [Caching Overview](../guide/caching-overview.md)
* [Data Caching](../guide/caching-data.md)
* [Fragment Caching](../guide/caching-fragment.md)
* [Page Caching](../guide/caching-page.md)
* [HTTP Caching](../guide/caching-http.md)
RESTful Web Services
--------------------
* [Quick Start](../guide/rest-quick-start.md)
* [Resources](../guide/rest-resources.md)
* [Controllers](../guide/rest-controllers.md)
* [Routing](../guide/rest-routing.md)
* [Response Formatting](../guide/rest-response-formatting.md)
* [Authentication](../guide/rest-authentication.md)
* [Rate Limiting](../guide/rest-rate-limiting.md)
* [Versioning](../guide/rest-versioning.md)
* [Error Handling](../guide/rest-error-handling.md)
الأدوات المساعدة أثناء تطوير التطبيقات
-----------------
* [Debug Toolbar and Debugger](https://www.yiiframework.com/extension/yiisoft/yii2-debug/doc/guide)
* [Generating Code using Gii](https://www.yiiframework.com/extension/yiisoft/yii2-gii/doc/guide)
* [Generating API Documentation](https://www.yiiframework.com/extension/yiisoft/yii2-apidoc)
فحص واختبار التطبيقات
-------
* [Testing Overview](../guide/test-overview.md)
* [Testing environment setup](../guide/test-environment-setup.md)
* [Unit Tests](../guide/test-unit.md)
* [Functional Tests](../guide/test-functional.md)
* [Acceptance Tests](../guide/test-acceptance.md)
* [Fixtures](../guide/test-fixtures.md)
مواضيع وعناوين مميزة
--------------
* [Advanced Project Template](https://www.yiiframework.com/extension/yiisoft/yii2-app-advanced/doc/guide)
* [Building Application from Scratch](../guide/tutorial-start-from-scratch.md)
* [Console Commands](../guide/tutorial-console.md)
* [Core Validators](../guide/tutorial-core-validators.md)
* [Docker](../guide/tutorial-docker.md)
* [Internationalization](../guide/tutorial-i18n.md)
* [Mailing](../guide/tutorial-mailing.md)
* [Performance Tuning](../guide/tutorial-performance-tuning.md)
* [Shared Hosting Environment](../guide/tutorial-shared-hosting.md)
* [Template Engines](../guide/tutorial-template-engines.md)
* [Working with Third-Party Code](../guide/tutorial-yii-integration.md)
* [Using Yii as a micro framework](../guide/tutorial-yii-as-micro-framework.md)
Widgets
-------
* [GridView](https://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
* [ListView](https://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](https://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](https://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](https://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](https://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](https://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](https://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
* [Bootstrap Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-bootstrap/doc/guide)
* [jQuery UI Widgets](https://www.yiiframework.com/extension/yiisoft/yii2-jui/doc/guide)
Helpers
-------
* [Helpers Overview](../guide/helper-overview.md)
* [ArrayHelper](../guide/helper-array.md)
* [Html](../guide/helper-html.md)
* [Url](../guide/helper-url.md)

57
docs/guide-ar/intro-yii.md

@ -0,0 +1,57 @@
# <div dir="rtl">ما هي بيئة العمل Yii</div>
<p dir="rtl">Yii هو إطار PHP عالي الأداء يعتمد على المكونات لتطوير تطبيقات الويب الحديثة بسرعة.
إن الاسم "Yii" (يُنطق بـ "يي" أو "[جي:]" يعني "بسيطًا وتطوريًا" باللغة الصينية. ومن الممكن ايضا
اعتباره اختصارًا لـ <b>Yes It Is</b>!</p>
# <div dir="rtl">ما هي أفضل التطبيقات أو البرمجيات التي يمكن برمجتها وتتناسب مع ال Yii</div>
<p dir="rtl">
Yii هو إطار عام لبرمجة الويب ، مما يعني أنه يمكن استخدامه لتطوير كافة أنواع
تطبيقات الويب باستخدام PHP. وذلك بسبب البنية القائمة على البنية التركيبة لبيئة العمل وترابطها مع المكونات والتخزين المؤقت، وهو مناسب بشكل خاص لتطوير portals, forums, content management systems (CMS), e-commerce projects, RESTful Web services. وما إلى ذلك.
</p>
# <div dir="rtl">كيف يمكن مقارنة بيئة العمل الخاصة بال Yii مع الأطر أو بيئات العمل الأخرى؟</div>
<p dir="rtl">
إذا كنت بالفعل على دراية بإطار العمل الأخرى ، فيمكنك معرفة كيف تتم مقارنة ال Yii:
<ul dir="rtl">
<li> مثل معظم أطر عمل ال PHP ، يطبق Yii النمط المعماري MVC (Model-View-Controller).</li>
<li> ال Yii يتبنى الفلسفة التي تقول أن الشيفرة البرمجية يجب أن تكتب بأسهل طريقها وادقها، ولكنها بذات الوقت يجب أن تكون أنيقة الكتابة مظهرا ومضمونا (شكلا وتطيبقا).</li>
<li> ال Yii هو إطار متكامل (full stack) يوفر العديد من الميزات الجاهزة للإستخدام والمعدة مسبقا، مثل ال query builders وال ActiveRecord لقواعد البيانات العلاقئية (relational) وغير العلائقية (Nosql)، بالإضافة الى دعم وتجهيز ال RESTful API والتخزين المؤقت (caching) وغيرها الكثير. </li>
<li> من مميزات ال Yii إمكانية التعديل (استبدال جزء معين أو تخيصيص وإضافة) جزء معين على أغلب ال Yii core code، وبالإضافة الى هذا، يمكنك بناء ملحقات برمجية اعتمادا على ال core code، ومن ثم نشر هذه الشيفرة وتوزيعها واستخدامها دون وجود أي مشاكل أو صعوبة تذكر.</li>
<li> الأداء العالي هو الهدف الأساسي من ال Yii.</li>
</ul>
</p>
<p dir="rtl">
ال Yii إطار عمل صمم من قبل فريق برمجي متكامل، فهو ليس مجرد عمل فردي ، بل يتكون من فريق تطوير أساسي وقوي(http://www.yiiframework.com/team/) ، بالإضافة إلى منتدى كبير
من المهنيين الذين يساهمون باستمرار في تطوير هذا الإطار. فريق المطورين الخاص بال Yii
يراقب عن كثب أحدث اتجاهات تطوير الويب وأفضل الممارسات والمميزات التي
وجدت في الأطر والمشاريع الأخرى. وتدرج بانتظام بإضافة أفضل الممارسات والميزات الى ال Yii عبر واجهات بسيطة وأنيقة.
</p>
# <div dir="rtl">الإصدارات الخاصة بال Yii</div>
<p dir="rtl">
يتوفر لدى Yii حاليًا إصداران رئيسيان: 1.1 و 2.0. الإصدار 1.1 هو الجيل القديم وهو الآن في وضع الصيانة. الإصدار 2.0 هو إعادة كتابة وهيكلة كاملة لل Yii، تم اعتماد أحدث التقنيات والبروتوكولات فيها مثل including Composer, PSR, namespaces, traits والكثير من الأمور الأخرى، وفي هذه الإرشادات، سيكون الكلام كله موجها الى الإصدار الثاني من بيئة العمل ال Yii.
</p>
# <div dir="rtl">المتطلبات الأساسية للعمل على إطار ال Yii</div>
<p dir="rtl">
<ul dir="rtl">
<li>الإصدار PHP 5.4.0 أو أكثر</li>
<li>المعرفة الأساسية بمفاهيم البرمجة كائنية التوجه OOP</li>
<li>المعرفة بآخر وأحدث التقنيات الموجودة بال php مثل ال namespaces, traits، الفهم لهذه المفاهيم سيسهل عليك العمل كثيرا</li>
</ul>
</p>
<p dir="rtl">
ملاحظة: يمكن التحقق من توافق المتطلبات الخاصة بك مع ال yii من خلال الدخول الى الصفحة requirement الموجودة بال yii
</p>

25
docs/guide-ar/start-prerequisites.md

@ -0,0 +1,25 @@
# <div dir="rtl">ماذا يجب أن تعرف قبل البدء بال Yii</div>
<p dir="rtl">
منحنى التعلم الخاص بال Yii ليس حادًا مثل أطر PHP الأخرى، ولكن لا يزال هناك بعض الأشياء التي يجب أن تتعلمها قبل البدء بـال Yii.
</p>
## <div dir="rtl">PHP</div>
<p dir="rtl">
ال Yii هو إطار عمل PHP، لذا تأكد من قراءة وفهم المرجع الرسمي الخاص باللغة (http://php.net/manual/en/langref.php). عند البدء بتطوير المشاريع أو التطبيقات باستخدام ال Yii ، ستكتب التعليمات البرمجية بطريقة كائنية التوجه OOP، لذا تأكد من أنك على دراية بـمفاهيم ال OOP (https://secure.php.net/manual/en/language.oop5.basic.php) وكذلك ال namespaces (https://secure.php.net/manual/en/language.namespaces.php).
</p>
## <div dir="rtl">البرمجة كائنية التوجه object oriented programming</div>
<p dir="rtl">
كمبرمج أو مطور يرغب بالعمل على ال Yii، يجب عليك أن تمتلك المعرفة الأساسية للبرمجة كائنية التوجه OOP. إذا لم تكن على دراية بها ، فيمكنك تعلم ذلك من خلال واحدة من هذه الدورات المنتشرة مثل (https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762).<br />
ملاحظة: كلما زاد تعقيد التطبيق أو المشروع الذي تعمل عليه، كلما احتجت الى مستوى أعلى وإحترافي أكثر من مفاهيم ال OOP لحل وإدارة التعقديات التي ستترب على مثل هذه المشاريع.
</p>
## <div dir="rtl">Command line and composer</div>
<p dir="rtl">تستخدم ال Yii بشكل كبير de-facto standard PHP package manager، ال Composer (https://getcomposer.org/)، لذلك تأكد من قرائتك وفهمك لهذا الموضوع قبل أن تبدء. بالإضافة الى ذلك إذا لم تكن على دراية باستخدام سطر الأوامر (command line) ، فقد حان الوقت لبدء المحاولة. بمجرد تعلم الأساسيات ، لن ترغب في العمل بدون إستخدام سطر الأوامر.<br />
ال composer: ويترجم حرفيا الى كلمة "الملحن"، وهي عبارة عن أداة لإدارة المشاريع البرمجية والتي تسمح لك بتحديث وتنزيل المكتبات البرمجية المطلوبة للمشروع الخاص بك.
</p>

20
docs/guide-es/test-acceptance.md

@ -0,0 +1,20 @@
Tests de aceptación
===================
Un test de aceptación verifica escenarios desde la perspectiva de un usuario.
Se accede a la aplicación testeada por medio de PhpBrowser o de un navegador de verdad.
En ambos casos los navegadores se comunican vía HTTP así que la aplicación debe ser
servida por un servidor web.
Los tests de aceptación se implementan con ayuda del _framework_ Codeception, que tiene
una buena documentación:
- [Codeception para el _framework_ Yii](http://codeception.com/for/yii)
- [Tests funcionales de Codeception](http://codeception.com/docs/04-FunctionalTests)
## Ejecución de tests en las plantillas básica y avanzada
Si ha empezado con la plantilla avanzada, consulte la [guía de testeo](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-testing.md)
para más detalles sobre la ejecución de tests.
Si ha empezado con la plantilla básica, consulte la [sección sobre testeo de su README](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing).

58
docs/guide-es/test-environment-setup.md

@ -1,49 +1,23 @@
Preparación del entorno de test Preparación del entorno de pruebas
=============================== ==================================
> Note: Esta sección se encuentra en desarrollo. Yii 2 ha mantenido oficialmente integración con el _framework_ de testeo [`Codeception`](https://github.com/Codeception/Codeception),
que le permite crear los siguientes tipos de tests:
Yii 2 ha mantenido integración oficial con el framework de testing [`Codeception`](https://github.com/Codeception/Codeception), - [Unitari](test-unit.md) - verifica que una unidad simple de código funciona como se espera;
que te permite crear los siguientes tipos de tests: - [Funcional](test-functional.md) - verifica escenarios desde la perspectiva de un usuario a través de la emulación de un navegador;
- [De aceptación](test-acceptance.md) - verifica escenarios desde la perspectiva de un usuario en un navegador.
- [Test de unidad](test-unit.md) - verifica que una unidad simple de código funciona como se espera; Yii provee grupos de pruebas listos para utilizar para los tres tipos de test, tanto en la plantilla de proyecto
- [Test funcional](test-functional.md) - verifica escenarios desde la perspectiva de un usuario a través de la emulación de un navegador; [`yii2-basic`](https://github.com/yiisoft/yii2-app-basic) como en
- [Test de aceptación](test-acceptance.md) - verifica escenarios desde la perspectiva de un usuario en un navegador. [`yii2-advanced`](https://github.com/yiisoft/yii2-app-advanced).
Yii provee grupos de pruebas listos para utilizar en ambos Codeception viene preinstalado tanto en la plantilla de proyecto básica como en la avanzada.
[`yii2-basic`](https://github.com/yiisoft/yii2-app-basic) y En caso de que no use una de estas plantillas, puede instalar Codeception ejecutando
[`yii2-advanced`](https://github.com/yiisoft/yii2-app-advanced) templates de proyectos. las siguientes órdenes de consola:
Para poder ejecutar estos tests es necesario instalar [Codeception](https://github.com/Codeception/Codeception).
Puedes instalarlo tanto localmente - únicamente para un proyecto en particular, o globalmente - para tu máquina de desarrollo.
Para la instalación local utiliza los siguientes comandos:
```
composer require "codeception/codeception=2.1.*"
composer require "codeception/specify=*"
composer require "codeception/verify=*"
```
Para la instalación global necesitarás la directiva `global`:
``` ```
composer global require "codeception/codeception=2.1.*" composer require codeception/codeception
composer global require "codeception/specify=*" composer require codeception/specify
composer global require "codeception/verify=*" composer require codeception/verify
``` ```
En caso de que nunca hayas utilizado Composer para paquetes globales, ejecuta `composer global status`. Esto debería mostrar la salida:
```
Changed current directory to <directory>
```
Entonces agrega `<directory>/vendor/bin` a tu variable de entorno `PATH`. Ahora podrás utilizar el `codecept` en la línea
de comandos a nivel global.
> Note: la instalación global te permite usar Codeception para todos los proyectos en los que trabajes en tu máquina de desarrollo y
te permite ejecutar el comando `codecept` globalmente sin especificar su ruta. De todos modos, ese acercamiento podría ser inapropiado,
por ejemplo, si 2 proyectos diferentes requieren diferentes versiones de Codeception instaladas.
Por simplicidad, todos los comandos relacionados a tests en esta guía están escritos asumiendo que Codeception
ha sido instalado en forma global.

26
docs/guide-es/test-functional.md

@ -1,11 +1,25 @@
Tests Funcionales Tests funcionales
================= =================
> Note: Esta sección se encuentra en desarrollo. Los tests funcionales verifican escenarios desde la perspectiva de un usuario.
Son similares a los [tests de aceptación](test-acceptance.md) pero en lugar de
comunicarse vía HTTP rellena el entorno como parámetros POST y GET y después ejecuta
una instancia de la aplicación directamente desde el código.
- [Tests Funcionales de Codeception](http://codeception.com/docs/04-FunctionalTests) Los tests funcionales son generalmente más rápidos que los tests de aceptación y
proporcionan _stack traces_ detalladas en los fallos.
Como regla general, debería preferirlos salvo que tenga una configuración de servidor
web especial o una interfaz de usuario compleja en Javascript.
Ejecutar test funcionales de templates básicos y avanzados Las pruebas funcionales se implementan con ayuda del _framework_ Codeception, que tiene
---------------------------------------------------------- una buena documentación:
Por favor consulta las instrucciones provistas en `apps/advanced/tests/README.md` y `apps/basic/tests/README.md`. - [Codeception para el _framework_ Yii](http://codeception.com/for/yii)
- [Tests funcionales de Codeception](http://codeception.com/docs/04-FunctionalTests)
## Ejecución de tests en las plantillas básica y avanzada
Si ha empezado con la plantilla avanzada, consulte la [guía de testeo](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-testing.md)
para más detalles sobre la ejecución de tests.
Si ha empezado con la plantilla básica, consulte la [sección sobre testeo de su README](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing).

80
docs/guide-es/test-overview.md

@ -0,0 +1,80 @@
Tests
=====
Las pruebas son una parte importante del desarrollo de software. Seamos conscientes
de ello o no, ralizamos pruebas contínuamente.
Por ejemplo, cuando escribimos una clase en PHP, podemos depurarla paso a paso o
simplemente usar declaraciones `echo` o `die` para verificar que la implementación
funciona conforme a nuestro plan inicial. En el caso de una aplicación web, introducimos
algunos datos de prueba en los formularios para asegurarnos de que la página interactúa
con nosotros como esperábamos.
El proceso de testeo se puede automatizar para que cada vez que necesitemos verificar
algo, solamente necesitemos invocar el código que lo hace por nosotros. El código que
verifica que el restulado coincide con lo que habíamos planeado se llama *test* y el proceso
de su creación y posterior ejecución es conocido como *testeo automatizado*, que es el
principal tema de estos capítulos sobre testeo.
## Desarrollo con tests
El Desarrollo Dirigido por Pruebas (_Test-Driven Development_ o TDD) y el Desarrollo
Dirigido por Corpotamientos (_Behavior-Driven Development_ o BDD) son enfoques para
desarrollar software, en los que se describe el comportamiento de un trozo de código
o de toda la funcionalidad como un conjunto de escenarios o pruebas antes de escribir
el código real y sólo entonces crear la implementación que permite pasar esos tests
verificando que se ha logrado el comportamiento pretendido.
El proceso de desarrollo de una funcionalidad es el siguiente:
- Crear un nuevo test que describe una funcionalidad a implementar.
- Ejecutar el nuevo test y asegurarse de que falla. Esto es lo esperado, dado que todavía no hay ninguna implementación.
- Escribir un código sencillo para superar el nuevo test.
- Ejecutar todos los tests y asegurarse de que se pasan todos.
- Mejorar el código y asegurarse de que los tests siguen superándose.
Una vez hecho, se repite el proceso de neuvo para otra funcionalidad o mejora.
Si se va a cambiar la funcionalidad existente, también hay que cambiar los tests.
> Tip: Si siente que está perdiendo tiempo haciendo un montón de iteraciones pequeñas
> y simples, intente cubrir más por cada escenario de test, de modo que haga más cosas antes
> de ejecutar los tests de nuevo. Si está depurando demasiado, intente hacer lo contrario.
La razón para crear los tests antes de hacer ninguna implementación es que eso nos permite
centrarnos en lo que queremos alcanzar y sumergirnos totalmente en «cómo hacerlo» después.
Normalmente conduce a mejores abstracciones y a un más fácil mantenimiento de los tests
cuando toque hacer ajustes a las funcionalidades o componentes menos acoplados.
Para resumir, las ventajas de este enfoque son las siguientes:
- Le mantiene centrado en una sola cosa en cada momento, lo que resulta en una mejor planificación e implementación.
- Resulta en más funcionalidades cubiertas por tests, y en mayor detalle. Es decir, si se superan los tests, lo más problable es que no haya nada roto.
A largo plazo normalmente tiene como efecto un buen ahorro de tiempo.
## Qué y cómo probar
Aunque el enfoque de primero los tests descrito arriba tiene sentido para el largo plazo
y proyectos relativamente complejos, sería excesivo para proyectos más simples.
Hay algunas indicaciones de cuándo es apropiado:
- El proyecto ya es grande y complejo.
- Los requisitos del proyecto están empezando a hacerse complejos. El proyecto crece constantemente.
- El proyecto pretende a ser a largo plazo.
- El coste de fallar es demasiado alto.
No hay nada malo en crear tests que cubran el comportamiento de una implementación existente.
- Es un proyecto legado que se va a renovar gradualmente.
- Le han dado un proyecto sobre el que trabajar y no tiene tests.
En algunos casos cualquier forma de testo automatizado sería exagerada:
- El proyecto es sencillo y no se va a volver más complejo.
- Es un proyecto puntual en el que no se seguirá trabajando.
De todas formas, si dispone de tiempo, es bueno automatizar las pruebas también en esos casos.
## Más lecturas
- Test Driven Development: By Example / Kent Beck. ISBN: 0321146530.

34
docs/guide-es/test-unit.md

@ -1,25 +1,25 @@
Tests de Unidad Pruebas unitarias
=============== =================
> Note: Esta sección se encuentra en desarrollo. Un test unitario se encarga de verificar que una unidad simple de código funcione como se espera.
Esto decir, dados diferentes parámetros de entrada, el test verifica que el método
de la clase devuelve el resultado esperado.
Normalmente los tests unitarios son desarrollados por la persona que escribe las clases testeadas.
Un test de unidad se encarga de verificar que una unidad simple de código funcione como se espera. En la programación orientada a objetos, Los tests unitarios en Yii están construidos en base a PHPUnit y, opcionalmente, Codeception, por lo que se recomienda consultar su respectiva documentación:
la unidad de código más básica es una clase. Por lo tanto, un test de unidad necesita verificar que cada método de la interfaz de la clase funciona apropiadamente.
Esto quiere decir que, dando diferentes parámetros de entrada, el test verifica que el método devuelve el resultado esperado.
Los tests de unidad son normalmente desarrollados por la persona que escribe las clases siendo testeadas.
Los tests de unidad en Yii están construidos en base a PHPUnit y opcionalmente, Codeception, por lo que se recomineda consultar su respectiva documentación: - [Codeception para el _framework_ Yii](http://codeception.com/for/yii)
- [Tests unitarios con Codeception](http://codeception.com/docs/05-UnitTests)
- [Documentación de PHPUnit, empezando por el capítulo 2](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html)
- [Documentación de PHPUnit comienza en el capítulo 2](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html). ## Ejecución de tests en las plantillas básica y avanzada
- [Tests de Unidad con Codeception](http://codeception.com/docs/05-UnitTests).
Ejecutar test de unidad de templates básicos y avanzados Si ha empezado con la plantilla avanzada, consulte la [guía de testeo](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/start-testing.md)
-------------------------------------------------------- para más detalles sobre la ejecución de tests.
Por favor consulta las instrucciones provistas en `apps/advanced/tests/README.md` y `apps/basic/tests/README.md`. Si ha empezado con la plantilla básica, consulte la [sección sobre testeo de su README](https://github.com/yiisoft/yii2-app-basic/blob/master/README.md#testing).
Test de unidad del Framework ##Tests unitarios del framework
----------------------------
Si quieres ejecutar tests de unidad para Yii en sí, consulta Si desea ejecutar tests unitarios para el framework Yii en sí, consulte
"[Comenzando a desarrollar con Yii 2](https://github.com/yiisoft/yii2/blob/master/docs/internals/getting-started.md)". «[Comenzando con el desarrollo de Yii 2](https://github.com/yiisoft/yii2/blob/master/docs/internals/getting-started.md)».

2
docs/guide-ru/tutorial-core-validators.md

@ -66,7 +66,7 @@ public function rules()
// проверяет, является ли значение атрибута "password" таким же, как "password_repeat" // проверяет, является ли значение атрибута "password" таким же, как "password_repeat"
['password', 'compare'], ['password', 'compare'],
// то же, что и выше, но атрбут для сравнения указан явно // то же, что и выше, но атрибут для сравнения указан явно
['password', 'compare', 'compareAttribute' => 'password_repeat'], ['password', 'compare', 'compareAttribute' => 'password_repeat'],
// проверяет, что возраст больше или равен 30 // проверяет, что возраст больше или равен 30

2
docs/guide-zh-CN/rest-authentication.md

@ -63,7 +63,7 @@ public function behaviors()
} }
``` ```
如果你系那个支持以上3个认证方式,可以使用`CompositeAuth`,如下所示: 如果你支持以上3个认证方式,可以使用`CompositeAuth`,如下所示:
```php ```php
use yii\filters\auth\CompositeAuth; use yii\filters\auth\CompositeAuth;

37
docs/guide/structure-widgets.md

@ -86,6 +86,10 @@ details.
## Creating Widgets <span id="creating-widgets"></span> ## Creating Widgets <span id="creating-widgets"></span>
Widget can be created in either of two different ways depending on the requirement.
### 1: Utilizing `widget()` method
To create a widget, extend from [[yii\base\Widget]] and override the [[yii\base\Widget::init()]] and/or To create a widget, extend from [[yii\base\Widget]] and override the [[yii\base\Widget::init()]] and/or
[[yii\base\Widget::run()]] methods. Usually, the `init()` method should contain the code that initializes the widget [[yii\base\Widget::run()]] methods. Usually, the `init()` method should contain the code that initializes the widget
properties, while the `run()` method should contain the code that generates the rendering result of the widget. properties, while the `run()` method should contain the code that generates the rendering result of the widget.
@ -128,6 +132,21 @@ use app\components\HelloWidget;
<?= HelloWidget::widget(['message' => 'Good morning']) ?> <?= HelloWidget::widget(['message' => 'Good morning']) ?>
``` ```
Sometimes, a widget may need to render a big chunk of content. While you can embed the content within the `run()`
method, a better approach is to put it in a [view](structure-views.md) and call [[yii\base\Widget::render()]] to
render it. For example,
```php
public function run()
{
return $this->render('hello');
}
```
### 2: Utilizing `begin()` and `end()` methods
This is similar to above one with minor difference.
Below is a variant of `HelloWidget` which takes the content enclosed within the `begin()` and `end()` calls, Below is a variant of `HelloWidget` which takes the content enclosed within the `begin()` and `end()` calls,
HTML-encodes it and then displays it. HTML-encodes it and then displays it.
@ -168,20 +187,15 @@ use app\components\HelloWidget;
?> ?>
<?php HelloWidget::begin(); ?> <?php HelloWidget::begin(); ?>
content that may contain <tag>'s sample content that may contain one or more <strong>HTML</strong> <pre>tags</pre>
<?php HelloWidget::end(); ?> If this content grows too big, use sub views
```
Sometimes, a widget may need to render a big chunk of content. While you can embed the content within the `run()` For e.g.
method, a better approach is to put it in a [view](structure-views.md) and call [[yii\base\Widget::render()]] to
render it. For example,
```php <?php echo $this->render('viewfile'); // Note: here render() method is of class \yii\base\View as this part of code is within view file and not in Widget class file ?>
public function run()
{ <?php HelloWidget::end(); ?>
return $this->render('hello');
}
``` ```
By default, views for a widget should be stored in files in the `WidgetPath/views` directory, where `WidgetPath` By default, views for a widget should be stored in files in the `WidgetPath/views` directory, where `WidgetPath`
@ -205,3 +219,4 @@ which can be utilized to solve the problem.
When a widget contains view code only, it is very similar to a [view](structure-views.md). In fact, in this case, When a widget contains view code only, it is very similar to a [view](structure-views.md). In fact, in this case,
their only difference is that a widget is a redistributable class, while a view is just a plain PHP script their only difference is that a widget is a redistributable class, while a view is just a plain PHP script
that you would prefer to keep within your application. that you would prefer to keep within your application.

3
framework/CHANGELOG.md

@ -4,6 +4,9 @@ Yii Framework 2 Change Log
2.0.16 under development 2.0.16 under development
------------------------ ------------------------
- Bug #13932: Fix number validator attributes comparison (uaoleg, s1lver)
- Bug #14039, #16636: Fixed validation for disabled inputs (s1lver, omzy83)
- Bug #16425: Check for additional values for disabled confirm dialog (Alex-Code, s1lver)
- Enh #14367: In `yii\db\mysql\QueryBuilder` added support fractional seconds for time types for MySQL >= 5.6.4 (konstantin-vl) - Enh #14367: In `yii\db\mysql\QueryBuilder` added support fractional seconds for time types for MySQL >= 5.6.4 (konstantin-vl)
- Bug #16766: `yii\filters\ContentNegotiator` was not setting `Vary` header to inform cache recipients (koteq, cebe, samdark) - Bug #16766: `yii\filters\ContentNegotiator` was not setting `Vary` header to inform cache recipients (koteq, cebe, samdark)
- Bug #11960: Fixed `checked` option ignore in `yii\helpers\BaseHtml::checkbox()` (misantron) - Bug #11960: Fixed `checked` option ignore in `yii\helpers\BaseHtml::checkbox()` (misantron)

6
framework/assets/yii.activeForm.js

@ -325,7 +325,7 @@
// client-side validation // client-side validation
$.each(data.attributes, function () { $.each(data.attributes, function () {
this.$form = $form; this.$form = $form;
if (!$(this.input).is(":disabled")) { if (!findInput($form, this).is(":disabled")) {
this.cancelled = false; this.cancelled = false;
// perform validation only if the form is being submitted or if an attribute is pending validation // perform validation only if the form is being submitted or if an attribute is pending validation
if (data.submitting || this.status === 2 || this.status === 3) { if (data.submitting || this.status === 2 || this.status === 3) {
@ -489,7 +489,6 @@
updateInput($(this), attribute, msg); updateInput($(this), attribute, msg);
} }
} }
}; };
var watchAttribute = function ($form, attribute) { var watchAttribute = function ($form, attribute) {
@ -625,8 +624,9 @@
if (submitting) { if (submitting) {
var errorAttributes = []; var errorAttributes = [];
var $input = findInput($form, this);
$.each(data.attributes, function () { $.each(data.attributes, function () {
if (!$(this.input).is(":disabled") && !this.cancelled && updateInput($form, this, messages)) { if (!$input.is(":disabled") && !this.cancelled && updateInput($form, this, messages)) {
errorAttributes.push(this); errorAttributes.push(this);
} }
}); });

2
framework/assets/yii.js

@ -483,7 +483,7 @@ window.yii = (function ($) {
return true; return true;
} }
if (message !== undefined) { if (message !== undefined && message !== false && message !== '') {
$.proxy(pub.confirm, this)(message, function () { $.proxy(pub.confirm, this)(message, function () {
pub.handleAction($this, event); pub.handleAction($this, event);
}); });

4
framework/assets/yii.validation.js

@ -286,8 +286,8 @@ yii.validation = (function ($) {
} }
if (options.type === 'number') { if (options.type === 'number') {
value = parseFloat(value); value = value ? parseFloat(value) : 0;
compareValue = parseFloat(compareValue); compareValue = compareValue ? parseFloat(compareValue) : 0;
} }
switch (options.operator) { switch (options.operator) {
case '==': case '==':

2
framework/db/QueryTrait.php

@ -85,7 +85,7 @@ trait QueryTrait
* *
* See [[QueryInterface::where()]] for detailed documentation. * See [[QueryInterface::where()]] for detailed documentation.
* *
* @param array $condition the conditions that should be put in the WHERE part. * @param string|array $condition the conditions that should be put in the WHERE part.
* @return $this the query object itself * @return $this the query object itself
* @see andWhere() * @see andWhere()
* @see orWhere() * @see orWhere()

2
framework/helpers/BaseArrayHelper.php

@ -509,7 +509,7 @@ class BaseArrayHelper
* ``` * ```
* *
* @param array $array * @param array $array
* @param string|\Closure $name * @param int|string|\Closure $name
* @param bool $keepKeys whether to maintain the array keys. If false, the resulting array * @param bool $keepKeys whether to maintain the array keys. If false, the resulting array
* will be re-indexed with integers. * will be re-indexed with integers.
* @return array the list of column values * @return array the list of column values

34
tests/js/data/yii.activeForm.html

@ -1,3 +1,37 @@
<form id="w0"> <form id="w0">
<input id="name" type="text" name="name" value=""> <input id="name" type="text" name="name" value="">
</form> </form>
<form id="w1">
<fieldset disabled="">
<div class="form-group required">
<label class="control-label" for="test_text">Test text</label>
<input type="text" id="test_text" class="form-control" name="Test[text]" aria-required="true">
<div class="help-block"></div>
</div>
</fieldset>
<fieldset disabled="">
<div class="form-group required">
<label class="control-label">Test radio</label>
<input type="hidden" name="Test[radio]" value="">
<div id="test_radio" aria-required="true">
<label><input type="radio" name="Test[radio]" value="1"> Test1</label>
<label><input type="radio" name="Test[radio]" value="0"> Test2</label>
</div>
<div class="help-block"></div>
</div>
</fieldset>
<fieldset disabled="">
<div class="form-group required">
<label class="control-label">Test checkbox</label>
<input type="hidden" name="Test[checkbox]" value="">
<div id="test_checkbox" aria-required="true">
<label><input type="checkbox" name="Test[checkbox][]" value="1"> Test1</label>
<label><input type="checkbox" name="Test[checkbox][]" value="0"> Test2</label>
</div>
<div class="help-block"></div>
</div>
</fieldset>
</form>

26
tests/js/tests/yii.activeForm.test.js

@ -78,6 +78,32 @@ describe('yii.activeForm', function () {
assert.isTrue(afterValidateSpy.calledOnce); assert.isTrue(afterValidateSpy.calledOnce);
}); });
}); });
describe('with disabled fields', function () {
var inputTypes = {
test_radio: 'radioList',
test_checkbox: 'checkboxList',
test_text: 'text input'
};
for (var key in inputTypes) {
if (inputTypes.hasOwnProperty(key)) {
(function () {
var inputId = key;
it(inputTypes[key] + ' disabled field', function () {
$activeForm = $('#w1');
$activeForm.yiiActiveForm({
id: inputId,
input: '#' + inputId
});
$activeForm.yiiActiveForm('validate');
assert.isFalse($activeForm.data('yiiActiveForm').validated);
});
})();
}
}
});
}); });
describe('resetForm method', function () { describe('resetForm method', function () {

27
tests/js/tests/yii.test.js

@ -1359,6 +1359,33 @@ describe('yii', function () {
}); });
}); });
describe('disabled confirm dialog', function () {
it('confirm data param = false', function () {
var element = $('#data-methods-no-data');
element.attr('data-confirm', false);
element.trigger($.Event('click'));
assert.isFalse(yiiConfirmSpy.called);
assert.isTrue(yiiHandleActionStub.called);
});
it('confirm data param = empty', function () {
var element = $('#data-methods-no-data');
element.attr('data-confirm', '');
element.trigger($.Event('click'));
assert.isFalse(yiiConfirmSpy.called);
assert.isTrue(yiiHandleActionStub.called);
});
it('confirm data param = undefined', function () {
var element = $('#data-methods-no-data');
element.attr('data-confirm', undefined);
element.trigger($.Event('click'));
assert.isFalse(yiiConfirmSpy.called);
assert.isTrue(yiiHandleActionStub.called);
});
});
describe('with clickableSelector with data-confirm', function () { describe('with clickableSelector with data-confirm', function () {
it('should call confirm and handleAction methods', function () { it('should call confirm and handleAction methods', function () {
var event = $.Event('click'); var event = $.Event('click');

35
tests/js/tests/yii.validation.test.js

@ -1518,6 +1518,41 @@ describe('yii.validation', function () {
{operator: '<', compareValue: '2', type: 'number'}, {operator: '<', compareValue: '2', type: 'number'},
false false
], ],
'number type, ">=" operator, 2nd is lower': [
10,
{operator: '>=', compareValue: 2, type: 'number'},
true
],
'number type, "<=" operator, 2nd is lower': [
10,
{operator: '<=', compareValue: 2, type: 'number'},
false
],
'number type, ">" operator, 2nd is lower': [
10,
{operator: '>', compareValue: 2, type: 'number'},
true
],
'number type, ">" operator, compare value undefined': [
undefined,
{operator: '>', compareValue: 2, type: 'number'},
false
],
'number type, "<" operator, compare value undefined': [
undefined,
{operator: '<', compareValue: 2, type: 'number'},
true
],
'number type, ">=" operator, compare value undefined': [
undefined,
{operator: '>=', compareValue: 2, type: 'number'},
false
],
'number type, "<=" operator, compare value undefined': [
undefined,
{operator: '<=', compareValue: 2, type: 'number'},
true
],
// default compare value // default compare value
'default compare value, "===" operator, against undefined': [undefined, {operator: '==='}, true] 'default compare value, "===" operator, against undefined': [undefined, {operator: '==='}, true]
}, function (value, options, expectValid) { }, function (value, options, expectValid) {

2
tests/mssql/docker-compose.yml

@ -12,6 +12,8 @@ services:
# Enable for debugging, Note: File-cache tests may be VERY slow or fail # Enable for debugging, Note: File-cache tests may be VERY slow or fail
#volumes: #volumes:
# - ../../..:/project # - ../../..:/project
volumes:
- ../../tests/data/config-docker.php:/project/tests/data/config.php
depends_on: depends_on:
- mssql - mssql
# Enable for debugging # Enable for debugging

Loading…
Cancel
Save