diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..a1bcd71c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: php + +php: + - 5.3 + +script: "php artisan test:core" + +notifications: + irc: + - "irc.freenode.org#laravel" \ No newline at end of file diff --git a/application/language/ar/validation.php b/application/language/ar/validation.php index cb15db34..fb88f6d8 100644 --- a/application/language/ar/validation.php +++ b/application/language/ar/validation.php @@ -24,6 +24,7 @@ "alpha" => "القيمة :attribute يمكنها أن تحتوي على أحرف فقط.", "alpha_dash" => "القيمة :attribute يمكنها أن تحتوي على أحرف و أرقام و إشارة الناقص فقط.", "alpha_num" => "القيمة :attribute يمكنها أن تحتوي على أحرف و أرقام فقط.", + "array" => "The :attribute must have selected elements.", "before" => "القيمة :attribute يجب أن تكون قبل تاريخ :date.", "between" => array( "numeric" => "القيمة :attribute يجب أن تكون بين :min و :max.", @@ -31,6 +32,10 @@ "string" => "النص :attribute يجب أن يكون بطول من :min إلى :max حرف.", ), "confirmed" => "القيمة :attribute التأكيدية غير مطابقة.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "القيمتان :attribute و :other يجب أن تختلفان.", "email" => "القيمة :attribute تمثل بريد إلكتروني غير صحيح.", "exists" => "القيمة المختارة :attribute غير موجودة.", diff --git a/application/language/bg/validation.php b/application/language/bg/validation.php index 4e46f6ff..fe01d9be 100644 --- a/application/language/bg/validation.php +++ b/application/language/bg/validation.php @@ -24,6 +24,7 @@ "alpha" => "Полето :attribute трябва да съдържа само букви.", "alpha_dash" => "Полето :attribute трябва да съдържа само букви, цифри, долна черта и тире.", "alpha_num" => "Полето :attribute трябва да съдържа само букви и цифри.", + "array" => "The :attribute must have selected elements.", "before" => "Полето :attribute трябва да бъде дата преди :date.", "between" => array( "numeric" => "Полето :attribute трябва да бъде между :min и :max.", @@ -31,6 +32,10 @@ "string" => "Полето :attribute трябва да бъде между :min и :max знака.", ), "confirmed" => "Полето :attribute не е потвърдено.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "Полетата :attribute и :other трябва да са различни.", "email" => "Полето :attribute е с невалиден формат.", "exists" => "Избраната стойност на :attribute вече съществува.", diff --git a/application/language/de/validation.php b/application/language/de/validation.php index 87189410..80c3874e 100644 --- a/application/language/de/validation.php +++ b/application/language/de/validation.php @@ -24,6 +24,7 @@ "alpha" => ":attribute darf nur Buchstaben beinhalten.", "alpha_dash" => ":attribute sollte nur aus Buchstaben, Nummern und Bindestrichen bestehen.", "alpha_num" => ":attribute sollte nur aus Buchstaben und Nummern bestehen.", + "array" => "The :attribute must have selected elements.", "before" => ":attribute muss ein Datum vor dem :date sein.", "between" => array( "numeric" => ":attribute muss zwischen :min und :max liegen.", @@ -31,6 +32,10 @@ "string" => ":attribute muss zwischen :min und :max Zeichen lang sein.", ), "confirmed" => ":attribute stimmt nicht mit der Bestätigung überein.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => ":attribute und :other müssen verschieden sein.", "email" => ":attribute ist keine gültige Email-Adresse.", "exists" => "Der gewählte Wert für :attribute ist ungültig.", diff --git a/application/language/en/validation.php b/application/language/en/validation.php index aade5eda..e5116996 100644 --- a/application/language/en/validation.php +++ b/application/language/en/validation.php @@ -24,6 +24,7 @@ "alpha" => "The :attribute may only contain letters.", "alpha_dash" => "The :attribute may only contain letters, numbers, and dashes.", "alpha_num" => "The :attribute may only contain letters and numbers.", + "array" => "The :attribute must have selected elements.", "before" => "The :attribute must be a date before :date.", "between" => array( "numeric" => "The :attribute must be between :min - :max.", @@ -31,6 +32,10 @@ "string" => "The :attribute must be between :min - :max characters.", ), "confirmed" => "The :attribute confirmation does not match.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "The :attribute and :other must be different.", "email" => "The :attribute format is invalid.", "exists" => "The selected :attribute is invalid.", diff --git a/application/language/fr/validation.php b/application/language/fr/validation.php index f5810be8..bbc0408f 100644 --- a/application/language/fr/validation.php +++ b/application/language/fr/validation.php @@ -24,6 +24,7 @@ "alpha" => "Le champ :attribute ne doit contenir que des lettres.", "alpha_dash" => "Le champ :attribute ne doit contenir que des lettres, nombres et des tirets.", "alpha_num" => "Le champ :attribute ne doit contenir que des lettres et nombres.", + "array" => "The :attribute must have selected elements.", "before" => "Le champ :attribute doit être une date avant :date.", "between" => array( "numeric" => "Le champ :attribute doit être entre :min - :max.", @@ -31,6 +32,10 @@ "string" => "Le champ :attribute doit être entre :min - :max caractères.", ), "confirmed" => "Le champ :attribute confirmation est différent.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "Les champ :attribute et :other doivent être différents.", "email" => "Le format du champ :attribute est invalide.", "exists" => "Le champ sélectionné :attribute est invalide.", diff --git a/application/language/he/validation.php b/application/language/he/validation.php index f0059b6a..f714dd8d 100644 --- a/application/language/he/validation.php +++ b/application/language/he/validation.php @@ -27,6 +27,7 @@ "alpha" => "הערך :attribute יכול להכיל רק אותיות.", "alpha_dash" => "הערך :attribute יכול להכיל רק אותיות, מספרים ומקפים.", "alpha_num" => "הערך :attribute יכול להכיל רק אותיות ומספרים.", + "array" => "The :attribute must have selected elements.", "before" => "הערך :attribute חייב להכיל תאריך לפני :date.", "between" => array( "numeric" => "הערך :attribute חייב להיות בין :min ל-:max.", @@ -34,6 +35,10 @@ "string" => "הערך :attribute חייב להכיל בין :min ל-:max תווים.", ), "confirmed" => "הערכים של :attribute חייבים להיות זהים.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "הערכים של :attribute ו-:other חייבים להיות שונים.", "email" => "הערך :attribute חייב להכיל כתובת אימייל תקינה.", "exists" => "הערך :attribute לא קיים.", diff --git a/application/language/hu/validation.php b/application/language/hu/validation.php index 30b2a0ca..ee0e7145 100644 --- a/application/language/hu/validation.php +++ b/application/language/hu/validation.php @@ -24,6 +24,7 @@ "alpha" => "A(z) :attribute csak betűket tartalmazhat.", "alpha_dash" => "A(z) :attribute betűket, számokat és kötőjeleket tartalmazhat.", "alpha_num" => "A(z) :attribute csak betűket és számokat tartalmazhat.", + "array" => "The :attribute must have selected elements.", "before" => "A :attribute :date előtti dátum kell legyen.", "between" => array( "numeric" => "A(z) :attribute :min - :max közötti érték kell legyen.", @@ -31,6 +32,10 @@ "string" => "A(z) :attribute :min - :max karakterhossz között kell legyen", ), "confirmed" => "A(z) :attribute megerősítése nem egyezett meg.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "A(z) :attribute és :other különböző kell legyen.", "email" => "A(z) :attribute formátuma nem megfelelő.", "exists" => "A(z) választott :attribute nem megfelelő.", diff --git a/application/language/id/validation.php b/application/language/id/validation.php index 3eafa4cc..51d0178e 100644 --- a/application/language/id/validation.php +++ b/application/language/id/validation.php @@ -24,6 +24,7 @@ "alpha" => "Isian :attribute hanya boleh berisi huruf.", "alpha_dash" => "Isian :attribute hanya boleh berisi huruf, angka, dan strip.", "alpha_num" => "Isian :attribute hanya boleh berisi huruf dan angka.", + "array" => "The :attribute must have selected elements.", "before" => "Isian :attribute harus tanggal sebelum :date.", "between" => array( "numeric" => "Isian :attribute harus antara :min - :max.", @@ -31,6 +32,10 @@ "string" => "Isian :attribute harus antara :min - :max karakter.", ), "confirmed" => "Konfirmasi :attribute tidak cocok.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "Isian :attribute dan :other harus berbeda.", "email" => "Format isian :attribute tidak valid.", "exists" => "Isian :attribute yang dipilih tidak valid.", diff --git a/application/language/ja/validation.php b/application/language/ja/validation.php index 45e3208b..19d5a1b3 100644 --- a/application/language/ja/validation.php +++ b/application/language/ja/validation.php @@ -40,6 +40,7 @@ "alpha" => ":attributeはアルファベッドのみがご利用できます。", "alpha_dash" => ":attributeは英数字とダッシュ(-)及び下線(_)がご利用できます。", "alpha_num" => ":attributeは英数字がご利用できます。", + "array" => "The :attribute must have selected elements.", "before" => ":attributeには、:date以前の日付をご利用ください。", "between" => array( "numeric" => ":attributeは、:minから、:maxまでの数字をご指定ください。", @@ -47,6 +48,10 @@ "string" => ":attributeは、:min文字から:max文字の間でご指定ください。", ), "confirmed" => ":attributeと、確認フィールドとが、一致していません。", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => ":attributeと:otherには、異なった内容を指定してください。", "email" => ":attributeには正しいメールアドレスの形式をご指定ください。", "exists" => "選択された:attributeは正しくありません。", diff --git a/application/language/nl/validation.php b/application/language/nl/validation.php index a604e034..ac0c8416 100644 --- a/application/language/nl/validation.php +++ b/application/language/nl/validation.php @@ -15,6 +15,7 @@ "alpha" => "Het :attribute mag alleen letters bevatten.", "alpha_dash" => "Het :attribute mag alleen letters, nummers, onderstreep(_) en strepen(-) bevatten.", "alpha_num" => "Het :attribute mag alleen letters en nummers", + "array" => "The :attribute must have selected elements.", "before" => "Het :attribute moet een datum voor :date zijn.", "between" => array( "numeric" => "Het :attribute moet tussen :min en :max zijn.", @@ -22,6 +23,10 @@ "string" => "Het :attribute moet tussen :min en :max tekens zijn.", ), "confirmed" => "Het :attribute bevestiging komt niet overeen.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "Het :attribute en :other moeten verschillend zijn.", "email" => "Het :attribute formaat is ongeldig.", "exists" => "Het gekozen :attribute is al ingebruik.", diff --git a/application/language/pl/validation.php b/application/language/pl/validation.php index ead856b1..0ec36d57 100644 --- a/application/language/pl/validation.php +++ b/application/language/pl/validation.php @@ -2,98 +2,103 @@ return array( - /* - |-------------------------------------------------------------------------- - | Validation Language Lines - |-------------------------------------------------------------------------- - | - | The following language lines contain the default error messages used - | by the validator class. Some of the rules contain multiple versions, - | such as the size (max, min, between) rules. These versions are used - | for different input types such as strings and files. - | - | These language lines may be easily changed to provide custom error - | messages in your application. Error messages for custom validation - | rules may also be added to this file. - | - */ + /* + |-------------------------------------------------------------------------- + | Validation Language Lines + |-------------------------------------------------------------------------- + | + | The following language lines contain the default error messages used + | by the validator class. Some of the rules contain multiple versions, + | such as the size (max, min, between) rules. These versions are used + | for different input types such as strings and files. + | + | These language lines may be easily changed to provide custom error + | messages in your application. Error messages for custom validation + | rules may also be added to this file. + | + */ - "accepted" => ":attribute musi zostać zaakceptowane.", - "active_url" => ":attribute nie jest prawidłowym adresem URL.", - "after" => ":attribute musi zawierać datę, która jest po :date.", - "alpha" => ":attribute może zawierać jedynie litery.", - "alpha_dash" => ":attribute może zawierać jedynie litery, cyfry i myślniki.", - "alpha_num" => ":attribute może zawierać jedynie litery i cyfry.", - "before" => ":attribute musi zawierać datę, która jest przed :date.", - "between" => array( - "numeric" => ":ttribute musi mieścić się w granicach :min - :max.", - "file" => ":attribute musi mieć :min - :max kilobajtów.", - "string" => ":attribute musi mieć :min - :max znaków.", - ), - "confirmed" => "Potwierdzenie :attribute się nie zgadza.", - "different" => ":attribute i :other muszą się od siebie różnić.", - "email" => "The :attribute format is invalid.", - "exists" => "Zaznaczona opcja :attribute jest nieprawidłowa.", - "image" => ":attribute musi być obrazkiem.", - "in" => "Zaznaczona opcja :attribute jest nieprawidłowa.", - "integer" => ":attribute musi być liczbą całkowitą.", - "ip" => ":attribute musi być prawidłowym adresem IP.", - "match" => "Format :attribute jest nieprawidłowy.", - "max" => array( - "numeric" => ":attribute musi być poniżej :max.", - "file" => ":attribute musi mieć poniżej :max kilobajtów.", - "string" => ":attribute musi mieć poniżej :max znaków.", - ), - "mimes" => ":attribute musi być plikiem rodzaju :values.", - "min" => array( - "numeric" => ":attribute musi być co najmniej :min.", - "file" => "Plik :attribute musi mieć co najmniej :min kilobajtów.", - "string" => ":attribute musi mieć co najmniej :min znaków.", - ), - "not_in" => "Zaznaczona opcja :attribute jest nieprawidłowa.", - "numeric" => ":attribute musi być numeryczne.", - "required" => "Pole :attribute jest wymagane.", - "same" => ":attribute i :other muszą być takie same.", - "size" => array( - "numeric" => ":attribute musi mieć rozmiary :size.", - "file" => ":attribute musi mieć :size kilobajtów.", - "string" => ":attribute musi mieć :size znaków.", - ), - "unique" => ":attribute zostało już użyte.", - "url" => "Format pola :attribute jest nieprawidłowy.", + "accepted" => ":attribute musi zostać zaakceptowane.", + "active_url" => ":attribute nie jest prawidłowym adresem URL.", + "after" => ":attribute musi zawierać datę, która jest po :date.", + "alpha" => ":attribute może zawierać jedynie litery.", + "alpha_dash" => ":attribute może zawierać jedynie litery, cyfry i myślniki.", + "alpha_num" => ":attribute może zawierać jedynie litery i cyfry.", + "array" => "The :attribute must have selected elements.", + "before" => ":attribute musi zawierać datę, która jest przed :date.", + "between" => array( + "numeric" => ":attribute musi mieścić się w granicach :min - :max.", + "file" => ":attribute musi mieć :min - :max kilobajtów.", + "string" => ":attribute musi mieć :min - :max znaków.", + ), + "confirmed" => "Potwierdzenie :attribute się nie zgadza.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", + "different" => ":attribute i :other muszą się od siebie różnić.", + "email" => "The :attribute format is invalid.", + "exists" => "Zaznaczona opcja :attribute jest nieprawidłowa.", + "image" => ":attribute musi być obrazkiem.", + "in" => "Zaznaczona opcja :attribute jest nieprawidłowa.", + "integer" => ":attribute musi być liczbą całkowitą.", + "ip" => ":attribute musi być prawidłowym adresem IP.", + "match" => "Format :attribute jest nieprawidłowy.", + "max" => array( + "numeric" => ":attribute musi być poniżej :max.", + "file" => ":attribute musi mieć poniżej :max kilobajtów.", + "string" => ":attribute musi mieć poniżej :max znaków.", + ), + "mimes" => ":attribute musi być plikiem rodzaju :values.", + "min" => array( + "numeric" => ":attribute musi być co najmniej :min.", + "file" => "Plik :attribute musi mieć co najmniej :min kilobajtów.", + "string" => ":attribute musi mieć co najmniej :min znaków.", + ), + "not_in" => "Zaznaczona opcja :attribute jest nieprawidłowa.", + "numeric" => ":attribute musi być numeryczne.", + "required" => "Pole :attribute jest wymagane.", + "same" => ":attribute i :other muszą być takie same.", + "size" => array( + "numeric" => ":attribute musi mieć rozmiary :size.", + "file" => ":attribute musi mieć :size kilobajtów.", + "string" => ":attribute musi mieć :size znaków.", + ), + "unique" => ":attribute zostało już użyte.", + "url" => "Format pola :attribute jest nieprawidłowy.", - /* - |-------------------------------------------------------------------------- - | Custom Validation Language Lines - |-------------------------------------------------------------------------- - | - | Here you may specify custom validation messages for attributes using the - | convention "attribute_rule" to name the lines. This helps keep your - | custom validation clean and tidy. - | - | So, say you want to use a custom validation message when validating that - | the "email" attribute is unique. Just add "email_unique" to this array - | with your custom message. The Validator will handle the rest! - | - */ + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute_rule" to name the lines. This helps keep your + | custom validation clean and tidy. + | + | So, say you want to use a custom validation message when validating that + | the "email" attribute is unique. Just add "email_unique" to this array + | with your custom message. The Validator will handle the rest! + | + */ - 'custom' => array(), + 'custom' => array(), - /* - |-------------------------------------------------------------------------- - | Validation Attributes - |-------------------------------------------------------------------------- - | - | The following language lines are used to swap attribute place-holders - | with something more reader friendly such as "E-Mail Address" instead - | of "email". Your users will thank you. - | - | The Validator class will automatically search this array of lines it - | is attempting to replace the :attribute place-holder in messages. - | It's pretty slick. We think you'll like it. - | - */ + /* + |-------------------------------------------------------------------------- + | Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as "E-Mail Address" instead + | of "email". Your users will thank you. + | + | The Validator class will automatically search this array of lines it + | is attempting to replace the :attribute place-holder in messages. + | It's pretty slick. We think you'll like it. + | + */ - 'attributes' => array(), + 'attributes' => array(), ); \ No newline at end of file diff --git a/application/language/ru/validation.php b/application/language/ru/validation.php index e8ee3a13..8fd15f5c 100644 --- a/application/language/ru/validation.php +++ b/application/language/ru/validation.php @@ -24,6 +24,7 @@ "alpha" => "Поле :attribute может содержать только буквы.", "alpha_dash" => "Поле :attribute может содержать только буквы, цифры и тире.", "alpha_num" => "Поле :attribute может содержать только буквы и цифры.", + "array" => "The :attribute must have selected elements.", "before" => "Поле :attribute должно быть датой перед :date.", "between" => array( "numeric" => "Поле :attribute должно быть между :min и :max.", @@ -31,6 +32,10 @@ "string" => "Поле :attribute должно быть от :min до :max символов.", ), "confirmed" => "Поле :attribute не совпадает с подтверждением.", + "count" => "The :attribute must have exactly :count selected elements.", + "countbetween" => "The :attribute must have between :min and :max selected elements.", + "countmax" => "The :attribute must have less than :max selected elements.", + "countmin" => "The :attribute must have at least :min selected elements.", "different" => "Поля :attribute и :other должны различаться.", "email" => "Поле :attribute имеет неверный формат.", "exists" => "Выбранное значение для :attribute уже существует.", diff --git a/application/language/tr/pagination.php b/application/language/tr/pagination.php new file mode 100644 index 00000000..fce594d6 --- /dev/null +++ b/application/language/tr/pagination.php @@ -0,0 +1,28 @@ + + * @link http://sinaneldem.com.tr + */ + +return array( + + /* + |-------------------------------------------------------------------------- + | Pagination Language Lines + |-------------------------------------------------------------------------- + | + | The following language lines are used by the paginator library to build + | the pagination links. You're free to change them to anything you want. + | If you come up with something more exciting, let us know. + | + */ + + 'previous' => '« Önceki', + 'next' => 'Sonraki »', + +); \ No newline at end of file diff --git a/application/language/tr/validation.php b/application/language/tr/validation.php new file mode 100644 index 00000000..18cb0458 --- /dev/null +++ b/application/language/tr/validation.php @@ -0,0 +1,108 @@ + + * @link http://sinaneldem.com.tr + */ + +return array( + + /* + |-------------------------------------------------------------------------- + | Validation Language Lines + |-------------------------------------------------------------------------- + | + | The following language lines contain the default error messages used + | by the validator class. Some of the rules contain multiple versions, + | such as the size (max, min, between) rules. These versions are used + | for different input types such as strings and files. + | + | These language lines may be easily changed to provide custom error + | messages in your application. Error messages for custom validation + | rules may also be added to this file. + | + */ + + "accepted" => ":attribute kabul edilmelidir.", + "active_url" => ":attribute geçerli bir URL olmalıdır.", + "after" => ":attribute şundan daha eski bir tarih olmalıdır :date.", + "alpha" => ":attribute sadece harflerden oluşmalıdır.", + "alpha_dash" => ":attribute sadece harfler, rakamlar ve tirelerden oluşmalıdır.", + "alpha_num" => ":attribute sadece harfler ve rakamlar içermelidir.", + "before" => ":attribute şundan daha önceki bir tarih olmalıdır :date.", + "between" => array( + "numeric" => ":attribute :min - :max arasında olmalıdır.", + "file" => ":attribute :min - :max arasındaki kilobyte değeri olmalıdır.", + "string" => ":attribute :min - :max arasında karakterden oluşmalıdır.", + ), + "confirmed" => ":attribute onayı eşleşmiyor.", + "different" => ":attribute ile :other birbirinden farklı olmalıdır.", + "email" => ":attribute biçimi geçersiz.", + "exists" => "Seçili :attribute geçersiz.", + "image" => ":attribute resim dosyası olmalıdır.", + "in" => "selected :attribute geçersiz.", + "integer" => ":attribute rakam olmalıdır.", + "ip" => ":attribute geçerli bir IP adresi olmalıdır.", + "match" => ":attribute biçimi geçersiz.", + "max" => array( + "numeric" => ":attribute şundan küçük olmalıdır :max.", + "file" => ":attribute şundan küçük olmalıdır :max kilobyte.", + "string" => ":attribute şundan küçük olmalıdır :max karakter.", + ), + "mimes" => ":attribute dosya biçimi :values olmalıdır.", + "min" => array( + "numeric" => ":attribute en az :min olmalıdır.", + "file" => ":attribute en az :min kilobyte olmalıdır.", + "string" => ":attribute en az :min karakter olmalıdır.", + ), + "not_in" => "Seçili :attribute geçersiz.", + "numeric" => ":attribute rakam olmalıdır.", + "required" => ":attribute alanı gereklidir.", + "same" => ":attribute ile :other eşleşmelidir.", + "size" => array( + "numeric" => ":attribute :size olmalıdır.", + "file" => ":attribute :size kilobyte olmalıdır.", + "string" => ":attribute :size karakter olmalıdır.", + ), + "unique" => ":attribute daha önceden kayıt edilmiş.", + "url" => ":attribute biçimi geçersiz.", + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute_rule" to name the lines. This helps keep your + | custom validation clean and tidy. + | + | So, say you want to use a custom validation message when validating that + | the "email" attribute is unique. Just add "email_unique" to this array + | with your custom message. The Validator will handle the rest! + | + */ + + 'custom' => array(), + + /* + |-------------------------------------------------------------------------- + | Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as "E-Mail Address" instead + | of "email". Your users will thank you. + | + | The Validator class will automatically search this array of lines it + | is attempting to replace the :attribute place-holder in messages. + | It's pretty slick. We think you'll like it. + | + */ + + 'attributes' => array(), + +); \ No newline at end of file diff --git a/laravel/bundle.php b/laravel/bundle.php index ea057475..1ef4d8c0 100644 --- a/laravel/bundle.php +++ b/laravel/bundle.php @@ -461,4 +461,16 @@ public static function names() return array_keys(static::$bundles); } + /** + * Expand given bundle path of form "[bundle::]path/...". + * + * @param string $path + * @return string + */ + public static function expand($path) + { + list($bundle, $element) = static::parse($path); + return static::path($bundle).$element; + } + } \ No newline at end of file diff --git a/laravel/cli/tasks/test/phpunit.php b/laravel/cli/tasks/test/phpunit.php index 67644838..32eadd58 100644 --- a/laravel/cli/tasks/test/phpunit.php +++ b/laravel/cli/tasks/test/phpunit.php @@ -1,12 +1,4 @@ - * @link http://laravel.com - */ // -------------------------------------------------------------- // Define the directory separator for the environment. @@ -18,22 +10,6 @@ // -------------------------------------------------------------- require 'paths.php'; -// -------------------------------------------------------------- -// Override the application paths when testing the core. -// -------------------------------------------------------------- -$config = file_get_contents('phpunit.xml'); - -if (strpos($config, 'laravel-tests') !== false) -{ - $path = path('bundle').'laravel-tests'.DS; - - set_path('app', $path.'application'.DS); - - set_path('bundle', $path.'bundles'.DS); - - set_path('storage', $path.'storage'.DS); -} - // -------------------------------------------------------------- // Bootstrap the Laravel core. // -------------------------------------------------------------- diff --git a/laravel/cli/tasks/test/runner.php b/laravel/cli/tasks/test/runner.php index 250450d1..b34e5225 100644 --- a/laravel/cli/tasks/test/runner.php +++ b/laravel/cli/tasks/test/runner.php @@ -7,6 +7,15 @@ class Runner extends Task { + /** + * The base directory where the tests will be executed. + * + * A phpunit.xml should also be stored in that directory. + * + * @var string + */ + protected $base_path; + /** * Run all of the unit tests for the application. * @@ -27,17 +36,8 @@ public function run($bundles = array()) */ public function core() { - if ( ! is_dir(path('bundle').'laravel-tests')) - { - throw new \Exception("The bundle [laravel-tests] has not been installed!"); - } - - // When testing the Laravel core, we will just stub the path directly - // so the test bundle is not required to be registered in the bundle - // configuration, as it is kind of a unique bundle. - $this->stub(path('bundle').'laravel-tests/cases'); - - $path = path('bundle').'laravel-tests/'; + $this->base_path = path('sys').'tests'.DS; + $this->stub(path('sys').'tests'.DS.'cases'); $this->test(); } @@ -55,6 +55,8 @@ public function bundle($bundles = array()) $bundles = Bundle::names(); } + $this->base_path = path('sys').'cli'.DS.'tasks'.DS.'test'.DS; + foreach ($bundles as $bundle) { // To run PHPUnit for the application, bundles, and the framework @@ -78,17 +80,20 @@ public function bundle($bundles = array()) protected function test() { // We'll simply fire off PHPUnit with the configuration switch - // pointing to our temporary configuration file. This allows + // pointing to our requested configuration file. This allows // us to flexibly run tests for any setup. - $path = path('base').'phpunit.xml'; + $path = 'phpunit.xml'; // fix the spaced directories problem when using the command line // strings with spaces inside should be wrapped in quotes. $path = escapeshellarg($path); - passthru('phpunit --configuration '.$path); + passthru('phpunit --configuration '.$path, $status); @unlink($path); + + // Pass through the exit status + exit($status); } /** @@ -108,7 +113,7 @@ protected function stub($directory) // locations depending on what the developer wants to test. foreach (array('bootstrap', 'directory') as $item) { - $stub = $this->{"swap_{$item}"}($stub, $path, $directory); + $stub = $this->{"swap_{$item}"}($stub, $directory); } File::put(path('base').'phpunit.xml', $stub); @@ -118,24 +123,22 @@ protected function stub($directory) * Swap the bootstrap file in the stub. * * @param string $stub - * @param string $path * @param string $directory * @return string */ - protected function swap_bootstrap($stub, $path, $directory) + protected function swap_bootstrap($stub, $directory) { - return str_replace('{{bootstrap}}', $path.'phpunit.php', $stub); + return str_replace('{{bootstrap}}', $this->base_path.'phpunit.php', $stub); } /** * Swap the directory in the stub. * * @param string $stub - * @param string $path * @param string $directory * @return string */ - protected function swap_directory($stub, $path, $directory) + protected function swap_directory($stub, $directory) { return str_replace('{{directory}}', $directory, $stub); } diff --git a/laravel/core.php b/laravel/core.php index b19d924d..0f33ccfd 100644 --- a/laravel/core.php +++ b/laravel/core.php @@ -17,6 +17,20 @@ define('DEFAULT_BUNDLE', 'application'); define('MB_STRING', (int) function_exists('mb_get_info')); +/* +|-------------------------------------------------------------------------- +| Start Output Buffering +|-------------------------------------------------------------------------- +| +| Output buffering allows us to capture all output at any time, so that we +| can discard it or treat it accordingly. An example of this is if you have +| echoed a string, but want to return a Redirect object. Because Symfony +| only checks if headers have been sent, your redirect just silently fails. +| +*/ + +ob_start('mb_output_handler'); + /* |-------------------------------------------------------------------------- | Require Core Classes diff --git a/laravel/database/eloquent/query.php b/laravel/database/eloquent/query.php index fa739d55..3aee79c9 100644 --- a/laravel/database/eloquent/query.php +++ b/laravel/database/eloquent/query.php @@ -38,7 +38,7 @@ class Query { ); /** - * Create a new query instance for a model. + * Creat a new query instance for a model. * * @param Model $model * @return void @@ -118,7 +118,7 @@ public function hydrate($model, $results) $new = new $class(array(), true); // We need to set the attributes manually in case the accessible property is - // set on the array which will prevent the mass assignment of attributes if + // set on the array which will prevent the mass assignemnt of attributes if // we were to pass them in using the constructor or fill methods. $new->fill_raw($result); @@ -141,7 +141,7 @@ public function hydrate($model, $results) } } - // The many to many relationships may have pivot table columns on them + // The many to many relationships may have pivot table column on them // so we will call the "clean" method on the relationship to remove // any pivot columns that are on the model. if ($this instanceof Relationships\Has_Many_And_Belongs_To) @@ -199,7 +199,7 @@ protected function nested_includes($relationship) foreach ($this->model_includes() as $include => $constraints) { // To get the nested includes, we want to find any includes that begin - // the relationship with a dot, then we will strip off the leading + // the relationship and a dot, then we will strip off the leading // nesting indicator and set the include in the array. if (starts_with($include, $relationship.'.')) { @@ -217,23 +217,22 @@ protected function nested_includes($relationship) */ protected function model_includes() { - $relationships = array_keys($this->model->includes); - $implicits = array(); + $includes = array(); - foreach ($relationships as $relationship) + foreach ($this->model->includes as $relationship => $constraints) { - $parts = explode('.', $relationship); - - $prefix = ''; - foreach ($parts as $part) + // When eager loading relationships, constraints may be set on the eager + // load definition; however, is none are set, we need to swap the key + // and the value of the array since there are no constraints. + if (is_numeric($relationship)) { - $implicits[$prefix.$part] = NULL; - $prefix .= $part.'.'; + list($relationship, $constraints) = array($constraints, null); } + + $includes[$relationship] = $constraints; } - // Add all implicit includes to the explicit ones - return $this->model->includes + $implicits; + return $includes; } /** @@ -278,4 +277,4 @@ public function __call($method, $parameters) return $this; } -} +} \ No newline at end of file diff --git a/laravel/database/query.php b/laravel/database/query.php index c77ad65b..83c92b83 100644 --- a/laravel/database/query.php +++ b/laravel/database/query.php @@ -2,7 +2,7 @@ use Closure; use Laravel\Database; -use Paginator; +use Laravel\Paginator; use Laravel\Database\Query\Grammars\Postgres; use Laravel\Database\Query\Grammars\SQLServer; @@ -140,7 +140,7 @@ public function distinct() */ public function select($columns = array('*')) { - $this->selects = is_array($columns) ? $columns : array($columns); + $this->selects = (array) $columns; return $this; } @@ -158,7 +158,7 @@ public function join($table, $column1, $operator = null, $column2 = null, $type { // If the "column" is really an instance of a Closure, the developer is // trying to create a join with a complex "ON" clause. So, we will add - // the join, and then call the Closure with the join. + // the join, and then call the Closure with the join/ if ($column1 instanceof Closure) { $this->joins[] = new Query\Join($type, $table); @@ -168,7 +168,7 @@ public function join($table, $column1, $operator = null, $column2 = null, $type // If the column is just a string, we can assume that the join just // has a simple on clause, and we'll create the join instance and - // add the clause automatically for the developer. + // add the clause automatically for the develoepr. else { $join = new Query\Join($type, $table); @@ -283,7 +283,7 @@ public function or_where($column, $operator = null, $value = null) */ public function or_where_id($value) { - return $this->or_where('id', '=', $value); + return $this->or_where('id', '=', $value); } /** @@ -395,7 +395,7 @@ public function or_where_not_null($column) } /** - * Add nested constraints to the query. + * Add a nested where condition to the query. * * @param Closure $callback * @param string $connector @@ -403,7 +403,24 @@ public function or_where_not_null($column) */ public function where_nested($callback, $connector = 'AND') { - call_user_func($callback, $this); + $type = 'where_nested'; + + // To handle a nested where statement, we will actually instantiate a new + // Query instance and run the callback over that instance, which will + // allow the developer to have a fresh query instance + $query = new Query($this->connection, $this->grammar, $this->from); + + call_user_func($callback, $query); + + // Once the callback has been run on the query, we will store the nested + // query instance on the where clause array so that it's passed to the + // query's query grammar instance when building. + if ($query->wheres !== null) + { + $this->wheres[] = compact('type', 'query', 'connector'); + } + + $this->bindings = array_merge($this->bindings, $query->bindings); return $this; } @@ -436,7 +453,7 @@ private function dynamic_where($method, $parameters) foreach ($segments as $segment) { - // If the segment is not a boolean connector, we can assume it is + // If the segment is not a boolean connector, we can assume it it is // a column name, and we'll add it to the query as a new constraint // of the query's where clause and keep iterating the segments. if ($segment != '_and_' and $segment != '_or_') @@ -475,7 +492,6 @@ public function group_by($column) * @param string $column * @param string $operator * @param mixed $value - * @return Query */ public function having($column, $operator, $value) { @@ -660,7 +676,7 @@ public function get($columns = array('*')) public function aggregate($aggregator, $columns) { // We'll set the aggregate value so the grammar does not try to compile - // a SELECT clause on the query. If an aggregator is present, its own + // a SELECT clause on the query. If an aggregator is present, it's own // grammar function will be used to build the SQL syntax. $this->aggregate = compact('aggregator', 'columns'); @@ -687,7 +703,7 @@ public function paginate($per_page = 20, $columns = array('*')) { // Because some database engines may throw errors if we leave orderings // on the query when retrieving the total number of records, we'll drop - // all of the orderings and put them back on the query. + // all of the ordreings and put them back on the query. list($orderings, $this->orderings) = array($this->orderings, null); $total = $this->count(reset($columns)); @@ -714,12 +730,12 @@ public function insert($values) { // Force every insert to be treated like a batch insert to make creating // the binding array simpler since we can just spin through the inserted - // rows as if there was more than one every time. + // rows as if there/ was more than one every time. if ( ! is_array(reset($values))) $values = array($values); $bindings = array(); - // We need to merge the insert values into the array of the query + // We need to merge the the insert values into the array of the query // bindings so that they will be bound to the PDO statement when it // is executed by the database connection. foreach ($values as $value) @@ -820,7 +836,7 @@ public function update($values) /** * Execute the query as a DELETE statement. * - * Optionally, an ID may be passed to the method to delete a specific row. + * Optionally, an ID may be passed to the method do delete a specific row. * * @param int $id * @return int @@ -837,7 +853,7 @@ public function delete($id = null) $sql = $this->grammar->delete($this); - return $this->connection->query($sql, $this->bindings); + return $this->connection->query($sql, $this->bindings); } /** @@ -853,7 +869,7 @@ public function __call($method, $parameters) } // All of the aggregate methods are handled by a single method, so we'll - // catch them all here and then pass them off to the aggregate method + // catch them all here and then pass them off to the agregate method // instead of creating methods for each one of them. if (in_array($method, array('count', 'min', 'max', 'avg', 'sum'))) { diff --git a/laravel/database/schema/grammars/mysql.php b/laravel/database/schema/grammars/mysql.php index efecc675..87d83a4e 100644 --- a/laravel/database/schema/grammars/mysql.php +++ b/laravel/database/schema/grammars/mysql.php @@ -383,7 +383,7 @@ protected function type_decimal(Fluent $column) */ protected function type_boolean(Fluent $column) { - return 'TINYINT'; + return 'TINYINT(1)'; } /** diff --git a/laravel/documentation/changes.md b/laravel/documentation/changes.md index 85608740..5ff87c38 100644 --- a/laravel/documentation/changes.md +++ b/laravel/documentation/changes.md @@ -2,6 +2,8 @@ # Laravel Change Log ## Contents +- [Laravel 3.2.5](#3.2.5) +- [Upgrading From 3.2.4](#upgrade-3.2.5) - [Laravel 3.2.4](#3.2.4) - [Upgrading From 3.2.3](#upgrade-3.2.4) - [Laravel 3.2.3](#3.2.3) @@ -33,6 +35,15 @@ ## Contents - [Laravel 3.1](#3.1) - [Upgrading From 3.0](#upgrade-3.1) + + +- Revert nested where code back to 3.2.3 tag. + + +## Upgrading From 3.2.4 + +- Replace the **laravel** folder. + ## Laravel 3.2.4 diff --git a/laravel/profiling/profiler.js b/laravel/profiling/profiler.js index ab73ad8e..8fc9fe3e 100755 --- a/laravel/profiling/profiler.js +++ b/laravel/profiling/profiler.js @@ -6,20 +6,20 @@ var anbu = { // the DOM every time they are used. el: { - main: $('.anbu'), - close: $('#anbu-close'), - zoom: $('#anbu-zoom'), - hide: $('#anbu-hide'), - show: $('#anbu-show'), - tab_pane: $('.anbu-tab-pane'), - hidden_tab_pane: $('.anbu-tab-pane:visible'), - tab: $('.anbu-tab'), - tabs: $('.anbu-tabs'), - tab_links: $('.anbu-tabs a'), - window: $('.anbu-window'), - closed_tabs: $('#anbu-closed-tabs'), - open_tabs: $('#anbu-open-tabs'), - content_area: $('.anbu-content-area') + main: jQuery('.anbu'), + close: jQuery('#anbu-close'), + zoom: jQuery('#anbu-zoom'), + hide: jQuery('#anbu-hide'), + show: jQuery('#anbu-show'), + tab_pane: jQuery('.anbu-tab-pane'), + hidden_tab_pane: jQuery('.anbu-tab-pane:visible'), + tab: jQuery('.anbu-tab'), + tabs: jQuery('.anbu-tabs'), + tab_links: jQuery('.anbu-tabs a'), + window: jQuery('.anbu-window'), + closed_tabs: jQuery('#anbu-closed-tabs'), + open_tabs: jQuery('#anbu-open-tabs'), + content_area: jQuery('.anbu-content-area') }, // CLASS ATTRIBUTES @@ -30,7 +30,7 @@ var anbu = { is_zoomed: false, // initial height of content area - small_height: $('.anbu-content-area').height(), + small_height: jQuery('.anbu-content-area').height(), // the name of the active tab css active_tab: 'anbu-active-tab', @@ -76,7 +76,7 @@ var anbu = { event.preventDefault(); }); anbu.el.tab.click(function(event) { - anbu.clicked_tab($(this)); + anbu.clicked_tab(jQuery(this)); event.preventDefault(); }); @@ -104,8 +104,8 @@ var anbu = { open_window: function(tab) { // can't directly assign this line, but it works - $('.anbu-tab-pane:visible').fadeOut(200); - $('.' + tab.attr(anbu.tab_data)).delay(220).fadeIn(300); + jQuery('.anbu-tab-pane:visible').fadeOut(200); + jQuery('.' + tab.attr(anbu.tab_data)).delay(220).fadeIn(300); anbu.el.tab_links.removeClass(anbu.active_tab); tab.addClass(anbu.active_tab); anbu.el.window.slideDown(300); @@ -178,7 +178,7 @@ var anbu = { anbu.is_zoomed = false; } else { // the 6px is padding on the top of the window - height = ($(window).height() - anbu.el.tabs.height() - 6) + 'px'; + height = (jQuery(window).height() - anbu.el.tabs.height() - 6) + 'px'; anbu.is_zoomed = true; } diff --git a/laravel/redirect.php b/laravel/redirect.php index 1042f7ec..874cb172 100644 --- a/laravel/redirect.php +++ b/laravel/redirect.php @@ -165,4 +165,23 @@ public function with_errors($container) return $this->with('errors', $errors); } + /** + * Send the headers and content of the response to the browser. + * + * @return void + */ + public function send() + { + // Dump all output buffering, this ensures + // that symphony will send our redirect headers + // properly if we've outputted any content from + // within Laravel. + while (ob_get_level() > 0) + { + ob_end_clean(); + } + + return parent::send(); + } + } \ No newline at end of file diff --git a/laravel/routing/controller.php b/laravel/routing/controller.php index 0a780bbc..e81d6b5f 100644 --- a/laravel/routing/controller.php +++ b/laravel/routing/controller.php @@ -179,6 +179,8 @@ protected static function references(&$destination, &$parameters) // controllers with much less code than would be usual. foreach ($parameters as $key => $value) { + if ( ! is_string($value)) continue; + $search = '(:'.($key + 1).')'; $destination = str_replace($search, $value, $destination, $count); diff --git a/laravel/tests/application/bundles.php b/laravel/tests/application/bundles.php new file mode 100644 index 00000000..1013f0cf --- /dev/null +++ b/laravel/tests/application/bundles.php @@ -0,0 +1,36 @@ + array( +| 'location' => 'admin', +| 'handles' => 'admin', +| ), +| +| Note that the "location" is relative to the "bundles" directory. +| Now the bundle will be recognized by Laravel and will be able +| to respond to requests beginning with "admin"! +| +| Have a bundle that lives in the root of the bundle directory +| and doesn't respond to any requests? Just add the bundle +| name to the array and we'll take care of the rest. +| +*/ + +return array('dashboard' => array('handles' => 'dashboard'), 'dummy'); \ No newline at end of file diff --git a/laravel/tests/application/config/application.php b/laravel/tests/application/config/application.php new file mode 100644 index 00000000..596baa24 --- /dev/null +++ b/laravel/tests/application/config/application.php @@ -0,0 +1,158 @@ + '', + + /* + |-------------------------------------------------------------------------- + | Application Index + |-------------------------------------------------------------------------- + | + | If you are including the "index.php" in your URLs, you can ignore this. + | + | However, if you are using mod_rewrite to get cleaner URLs, just set + | this option to an empty string and we'll take care of the rest. + | + */ + + 'index' => 'index.php', + + /* + |-------------------------------------------------------------------------- + | Application Key + |-------------------------------------------------------------------------- + | + | This key is used by the encryption and cookie classes to generate secure + | encrypted strings and hashes. It is extremely important that this key + | remain secret and should not be shared with anyone. Make it about 32 + | characters of random gibberish. + | + */ + + 'key' => '', + + /* + |-------------------------------------------------------------------------- + | Application Character Encoding + |-------------------------------------------------------------------------- + | + | The default character encoding used by your application. This encoding + | will be used by the Str, Text, Form, and any other classes that need + | to know what type of encoding to use for your awesome application. + | + */ + + 'encoding' => 'UTF-8', + + /* + |-------------------------------------------------------------------------- + | Application Language + |-------------------------------------------------------------------------- + | + | The default language of your application. This language will be used by + | Lang library as the default language when doing string localization. + | + */ + + 'language' => 'en', + + /* + |-------------------------------------------------------------------------- + | SSL Link Generation + |-------------------------------------------------------------------------- + | + | Many sites use SSL to protect their users data. However, you may not + | always be able to use SSL on your development machine, meaning all HTTPS + | will be broken during development. + | + | For this reason, you may wish to disable the generation of HTTPS links + | throughout your application. This option does just that. All attempts to + | generate HTTPS links will generate regular HTTP links instead. + | + */ + + 'ssl' => true, + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | The default timezone of your application. This timezone will be used when + | Laravel needs a date, such as when writing to a log file or travelling + | to a distant star at warp speed. + | + */ + + 'timezone' => 'UTC', + + /* + |-------------------------------------------------------------------------- + | Class Aliases + |-------------------------------------------------------------------------- + | + | Here, you can specify any class aliases that you would like registered + | when Laravel loads. Aliases are lazy-loaded, so add as many as you want. + | + | Aliases make it more convenient to use namespaced classes. Instead of + | referring to the class using its full namespace, you may simply use + | the alias defined here. + | + | We have already aliased common Laravel classes to make your life easier. + | + */ + + 'aliases' => array( + 'Auth' => 'Laravel\\Auth', + 'Asset' => 'Laravel\\Asset', + 'Autoloader' => 'Laravel\\Autoloader', + 'Blade' => 'Laravel\\Blade', + 'Bundle' => 'Laravel\\Bundle', + 'Cache' => 'Laravel\\Cache', + 'Config' => 'Laravel\\Config', + 'Controller' => 'Laravel\\Routing\\Controller', + 'Cookie' => 'Laravel\\Cookie', + 'Crypter' => 'Laravel\\Crypter', + 'DB' => 'Laravel\\Database', + 'Event' => 'Laravel\\Event', + 'File' => 'Laravel\\File', + 'Filter' => 'Laravel\\Routing\\Filter', + 'Form' => 'Laravel\\Form', + 'Hash' => 'Laravel\\Hash', + 'HTML' => 'Laravel\\HTML', + 'Input' => 'Laravel\\Input', + 'IoC' => 'Laravel\\IoC', + 'Lang' => 'Laravel\\Lang', + 'Log' => 'Laravel\\Log', + 'Memcached' => 'Laravel\\Memcached', + 'Paginator' => 'Laravel\\Paginator', + 'URL' => 'Laravel\\URL', + 'Redirect' => 'Laravel\\Redirect', + 'Redis' => 'Laravel\\Redis', + 'Request' => 'Laravel\\Request', + 'Response' => 'Laravel\\Response', + 'Route' => 'Laravel\\Routing\\Route', + 'Router' => 'Laravel\\Routing\\Router', + 'Schema' => 'Laravel\\Database\\Schema', + 'Section' => 'Laravel\\Section', + 'Session' => 'Laravel\\Session', + 'Str' => 'Laravel\\Str', + 'Task' => 'Laravel\\CLI\\Tasks\\Task', + 'URI' => 'Laravel\\URI', + 'Validator' => 'Laravel\\Validator', + 'View' => 'Laravel\\View', + ), + +); diff --git a/laravel/tests/application/config/auth.php b/laravel/tests/application/config/auth.php new file mode 100644 index 00000000..d715f063 --- /dev/null +++ b/laravel/tests/application/config/auth.php @@ -0,0 +1,73 @@ + 'fluent', + + /* + |-------------------------------------------------------------------------- + | Authentication Username + |-------------------------------------------------------------------------- + | + | Here you may specify the database column that should be considered the + | "username" for your users. Typically, this will either be "username" + | or "email". Of course, you're free to change the value to anything. + | + */ + + 'username' => 'username', + + /* + |-------------------------------------------------------------------------- + | Authentication Password + |-------------------------------------------------------------------------- + | + | Here you may specify the database column that should be considered the + | "password" for your users. Typically, this will be "password" but, + | again, you're free to change the value to anything you see fit. + | + */ + + 'password' => 'password', + + /* + |-------------------------------------------------------------------------- + | Authentication Model + |-------------------------------------------------------------------------- + | + | When using the "eloquent" authentication driver, you may specify the + | model that should be considered the "User" model. This model will + | be used to authenticate and load the users of your application. + | + */ + + 'model' => 'User', + + /* + |-------------------------------------------------------------------------- + | Authentication Table + |-------------------------------------------------------------------------- + | + | When using the "fluent" authentication driver, the database table used + | to load users may be specified here. This table will be used in by + | the fluent query builder to authenticate and load your users. + | + */ + + 'table' => 'users', + +); diff --git a/laravel/tests/application/config/cache.php b/laravel/tests/application/config/cache.php new file mode 100644 index 00000000..73fd4c9c --- /dev/null +++ b/laravel/tests/application/config/cache.php @@ -0,0 +1,71 @@ + 'file', + + /* + |-------------------------------------------------------------------------- + | Cache Key + |-------------------------------------------------------------------------- + | + | This key will be prepended to item keys stored using Memcached and APC + | to prevent collisions with other applications on the server. Since the + | memory based stores could be shared by other applications, we need to + | be polite and use a prefix to uniquely identifier our items. + | + */ + + 'key' => 'laravel', + + /* + |-------------------------------------------------------------------------- + | Cache Database + |-------------------------------------------------------------------------- + | + | When using the database cache driver, this database table will be used + | to store the cached item. You may also add a "connection" option to + | the array to specify which database connection should be used. + | + */ + + 'database' => array('table' => 'laravel_cache'), + + /* + |-------------------------------------------------------------------------- + | Memcached Servers + |-------------------------------------------------------------------------- + | + | The Memcached servers used by your application. Memcached is a free and + | open source, high-performance, distributed memory caching system. It is + | generic in nature but intended for use in speeding up web applications + | by alleviating database load. + | + | For more information, check out: http://memcached.org + | + */ + + 'memcached' => array( + + array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), + + ), + +); \ No newline at end of file diff --git a/laravel/tests/application/config/database.php b/laravel/tests/application/config/database.php new file mode 100644 index 00000000..b7b9fd96 --- /dev/null +++ b/laravel/tests/application/config/database.php @@ -0,0 +1,108 @@ + 'sqlite', + + /* + |-------------------------------------------------------------------------- + | PDO Fetch Style + |-------------------------------------------------------------------------- + | + | By default, database results will be returned as instances of the PHP + | stdClass object; however, you may wish to retrieve records as arrays + | instead of objects. Here you can control the PDO fetch style of the + | database queries run by your application. + | + */ + + 'fetch' => PDO::FETCH_CLASS, + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | All of the database connections used by your application. Many of your + | applications will no doubt only use one connection; however, you have + | the freedom to specify as many connections as you can handle. + | + | All database work in Laravel is done through the PHP's PDO facilities, + | so make sure you have the PDO drivers for your particlar database of + | choice installed on your machine. + | + | Drivers: 'mysql', 'pgsql', 'sqlsrv', 'sqlite'. + | + */ + + 'connections' => array( + + 'sqlite' => array( + 'driver' => 'sqlite', + 'database' => 'application', + 'prefix' => '', + ), + + 'mysql' => array( + 'driver' => 'mysql', + 'host' => 'localhost', + 'database' => 'database', + 'username' => 'root', + 'password' => 'password', + 'charset' => 'utf8', + 'prefix' => '', + ), + + 'pgsql' => array( + 'driver' => 'pgsql', + 'host' => 'localhost', + 'database' => 'database', + 'username' => 'root', + 'password' => 'password', + 'charset' => 'utf8', + 'prefix' => '', + ), + + 'sqlsrv' => array( + 'driver' => 'sqlsrv', + 'host' => 'localhost', + 'database' => 'database', + 'username' => 'root', + 'password' => 'password', + 'prefix' => '', + ), + + ), + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store. However, it + | provides a richer set of commands than a typical key-value store such as + | APC or memcached. All the cool kids are using it. + | + | To get the scoop on Redis, check out: http://redis.io + | + */ + + 'redis' => array( + + 'default' => array('host' => '127.0.0.1', 'port' => 6379), + + ), + +); \ No newline at end of file diff --git a/laravel/tests/application/config/error.php b/laravel/tests/application/config/error.php new file mode 100644 index 00000000..87db9665 --- /dev/null +++ b/laravel/tests/application/config/error.php @@ -0,0 +1,69 @@ + array(E_NOTICE, E_USER_NOTICE, E_DEPRECATED, E_USER_DEPRECATED), + + /* + |-------------------------------------------------------------------------- + | Error Detail + |-------------------------------------------------------------------------- + | + | Detailed error messages contain information about the file in which an + | error occurs, as well as a PHP stack trace containing the call stack. + | You'll want them when you're trying to debug your application. + | + | If your application is in production, you'll want to turn off the error + | details for enhanced security and user experience since the exception + | stack trace could contain sensitive information. + | + */ + + 'detail' => true, + + /* + |-------------------------------------------------------------------------- + | Error Logging + |-------------------------------------------------------------------------- + | + | When error logging is enabled, the "logger" Closure defined below will + | be called for every error in your application. You are free to log the + | errors however you want. Enjoy the flexibility. + | + */ + + 'log' => false, + + /* + |-------------------------------------------------------------------------- + | Error Logger + |-------------------------------------------------------------------------- + | + | Because of the various ways of managing error logging, you get complete + | flexibility to manage error logging as you see fit. This function will + | be called anytime an error occurs within your application and error + | logging is enabled. + | + | You may log the error message however you like; however, a simple log + | solution has been setup for you which will log all error messages to + | text files within the application storage directory. + | + */ + + 'logger' => function($exception) + { + Log::exception($exception); + }, + +); \ No newline at end of file diff --git a/laravel/tests/application/config/local/database.php b/laravel/tests/application/config/local/database.php new file mode 100644 index 00000000..bd94d7ba --- /dev/null +++ b/laravel/tests/application/config/local/database.php @@ -0,0 +1,7 @@ + 'sqlite', + +); \ No newline at end of file diff --git a/laravel/tests/application/config/mimes.php b/laravel/tests/application/config/mimes.php new file mode 100644 index 00000000..e2bd4fbb --- /dev/null +++ b/laravel/tests/application/config/mimes.php @@ -0,0 +1,97 @@ + 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream'), + 'bin' => 'application/macbinary', + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => array('application/octet-stream', 'application/x-msdownload'), + 'class' => 'application/octet-stream', + 'psd' => 'application/x-photoshop', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => array('application/pdf', 'application/x-download'), + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'), + 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'), + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'php' => array('application/x-httpd-php', 'text/x-php'), + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/x-javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'), + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => 'audio/x-wav', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => array('image/jpeg', 'image/pjpeg'), + 'jpg' => array('image/jpeg', 'image/pjpeg'), + 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'png' => 'image/png', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => array('text/plain', 'text/x-log'), + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'word' => array('application/msword', 'application/octet-stream'), + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => array('application/json', 'text/json'), + +); \ No newline at end of file diff --git a/laravel/tests/application/config/session.php b/laravel/tests/application/config/session.php new file mode 100644 index 00000000..3b6e6a69 --- /dev/null +++ b/laravel/tests/application/config/session.php @@ -0,0 +1,117 @@ + '', + + /* + |-------------------------------------------------------------------------- + | Session Database + |-------------------------------------------------------------------------- + | + | The database table on which the session should be stored. It probably + | goes without saying that this option only matters if you are using + | the super slick database session driver. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Garbage Collection Probability + |-------------------------------------------------------------------------- + | + | Some session drivers require the manual clean-up of expired sessions. + | This option specifies the probability of session garbage collection + | occuring for any given request. + | + | For example, the default value states that garbage collection has a + | 2% chance of occuring for any given request to the application. + | Feel free to tune this to your application's size and speed. + | + */ + + 'sweepage' => array(2, 100), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | The number of minutes a session can be idle before expiring. + | + */ + + 'lifetime' => 60, + + /* + |-------------------------------------------------------------------------- + | Session Expiration On Close + |-------------------------------------------------------------------------- + | + | Determines if the session should expire when the user's web browser closes. + | + */ + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | The name that should be given to the session cookie. + | + */ + + 'cookie' => 'laravel_session', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The path for which the session cookie is available. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | The domain for which the session cookie is available. + | + */ + + 'domain' => null, + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Session Cookie + |-------------------------------------------------------------------------- + | + | Determines if the cookie should only be sent over HTTPS. + | + */ + + 'secure' => false, + +); \ No newline at end of file diff --git a/laravel/tests/application/config/strings.php b/laravel/tests/application/config/strings.php new file mode 100644 index 00000000..730f973e --- /dev/null +++ b/laravel/tests/application/config/strings.php @@ -0,0 +1,187 @@ + array( + '/(quiz)$/i' => "$1zes", + '/^(ox)$/i' => "$1en", + '/([m|l])ouse$/i' => "$1ice", + '/(matr|vert|ind)ix|ex$/i' => "$1ices", + '/(x|ch|ss|sh)$/i' => "$1es", + '/([^aeiouy]|qu)y$/i' => "$1ies", + '/(hive)$/i' => "$1s", + '/(?:([^f])fe|([lr])f)$/i' => "$1$2ves", + '/(shea|lea|loa|thie)f$/i' => "$1ves", + '/sis$/i' => "ses", + '/([ti])um$/i' => "$1a", + '/(tomat|potat|ech|her|vet)o$/i' => "$1oes", + '/(bu)s$/i' => "$1ses", + '/(alias)$/i' => "$1es", + '/(octop)us$/i' => "$1i", + '/(ax|test)is$/i' => "$1es", + '/(us)$/i' => "$1es", + '/s$/i' => "s", + '/$/' => "s" + ), + + 'singular' => array( + '/(quiz)zes$/i' => "$1", + '/(matr)ices$/i' => "$1ix", + '/(vert|ind)ices$/i' => "$1ex", + '/^(ox)en$/i' => "$1", + '/(alias)es$/i' => "$1", + '/(octop|vir)i$/i' => "$1us", + '/(cris|ax|test)es$/i' => "$1is", + '/(shoe)s$/i' => "$1", + '/(o)es$/i' => "$1", + '/(bus)es$/i' => "$1", + '/([m|l])ice$/i' => "$1ouse", + '/(x|ch|ss|sh)es$/i' => "$1", + '/(m)ovies$/i' => "$1ovie", + '/(s)eries$/i' => "$1eries", + '/([^aeiouy]|qu)ies$/i' => "$1y", + '/([lr])ves$/i' => "$1f", + '/(tive)s$/i' => "$1", + '/(hive)s$/i' => "$1", + '/(li|wi|kni)ves$/i' => "$1fe", + '/(shea|loa|lea|thie)ves$/i' => "$1f", + '/(^analy)ses$/i' => "$1sis", + '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => "$1$2sis", + '/([ti])a$/i' => "$1um", + '/(n)ews$/i' => "$1ews", + '/(h|bl)ouses$/i' => "$1ouse", + '/(corpse)s$/i' => "$1", + '/(us)es$/i' => "$1", + '/(us|ss)$/i' => "$1", + '/s$/i' => "", + ), + + 'irregular' => array( + 'child' => 'children', + 'foot' => 'feet', + 'goose' => 'geese', + 'man' => 'men', + 'move' => 'moves', + 'person' => 'people', + 'sex' => 'sexes', + 'tooth' => 'teeth', + ), + + 'uncountable' => array( + 'audio', + 'equipment', + 'deer', + 'fish', + 'gold', + 'information', + 'money', + 'rice', + 'police', + 'series', + 'sheep', + 'species', + ), + + /* + |-------------------------------------------------------------------------- + | ASCII Characters + |-------------------------------------------------------------------------- + | + | This array contains foreign characters and their 7-bit ASCII equivalents. + | The array is used by the "ascii" method on the Str class to get strings + | ready for inclusion in a URL slug. + | + | Of course, the "ascii" method may also be used by you for whatever your + | application requires. Feel free to add any characters we missed, and be + | sure to let us know about them! + | + */ + + 'ascii' => array( + + '/æ|ǽ/' => 'ae', + '/œ/' => 'oe', + '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|А/' => 'A', + '/à|á|â|ã|ä|å|ǻ|ā|ă|ą|ǎ|ª|а/' => 'a', + '/Б/' => 'B', + '/б/' => 'b', + '/Ç|Ć|Ĉ|Ċ|Č|Ц/' => 'C', + '/ç|ć|ĉ|ċ|č|ц/' => 'c', + '/Ð|Ď|Đ|Д/' => 'Dj', + '/ð|ď|đ|д/' => 'dj', + '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Е|Ё|Э/' => 'E', + '/è|é|ê|ë|ē|ĕ|ė|ę|ě|е|ё|э/' => 'e', + '/Ф/' => 'F', + '/ƒ|ф/' => 'f', + '/Ĝ|Ğ|Ġ|Ģ|Г/' => 'G', + '/ĝ|ğ|ġ|ģ|г/' => 'g', + '/Ĥ|Ħ|Х/' => 'H', + '/ĥ|ħ|х/' => 'h', + '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|И/' => 'I', + '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|и/' => 'i', + '/Ĵ|Й/' => 'J', + '/ĵ|й/' => 'j', + '/Ķ|К/' => 'K', + '/ķ|к/' => 'k', + '/Ĺ|Ļ|Ľ|Ŀ|Ł|Л/' => 'L', + '/ĺ|ļ|ľ|ŀ|ł|л/' => 'l', + '/М/' => 'M', + '/м/' => 'm', + '/Ñ|Ń|Ņ|Ň|Н/' => 'N', + '/ñ|ń|ņ|ň|ʼn|н/' => 'n', + '/Ö|Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|О/' => 'O', + '/ö|ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|о/' => 'o', + '/П/' => 'P', + '/п/' => 'p', + '/Ŕ|Ŗ|Ř|Р/' => 'R', + '/ŕ|ŗ|ř|р/' => 'r', + '/Ś|Ŝ|Ş|Ș|Š|С/' => 'S', + '/ś|ŝ|ş|ș|š|ſ|с/' => 's', + '/Ţ|Ț|Ť|Ŧ|Т/' => 'T', + '/ţ|ț|ť|ŧ|т/' => 't', + '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ü|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|У/' => 'U', + '/ù|ú|û|ũ|ū|ŭ|ů|ü|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|у/' => 'u', + '/В/' => 'V', + '/в/' => 'v', + '/Ý|Ÿ|Ŷ|Ы/' => 'Y', + '/ý|ÿ|ŷ|ы/' => 'y', + '/Ŵ/' => 'W', + '/ŵ/' => 'w', + '/Ź|Ż|Ž|З/' => 'Z', + '/ź|ż|ž|з/' => 'z', + '/Æ|Ǽ/' => 'AE', + '/ß/'=> 'ss', + '/IJ/' => 'IJ', + '/ij/' => 'ij', + '/Œ/' => 'OE', + '/Ч/' => 'Ch', + '/ч/' => 'ch', + '/Ю/' => 'Ju', + '/ю/' => 'ju', + '/Я/' => 'Ja', + '/я/' => 'ja', + '/Ш/' => 'Sh', + '/ш/' => 'sh', + '/Щ/' => 'Shch', + '/щ/' => 'shch', + '/Ж/' => 'Zh', + '/ж/' => 'zh', + + ), + +); \ No newline at end of file diff --git a/laravel/tests/application/controllers/admin/panel.php b/laravel/tests/application/controllers/admin/panel.php new file mode 100644 index 00000000..da3b49d7 --- /dev/null +++ b/laravel/tests/application/controllers/admin/panel.php @@ -0,0 +1,10 @@ +filter('before', 'test-all-before'); + $this->filter('after', 'test-all-after'); + $this->filter('before', 'test-profile-before')->only(array('profile')); + $this->filter('before', 'test-except')->except(array('index', 'profile')); + $this->filter('before', 'test-on-post')->on(array('post')); + $this->filter('before', 'test-on-get-put')->on(array('get', 'put')); + $this->filter('before', 'test-before-filter')->only('login'); + $this->filter('after', 'test-before-filter')->only('logout'); + $this->filter('before', 'test-param:1,2')->only('edit'); + $this->filter('before', 'test-multi-1|test-multi-2')->only('save'); + } + + public function action_index() + { + return __FUNCTION__; + } + + public function action_profile() + { + return __FUNCTION__; + } + + public function action_show() + { + return __FUNCTION__; + } + + public function action_edit() + { + return __FUNCTION__; + } + + public function action_save() + { + return __FUNCTION__; + } + + public function action_login() + { + return __FUNCTION__; + } + + public function action_logout() + { + return __FUNCTION__; + } + +} \ No newline at end of file diff --git a/laravel/tests/application/controllers/home.php b/laravel/tests/application/controllers/home.php new file mode 100644 index 00000000..3f442005 --- /dev/null +++ b/laravel/tests/application/controllers/home.php @@ -0,0 +1,42 @@ + '« Previous', + 'next' => 'Next »', + +); \ No newline at end of file diff --git a/laravel/tests/application/language/en/validation.php b/laravel/tests/application/language/en/validation.php new file mode 100644 index 00000000..5c6354dd --- /dev/null +++ b/laravel/tests/application/language/en/validation.php @@ -0,0 +1,96 @@ + "The :attribute must be accepted.", + "active_url" => "The :attribute is not a valid URL.", + "alpha" => "The :attribute may only contain letters.", + "alpha_dash" => "The :attribute may only contain letters, numbers, and dashes.", + "alpha_num" => "The :attribute may only contain letters and numbers.", + "between" => array( + "numeric" => "The :attribute must be between :min - :max.", + "file" => "The :attribute must be between :min - :max kilobytes.", + "string" => "The :attribute must be between :min - :max characters.", + ), + "confirmed" => "The :attribute confirmation does not match.", + "different" => "The :attribute and :other must be different.", + "email" => "The :attribute format is invalid.", + "exists" => "The selected :attribute is invalid.", + "image" => "The :attribute must be an image.", + "in" => "The selected :attribute is invalid.", + "integer" => "The :attribute must be an integer.", + "ip" => "The :attribute must be a valid IP address.", + "max" => array( + "numeric" => "The :attribute must be less than :max.", + "file" => "The :attribute must be less than :max kilobytes.", + "string" => "The :attribute must be less than :max characters.", + ), + "mimes" => "The :attribute must be a file of type: :values.", + "min" => array( + "numeric" => "The :attribute must be at least :min.", + "file" => "The :attribute must be at least :min kilobytes.", + "string" => "The :attribute must be at least :min characters.", + ), + "not_in" => "The selected :attribute is invalid.", + "numeric" => "The :attribute must be a number.", + "required" => "The :attribute field is required.", + "same" => "The :attribute and :other must match.", + "size" => array( + "numeric" => "The :attribute must be :size.", + "file" => "The :attribute must be :size kilobyte.", + "string" => "The :attribute must be :size characters.", + ), + "unique" => "The :attribute has already been taken.", + "url" => "The :attribute format is invalid.", + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute_rule" to name the lines. This helps keep your + | custom validation clean and tidy. + | + | So, say you want to use a custom validation message when validating that + | the "email" attribute is unique. Just add "email_unique" to this array + | with your custom message. The Validator will handle the rest! + | + */ + + 'custom' => array('custom_required' => 'This field is required!'), + + /* + |-------------------------------------------------------------------------- + | Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as "E-Mail Address" instead + | of "email". Your users will thank you. + | + | The Validator class will automatically search this array of lines it + | is attempting to replace the :attribute place-holder in messages. + | It's pretty slick. We think you'll like it. + | + */ + + 'attributes' => array('test_attribute' => 'attribute'), + +); \ No newline at end of file diff --git a/laravel/tests/application/language/sp/validation.php b/laravel/tests/application/language/sp/validation.php new file mode 100644 index 00000000..b9bcbe74 --- /dev/null +++ b/laravel/tests/application/language/sp/validation.php @@ -0,0 +1,7 @@ + 'El campo de atributo es necesario.', + +); \ No newline at end of file diff --git a/laravel/tests/application/libraries/.gitignore b/laravel/tests/application/libraries/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/laravel/tests/application/migrations/.gitignore b/laravel/tests/application/migrations/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/laravel/tests/application/models/.gitignore b/laravel/tests/application/models/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/laravel/tests/application/models/autoloader.php b/laravel/tests/application/models/autoloader.php new file mode 100644 index 00000000..0e9027dc --- /dev/null +++ b/laravel/tests/application/models/autoloader.php @@ -0,0 +1,3 @@ + 'home', function() +{ + return View::make('home.index'); +})); + +Route::controller(array( + 'auth', 'filter', 'home', 'restful', + 'template.basic', 'template.name', 'template.override', + 'admin.panel', +)); + +/* +|-------------------------------------------------------------------------- +| Route Filters +|-------------------------------------------------------------------------- +| +| Filters provide a convenient method for attaching functionality to your +| routes. The built-in "before" and "after" filters are called before and +| after every request to your application, and you may even create other +| filters that can be attached to individual routes. +| +| Let's walk through an example... +| +| First, define a filter: +| +| Filter::register('filter', function() +| { +| return 'Filtered!'; +| }); +| +| Next, attach the filter to a route: +| +| Router::register('GET /', array('before' => 'filter', function() +| { +| return 'Hello World!'; +| })); +| +*/ + +Filter::register('before', function() +{ + $_SERVER['before'] = true; +}); + +Filter::register('after', function() +{ + $_SERVER['after'] = true; +}); + +Filter::register('csrf', function() +{ + if (Request::forged()) return Response::error('500'); +}); + +Filter::register('auth', function() +{ + if (Auth::guest()) return Redirect::to('login'); +}); \ No newline at end of file diff --git a/laravel/tests/application/start.php b/laravel/tests/application/start.php new file mode 100644 index 00000000..085dd090 --- /dev/null +++ b/laravel/tests/application/start.php @@ -0,0 +1,157 @@ + path('app').'controllers/base.php', +)); + +/* +|-------------------------------------------------------------------------- +| Auto-Loader Directories +|-------------------------------------------------------------------------- +| +| The Laravel auto-loader can search directories for files using the PSR-0 +| naming convention. This convention basically organizes classes by using +| the class namespace to indicate the directory structure. +| +*/ + +Autoloader::directories(array( + path('app').'models', + path('app').'libraries', +)); + +/* +|-------------------------------------------------------------------------- +| Laravel View Loader +|-------------------------------------------------------------------------- +| +| The Laravel view loader is responsible for returning the full file path +| for the given bundle and view. Of course, a default implementation is +| provided to load views according to typical Laravel conventions but +| you may change this to customize how your views are organized. +| +*/ + +Event::listen(View::loader, function($bundle, $view) +{ + return View::file($bundle, $view, Bundle::path($bundle).'views'); +}); + +/* +|-------------------------------------------------------------------------- +| Laravel Language Loader +|-------------------------------------------------------------------------- +| +| The Laravel language loader is responsible for returning the array of +| language lines for a given bundle, language, and "file". A default +| implementation has been provided which uses the default language +| directories included with Laravel. +| +*/ + +Event::listen(Lang::loader, function($bundle, $language, $file) +{ + return Lang::file($bundle, $language, $file); +}); + +/* +|-------------------------------------------------------------------------- +| Enable The Blade View Engine +|-------------------------------------------------------------------------- +| +| The Blade view engine provides a clean, beautiful templating language +| for your application, including syntax for echoing data and all of +| the typical PHP control structures. We'll simply enable it here. +| +*/ + +Blade::sharpen(); + +/* +|-------------------------------------------------------------------------- +| Set The Default Timezone +|-------------------------------------------------------------------------- +| +| We need to set the default timezone for the application. This controls +| the timezone that will be used by any of the date methods and classes +| utilized by Laravel or your application. The timezone may be set in +| your application configuration file. +| +*/ + +date_default_timezone_set(Config::get('application.timezone')); + +/* +|-------------------------------------------------------------------------- +| Start / Load The User Session +|-------------------------------------------------------------------------- +| +| Sessions allow the web, which is stateless, to simulate state. In other +| words, sessions allow you to store information about the current user +| and state of your application. Here we'll just fire up the session +| if a session driver has been configured. +| +*/ + +if ( ! Request::cli() and Config::get('session.driver') !== '') +{ + Session::load(); +} \ No newline at end of file diff --git a/laravel/tests/application/tasks/.gitignore b/laravel/tests/application/tasks/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/laravel/tests/application/views/error/404.php b/laravel/tests/application/views/error/404.php new file mode 100644 index 00000000..9b9bf55b --- /dev/null +++ b/laravel/tests/application/views/error/404.php @@ -0,0 +1,103 @@ + + + + + + Error 404 - Not Found + + + + +
+ + +

+ +

Server Error: 404 (Not Found)

+ +

What does this mean?

+ +

+ We couldn't find the page you requested on our servers. We're really sorry + about that. It's our fault, not yours. We'll work hard to get this page + back online as soon as possible. +

+ +

+ Perhaps you would like to go to our ? +

+
+ + \ No newline at end of file diff --git a/laravel/tests/application/views/error/500.php b/laravel/tests/application/views/error/500.php new file mode 100644 index 00000000..4dcd92ad --- /dev/null +++ b/laravel/tests/application/views/error/500.php @@ -0,0 +1,103 @@ + + + + + + Error 500 - Internal Server Error + + + + +
+ + +

+ +

Server Error: 500 (Internal Server Error)

+ +

What does this mean?

+ +

+ Something went wrong on our servers while we were processing your request. + We're really sorry about this, and will work hard to get this resolved as + soon as possible. +

+ +

+ Perhaps you would like to go to our ? +

+
+ + \ No newline at end of file diff --git a/laravel/tests/application/views/home/index.php b/laravel/tests/application/views/home/index.php new file mode 100644 index 00000000..39497146 --- /dev/null +++ b/laravel/tests/application/views/home/index.php @@ -0,0 +1,122 @@ + + + + + + Laravel - A Framework For Web Artisans + + + + +
+

Welcome To Laravel

+ +

A Framework For Web Artisans

+ +

+ You have successfully installed the Laravel framework. Laravel is a simple framework + that helps web artisans create beautiful, creative applications using elegant, expressive + syntax. You'll love using it. +

+ +

Learn the terrain.

+ +

+ You've landed yourself on our default home page. The route that + is generating this page lives at: +

+ +
APP_PATH/routes.php
+ +

And the view sitting before you can be found at:

+ +
APP_PATH/views/home/index.php
+ +

Create something beautiful.

+ +

+ Now that you're up and running, it's time to start creating! + Here are some links to help you get started: +

+ + + +
+ + \ No newline at end of file diff --git a/laravel/tests/application/views/tests/basic.php b/laravel/tests/application/views/tests/basic.php new file mode 100644 index 00000000..c961dc2f --- /dev/null +++ b/laravel/tests/application/views/tests/basic.php @@ -0,0 +1 @@ + is \ No newline at end of file diff --git a/laravel/tests/application/views/tests/nested.php b/laravel/tests/application/views/tests/nested.php new file mode 100644 index 00000000..9ce498e5 --- /dev/null +++ b/laravel/tests/application/views/tests/nested.php @@ -0,0 +1 @@ +Taylor \ No newline at end of file diff --git a/laravel/tests/bundles/.gitignore b/laravel/tests/bundles/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/laravel/tests/bundles/dashboard/config/meta.php b/laravel/tests/bundles/dashboard/config/meta.php new file mode 100644 index 00000000..a82d1703 --- /dev/null +++ b/laravel/tests/bundles/dashboard/config/meta.php @@ -0,0 +1,7 @@ + 'dashboard', + +); \ No newline at end of file diff --git a/laravel/tests/bundles/dashboard/controllers/panel.php b/laravel/tests/bundles/dashboard/controllers/panel.php new file mode 100644 index 00000000..b532296d --- /dev/null +++ b/laravel/tests/bundles/dashboard/controllers/panel.php @@ -0,0 +1,10 @@ + 'dashboard', function() +{ + // +})); + +Route::controller('dashboard::panel'); \ No newline at end of file diff --git a/laravel/tests/bundles/dummy/routes.php b/laravel/tests/bundles/dummy/routes.php new file mode 100644 index 00000000..2117e2e0 --- /dev/null +++ b/laravel/tests/bundles/dummy/routes.php @@ -0,0 +1,6 @@ +assertTrue($container === Asset::container('foo')); + $this->assertInstanceOf('\\Laravel\\Asset_Container', $container); + } + + /** + * Test the Asset::container method for default container creation. + * + * @group laravel + */ + public function testDefaultContainerCreatedByDefault() + { + $this->assertEquals('default', Asset::container()->name); + } + + /** + * Test the Asset::__callStatic method. + * + * @group laravel + */ + public function testContainerMethodsCanBeDynamicallyCalled() + { + Asset::style('common', 'common.css'); + + $this->assertEquals('common.css', Asset::container()->assets['style']['common']['source']); + } + + /** + * Test the Asset_Container constructor. + * + * @group laravel + */ + public function testNameIsSetOnAssetContainerConstruction() + { + $container = $this->getContainer(); + + $this->assertEquals('foo', $container->name); + } + + /** + * Test the Asset_Container::add method. + * + * @group laravel + */ + public function testAddMethodProperlySniffsAssetType() + { + $container = $this->getContainer(); + + $container->add('jquery', 'jquery.js'); + $container->add('common', 'common.css'); + + $this->assertEquals('jquery.js', $container->assets['script']['jquery']['source']); + $this->assertEquals('common.css', $container->assets['style']['common']['source']); + } + + /** + * Test the Asset_Container::style method. + * + * @group laravel + */ + public function testStyleMethodProperlyRegistersAnAsset() + { + $container = $this->getContainer(); + + $container->style('common', 'common.css'); + + $this->assertEquals('common.css', $container->assets['style']['common']['source']); + } + + /** + * Test the Asset_Container::style method sets media attribute. + * + * @group laravel + */ + public function testStyleMethodProperlySetsMediaAttributeIfNotSet() + { + $container = $this->getContainer(); + + $container->style('common', 'common.css'); + + $this->assertEquals('all', $container->assets['style']['common']['attributes']['media']); + } + + /** + * Test the Asset_Container::style method sets media attribute. + * + * @group laravel + */ + public function testStyleMethodProperlyIgnoresMediaAttributeIfSet() + { + $container = $this->getContainer(); + + $container->style('common', 'common.css', array(), array('media' => 'print')); + + $this->assertEquals('print', $container->assets['style']['common']['attributes']['media']); + } + + /** + * Test the Asset_Container::script method. + * + * @group laravel + */ + public function testScriptMethodProperlyRegistersAnAsset() + { + $container = $this->getContainer(); + + $container->script('jquery', 'jquery.js'); + + $this->assertEquals('jquery.js', $container->assets['script']['jquery']['source']); + } + + /** + * Test the Asset_Container::add method properly sets dependencies. + * + * @group laravel + */ + public function testAddMethodProperlySetsDependencies() + { + $container = $this->getContainer(); + + $container->add('common', 'common.css', 'jquery'); + $container->add('jquery', 'jquery.js', array('jquery-ui')); + + $this->assertEquals(array('jquery'), $container->assets['style']['common']['dependencies']); + $this->assertEquals(array('jquery-ui'), $container->assets['script']['jquery']['dependencies']); + } + + /** + * Test the Asset_Container::add method properly sets attributes. + * + * @group laravel + */ + public function testAddMethodProperlySetsAttributes() + { + $container = $this->getContainer(); + + $container->add('common', 'common.css', array(), array('media' => 'print')); + $container->add('jquery', 'jquery.js', array(), array('defer')); + + $this->assertEquals(array('media' => 'print'), $container->assets['style']['common']['attributes']); + $this->assertEquals(array('defer'), $container->assets['script']['jquery']['attributes']); + } + + /** + * Test the Asset_Container::bundle method. + * + * @group laravel + */ + public function testBundleMethodCorrectlySetsTheAssetBundle() + { + $container = $this->getContainer(); + + $container->bundle('eloquent'); + + $this->assertEquals('eloquent', $container->bundle); + } + + /** + * Test the Asset_Container::path method. + * + * @group laravel + */ + public function testPathMethodReturnsCorrectPathForABundleAsset() + { + $container = $this->getContainer(); + + $container->bundle('eloquent'); + + $this->assertEquals('/bundles/eloquent/foo.jpg', $container->path('foo.jpg')); + } + + /** + * Test the Asset_Container::path method. + * + * @group laravel + */ + public function testPathMethodReturnsCorrectPathForAnApplicationAsset() + { + $container = $this->getContainer(); + + $this->assertEquals('/foo.jpg', $container->path('foo.jpg')); + } + + /** + * Test the Asset_Container::scripts method. + * + * @group laravel + */ + public function testScriptsCanBeRetrieved() + { + $container = $this->getContainer(); + + $container->script('dojo', 'dojo.js', array('jquery-ui')); + $container->script('jquery', 'jquery.js', array('jquery-ui', 'dojo')); + $container->script('jquery-ui', 'jquery-ui.js'); + + $scripts = $container->scripts(); + + $this->assertTrue(strpos($scripts, 'jquery.js') > 0); + $this->assertTrue(strpos($scripts, 'jquery.js') > strpos($scripts, 'jquery-ui.js')); + $this->assertTrue(strpos($scripts, 'dojo.js') > strpos($scripts, 'jquery-ui.js')); + } + + /** + * Test the Asset_Container::styles method. + * + * @group laravel + */ + public function testStylesCanBeRetrieved() + { + $container = $this->getContainer(); + + $container->style('dojo', 'dojo.css', array('jquery-ui'), array('media' => 'print')); + $container->style('jquery', 'jquery.css', array('jquery-ui', 'dojo')); + $container->style('jquery-ui', 'jquery-ui.css'); + + $styles = $container->styles(); + + $this->assertTrue(strpos($styles, 'jquery.css') > 0); + $this->assertTrue(strpos($styles, 'media="print"') > 0); + $this->assertTrue(strpos($styles, 'jquery.css') > strpos($styles, 'jquery-ui.css')); + $this->assertTrue(strpos($styles, 'dojo.css') > strpos($styles, 'jquery-ui.css')); + } + + /** + * Get an asset container instance. + * + * @param string $name + * @return Asset_Container + */ + private function getContainer($name = 'foo') + { + return new Laravel\Asset_Container($name); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/auth.test.php b/laravel/tests/cases/auth.test.php new file mode 100644 index 00000000..16ba428a --- /dev/null +++ b/laravel/tests/cases/auth.test.php @@ -0,0 +1,359 @@ +user = null; + Session::$instance = null; + Config::set('database.default', 'sqlite'); + } + + /** + * Tear down the test environment. + */ + public function tearDown() + { + $_SERVER['auth.login.stub'] = null; + Cookie::$jar = array(); + Config::$items = array(); + Auth::driver()->user = null; + Session::$instance = null; + Config::set('database.default', 'mysql'); + } + + /** + * Set one of the $_SERVER variables. + * + * @param string $key + * @param string $value + */ + protected function setServerVar($key, $value) + { + $_SERVER[$key] = $value; + + $this->restartRequest(); + } + + /** + * Reinitialize the global request. + * + * @return void + */ + protected function restartRequest() + { + // FIXME: Ugly hack, but old contents from previous requests seem to + // trip up the Foundation class. + $_FILES = array(); + + Request::$foundation = RequestFoundation::createFromGlobals(); + } + + /** + * Test the Auth::user method. + * + * @group laravel + */ + public function testUserMethodReturnsCurrentUser() + { + Auth::driver()->user = 'Taylor'; + + $this->assertEquals('Taylor', Auth::user()); + } + + /** + * Test the Auth::check method. + * + * @group laravel + */ + public function testCheckMethodReturnsTrueWhenUserIsSet() + { + $auth = new AuthUserReturnsDummy; + + $this->assertTrue($auth->check()); + } + + /** + * Test the Auth::check method. + * + * @group laravel + */ + public function testCheckMethodReturnsFalseWhenNoUserIsSet() + { + $auth = new AuthUserReturnsNull; + + $this->assertFalse($auth->check()); + } + + /** + * Test the Auth::guest method. + * + * @group laravel + */ + public function testGuestReturnsTrueWhenNoUserIsSet() + { + $auth = new AuthUserReturnsNull; + + $this->assertTrue($auth->guest()); + } + + /** + * Test the Auth::guest method. + * + * @group laravel + */ + public function testGuestReturnsFalseWhenUserIsSet() + { + $auth = new AuthUserReturnsDummy; + + $this->assertFalse($auth->guest()); + } + + /** + * Test the Auth::user method. + * + * @group laravel + */ + public function testUserMethodReturnsNullWhenNoUserExistsAndNoRecallerExists() + { + Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver')); + + $this->assertNull(Auth::user()); + } + + /** + * Test the Auth::user method. + * + * @group laravel + */ + public function testUserReturnsUserByID() + { + Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver')); + + Auth::login(1); + + $this->assertEquals('Taylor Otwell', Auth::user()->name); + + Auth::logout(); + } + + /** + * Test the Auth::user method. + * + * @group laravel + */ + public function testNullReturnedWhenUserIDNotValidInteger() + { + Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver')); + + Auth::login('asdlkasd'); + + $this->assertNull(Auth::user()); + } + + /** + * Test the Auth::recall method. + * + * @group laravel + */ + public function testUserCanBeRecalledViaCookie() + { + Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver')); + + $cookie = Crypter::encrypt('1|'.Str::random(40)); + Cookie::forever('authloginstub_remember', $cookie); + + $auth = new AuthLoginStub; + + $this->assertEquals('Taylor Otwell', $auth->user()->name); + + $this->assertTrue($auth->user()->id === $_SERVER['auth.login.stub']['user']); + } + + /** + * Test the Auth::attempt method. + * + * @group laravel + */ + public function testAttemptMethodReturnsFalseWhenCredentialsAreInvalid() + { + $this->assertFalse(Auth::attempt(array('username' => 'foo', 'password' => 'foo'))); + $this->assertFalse(Auth::attempt(array('username' => 'foo', 'password' => null))); + $this->assertFalse(Auth::attempt(array('username' => null, 'password' => null))); + $this->assertFalse(Auth::attempt(array('username' => 'taylor', 'password' => 'password'))); + $this->assertFalse(Auth::attempt(array('username' => 'taylor', 'password' => 232))); + } + + /** + * Test the Auth::attempt method. + * + * @group laravel + */ + public function testAttemptReturnsTrueWhenCredentialsAreCorrect() + { + Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver')); + + $auth = new AuthLoginStub; + + $this->assertTrue($auth->attempt(array('username' => 'taylor', 'password' => 'password1'))); + $this->assertEquals('1', $_SERVER['auth.login.stub']['user']); + $this->assertFalse($_SERVER['auth.login.stub']['remember']); + + $auth_secure = new AuthLoginStub; + + $this->assertTrue($auth_secure->attempt(array('username' => 'taylor', 'password' => 'password1', 'remember' => true))); + $this->assertEquals('1', $_SERVER['auth.login.stub']['user']); + $this->assertTrue($_SERVER['auth.login.stub']['remember']); + + $auth_secure->logout(); + $auth->logout(); + } + + /** + * Test Auth::login method. + * + * @group laravel + */ + public function testLoginMethodStoresUserKeyInSession() + { + Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver')); + + $user = new StdClass; + $user->id = 10; + Auth::login($user); + // FIXME: Not sure whether hard-coding the key is a good idea. + $user = Session::$instance->session['data']['laravel_auth_drivers_fluent_login']; + $this->assertEquals(10, $user->id); + + + Auth::logout(); + + Auth::login(5); + $user = Session::$instance->session['data']['laravel_auth_drivers_fluent_login']; + $this->assertEquals(5, $user); + Auth::logout(5); + } + + /** + * Test the Auth::login method. + * + * @group laravel + */ + public function testLoginStoresRememberCookieWhenNeeded() + { + Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver')); + + $this->setServerVar('HTTPS', 'on'); + + // Set the session vars to make sure remember cookie uses them + Config::set('session.path', 'foo'); + Config::set('session.domain', 'bar'); + Config::set('session.secure', true); + + Auth::login(1, true); + + $this->assertTrue(isset(Cookie::$jar['laravel_auth_drivers_fluent_remember'])); + + $cookie = Cookie::$jar['laravel_auth_drivers_fluent_remember']['value']; + $cookie = explode('|', Crypter::decrypt($cookie)); + $this->assertEquals(1, $cookie[0]); + $this->assertEquals('foo', Cookie::$jar['laravel_auth_drivers_fluent_remember']['path']); + $this->assertEquals('bar', Cookie::$jar['laravel_auth_drivers_fluent_remember']['domain']); + $this->assertTrue(Cookie::$jar['laravel_auth_drivers_fluent_remember']['secure']); + + Auth::logout(); + + $this->setServerVar('HTTPS', 'off'); + } + + /** + * Test the Auth::logout method. + * + * @group laravel + */ + public function testLogoutMethodLogsOutUser() + { + Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver')); + + $data = Session::$instance->session['data']['laravel_auth_drivers_fluent_login'] = 1; + + Auth::logout(); + + // A workaround since Cookie will is only stored in memory, until Response class is called. + Auth::driver()->token = null; + + $this->assertNull(Auth::user()); + + $this->assertFalse(isset(Session::$instance->session['data']['laravel_auth_drivers_fluent_login'])); + $this->assertTrue(Cookie::$jar['laravel_auth_drivers_fluent_remember']['expiration'] < time()); + } + +} + +class AuthUserReturnsNull extends Laravel\Auth\Drivers\Driver { + + public function user() { return null; } + + public function retrieve($id) { return null; } + + public function attempt($arguments = array()) { return null; } + +} + +class AuthUserReturnsDummy extends Laravel\Auth\Drivers\Driver { + + public function user() { return 'Taylor'; } + + public function retrieve($id) { return null; } + + public function attempt($arguments = array()) + { + return $this->login($arguments['username']); + } + +} + +class AuthLoginStub extends Laravel\Auth\Drivers\Fluent { + + public function login($user, $remember = false) + { + if (is_null($remember)) $remember = false; + + $_SERVER['auth.login.stub'] = compact('user', 'remember'); + + return parent::login($user, $remember); + } + + public function logout() + { + parent::logout(); + } + + public function retrieve($id) + { + $user = parent::retrieve($id); + + $_SERVER['auth.login.stub'] = array( + 'user' => $user->id, + 'remember' => false, + ); + + return $user; + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/autoloader.test.php b/laravel/tests/cases/autoloader.test.php new file mode 100644 index 00000000..80605447 --- /dev/null +++ b/laravel/tests/cases/autoloader.test.php @@ -0,0 +1,102 @@ + path('app').'models/foo.php', + )); + + $this->assertEquals(path('app').'models/foo.php', Autoloader::$mappings['Foo']); + } + + /** + * Test the Autoloader::alias method. + * + * @group laravel + */ + public function testAliasesCanBeRegistered() + { + Autoloader::alias('Foo\\Bar', 'Foo'); + + $this->assertEquals('Foo\\Bar', Autoloader::$aliases['Foo']); + } + + /** + * Test the Autoloader::directories method. + * + * @group laravel + */ + public function testPsrDirectoriesCanBeRegistered() + { + Autoloader::directories(array( + path('app').'foo'.DS.'bar', + path('app').'foo'.DS.'baz'.DS.DS, + )); + + $this->assertTrue(in_array(path('app').'foo'.DS.'bar'.DS, Autoloader::$directories)); + $this->assertTrue(in_array(path('app').'foo'.DS.'baz'.DS, Autoloader::$directories)); + } + + /** + * Test the Autoloader::namespaces method. + * + * @group laravel + */ + public function testNamespacesCanBeRegistered() + { + Autoloader::namespaces(array( + 'Autoloader_1' => path('bundle').'autoload'.DS.'models', + 'Autoloader_2' => path('bundle').'autoload'.DS.'libraries'.DS.DS, + )); + + $this->assertEquals(path('bundle').'autoload'.DS.'models'.DS, Autoloader::$namespaces['Autoloader_1\\']); + $this->assertEquals(path('bundle').'autoload'.DS.'libraries'.DS, Autoloader::$namespaces['Autoloader_2\\']); + } + + /** + * Test the loading of PSR-0 models and libraries. + * + * @group laravel + */ + public function testPsrLibrariesAndModelsCanBeLoaded() + { + $this->assertInstanceOf('User', new User); + $this->assertInstanceOf('Repositories\\User', new Repositories\User); + } + + /** + * Test the loading of hard-coded classes. + * + * @group laravel + */ + public function testHardcodedClassesCanBeLoaded() + { + Autoloader::map(array( + 'Autoloader_HardCoded' => path('app').'models'.DS.'autoloader.php', + )); + + $this->assertInstanceOf('Autoloader_HardCoded', new Autoloader_HardCoded); + } + + /** + * Test the loading of classes mapped by namespaces. + * + * @group laravel + */ + public function testClassesMappedByNamespaceCanBeLoaded() + { + Autoloader::namespaces(array( + 'Dashboard' => path('bundle').'dashboard'.DS.'models', + )); + + $this->assertInstanceOf('Dashboard\\Repository', new Dashboard\Repository); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/blade.test.php b/laravel/tests/cases/blade.test.php new file mode 100644 index 00000000..343be2ea --- /dev/null +++ b/laravel/tests/cases/blade.test.php @@ -0,0 +1,63 @@ +assertEquals('', Blade::compile_string($blade1)); + $this->assertEquals('', Blade::compile_string($blade2)); + } + + /** + * Test the compilation of control structures. + * + * @group laravel + */ + public function testControlStructuresAreCreatedCorrectly() + { + $blade1 = "@if (true)\nfoo\n@endif"; + $blade2 = "@if (count(".'$something'.") > 0)\nfoo\n@endif"; + $blade3 = "@if (true)\nfoo\n@elseif (false)\nbar\n@endif"; + $blade4 = "@if (true)\nfoo\n@else\nbar\n@endif"; + + $this->assertEquals("\nfoo\n", Blade::compile_string($blade1)); + $this->assertEquals(" 0): ?>\nfoo\n", Blade::compile_string($blade2)); + $this->assertEquals("\nfoo\n\nbar\n", Blade::compile_string($blade3)); + $this->assertEquals("\nfoo\n\nbar\n", Blade::compile_string($blade4)); + } + + /** + * Test the compilation of yield statements. + * + * @group laravel + */ + public function testYieldsAreCompiledCorrectly() + { + $blade = "@yield('something')"; + + $this->assertEquals("", Blade::compile_string($blade)); + } + + /** + * Test the compilation of section statements. + * + * @group laravel + */ + public function testSectionsAreCompiledCorrectly() + { + $blade = "@section('something')\nfoo\n@endsection"; + + $this->assertEquals("\nfoo\n", Blade::compile_string($blade)); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/bundle.test.php b/laravel/tests/cases/bundle.test.php new file mode 100644 index 00000000..9826a50f --- /dev/null +++ b/laravel/tests/cases/bundle.test.php @@ -0,0 +1,251 @@ + 'foo-baz')); + $this->assertEquals('foo-baz', Bundle::$bundles['foo-baz']['handles']); + $this->assertFalse(Bundle::$bundles['foo-baz']['auto']); + + Bundle::register('foo-bar', array()); + $this->assertFalse(Bundle::$bundles['foo-baz']['auto']); + $this->assertNull(Bundle::$bundles['foo-bar']['handles']); + + unset(Bundle::$bundles['foo-baz']); + unset(Bundle::$bundles['foo-bar']); + } + + /** + * Test the Bundle::start method. + * + * @group laravel + */ + public function testStartMethodStartsBundle() + { + $_SERVER['bundle.dummy.start'] = 0; + $_SERVER['bundle.dummy.routes'] = 0; + + $_SERVER['started.dummy'] = false; + + Event::listen('laravel.started: dummy', function() + { + $_SERVER['started.dummy'] = true; + }); + + Bundle::register('dummy'); + Bundle::start('dummy'); + + $this->assertTrue($_SERVER['started.dummy']); + $this->assertEquals(1, $_SERVER['bundle.dummy.start']); + $this->assertEquals(1, $_SERVER['bundle.dummy.routes']); + + Bundle::start('dummy'); + + $this->assertEquals(1, $_SERVER['bundle.dummy.start']); + $this->assertEquals(1, $_SERVER['bundle.dummy.routes']); + } + + /** + * Test Bundle::handles method. + * + * @group laravel + */ + public function testHandlesMethodReturnsBundleThatHandlesURI() + { + Bundle::register('foo', array('handles' => 'foo-bar')); + $this->assertEquals('foo', Bundle::handles('foo-bar/admin')); + unset(Bundle::$bundles['foo']); + } + + /** + * Test the Bundle::exist method. + * + * @group laravel + */ + public function testExistMethodIndicatesIfBundleExist() + { + $this->assertTrue(Bundle::exists('dashboard')); + $this->assertFalse(Bundle::exists('foo')); + } + + /** + * Test the Bundle::started method. + * + * @group laravel + */ + public function testStartedMethodIndicatesIfBundleIsStarted() + { + Bundle::register('dummy'); + Bundle::start('dummy'); + $this->assertTrue(Bundle::started('dummy')); + } + + /** + * Test the Bundle::prefix method. + * + * @group laravel + */ + public function testPrefixMethodReturnsCorrectPrefix() + { + $this->assertEquals('dummy::', Bundle::prefix('dummy')); + $this->assertEquals('', Bundle::prefix(DEFAULT_BUNDLE)); + } + + /** + * Test the Bundle::class_prefix method. + * + * @group laravel + */ + public function testClassPrefixMethodReturnsProperClassPrefixForBundle() + { + $this->assertEquals('Dummy_', Bundle::class_prefix('dummy')); + $this->assertEquals('', Bundle::class_prefix(DEFAULT_BUNDLE)); + } + + /** + * Test the Bundle::path method. + * + * @group laravel + */ + public function testPathMethodReturnsCorrectPath() + { + $this->assertEquals(path('app'), Bundle::path(null)); + $this->assertEquals(path('app'), Bundle::path(DEFAULT_BUNDLE)); + $this->assertEquals(path('bundle').'dashboard'.DS, Bundle::path('dashboard')); + } + + /** + * Test the Bundle::asset method. + * + * @group laravel + */ + public function testAssetPathReturnsPathToBundlesAssets() + { + $this->assertEquals('/bundles/dashboard/', Bundle::assets('dashboard')); + $this->assertEquals('/', Bundle::assets(DEFAULT_BUNDLE)); + + Config::set('application.url', ''); + } + + /** + * Test the Bundle::name method. + * + * @group laravel + */ + public function testBundleNameCanBeRetrievedFromIdentifier() + { + $this->assertEquals(DEFAULT_BUNDLE, Bundle::name('something')); + $this->assertEquals(DEFAULT_BUNDLE, Bundle::name('something.else')); + $this->assertEquals('bundle', Bundle::name('bundle::something.else')); + } + + /** + * Test the Bundle::element method. + * + * @group laravel + */ + public function testElementCanBeRetrievedFromIdentifier() + { + $this->assertEquals('something', Bundle::element('something')); + $this->assertEquals('something.else', Bundle::element('something.else')); + $this->assertEquals('something.else', Bundle::element('bundle::something.else')); + } + + /** + * Test the Bundle::identifier method. + * + * @group laravel + */ + public function testIdentifierCanBeConstructed() + { + $this->assertEquals('something.else', Bundle::identifier(DEFAULT_BUNDLE, 'something.else')); + $this->assertEquals('dashboard::something', Bundle::identifier('dashboard', 'something')); + $this->assertEquals('dashboard::something.else', Bundle::identifier('dashboard', 'something.else')); + } + + /** + * Test the Bundle::resolve method. + * + * @group laravel + */ + public function testBundleNamesCanBeResolved() + { + $this->assertEquals(DEFAULT_BUNDLE, Bundle::resolve('foo')); + $this->assertEquals('dashboard', Bundle::resolve('dashboard')); + } + + /** + * Test the Bundle::parse method. + * + * @group laravel + */ + public function testParseMethodReturnsElementAndIdentifier() + { + $this->assertEquals(array('application', 'something'), Bundle::parse('something')); + $this->assertEquals(array('application', 'something.else'), Bundle::parse('something.else')); + $this->assertEquals(array('dashboard', 'something'), Bundle::parse('dashboard::something')); + $this->assertEquals(array('dashboard', 'something.else'), Bundle::parse('dashboard::something.else')); + } + + /** + * Test the Bundle::get method. + * + * @group laravel + */ + public function testOptionMethodReturnsBundleOption() + { + $this->assertFalse(Bundle::option('dashboard', 'auto')); + $this->assertEquals('dashboard', Bundle::option('dashboard', 'location')); + } + + /** + * Test the Bundle::all method. + * + * @group laravel + */ + public function testAllMethodReturnsBundleArray() + { + Bundle::register('foo'); + $this->assertEquals(Bundle::$bundles, Bundle::all()); + unset(Bundle::$bundles['foo']); + } + + /** + * Test the Bundle::names method. + * + * @group laravel + */ + public function testNamesMethodReturnsBundleNames() + { + Bundle::register('foo'); + $this->assertEquals(array('dashboard', 'dummy', 'foo'), Bundle::names()); + unset(Bundle::$bundles['foo']); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/config.test.php b/laravel/tests/cases/config.test.php new file mode 100644 index 00000000..573b8cff --- /dev/null +++ b/laravel/tests/cases/config.test.php @@ -0,0 +1,79 @@ +assertEquals('UTF-8', Config::get('application.encoding')); + $this->assertEquals('mysql', Config::get('database.connections.mysql.driver')); + $this->assertEquals('dashboard', Config::get('dashboard::meta.bundle')); + } + + /** + * Test the Config::has method. + * + * @group laravel + */ + public function testHasMethodIndicatesIfConfigItemExists() + { + $this->assertFalse(Config::has('application.foo')); + $this->assertTrue(Config::has('application.encoding')); + } + + /** + * Test the Config::set method. + * + * @group laravel + */ + public function testConfigItemsCanBeSet() + { + Config::set('application.encoding', 'foo'); + Config::set('dashboard::meta.bundle', 'bar'); + + $this->assertEquals('foo', Config::get('application.encoding')); + $this->assertEquals('bar', Config::get('dashboard::meta.bundle')); + } + + /** + * Test that environment configurations are loaded correctly. + * + * @group laravel + */ + public function testEnvironmentConfigsOverrideNormalConfigurations() + { + $_SERVER['LARAVEL_ENV'] = 'local'; + + $this->assertEquals('sqlite', Config::get('database.default')); + + unset($_SERVER['LARAVEL_ENV']); + } + + /** + * Test that items can be set after the entire file has already been loaded. + * + * @group laravel + */ + public function testItemsCanBeSetAfterEntireFileIsLoaded() + { + Config::get('application'); + Config::set('application.key', 'taylor'); + $application = Config::get('application'); + + $this->assertEquals('taylor', $application['key']); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/controller.test.php b/laravel/tests/cases/controller.test.php new file mode 100644 index 00000000..9eb192b9 --- /dev/null +++ b/laravel/tests/cases/controller.test.php @@ -0,0 +1,267 @@ +assertEquals('action_index', Controller::call('auth@index')->content); + $this->assertEquals('Admin_Panel_Index', Controller::call('admin.panel@index')->content); + $this->assertEquals('Taylor', Controller::call('auth@profile', array('Taylor'))->content); + $this->assertEquals('Dashboard_Panel_Index', Controller::call('dashboard::panel@index')->content); + } + + /** + * Test basic controller filters are called. + * + * @group laravel + */ + public function testAssignedBeforeFiltersAreRun() + { + $_SERVER['test-all-after'] = false; + $_SERVER['test-all-before'] = false; + + Controller::call('filter@index'); + + $this->assertTrue($_SERVER['test-all-after']); + $this->assertTrue($_SERVER['test-all-before']); + } + + /** + * Test that "only" filters only apply to their assigned methods. + * + * @group laravel + */ + public function testOnlyFiltersOnlyApplyToTheirAssignedMethods() + { + $_SERVER['test-profile-before'] = false; + + Controller::call('filter@index'); + + $this->assertFalse($_SERVER['test-profile-before']); + + Controller::call('filter@profile'); + + $this->assertTrue($_SERVER['test-profile-before']); + } + + /** + * Test that "except" filters only apply to the excluded methods. + * + * @group laravel + */ + public function testExceptFiltersOnlyApplyToTheExlucdedMethods() + { + $_SERVER['test-except'] = false; + + Controller::call('filter@index'); + Controller::call('filter@profile'); + + $this->assertFalse($_SERVER['test-except']); + + Controller::call('filter@show'); + + $this->assertTrue($_SERVER['test-except']); + } + + /** + * Test that filters can be constrained by the request method. + * + * @group laravel + */ + public function testFiltersCanBeConstrainedByRequestMethod() + { + $_SERVER['test-on-post'] = false; + + Request::$foundation->setMethod('GET'); + Controller::call('filter@index'); + + $this->assertFalse($_SERVER['test-on-post']); + + Request::$foundation->setMethod('POST'); + Controller::call('filter@index'); + + $this->assertTrue($_SERVER['test-on-post']); + + $_SERVER['test-on-get-put'] = false; + + Request::$foundation->setMethod('POST'); + Controller::call('filter@index'); + + $this->assertFalse($_SERVER['test-on-get-put']); + + Request::$foundation->setMethod('PUT'); + Controller::call('filter@index'); + + $this->assertTrue($_SERVER['test-on-get-put']); + } + + public function testGlobalBeforeFilterIsNotCalledByController() + { + $_SERVER['before'] = false; + $_SERVER['after'] = false; + + Controller::call('auth@index'); + + $this->assertFalse($_SERVER['before']); + $this->assertFalse($_SERVER['after']); + } + + /** + * Test that before filters can override the controller response. + * + * @group laravel + */ + public function testBeforeFiltersCanOverrideResponses() + { + $this->assertEquals('Filtered!', Controller::call('filter@login')->content); + } + + /** + * Test that after filters do not affect the response. + * + * @group laravel + */ + public function testAfterFiltersDoNotAffectControllerResponse() + { + $this->assertEquals('action_logout', Controller::call('filter@logout')->content); + } + + /** + * Test that filter parameters are passed to the filter. + * + * @group laravel + */ + public function testFilterParametersArePassedToTheFilter() + { + $this->assertEquals('12', Controller::call('filter@edit')->content); + } + + /** + * Test that multiple filters can be assigned to a single method. + * + * @group laravel + */ + public function testMultipleFiltersCanBeAssignedToAnAction() + { + $_SERVER['test-multi-1'] = false; + $_SERVER['test-multi-2'] = false; + + Controller::call('filter@save'); + + $this->assertTrue($_SERVER['test-multi-1']); + $this->assertTrue($_SERVER['test-multi-2']); + } + + /** + * Test Restful controllers respond by request method. + * + * @group laravel + */ + public function testRestfulControllersRespondWithRestfulMethods() + { + Request::$foundation->setMethod('GET'); + //$_SERVER['REQUEST_METHOD'] = 'GET'; + + $this->assertEquals('get_index', Controller::call('restful@index')->content); + + //$_SERVER['REQUEST_METHOD'] = 'PUT'; + Request::$foundation->setMethod('PUT'); + + $this->assertEquals(404, Controller::call('restful@index')->status()); + + //$_SERVER['REQUEST_METHOD'] = 'POST'; + Request::$foundation->setMethod('POST'); + + $this->assertEquals('post_index', Controller::call('restful@index')->content); + } + + /** + * Test that the template is returned by template controllers. + * + * @group laravel + */ + public function testTemplateControllersReturnTheTemplate() + { + $response = Controller::call('template.basic@index'); + + $home = file_get_contents(path('app').'views/home/index.php'); + + $this->assertEquals($home, $response->content); + } + + /** + * Test that controller templates can be named views. + * + * @group laravel + */ + public function testControllerTemplatesCanBeNamedViews() + { + View::name('home.index', 'home'); + + $response = Controller::call('template.named@index'); + + $home = file_get_contents(path('app').'views/home/index.php'); + + $this->assertEquals($home, $response->content); + + View::$names = array(); + } + + /** + * Test that the "layout" method is called on the controller. + * + * @group laravel + */ + public function testTheTemplateCanBeOverriden() + { + $this->assertEquals('Layout', Controller::call('template.override@index')->content); + } + + /** + * Test the Controller::resolve method. + * + * @group laravel + */ + public function testResolveMethodChecksTheIoCContainer() + { + IoC::register('controller: home', function() + { + require_once path('app').'controllers/home.php'; + + $controller = new Home_Controller; + + $controller->foo = 'bar'; + + return $controller; + }); + + $controller = Controller::resolve(DEFAULT_BUNDLE, 'home'); + + $this->assertEquals('bar', $controller->foo); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/cookie.test.php b/laravel/tests/cases/cookie.test.php new file mode 100644 index 00000000..f62f7857 --- /dev/null +++ b/laravel/tests/cases/cookie.test.php @@ -0,0 +1,134 @@ +restartRequest(); + } + + /** + * Reinitialize the global request. + * + * @return void + */ + protected function restartRequest() + { + // FIXME: Ugly hack, but old contents from previous requests seem to + // trip up the Foundation class. + $_FILES = array(); + + Request::$foundation = RequestFoundation::createFromGlobals(); + } + + /** + * Test Cookie::has method. + * + * @group laravel + */ + public function testHasMethodIndicatesIfCookieInSet() + { + Cookie::$jar['foo'] = array('value' => 'bar'); + $this->assertTrue(Cookie::has('foo')); + $this->assertFalse(Cookie::has('bar')); + + Cookie::put('baz', 'foo'); + $this->assertTrue(Cookie::has('baz')); + } + + /** + * Test the Cookie::get method. + * + * @group laravel + */ + public function testGetMethodCanReturnValueOfCookies() + { + Cookie::$jar['foo'] = array('value' => 'bar'); + $this->assertEquals('bar', Cookie::get('foo')); + + Cookie::put('bar', 'baz'); + $this->assertEquals('baz', Cookie::get('bar')); + } + + /** + * Test Cookie::forever method. + * + * @group laravel + */ + public function testForeverShouldUseATonOfMinutes() + { + Cookie::forever('foo', 'bar'); + $this->assertEquals('bar', Cookie::$jar['foo']['value']); + + // Shouldn't be able to test this cause while we indicate -2000 seconds + // cookie expiration store timestamp. + // $this->assertEquals(525600, Cookie::$jar['foo']['expiration']); + + $this->setServerVar('HTTPS', 'on'); + + Cookie::forever('bar', 'baz', 'path', 'domain', true); + $this->assertEquals('path', Cookie::$jar['bar']['path']); + $this->assertEquals('domain', Cookie::$jar['bar']['domain']); + $this->assertTrue(Cookie::$jar['bar']['secure']); + + $this->setServerVar('HTTPS', 'off'); + } + + /** + * Test the Cookie::forget method. + * + * @group laravel + */ + public function testForgetSetsCookieWithExpiration() + { + Cookie::forget('bar', 'path', 'domain'); + + // Shouldn't be able to test this cause while we indicate -2000 seconds + // cookie expiration store timestamp. + //$this->assertEquals(-2000, Cookie::$jar['bar']['expiration']); + + $this->assertEquals('path', Cookie::$jar['bar']['path']); + $this->assertEquals('domain', Cookie::$jar['bar']['domain']); + $this->assertFalse(Cookie::$jar['bar']['secure']); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/database.test.php b/laravel/tests/cases/database.test.php new file mode 100644 index 00000000..84b1faaf --- /dev/null +++ b/laravel/tests/cases/database.test.php @@ -0,0 +1,74 @@ +assertTrue(isset(DB::$connections[Config::get('database.default')])); + + $connection = DatabaseConnectStub::connection('mysql'); + $this->assertTrue(isset(DB::$connections['mysql'])); + $this->assertEquals(DB::$connections['mysql']->pdo->laravel_config, Config::get('database.connections.mysql')); + } + + /** + * Test the DB::profile method. + * + * @group laravel + */ + public function testProfileMethodReturnsQueries() + { + Laravel\Database\Connection::$queries = array('Taylor'); + $this->assertEquals(array('Taylor'), DB::profile()); + Laravel\Database\Connection::$queries = array(); + } + + /** + * Test the __callStatic method. + * + * @group laravel + */ + public function testConnectionMethodsCanBeCalledStaticly() + { + $this->assertEquals('sqlite', DB::driver()); + } + +} + +class DatabaseConnectStub extends Laravel\Database { + + protected static function connect($config) { return new PDOStub($config); } + +} + +class PDOStub extends PDO { + + public $laravel_config; + + public function __construct($config) { $this->laravel_config = $config; } + + public function foo() { return 'foo'; } + +} \ No newline at end of file diff --git a/laravel/tests/cases/event.test.php b/laravel/tests/cases/event.test.php new file mode 100644 index 00000000..52063833 --- /dev/null +++ b/laravel/tests/cases/event.test.php @@ -0,0 +1,43 @@ +assertEquals(1, $responses[0]); + $this->assertEquals(2, $responses[1]); + } + + /** + * Test parameters can be passed to event listeners. + * + * @group laravel + */ + public function testParametersCanBePassedToEvents() + { + Event::listen('test.event', function($var) { return $var; }); + + $responses = Event::fire('test.event', array('Taylor')); + + $this->assertEquals('Taylor', $responses[0]); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/fluent.test.php b/laravel/tests/cases/fluent.test.php new file mode 100644 index 00000000..87c0e0db --- /dev/null +++ b/laravel/tests/cases/fluent.test.php @@ -0,0 +1,50 @@ + 'Taylor', 'age' => 25); + + $fluent = new Fluent($array); + + $this->assertEquals($array, $fluent->attributes); + } + + /** + * Test the Fluent::get method. + * + * @group laravel + */ + public function testGetMethodReturnsAttribute() + { + $fluent = new Fluent(array('name' => 'Taylor')); + + $this->assertEquals('Taylor', $fluent->get('name')); + $this->assertEquals('Default', $fluent->get('foo', 'Default')); + $this->assertEquals('Taylor', $fluent->name); + $this->assertNull($fluent->foo); + } + + public function testMagicMethodsCanBeUsedToSetAttributes() + { + $fluent = new Fluent; + + $fluent->name = 'Taylor'; + $fluent->developer(); + $fluent->age(25); + + $this->assertEquals('Taylor', $fluent->name); + $this->assertTrue($fluent->developer); + $this->assertEquals(25, $fluent->age); + $this->assertInstanceOf('Laravel\\Fluent', $fluent->programmer()); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/hash.test.php b/laravel/tests/cases/hash.test.php new file mode 100644 index 00000000..4dca2713 --- /dev/null +++ b/laravel/tests/cases/hash.test.php @@ -0,0 +1,37 @@ +assertTrue(strlen(Hash::make('taylor')) == 60); + } + + /** + * Test the Hash::check method. + * + * @group laravel + */ + public function testHashCheckFailsWhenNotMatching() + { + $hash = Hash::make('taylor'); + + $this->assertFalse(Hash::check('foo', $hash)); + } + + /** + * Test the Hash::check method. + * + * @group laravel + */ + public function testHashCheckPassesWhenMatches() + { + $this->assertTrue(Hash::check('taylor', Hash::make('taylor'))); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/input.test.php b/laravel/tests/cases/input.test.php new file mode 100644 index 00000000..5a1890f0 --- /dev/null +++ b/laravel/tests/cases/input.test.php @@ -0,0 +1,174 @@ +request->add(array('name' => 'Taylor')); + + $_FILES = array('age' => 25); + + $this->assertEquals(Input::all(), array('name' => 'Taylor', 'age' => 25)); + } + + /** + * Test the Input::has method. + * + * @group laravel + */ + public function testHasMethodIndicatesTheExistenceOfInput() + { + $this->assertFalse(Input::has('foo')); + + Request::foundation()->request->add(array('name' => 'Taylor')); + + $this->assertTrue(Input::has('name')); + } + + /** + * Test the Input::get method. + * + * @group laravel + */ + public function testGetMethodReturnsInputValue() + { + Request::foundation()->request->add(array('name' => 'Taylor')); + + $this->assertEquals('Taylor', Input::get('name')); + $this->assertEquals('Default', Input::get('foo', 'Default')); + } + + /** + * Test the Input::only method. + * + * @group laravel + */ + public function testOnlyMethodReturnsSubsetOfInput() + { + Request::foundation()->request->add(array('name' => 'Taylor', 'age' => 25)); + + $this->assertEquals(array('name' => 'Taylor'), Input::only(array('name'))); + } + + /** + * Test the Input::except method. + * + * @group laravel + */ + public function testExceptMethodReturnsSubsetOfInput() + { + Request::foundation()->request->add(array('name' => 'Taylor', 'age' => 25)); + + $this->assertEquals(array('age' => 25), Input::except(array('name'))); + } + + /** + * Test the Input::old method. + * + * @group laravel + */ + public function testOldInputCanBeRetrievedFromSession() + { + $this->setSession(); + + Session::$instance->session['data']['laravel_old_input'] = array('name' => 'Taylor'); + + $this->assertNull(Input::old('foo')); + $this->assertTrue(Input::had('name')); + $this->assertFalse(Input::had('foo')); + $this->assertEquals('Taylor', Input::old('name')); + } + + /** + * Test the Input::file method. + * + * @group laravel + */ + public function testFileMethodReturnsFromFileArray() + { + $_FILES['foo'] = array('name' => 'Taylor', 'size' => 100); + + $this->assertEquals('Taylor', Input::file('foo.name')); + $this->assertEquals(array('name' => 'Taylor', 'size' => 100), Input::file('foo')); + } + + /** + * Test the Input::flash method. + * + * @group laravel + */ + public function testFlashMethodFlashesInputToSession() + { + $this->setSession(); + + $input = array('name' => 'Taylor', 'age' => 25); + Request::foundation()->request->add($input); + + Input::flash(); + + $this->assertEquals($input, Session::$instance->session['data'][':new:']['laravel_old_input']); + + Input::flash('only', array('name')); + + $this->assertEquals(array('name' => 'Taylor'), Session::$instance->session['data'][':new:']['laravel_old_input']); + + Input::flash('except', array('name')); + + $this->assertEquals(array('age' => 25), Session::$instance->session['data'][':new:']['laravel_old_input']); + } + + /** + * Test the Input::flush method. + * + * @group laravel + */ + public function testFlushMethodClearsFlashedInput() + { + $this->setSession(); + + $input = array('name' => 'Taylor', 'age' => 30); + Request::foundation()->request->add($input); + + Input::flash(); + + $this->assertEquals($input, Session::$instance->session['data'][':new:']['laravel_old_input']); + + Input::flush(); + + $this->assertEquals(array(), Session::$instance->session['data'][':new:']['laravel_old_input']); + } + + /** + * Set the session payload instance. + */ + protected function setSession() + { + $driver = $this->getMock('Laravel\\Session\\Drivers\\Driver'); + + Session::$instance = new Laravel\Session\Payload($driver); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/ioc.test.php b/laravel/tests/cases/ioc.test.php new file mode 100644 index 00000000..56918337 --- /dev/null +++ b/laravel/tests/cases/ioc.test.php @@ -0,0 +1,74 @@ +assertEquals('Taylor', IoC::resolve('foo')); + } + + /** + * Test that singletons are created once. + * + * @group laravel + */ + public function testSingletonsAreCreatedOnce() + { + IoC::singleton('foo', function() + { + return new StdClass; + }); + + $object = IoC::resolve('foo'); + + $this->assertTrue($object === IoC::resolve('foo')); + } + + /** + * Test the IoC::instance method. + * + * @group laravel + */ + public function testInstancesAreReturnedBySingleton() + { + $object = new StdClass; + + IoC::instance('bar', $object); + + $this->assertTrue($object === IoC::resolve('bar')); + } + + /** + * Test the IoC::registered method. + */ + public function testRegisteredMethodIndicatesIfRegistered() + { + IoC::register('foo', function() {}); + + $this->assertTrue(IoC::registered('foo')); + $this->assertFalse(IoC::registered('baz')); + } + + /** + * Test the IoC::controller method. + * + * @group laravel + */ + public function testControllerMethodRegistersAController() + { + IoC::register('controller: ioc.test', function() {}); + + $this->assertTrue(IoC::registered('controller: ioc.test')); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/lang.test.php b/laravel/tests/cases/lang.test.php new file mode 100644 index 00000000..74640ccd --- /dev/null +++ b/laravel/tests/cases/lang.test.php @@ -0,0 +1,68 @@ +assertEquals($validation['required'], Lang::line('validation.required')->get()); + $this->assertEquals('Taylor', Lang::line('validation.foo')->get(null, 'Taylor')); + } + + /** + * Test the Lang::line method. + * + * @group laravel + */ + public function testGetMethodCanGetLinesForAGivenLanguage() + { + $validation = require path('app').'language/sp/validation.php'; + + $this->assertEquals($validation['required'], Lang::line('validation.required')->get('sp')); + } + + /** + * Test the __toString method. + * + * @group laravel + */ + public function testLineCanBeCastAsString() + { + $validation = require path('app').'language/en/validation.php'; + + $this->assertEquals($validation['required'], (string) Lang::line('validation.required')); + } + + /** + * Test that string replacements are made on lines. + * + * @group laravel + */ + public function testReplacementsAreMadeOnLines() + { + $validation = require path('app').'language/en/validation.php'; + + $line = str_replace(':attribute', 'e-mail', $validation['required']); + + $this->assertEquals($line, Lang::line('validation.required', array('attribute' => 'e-mail'))->get()); + } + + /** + * Test the Lang::has method. + * + * @group laravel + */ + public function testHasMethodIndicatesIfLangaugeLineExists() + { + $this->assertTrue(Lang::has('validation')); + $this->assertTrue(Lang::has('validation.required')); + $this->assertFalse(Lang::has('validation.foo')); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/messages.test.php b/laravel/tests/cases/messages.test.php new file mode 100644 index 00000000..f007ecb7 --- /dev/null +++ b/laravel/tests/cases/messages.test.php @@ -0,0 +1,115 @@ +messages = new Laravel\Messages; + } + + /** + * Test the Messages::add method. + * + * @group laravel + */ + public function testAddingMessagesDoesNotCreateDuplicateMessages() + { + $this->messages->add('email', 'test'); + $this->messages->add('email', 'test'); + $this->assertCount(1, $this->messages->messages); + } + + /** + * Test the Messages::add method. + * + * @group laravel + */ + public function testAddMethodPutsMessageInMessagesArray() + { + $this->messages->add('email', 'test'); + $this->assertArrayHasKey('email', $this->messages->messages); + $this->assertEquals('test', $this->messages->messages['email'][0]); + } + + /** + * Test the Messages::has method. + * + * @group laravel + */ + public function testHasMethodReturnsTrue() + { + $this->messages->add('email', 'test'); + $this->assertTrue($this->messages->has('email')); + } + + /** + * Test the Messages::has method. + * + * @group laravel + */ + public function testHasMethodReturnsFalse() + { + $this->assertFalse($this->messages->has('something')); + } + + /** + * Test the Messages::first method. + * + * @group laravel + */ + public function testFirstMethodReturnsSingleString() + { + $this->messages->add('email', 'test'); + $this->assertEquals('test', $this->messages->first('email')); + $this->assertEquals('', $this->messages->first('something')); + } + + /** + * Test the Messages::get method. + * + * @group laravel + */ + public function testGetMethodReturnsAllMessagesForAttribute() + { + $messages = array('email' => array('something', 'else')); + $this->messages->messages = $messages; + $this->assertEquals(array('something', 'else'), $this->messages->get('email')); + } + + /** + * Test the Messages::all method. + * + * @group laravel + */ + public function testAllMethodReturnsAllErrorMessages() + { + $messages = array('email' => array('something', 'else'), 'name' => array('foo')); + $this->messages->messages = $messages; + $this->assertEquals(array('something', 'else', 'foo'), $this->messages->all()); + } + + /** + * Test the Messages::get method. + * + * @group laravel + */ + public function testMessagesRespectFormat() + { + $this->messages->add('email', 'test'); + $this->assertEquals('

test

', $this->messages->first('email', '

:message

')); + $this->assertEquals(array('

test

'), $this->messages->get('email', '

:message

')); + $this->assertEquals(array('

test

'), $this->messages->all('

:message

')); + } + + +} \ No newline at end of file diff --git a/laravel/tests/cases/query.test.php b/laravel/tests/cases/query.test.php new file mode 100644 index 00000000..17279150 --- /dev/null +++ b/laravel/tests/cases/query.test.php @@ -0,0 +1,48 @@ +assertEquals('taylor@example.com', $this->query()->find(1)->email); + } + + /** + * Test the select method. + * + * @group laravel + */ + public function testSelectMethodLimitsColumns() + { + $result = $this->query()->select(array('email'))->first(); + + $this->assertTrue(isset($result->email)); + $this->assertFalse(isset($result->name)); + } + + /** + * Test the raw_where method. + * + * @group laravel + */ + public function testRawWhereCanBeUsed() + { + + } + + /** + * Get the query instance for the test case. + * + * @return Query + */ + protected function query() + { + return DB::table('query_test'); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/redirect.test.php b/laravel/tests/cases/redirect.test.php new file mode 100644 index 00000000..cce63a81 --- /dev/null +++ b/laravel/tests/cases/redirect.test.php @@ -0,0 +1,143 @@ +assertEquals(302, $redirect->status()); + $this->assertEquals('http://localhost/user/profile', $redirect->headers()->get('location')); + + $redirect = Redirect::to('user/profile', 301, true); + + $this->assertEquals(301, $redirect->status()); + $this->assertEquals('https://localhost/user/profile', $redirect->headers()->get('location')); + + $redirect = Redirect::to_secure('user/profile', 301); + + $this->assertEquals(301, $redirect->status()); + $this->assertEquals('https://localhost/user/profile', $redirect->headers()->get('location')); + } + + /** + * Test the Redirect::to_route method. + * + * @group laravel + */ + public function testRedirectsCanBeGeneratedForNamedRoutes() + { + Route::get('redirect', array('as' => 'redirect')); + Route::get('redirect/(:any)/(:any)', array('as' => 'redirect-2')); + Route::get('secure/redirect', array('https' => true, 'as' => 'redirect-3')); + + $this->assertEquals(301, Redirect::to_route('redirect', array(), 301, true)->status()); + $this->assertEquals('http://localhost/redirect', Redirect::to_route('redirect')->headers()->get('location')); + $this->assertEquals('https://localhost/secure/redirect', Redirect::to_route('redirect-3', array(), 302)->headers()->get('location')); + $this->assertEquals('http://localhost/redirect/1/2', Redirect::to_route('redirect-2', array('1', '2'))->headers()->get('location')); + } + + /** + * Test the Redirect::with method. + * + * @group laravel + */ + public function testWithMethodFlashesItemToSession() + { + $this->setSession(); + + $redirect = Redirect::to('')->with('name', 'Taylor'); + + $this->assertEquals('Taylor', Session::$instance->session['data'][':new:']['name']); + } + + /** + * Test the Redirect::with_input function. + * + * @group laravel + */ + public function testWithInputMethodFlashesInputToTheSession() + { + $this->setSession(); + + $input = array('name' => 'Taylor', 'age' => 25); + Request::foundation()->request->add($input); + + $redirect = Redirect::to('')->with_input(); + + $this->assertEquals($input, Session::$instance->session['data'][':new:']['laravel_old_input']); + + $redirect = Redirect::to('')->with_input('only', array('name')); + + $this->assertEquals(array('name' => 'Taylor'), Session::$instance->session['data'][':new:']['laravel_old_input']); + + $redirect = Redirect::to('')->with_input('except', array('name')); + + $this->assertEquals(array('age' => 25), Session::$instance->session['data'][':new:']['laravel_old_input']); + } + + /** + * Test the Redirect::with_errors method. + * + * @group laravel + */ + public function testWithErrorsFlashesErrorsToTheSession() + { + $this->setSession(); + + Redirect::to('')->with_errors(array('name' => 'Taylor')); + + $this->assertEquals(array('name' => 'Taylor'), Session::$instance->session['data'][':new:']['errors']); + + $validator = Validator::make(array(), array()); + $validator->errors = array('name' => 'Taylor'); + + Redirect::to('')->with_errors($validator); + + $this->assertEquals(array('name' => 'Taylor'), Session::$instance->session['data'][':new:']['errors']); + } + + /** + * Set the session payload instance. + */ + protected function setSession() + { + $driver = $this->getMock('Laravel\\Session\\Drivers\\Driver'); + + Session::$instance = new Laravel\Session\Payload($driver); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/request.test.php b/laravel/tests/cases/request.test.php new file mode 100644 index 00000000..4641a532 --- /dev/null +++ b/laravel/tests/cases/request.test.php @@ -0,0 +1,177 @@ +restartRequest(); + } + + /** + * Set one of the $_POST variables. + * + * @param string $key + * @param string $value + */ + protected function setPostVar($key, $value) + { + $_POST[$key] = $value; + + $this->restartRequest(); + } + + /** + * Reinitialize the global request. + * + * @return void + */ + protected function restartRequest() + { + // FIXME: Ugly hack, but old contents from previous requests seem to + // trip up the Foundation class. + $_FILES = array(); + + Request::$foundation = RequestFoundation::createFromGlobals(); + } + + /** + * Test the Request::method method. + * + * @group laravel + */ + public function testMethodReturnsTheHTTPRequestMethod() + { + $this->setServerVar('REQUEST_METHOD', 'POST'); + + $this->assertEquals('POST', Request::method()); + + $this->setPostVar(Request::spoofer, 'PUT'); + + $this->assertEquals('PUT', Request::method()); + } + + /** + * Test the Request::server method. + * + * @group laravel + */ + public function testServerMethodReturnsFromServerArray() + { + $this->setServerVar('TEST', 'something'); + $this->setServerVar('USER', array('NAME' => 'taylor')); + + $this->assertEquals('something', Request::server('test')); + $this->assertEquals('taylor', Request::server('user.name')); + } + + /** + * Test the Request::ip method. + * + * @group laravel + */ + public function testIPMethodReturnsClientIPAddress() + { + $this->setServerVar('REMOTE_ADDR', 'something'); + $this->assertEquals('something', Request::ip()); + + $this->setServerVar('HTTP_CLIENT_IP', 'something'); + $this->assertEquals('something', Request::ip()); + + $this->setServerVar('HTTP_CLIENT_IP', 'something'); + $this->assertEquals('something', Request::ip()); + + $_SERVER = array(); + $this->restartRequest(); + $this->assertEquals('0.0.0.0', Request::ip()); + } + + /** + * Test the Request::secure method. + * + * @group laravel + */ + public function testSecureMethodsIndicatesIfHTTPS() + { + $this->setServerVar('HTTPS', 'on'); + + $this->assertTrue(Request::secure()); + + $this->setServerVar('HTTPS', 'off'); + + $this->assertFalse(Request::secure()); + } + + /** + * Test the Request::ajax method. + * + * @group laravel + */ + public function testAjaxMethodIndicatesWhenAjax() + { + $this->assertFalse(Request::ajax()); + + $this->setServerVar('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest'); + + $this->assertTrue(Request::ajax()); + } + + /** + * Test the Request::forged method. + * + * @group laravel + */ + public function testForgedMethodIndicatesIfRequestWasForged() + { + Session::$instance = new SessionPayloadTokenStub; + + $input = array(Session::csrf_token => 'Foo'); + Request::foundation()->request->add($input); + + $this->assertTrue(Request::forged()); + + $input = array(Session::csrf_token => 'Taylor'); + Request::foundation()->request->add($input); + + $this->assertFalse(Request::forged()); + } + + /** + * Test the Request::route method. + * + * @group laravel + */ + public function testRouteMethodReturnsStaticRoute() + { + Request::$route = 'Taylor'; + + $this->assertEquals('Taylor', Request::route()); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/response.test.php b/laravel/tests/cases/response.test.php new file mode 100644 index 00000000..11e48e74 --- /dev/null +++ b/laravel/tests/cases/response.test.php @@ -0,0 +1,89 @@ + 'baz')); + + $this->assertEquals('foo', $response->content); + $this->assertEquals(201, $response->status()); + $this->assertArrayHasKey('bar', $response->headers()->all()); + $this->assertEquals('baz', $response->headers()->get('bar')); + } + + /** + * Test the Response::view method. + * + * @group laravel + */ + public function testViewMethodSetsContentToView() + { + $response = Response::view('home.index', array('name' => 'Taylor')); + + $this->assertEquals('home.index', $response->content->view); + $this->assertEquals('Taylor', $response->content->data['name']); + } + + /** + * Test the Response::error method. + * + * @group laravel + */ + public function testErrorMethodSetsContentToErrorView() + { + $response = Response::error('404', array('name' => 'Taylor')); + + $this->assertEquals(404, $response->status()); + $this->assertEquals('error.404', $response->content->view); + $this->assertEquals('Taylor', $response->content->data['name']); + } + + /** + * Test the Response::prepare method. + * + * @group laravel + */ + public function testPrepareMethodCreatesAResponseInstanceFromGivenValue() + { + $response = Response::prepare('Taylor'); + + $this->assertInstanceOf('Laravel\\Response', $response); + $this->assertEquals('Taylor', $response->content); + + $response = Response::prepare(new Response('Taylor')); + + $this->assertInstanceOf('Laravel\\Response', $response); + $this->assertEquals('Taylor', $response->content); + } + + /** + * Test the Response::header method. + * + * @group laravel + */ + public function testHeaderMethodSetsValueInHeaderArray() + { + $response = Response::make('')->header('foo', 'bar'); + + $this->assertEquals('bar', $response->headers()->get('foo')); + } + + /** + * Test the Response::status method. + * + * @group laravel + */ + public function testStatusMethodSetsStatusCode() + { + $response = Response::make('')->status(404); + + $this->assertEquals(404, $response->status()); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/route.test.php b/laravel/tests/cases/route.test.php new file mode 100644 index 00000000..48919135 --- /dev/null +++ b/laravel/tests/cases/route.test.php @@ -0,0 +1,179 @@ + 'profile')); + $this->assertTrue($route->is('profile')); + $this->assertFalse($route->is('something')); + } + + /** + * Test the basic execution of a route. + * + * @group laravel + */ + public function testBasicRoutesCanBeExecutedProperly() + { + $route = new Route('GET', '', array(function() { return 'Route!'; })); + + $this->assertEquals('Route!', $route->call()->content); + $this->assertInstanceOf('Laravel\\Response', $route->call()); + } + + /** + * Test that route parameters are passed into the handlers. + * + * @group laravel + */ + public function testRouteParametersArePassedIntoTheHandler() + { + $route = new Route('GET', '', array(function($var) { return $var; }), array('Taylor')); + + $this->assertEquals('Taylor', $route->call()->content); + $this->assertInstanceOf('Laravel\\Response', $route->call()); + } + + /** + * Test that calling a route calls the global before and after filters. + * + * @group laravel + */ + public function testCallingARouteCallsTheBeforeAndAfterFilters() + { + $route = new Route('GET', '', array(function() { return 'Hi!'; })); + + $_SERVER['before'] = false; + $_SERVER['after'] = false; + + $route->call(); + + $this->assertTrue($_SERVER['before']); + $this->assertTrue($_SERVER['after']); + } + + /** + * Test that before filters override the route response. + * + * @group laravel + */ + public function testBeforeFiltersOverrideTheRouteResponse() + { + Filter::register('test-before', function() + { + return 'Filtered!'; + }); + + $route = new Route('GET', '', array('before' => 'test-before', function() { + return 'Route!'; + })); + + $this->assertEquals('Filtered!', $route->call()->content); + } + + /** + * Test that after filters do not affect the route response. + * + * @group laravel + */ + public function testAfterFilterDoesNotAffectTheResponse() + { + $_SERVER['test-after'] = false; + + Filter::register('test-after', function() + { + $_SERVER['test-after'] = true; + return 'Filtered!'; + }); + + $route = new Route('GET', '', array('after' => 'test-after', function() + { + return 'Route!'; + })); + + $this->assertEquals('Route!', $route->call()->content); + $this->assertTrue($_SERVER['test-after']); + } + + /** + * Test that the route calls the appropriate controller method when delegating. + * + * @group laravel + */ + public function testControllerActionCalledWhenDelegating() + { + $_SERVER['REQUEST_METHOD'] = 'GET'; + + $route = new Route('GET', '', array('uses' => 'auth@index')); + + $this->assertEquals('action_index', $route->call()->content); + } + + /** + * Test that filter parameters are passed to the filter. + * + * @group laravel + */ + public function testFilterParametersArePassedToFilter() + { + Filter::register('test-params', function($var1, $var2) + { + return $var1.$var2; + }); + + $route = new Route('GET', '', array('before' => 'test-params:1,2')); + + $this->assertEquals('12', $route->call()->content); + } + + /** + * Test that multiple filters can be assigned to a route. + * + * @group laravel + */ + public function testMultipleFiltersCanBeAssignedToARoute() + { + $_SERVER['test-multi-1'] = false; + $_SERVER['test-multi-2'] = false; + + Filter::register('test-multi-1', function() { $_SERVER['test-multi-1'] = true; }); + Filter::register('test-multi-2', function() { $_SERVER['test-multi-2'] = true; }); + + $route = new Route('GET', '', array('before' => 'test-multi-1|test-multi-2')); + + $route->call(); + + $this->assertTrue($_SERVER['test-multi-1']); + $this->assertTrue($_SERVER['test-multi-2']); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/routing.test.php b/laravel/tests/cases/routing.test.php new file mode 100644 index 00000000..68a112a0 --- /dev/null +++ b/laravel/tests/cases/routing.test.php @@ -0,0 +1,160 @@ + 'home')); + Route::get('dashboard', array('as' => 'dashboard')); + + $home = Router::find('home'); + $dashboard = Router::find('dashboard'); + + $this->assertTrue(isset($home['/'])); + $this->assertTrue(isset($dashboard['dashboard'])); + } + + /** + * Test the basic routing mechanism. + * + * @group laravel + */ + public function testBasicRouteCanBeRouted() + { + Route::get('/', function() {}); + Route::get('home, main', function() {}); + + $this->assertEquals('/', Router::route('GET', '/')->uri); + $this->assertEquals('home', Router::route('GET', 'home')->uri); + $this->assertEquals('main', Router::route('GET', 'main')->uri); + } + + /** + * Test that the router can handle basic wildcards. + * + * @group laravel + */ + public function testWildcardRoutesCanBeRouted() + { + Route::get('user/(:num)', function() {}); + Route::get('profile/(:any)/(:num)', function() {}); + + $this->assertNull(Router::route('GET', 'user/1.5')); + $this->assertNull(Router::route('GET', 'user/taylor')); + $this->assertEquals(array(25), Router::route('GET', 'user/25')->parameters); + $this->assertEquals('user/(:num)', Router::route('GET', 'user/1')->uri); + + $this->assertNull(Router::route('GET', 'profile/1/otwell')); + $this->assertNull(Router::route('POST', 'profile/taylor/1')); + $this->assertNull(Router::route('GET', 'profile/taylor/otwell')); + $this->assertNull(Router::route('GET', 'profile/taylor/1/otwell')); + $this->assertEquals(array('taylor', 25), Router::route('GET', 'profile/taylor/25')->parameters); + $this->assertEquals('profile/(:any)/(:num)', Router::route('GET', 'profile/taylor/1')->uri); + } + + /** + * Test that optional wildcards can be routed. + * + * @group laravel + */ + public function testOptionalWildcardsCanBeRouted() + { + Route::get('user/(:num?)', function() {}); + Route::get('profile/(:any)/(:any?)', function() {}); + + $this->assertNull(Router::route('GET', 'user/taylor')); + $this->assertEquals('user/(:num?)', Router::route('GET', 'user')->uri); + $this->assertEquals(array(25), Router::route('GET', 'user/25')->parameters); + $this->assertEquals('user/(:num?)', Router::route('GET', 'user/1')->uri); + + $this->assertNull(Router::route('GET', 'profile/taylor/otwell/test')); + $this->assertEquals('profile/(:any)/(:any?)', Router::route('GET', 'profile/taylor')->uri); + $this->assertEquals('profile/(:any)/(:any?)', Router::route('GET', 'profile/taylor/25')->uri); + $this->assertEquals('profile/(:any)/(:any?)', Router::route('GET', 'profile/taylor/otwell')->uri); + $this->assertEquals(array('taylor', 'otwell'), Router::route('GET', 'profile/taylor/otwell')->parameters); + } + + /** + * Test that basic controller routing is working. + * + * @group laravel + */ + public function testBasicRouteToControllerIsRouted() + { + $this->assertEquals('auth@(:1)', Router::route('GET', 'auth')->action['uses']); + $this->assertEquals('home@(:1)', Router::route('GET', 'home/index')->action['uses']); + $this->assertEquals('home@(:1)', Router::route('GET', 'home/profile')->action['uses']); + $this->assertEquals('admin.panel@(:1)', Router::route('GET', 'admin/panel')->action['uses']); + $this->assertEquals('admin.panel@(:1)', Router::route('GET', 'admin/panel/show')->action['uses']); + } + + /** + * Test basic bundle route resolution. + * + * @group laravel + */ + public function testRoutesToBundlesCanBeResolved() + { + $this->assertNull(Router::route('GET', 'dashboard/foo')); + $this->assertEquals('dashboard', Router::route('GET', 'dashboard')->uri); + } + + /** + * Test bundle controller route resolution. + * + * @group laravel + */ + public function testBundleControllersCanBeResolved() + { + $this->assertEquals('dashboard::panel@(:1)', Router::route('GET', 'dashboard/panel')->action['uses']); + $this->assertEquals('dashboard::panel@(:1)', Router::route('GET', 'dashboard/panel/show')->action['uses']); + } + + /** + * Test foreign characters can be used in routes. + * + * @group laravel + */ + public function testForeignCharsInRoutes() + { + Route::get(urlencode('مدرس_رياضيات').'/(:any)', function() {}); + Route::get(urlencode('مدرس_رياضيات'), function() {}); + Route::get(urlencode('ÇœŪ'), function() {}); + Route::get(urlencode('私は料理が大好き'), function() {}); + + $this->assertEquals(array(urlencode('مدرس_رياضيات')), Router::route('GET', urlencode('مدرس_رياضيات').'/'.urlencode('مدرس_رياضيات'))->parameters); + $this->assertEquals(urlencode('مدرس_رياضيات'), Router::route('GET', urlencode('مدرس_رياضيات'))->uri); + $this->assertEquals(urlencode('ÇœŪ'), Router::route('GET', urlencode('ÇœŪ'))->uri); + $this->assertEquals(urlencode('私は料理が大好き'), Router::route('GET', urlencode('私は料理が大好き'))->uri); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/session.test.php b/laravel/tests/cases/session.test.php new file mode 100644 index 00000000..cf6946a7 --- /dev/null +++ b/laravel/tests/cases/session.test.php @@ -0,0 +1,443 @@ +assertEquals('Foo', Session::test()); + } + + /** + * Test the Session::started method. + * + * @group laravel + */ + public function testStartedMethodIndicatesIfSessionIsStarted() + { + $this->assertFalse(Session::started()); + Session::$instance = 'foo'; + $this->assertTrue(Session::started()); + } + + /** + * Test the Payload::load method. + * + * @group laravel + */ + public function testLoadMethodCreatesNewSessionWithNullIDGiven() + { + $payload = $this->getPayload(); + $payload->load(null); + $this->verifyNewSession($payload); + } + + /** + * Test the Payload::load method. + * + * @group laravel + */ + public function testLoadMethodCreatesNewSessionWhenSessionIsExpired() + { + $payload = $this->getPayload(); + + $session = $this->getSession(); + $session['last_activity'] = time() - 10000; + + $payload->driver->expects($this->any()) + ->method('load') + ->will($this->returnValue($session)); + + $payload->load('foo'); + + $this->verifyNewSession($payload); + $this->assertTrue($payload->session['id'] !== $session['id']); + } + + /** + * Assert that a session is new. + * + * @param Payload $payload + * @return void + */ + protected function verifyNewSession($payload) + { + $this->assertFalse($payload->exists); + $this->assertTrue(isset($payload->session['id'])); + $this->assertEquals(array(), $payload->session['data'][':new:']); + $this->assertEquals(array(), $payload->session['data'][':old:']); + $this->assertTrue(isset($payload->session['data'][Session::csrf_token])); + } + + /** + * Test the Payload::load method. + * + * @group laravel + */ + public function testLoadMethodSetsValidSession() + { + $payload = $this->getPayload(); + + $session = $this->getSession(); + + $payload->driver->expects($this->any()) + ->method('load') + ->will($this->returnValue($session)); + + $payload->load('foo'); + + $this->assertEquals($session, $payload->session); + } + + /** + * Test the Payload::load method. + * + * @group laravel + */ + public function testLoadMethodSetsCSRFTokenIfDoesntExist() + { + $payload = $this->getPayload(); + + $session = $this->getSession(); + + unset($session['data']['csrf_token']); + + $payload->driver->expects($this->any()) + ->method('load') + ->will($this->returnValue($session)); + + $payload->load('foo'); + + $this->assertEquals('foo', $payload->session['id']); + $this->assertTrue(isset($payload->session['data']['csrf_token'])); + } + + /** + * Test the various data retrieval methods. + * + * @group laravel + */ + public function testSessionDataCanBeRetrievedProperly() + { + $payload = $this->getPayload(); + + $payload->session = $this->getSession(); + + $this->assertTrue($payload->has('name')); + $this->assertEquals('Taylor', $payload->get('name')); + $this->assertFalse($payload->has('foo')); + $this->assertEquals('Default', $payload->get('foo', 'Default')); + $this->assertTrue($payload->has('votes')); + $this->assertEquals(10, $payload->get('votes')); + $this->assertTrue($payload->has('state')); + $this->assertEquals('AR', $payload->get('state')); + } + + /** + * Test the various data manipulation methods. + * + * @group laravel + */ + public function testDataCanBeSetProperly() + { + $payload = $this->getPayload(); + + $payload->session = $this->getSession(); + + // Test the "put" and "flash" methods. + $payload->put('name', 'Weldon'); + $this->assertEquals('Weldon', $payload->session['data']['name']); + $payload->flash('language', 'php'); + $this->assertEquals('php', $payload->session['data'][':new:']['language']); + + // Test the "reflash" method. + $payload->session['data'][':new:'] = array('name' => 'Taylor'); + $payload->session['data'][':old:'] = array('age' => 25); + $payload->reflash(); + $this->assertEquals(array('name' => 'Taylor', 'age' => 25), $payload->session['data'][':new:']); + + // Test the "keep" method. + $payload->session['data'][':new:'] = array(); + $payload->keep(array('age')); + $this->assertEquals(25, $payload->session['data'][':new:']['age']); + } + + /** + * Test the Payload::forget method. + * + * @group laravel + */ + public function testSessionDataCanBeForgotten() + { + $payload = $this->getPayload(); + + $payload->session = $this->getSession(); + + $this->assertTrue(isset($payload->session['data']['name'])); + $payload->forget('name'); + $this->assertFalse(isset($payload->session['data']['name'])); + } + + /** + * Test the Payload::flush method. + * + * @group laravel + */ + public function testFlushMaintainsTokenButDeletesEverythingElse() + { + $payload = $this->getPayload(); + + $payload->session = $this->getSession(); + + $this->assertTrue(isset($payload->session['data']['name'])); + $payload->flush(); + $this->assertFalse(isset($payload->session['data']['name'])); + $this->assertEquals('bar', $payload->session['data']['csrf_token']); + $this->assertEquals(array(), $payload->session['data'][':new:']); + $this->assertEquals(array(), $payload->session['data'][':old:']); + } + + /** + * Test the Payload::regenerate method. + * + * @group laravel + */ + public function testRegenerateMethodSetsNewIDAndTurnsOffExistenceIndicator() + { + $payload = $this->getPayload(); + + $payload->sesion = $this->getSession(); + $payload->exists = true; + $payload->regenerate(); + + $this->assertFalse($payload->exists); + $this->assertTrue(strlen($payload->session['id']) == 40); + } + + /** + * Test the Payload::token method. + * + * @group laravel + */ + public function testTokenMethodReturnsCSRFToken() + { + $payload = $this->getPayload(); + $payload->session = $this->getSession(); + + $this->assertEquals('bar', $payload->token()); + } + + /** + * Test the Payload::save method. + * + * @group laravel + */ + public function testSaveMethodCorrectlyCallsDriver() + { + $payload = $this->getPayload(); + $session = $this->getSession(); + $payload->session = $session; + $payload->exists = true; + $config = Laravel\Config::get('session'); + + $expect = $session; + $expect['data'][':old:'] = $session['data'][':new:']; + $expect['data'][':new:'] = array(); + + $payload->driver->expects($this->once()) + ->method('save') + ->with($this->equalTo($expect), $this->equalTo($config), $this->equalTo(true)); + + $payload->save(); + + $this->assertEquals($session['data'][':new:'], $payload->session['data'][':old:']); + } + + /** + * Test the Payload::save method. + * + * @group laravel + */ + public function testSaveMethodSweepsIfSweeperAndOddsHitWithTimeGreaterThanThreshold() + { + Config::set('session.sweepage', array(100, 100)); + + $payload = $this->getPayload(); + $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\File', array('save', 'sweep'), array(null)); + $payload->session = $this->getSession(); + + $expiration = time() - (Config::get('session.lifetime') * 60); + + // Here we set the time to the expected expiration minus 5 seconds, just to + // allow plenty of room for PHP execution. In the next test, we'll do the + // same thing except add 5 seconds to check that the time is between a + // given window. + $payload->driver->expects($this->once()) + ->method('sweep') + ->with($this->greaterThan($expiration - 5)); + + $payload->save(); + + Config::set('session.sweepage', array(2, 100)); + } + + /** + * Test the Payload::save method. + * + * @group laravel + */ + public function testSaveMethodSweepsIfSweeperAndOddsHitWithTimeLessThanThreshold() + { + Config::set('session.sweepage', array(100, 100)); + + $payload = $this->getPayload(); + $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\File', array('save', 'sweep'), array(null)); + $payload->session = $this->getSession(); + + $expiration = time() - (Config::get('session.lifetime') * 60); + + $payload->driver->expects($this->once()) + ->method('sweep') + ->with($this->lessThan($expiration + 5)); + + $payload->save(); + + Config::set('session.sweepage', array(2, 100)); + } + + /** + * Test that the session sweeper is never called if not a sweeper. + * + * @group laravel + */ + public function testSweeperShouldntBeCalledIfDriverIsntSweeper() + { + Config::set('session.sweepage', array(100, 100)); + + $payload = $this->getPayload(); + $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\APC', array('save', 'sweep'), array(), '', false); + $payload->session = $this->getSession(); + + $payload->driver->expects($this->never())->method('sweep'); + + $payload->save(); + + Config::set('session.sweepage', array(2, 100)); + } + + /** + * Test the Payload::save method. + * + * @group laravel + */ + public function testSaveMethodSetsCookieWithCorrectValues() + { + $payload = $this->getPayload(); + $payload->session = $this->getSession(); + $payload->save(); + + $this->assertTrue(isset(Cookie::$jar[Config::get('session.cookie')])); + + $cookie = Cookie::$jar[Config::get('session.cookie')]; + + $this->assertEquals('foo', $cookie['value']); + // Shouldn't be able to test this cause session.lifetime store number of minutes + // while cookie expiration store timestamp when it going to expired. + // $this->assertEquals(Config::get('session.lifetime'), $cookie['expiration']); + $this->assertEquals(Config::get('session.domain'), $cookie['domain']); + $this->assertEquals(Config::get('session.path'), $cookie['path']); + $this->assertEquals(Config::get('session.secure'), $cookie['secure']); + } + + /** + * Test the Session::activity method. + * + * @group laravel + */ + public function testActivityMethodReturnsLastActivity() + { + $payload = $this->getPayload(); + $payload->session['last_activity'] = 10; + $this->assertEquals(10, $payload->activity()); + } + + /** + * Get a session payload instance. + * + * @return Payload + */ + protected function getPayload() + { + return new Payload($this->getMockDriver()); + } + + /** + * Get a mock driver instance. + * + * @return Driver + */ + protected function getMockDriver() + { + $mock = $this->getMock('Laravel\\Session\\Drivers\\Driver', array('id', 'load', 'save', 'delete')); + + $mock->expects($this->any())->method('id')->will($this->returnValue(Str::random(40))); + + return $mock; + } + + /** + * Get a dummy session. + * + * @return array + */ + protected function getSession() + { + return array( + 'id' => 'foo', + 'last_activity' => time(), + 'data' => array( + 'name' => 'Taylor', + 'age' => 25, + 'csrf_token' => 'bar', + ':new:' => array( + 'votes' => 10, + ), + ':old:' => array( + 'state' => 'AR', + ), + )); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/str.test.php b/laravel/tests/cases/str.test.php new file mode 100644 index 00000000..7daab540 --- /dev/null +++ b/laravel/tests/cases/str.test.php @@ -0,0 +1,133 @@ +assertEquals('UTF-8', Config::get('application.encoding')); + Config::set('application.encoding', 'foo'); + $this->assertEquals('foo', Config::get('application.encoding')); + Config::set('application.encoding', 'UTF-8'); + } + + /** + * Test the Str::length method. + * + * @group laravel + */ + public function testStringLengthIsCorrect() + { + $this->assertEquals(6, Str::length('Taylor')); + $this->assertEquals(5, Str::length('ラドクリフ')); + } + + /** + * Test the Str::lower method. + * + * @group laravel + */ + public function testStringCanBeConvertedToLowercase() + { + $this->assertEquals('taylor', Str::lower('TAYLOR')); + $this->assertEquals('άχιστη', Str::lower('ΆΧΙΣΤΗ')); + } + + /** + * Test the Str::upper method. + * + * @group laravel + */ + public function testStringCanBeConvertedToUppercase() + { + $this->assertEquals('TAYLOR', Str::upper('taylor')); + $this->assertEquals('ΆΧΙΣΤΗ', Str::upper('άχιστη')); + } + + /** + * Test the Str::title method. + * + * @group laravel + */ + public function testStringCanBeConvertedToTitleCase() + { + $this->assertEquals('Taylor', Str::title('taylor')); + $this->assertEquals('Άχιστη', Str::title('άχιστη')); + } + + /** + * Test the Str::limit method. + * + * @group laravel + */ + public function testStringCanBeLimitedByCharacters() + { + $this->assertEquals('Tay...', Str::limit('Taylor', 3)); + $this->assertEquals('Taylor', Str::limit('Taylor', 6)); + $this->assertEquals('Tay___', Str::limit('Taylor', 3, '___')); + } + + /** + * Test the Str::words method. + * + * @group laravel + */ + public function testStringCanBeLimitedByWords() + { + $this->assertEquals('Taylor...', Str::words('Taylor Otwell', 1)); + $this->assertEquals('Taylor___', Str::words('Taylor Otwell', 1, '___')); + $this->assertEquals('Taylor Otwell', Str::words('Taylor Otwell', 3)); + } + + /** + * Test the Str::plural and Str::singular methods. + * + * @group laravel + */ + public function testStringsCanBeSingularOrPlural() + { + $this->assertEquals('user', Str::singular('users')); + $this->assertEquals('users', Str::plural('user')); + $this->assertEquals('User', Str::singular('Users')); + $this->assertEquals('Users', Str::plural('User')); + $this->assertEquals('user', Str::plural('user', 1)); + $this->assertEquals('users', Str::plural('user', 2)); + } + + /** + * Test the Str::slug method. + * + * @group laravel + */ + public function testStringsCanBeSlugged() + { + $this->assertEquals('my-new-post', Str::slug('My nEw post!!!')); + $this->assertEquals('my_new_post', Str::slug('My nEw post!!!', '_')); + } + + /** + * Test the Str::classify method. + * + * @group laravel + */ + public function testStringsCanBeClassified() + { + $this->assertEquals('Something_Else', Str::classify('something.else')); + $this->assertEquals('Something_Else', Str::classify('something_else')); + } + + /** + * Test the Str::random method. + * + * @group laravel + */ + public function testRandomStringsCanBeGenerated() + { + $this->assertEquals(40, strlen(Str::random(40))); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/uri.test.php b/laravel/tests/cases/uri.test.php new file mode 100644 index 00000000..8f2b85ff --- /dev/null +++ b/laravel/tests/cases/uri.test.php @@ -0,0 +1,75 @@ +setRequestUri($uri); + + $this->assertEquals($expectation, URI::current()); + } + + /** + * Test the URI::segment method. + * + * @group laravel + */ + public function testSegmentMethodReturnsAURISegment() + { + $this->setRequestUri('/user/profile'); + + $this->assertEquals('user', URI::segment(1)); + $this->assertEquals('profile', URI::segment(2)); + } + + /** + * Data provider for the URI::current test. + */ + public function requestUriProvider() + { + return array( + array('/user', 'user'), + array('/user/', 'user'), + array('', '/'), + array('/', '/'), + array('//', '/'), + array('/user', 'user'), + array('/user/', 'user'), + array('/user/profile', 'user/profile'), + ); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/url.test.php b/laravel/tests/cases/url.test.php new file mode 100644 index 00000000..393211be --- /dev/null +++ b/laravel/tests/cases/url.test.php @@ -0,0 +1,106 @@ +assertEquals('http://localhost/index.php/user/profile', URL::to('user/profile')); + $this->assertEquals('https://localhost/index.php/user/profile', URL::to('user/profile', true)); + + Config::set('application.index', ''); + + $this->assertEquals('http://localhost/user/profile', URL::to('user/profile')); + $this->assertEquals('https://localhost/user/profile', URL::to('user/profile', true)); + + Config::set('application.ssl', false); + + $this->assertEquals('http://localhost/user/profile', URL::to('user/profile', true)); + } + + /** + * Test the URL::to_action method. + * + * @group laravel + */ + public function testToActionMethodGeneratesURLToControllerAction() + { + Route::get('foo/bar/(:any?)', 'foo@baz'); + $this->assertEquals('http://localhost/index.php/x/y', URL::to_action('x@y')); + $this->assertEquals('http://localhost/index.php/x/y/Taylor', URL::to_action('x@y', array('Taylor'))); + $this->assertEquals('http://localhost/index.php/foo/bar', URL::to_action('foo@baz')); + $this->assertEquals('http://localhost/index.php/foo/bar/Taylor', URL::to_action('foo@baz', array('Taylor'))); + } + + /** + * Test the URL::to_asset method. + * + * @group laravel + */ + public function testToAssetGeneratesURLWithoutFrontControllerInURL() + { + $this->assertEquals('http://localhost/image.jpg', URL::to_asset('image.jpg')); + $this->assertEquals('https://localhost/image.jpg', URL::to_asset('image.jpg', true)); + + Config::set('application.index', ''); + + $this->assertEquals('http://localhost/image.jpg', URL::to_asset('image.jpg')); + $this->assertEquals('https://localhost/image.jpg', URL::to_asset('image.jpg', true)); + + Request::foundation()->server->add(array('HTTPS' => 'on')); + + $this->assertEquals('https://localhost/image.jpg', URL::to_asset('image.jpg')); + } + + /** + * Test the URL::to_route method. + * + * @group laravel + */ + public function testToRouteMethodGeneratesURLsToRoutes() + { + Route::get('url/test', array('as' => 'url-test')); + Route::get('url/test/(:any)/(:any?)', array('as' => 'url-test-2')); + Route::get('url/secure/(:any)/(:any?)', array('as' => 'url-test-3', 'https' => true)); + + $this->assertEquals('http://localhost/index.php/url/test', URL::to_route('url-test')); + $this->assertEquals('http://localhost/index.php/url/test/taylor', URL::to_route('url-test-2', array('taylor'))); + $this->assertEquals('https://localhost/index.php/url/secure/taylor', URL::to_route('url-test-3', array('taylor'))); + $this->assertEquals('http://localhost/index.php/url/test/taylor/otwell', URL::to_route('url-test-2', array('taylor', 'otwell'))); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/validator.test.php b/laravel/tests/cases/validator.test.php new file mode 100644 index 00000000..bde1cea1 --- /dev/null +++ b/laravel/tests/cases/validator.test.php @@ -0,0 +1,669 @@ + 'Taylor Otwell'); + $rules = array('name' => 'required'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['name'] = ''; + $this->assertFalse(Validator::make($input, $rules)->valid()); + + unset($input['name']); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + $_FILES['name']['tmp_name'] = 'foo'; + $this->assertTrue(Validator::make($_FILES, $rules)->valid()); + + $_FILES['name']['tmp_name'] = ''; + $this->assertFalse(Validator::make($_FILES, $rules)->valid()); + } + + /** + * Test the confirmed validation rule. + * + * @group laravel + */ + public function testTheConfirmedRule() + { + $input = array('password' => 'foo', 'password_confirmation' => 'foo'); + $rules = array('password' => 'confirmed'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['password_confirmation'] = 'foo_bar'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + + unset($input['password_confirmation']); + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the different validation rule. + * + * @group laravel + */ + public function testTheDifferentRule() + { + $input = array('password' => 'foo', 'password_confirmation' => 'bar'); + $rules = array('password' => 'different:password_confirmation'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['password_confirmation'] = 'foo'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + + unset($input['password_confirmation']); + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the accepted validation rule. + * + * @group laravel + */ + public function testTheAcceptedRule() + { + $input = array('terms' => '1'); + $rules = array('terms' => 'accepted'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['terms'] = 'yes'; + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['terms'] = '2'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // The accepted rule implies required, so should fail if field not present. + unset($input['terms']); + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the numeric validation rule. + * + * @group laravel + */ + public function testTheNumericRule() + { + $input = array('amount' => '1.21'); + $rules = array('amount' => 'numeric'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['amount'] = '1'; + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['amount'] = 1.2; + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['amount'] = '1.2a'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the integer validation rule. + * + * @group laravel + */ + public function testTheIntegerRule() + { + $input = array('amount' => '1'); + $rules = array('amount' => 'integer'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['amount'] = '0'; + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['amount'] = 1.2; + $this->assertFalse(Validator::make($input, $rules)->valid()); + + $input['amount'] = '1.2a'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the size validation rule. + * + * @group laravel + */ + public function testTheSizeRule() + { + $input = array('amount' => '1.21'); + $rules = array('amount' => 'numeric|size:1.21'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $rules = array('amount' => 'numeric|size:1'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // If no numeric rule is on the field, it is treated as a string + $input = array('amount' => '111'); + $rules = array('amount' => 'size:3'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $rules = array('amount' => 'size:4'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // The size rules checks kilobytes on files + $_FILES['photo']['tmp_name'] = 'foo'; + $_FILES['photo']['size'] = 10240; + $rules = array('photo' => 'size:10'); + $this->assertTrue(Validator::make($_FILES, $rules)->valid()); + + $_FILES['photo']['size'] = 14000; + $this->assertFalse(Validator::make($_FILES, $rules)->valid()); + } + + /** + * Test the between validation rule. + * + * @group laravel + */ + public function testTheBetweenRule() + { + $input = array('amount' => '1.21'); + $rules = array('amount' => 'numeric|between:1,2'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $rules = array('amount' => 'numeric|between:2,3'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // If no numeric rule is on the field, it is treated as a string + $input = array('amount' => '111'); + $rules = array('amount' => 'between:1,3'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $rules = array('amount' => 'between:100,111'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // The size rules checks kilobytes on files + $_FILES['photo']['tmp_name'] = 'foo'; + $_FILES['photo']['size'] = 10240; + $rules = array('photo' => 'between:9,11'); + $this->assertTrue(Validator::make($_FILES, $rules)->valid()); + + $_FILES['photo']['size'] = 14000; + $this->assertFalse(Validator::make($_FILES, $rules)->valid()); + } + + /** + * Test the between validation rule. + * + * @group laravel + */ + public function testTheMinRule() + { + $input = array('amount' => '1.21'); + $rules = array('amount' => 'numeric|min:1'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $rules = array('amount' => 'numeric|min:2'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // If no numeric rule is on the field, it is treated as a string + $input = array('amount' => '01'); + $rules = array('amount' => 'min:2'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $rules = array('amount' => 'min:3'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // The size rules checks kilobytes on files + $_FILES['photo']['tmp_name'] = 'foo'; + $_FILES['photo']['size'] = 10240; + $rules = array('photo' => 'min:9'); + $this->assertTrue(Validator::make($_FILES, $rules)->valid()); + + $_FILES['photo']['size'] = 8000; + $this->assertFalse(Validator::make($_FILES, $rules)->valid()); + } + + /** + * Test the between validation rule. + * + * @group laravel + */ + public function testTheMaxRule() + { + $input = array('amount' => '1.21'); + $rules = array('amount' => 'numeric|max:2'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $rules = array('amount' => 'numeric|max:1'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // If no numeric rule is on the field, it is treated as a string + $input = array('amount' => '01'); + $rules = array('amount' => 'max:3'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $rules = array('amount' => 'max:1'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + // The size rules checks kilobytes on files + $_FILES['photo']['tmp_name'] = 'foo'; + $_FILES['photo']['size'] = 10240; + $rules = array('photo' => 'max:11'); + $this->assertTrue(Validator::make($_FILES, $rules)->valid()); + + $_FILES['photo']['size'] = 140000; + $this->assertFalse(Validator::make($_FILES, $rules)->valid()); + } + + /** + * Test the in validation rule. + * + * @group laravel + */ + public function testTheInRule() + { + $input = array('size' => 'L'); + $rules = array('size' => 'in:S,M,L'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['size'] = 'XL'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the not-in validation rule. + * + * @group laravel + */ + public function testTheNotInRule() + { + $input = array('size' => 'L'); + $rules = array('size' => 'not_in:S,M,L'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + $input['size'] = 'XL'; + $this->assertTrue(Validator::make($input, $rules)->valid()); + } + + /** + * Test the IP validation rule. + * + * @group laravel + */ + public function testTheIPRule() + { + $input = array('ip' => '192.168.1.1'); + $rules = array('ip' => 'ip'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['ip'] = '192.111'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the e-mail validation rule. + * + * @group laravel + */ + public function testTheEmailRule() + { + $input = array('email' => 'example@gmail.com'); + $rules = array('email' => 'email'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['email'] = 'blas-asok'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the URL validation rule. + * + * @group laravel + */ + public function testTheUrlRule() + { + $input = array('url' => 'http://www.google.com'); + $rules = array('url' => 'url'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['url'] = 'blas-asok'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the active URL validation rule. + * + * @group laravel + */ + public function testTheActiveUrlRule() + { + $input = array('url' => 'http://google.com'); + $rules = array('url' => 'active_url'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['url'] = 'http://asdlk-aselkaiwels.com'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the image validation rule. + * + * @group laravel + */ + public function testTheImageRule() + { + $_FILES['photo']['tmp_name'] = path('storage').'files/desert.jpg'; + $rules = array('photo' => 'image'); + $this->assertTrue(Validator::make($_FILES, $rules)->valid()); + + $_FILES['photo']['tmp_name'] = path('app').'routes.php'; + $this->assertFalse(Validator::make($_FILES, $rules)->valid()); + } + + /** + * Test the alpha validation rule. + * + * @group laravel + */ + public function testTheAlphaRule() + { + $input = array('name' => 'TaylorOtwell'); + $rules = array('name' => 'alpha'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['name'] = 'Taylor Otwell'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the alpha_num validation rule. + * + * @group laravel + */ + public function testTheAlphaNumRule() + { + $input = array('name' => 'TaylorOtwell1'); + $rules = array('name' => 'alpha_num'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['name'] = 'Taylor Otwell'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the alpha_num validation rule. + * + * @group laravel + */ + public function testTheAlphaDashRule() + { + $input = array('name' => 'Taylor-Otwell_1'); + $rules = array('name' => 'alpha_dash'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['name'] = 'Taylor Otwell'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test the mimes validation rule. + * + * @group laravel + */ + public function testTheMimesRule() + { + $_FILES['file']['tmp_name'] = path('app').'routes.php'; + $rules = array('file' => 'mimes:php,txt'); + $this->assertTrue(Validator::make($_FILES, $rules)->valid()); + + $rules = array('file' => 'mimes:jpg,bmp'); + $this->assertFalse(Validator::make($_FILES, $rules)->valid()); + + $_FILES['file']['tmp_name'] = path('storage').'files/desert.jpg'; + $rules['file'] = 'mimes:jpg,bmp'; + $this->assertTrue(Validator::make($_FILES, $rules)->valid()); + + $rules['file'] = 'mimes:txt,bmp'; + $this->assertFalse(Validator::make($_FILES, $rules)->valid()); + } + + /** + * Test the unique validation rule. + * + * @group laravel + */ + public function testUniqueRule() + { + $input = array('code' => 'ZZ'); + $rules = array('code' => 'unique:validation_unique'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input = array('code' => 'AR'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + $rules = array('code' => 'unique:validation_unique,code,AR,code'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + } + + /** + * Tests the exists validation rule. + * + * @group laravel + */ + public function testExistsRule() + { + $input = array('code' => 'TX'); + $rules = array('code' => 'exists:validation_unique'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['code'] = array('TX', 'NY'); + $rules = array('code' => 'exists:validation_unique,code'); + $this->assertTrue(Validator::make($input, $rules)->valid()); + + $input['code'] = array('TX', 'XX'); + $this->assertFalse(Validator::make($input, $rules)->valid()); + + $input['code'] = 'XX'; + $this->assertFalse(Validator::make($input, $rules)->valid()); + } + + /** + * Test that the validator sets the correct messages. + * + * @group laravel + */ + public function testCorrectMessagesAreSet() + { + $lang = require path('app').'language/en/validation.php'; + + $input = array('email' => 'example-foo'); + $rules = array('name' => 'required', 'email' => 'required|email'); + $v = Validator::make($input, $rules); + $v->valid(); + $messages = $v->errors; + $this->assertInstanceOf('Laravel\\Messages', $messages); + $this->assertEquals(str_replace(':attribute', 'name', $lang['required']), $messages->first('name')); + $this->assertEquals(str_replace(':attribute', 'email', $lang['email']), $messages->first('email')); + } + + /** + * Test that custom messages are recognized. + * + * @group laravel + */ + public function testCustomMessagesAreRecognize() + { + $messages = array('required' => 'Required!'); + $rules = array('name' => 'required'); + $v = Validator::make(array(), $rules, $messages); + $v->valid(); + $this->assertEquals('Required!', $v->errors->first('name')); + + $messages['email_required'] = 'Email Required!'; + $rules = array('name' => 'required', 'email' => 'required'); + $v = Validator::make(array(), $rules, $messages); + $v->valid(); + $this->assertEquals('Required!', $v->errors->first('name')); + $this->assertEquals('Email Required!', $v->errors->first('email')); + + $rules = array('custom' => 'required'); + $v = Validator::make(array(), $rules); + $v->valid(); + $this->assertEquals('This field is required!', $v->errors->first('custom')); + } + + /** + * Test that size replacements are made on messages. + * + * @group laravel + */ + public function testNumericSizeReplacementsAreMade() + { + $lang = require path('app').'language/en/validation.php'; + + $input = array('amount' => 100); + $rules = array('amount' => 'numeric|size:80'); + $v = Validator::make($input, $rules); + $v->valid(); + $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['numeric']), $v->errors->first('amount')); + + $rules = array('amount' => 'numeric|between:70,80'); + $v = Validator::make($input, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['numeric']); + $this->assertEquals($expect, $v->errors->first('amount')); + + $rules = array('amount' => 'numeric|min:120'); + $v = Validator::make($input, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['numeric']); + $this->assertEquals($expect, $v->errors->first('amount')); + + $rules = array('amount' => 'numeric|max:20'); + $v = Validator::make($input, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':max'), array('amount', '20'), $lang['max']['numeric']); + $this->assertEquals($expect, $v->errors->first('amount')); + } + + /** + * Test that string size replacements are made on messages. + * + * @group laravel + */ + public function testStringSizeReplacementsAreMade() + { + $lang = require path('app').'language/en/validation.php'; + + $input = array('amount' => '100'); + $rules = array('amount' => 'size:80'); + $v = Validator::make($input, $rules); + $v->valid(); + $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['string']), $v->errors->first('amount')); + + $rules = array('amount' => 'between:70,80'); + $v = Validator::make($input, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['string']); + $this->assertEquals($expect, $v->errors->first('amount')); + + $rules = array('amount' => 'min:120'); + $v = Validator::make($input, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['string']); + $this->assertEquals($expect, $v->errors->first('amount')); + + $rules = array('amount' => 'max:2'); + $v = Validator::make($input, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':max'), array('amount', '2'), $lang['max']['string']); + $this->assertEquals($expect, $v->errors->first('amount')); + } + + /** + * Test that string size replacements are made on messages. + * + * @group laravel + */ + public function testFileSizeReplacementsAreMade() + { + $lang = require path('app').'language/en/validation.php'; + + $_FILES['amount']['tmp_name'] = 'foo'; + $_FILES['amount']['size'] = 10000; + $rules = array('amount' => 'size:80'); + $v = Validator::make($_FILES, $rules); + $v->valid(); + $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['file']), $v->errors->first('amount')); + + $rules = array('amount' => 'between:70,80'); + $v = Validator::make($_FILES, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['file']); + $this->assertEquals($expect, $v->errors->first('amount')); + + $rules = array('amount' => 'min:120'); + $v = Validator::make($_FILES, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['file']); + $this->assertEquals($expect, $v->errors->first('amount')); + + $rules = array('amount' => 'max:2'); + $v = Validator::make($_FILES, $rules); + $v->valid(); + $expect = str_replace(array(':attribute', ':max'), array('amount', '2'), $lang['max']['file']); + $this->assertEquals($expect, $v->errors->first('amount')); + } + + /** + * Test that values get replaced in messages. + * + * @group laravel + */ + public function testValuesGetReplaced() + { + $lang = require path('app').'language/en/validation.php'; + + $_FILES['file']['tmp_name'] = path('storage').'files/desert.jpg'; + $rules = array('file' => 'mimes:php,txt'); + $v = Validator::make($_FILES, $rules); + $v->valid(); + + $expect = str_replace(array(':attribute', ':values'), array('file', 'php, txt'), $lang['mimes']); + $this->assertEquals($expect, $v->errors->first('file')); + } + + /** + * Test custom attribute names are replaced. + * + * @group laravel + */ + public function testCustomAttributesAreReplaced() + { + $lang = require path('app').'language/en/validation.php'; + + $rules = array('test_attribute' => 'required'); + $v = Validator::make(array(), $rules); + $v->valid(); + + $expect = str_replace(':attribute', 'attribute', $lang['required']); + $this->assertEquals($expect, $v->errors->first('test_attribute')); + } + +} \ No newline at end of file diff --git a/laravel/tests/cases/view.test.php b/laravel/tests/cases/view.test.php new file mode 100644 index 00000000..9716724a --- /dev/null +++ b/laravel/tests/cases/view.test.php @@ -0,0 +1,255 @@ +assertInstanceOf('Laravel\\View', View::make('home.index')); + } + + /** + * Test the View class constructor. + * + * @group laravel + */ + public function testViewNameIsSetByConstrutor() + { + $view = new View('home.index'); + + $this->assertEquals('home.index', $view->view); + } + + /** + * Test the View class constructor. + * + * @group laravel + */ + public function testViewIsCreatedWithCorrectPath() + { + $view = new View('home.index'); + + $this->assertEquals( + str_replace(DS, '/', path('app')).'views/home/index.php', + str_replace(DS, '/', $view->path) + ); + } + + /** + * Test the View class constructor for bundles. + * + * @group laravel + */ + public function testBundleViewIsCreatedWithCorrectPath() + { + $view = new View('home.index'); + + $this->assertEquals( + str_replace(DS, '/', Bundle::path(DEFAULT_BUNDLE)).'views/home/index.php', + str_replace(DS, '/', $view->path) + ); + } + + /** + * Test the View class constructor. + * + * @group laravel + */ + public function testDataIsSetOnViewByConstructor() + { + $view = new View('home.index', array('name' => 'Taylor')); + + $this->assertEquals('Taylor', $view->data['name']); + } + + /** + * Test the View::name method. + * + * @group laravel + */ + public function testNameMethodRegistersAViewName() + { + View::name('home.index', 'home'); + + $this->assertEquals('home.index', View::$names['home']); + } + + /** + * Test the View::shared method. + * + * @group laravel + */ + public function testSharedMethodAddsDataToSharedArray() + { + View::share('comment', 'Taylor'); + + $this->assertEquals('Taylor', View::$shared['comment']); + } + + /** + * Test the View::with method. + * + * @group laravel + */ + public function testViewDataCanBeSetUsingWithMethod() + { + $view = View::make('home.index')->with('comment', 'Taylor'); + + $this->assertEquals('Taylor', $view->data['comment']); + } + + /** + * Test the View class constructor. + * + * @group laravel + */ + public function testEmptyMessageContainerSetOnViewWhenNoErrorsInSession() + { + $view = new View('home.index'); + + $this->assertInstanceOf('Laravel\\Messages', $view->data['errors']); + } + + /** + * Test the View __set method. + * + * @group laravel + */ + public function testDataCanBeSetOnViewsThroughMagicMethods() + { + $view = new View('home.index'); + + $view->comment = 'Taylor'; + + $this->assertEquals('Taylor', $view->data['comment']); + } + + /** + * Test the View __get method. + * + * @group laravel + */ + public function testDataCanBeRetrievedFromViewsThroughMagicMethods() + { + $view = new View('home.index'); + + $view->comment = 'Taylor'; + + $this->assertEquals('Taylor', $view->comment); + } + + /** + * Test the View's ArrayAccess implementation. + * + * @group laravel + */ + public function testDataCanBeSetOnTheViewThroughArrayAccess() + { + $view = new View('home.index'); + + $view['comment'] = 'Taylor'; + + $this->assertEquals('Taylor', $view->data['comment']); + } + + /** + * Test the View's ArrayAccess implementation. + * + * @group laravel + */ + public function testDataCanBeRetrievedThroughArrayAccess() + { + $view = new View('home.index'); + + $view['comment'] = 'Taylor'; + + $this->assertEquals('Taylor', $view['comment']); + } + + /** + * Test the View::nest method. + * + * @group laravel + */ + public function testNestMethodSetsViewInstanceInData() + { + $view = View::make('home.index')->nest('partial', 'tests.basic'); + + $this->assertEquals('tests.basic', $view->data['partial']->view); + + $this->assertInstanceOf('Laravel\\View', $view->data['partial']); + } + + /** + * Test that the registered data is passed to the view correctly. + * + * @group laravel + */ + public function testDataIsPassedToViewCorrectly() + { + View::share('name', 'Taylor'); + + $view = View::make('tests.basic')->with('age', 25)->render(); + + $this->assertEquals('Taylor is 25', $view); + } + + /** + * Test that the View class renders nested views. + * + * @group laravel + */ + public function testNestedViewsAreRendered() + { + $view = View::make('tests.basic') + ->with('age', 25) + ->nest('name', 'tests.nested'); + + $this->assertEquals('Taylor is 25', $view->render()); + } + + /** + * Test that the View class renders nested responses. + * + * @group laravel + */ + public function testNestedResponsesAreRendered() + { + $view = View::make('tests.basic') + ->with('age', 25) + ->with('name', Response::view('tests.nested')); + + $this->assertEquals('Taylor is 25', $view->render()); + } + + /** + * Test the View class raises a composer event. + * + * @group laravel + */ + public function testComposerEventIsCalledWhenViewIsRendering() + { + View::composer('tests.basic', function($view) + { + $view->data = array('name' => 'Taylor', 'age' => 25); + }); + + $view = View::make('tests.basic')->render(); + + $this->assertEquals('Taylor is 25', $view); + } + +} \ No newline at end of file diff --git a/laravel/tests/phpunit.php b/laravel/tests/phpunit.php new file mode 100644 index 00000000..8e5ba204 --- /dev/null +++ b/laravel/tests/phpunit.php @@ -0,0 +1,32 @@ += $parameters[0]); + } + + /** + * Validate that an attribute of type array has a maximum of elements. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validate_countmax($attribute, $value, $parameters) + { + return (is_array($value) && count($value) <= $parameters[0]); + } + + /** + * Validate that an attribute of type array has elements between max and min. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validate_countbetween($attribute, $value, $parameters) + { + return (is_array($value) && count($value) >= $parameters[0] && count($value) <= $parameters[1] ); + } + /** * Validate the date is before a given date. * @@ -953,6 +1017,62 @@ protected function replace_after($message, $attribute, $rule, $parameters) return str_replace(':date', $parameters[0], $message); } + /** + * Replace all place-holders for the count rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_count($message, $attribute, $rule, $parameters) + { + return str_replace(':count', $parameters[0], $message); + } + + /** + * Replace all place-holders for the countmin rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_countmin($message, $attribute, $rule, $parameters) + { + return str_replace(':min', $parameters[0], $message); + } + + /** + * Replace all place-holders for the countmax rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_countmax($message, $attribute, $rule, $parameters) + { + return str_replace(':max', $parameters[0], $message); + } + + /** + * Replace all place-holders for the between rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_countbetween($message, $attribute, $rule, $parameters) + { + return str_replace(array(':min', ':max'), $parameters, $message); + } + /** * Get the displayable name for a given attribute. *