Browse Source

Merge pull request #2200 from ravage84/skip-validation-baking

Implemented skipping of fields for the data validation rules when baking.
Mark Story 12 years ago
parent
commit
3ddbddc2f1

+ 25 - 4
lib/Cake/Console/Command/Task/ModelTask.php

@@ -350,18 +350,27 @@ class ModelTask extends BakeTask {
 		if (!$model instanceof Model) {
 			return false;
 		}
-		$fields = $model->schema();
 
+		$fields = $model->schema();
 		if (empty($fields)) {
 			return false;
 		}
+
+		$skipFields = false;
 		$validate = array();
 		$this->initValidations();
 		foreach ($fields as $fieldName => $field) {
 			$validation = $this->fieldValidation($fieldName, $field, $model->primaryKey);
+			if (isset($validation['_skipFields'])) {
+				unset($validation['_skipFields']);
+				$skipFields = true;
+			}
 			if (!empty($validation)) {
 				$validate[$fieldName] = $validation;
 			}
+			if ($skipFields) {
+				return $validate;
+			}
 		}
 		return $validate;
 	}
@@ -401,6 +410,11 @@ class ModelTask extends BakeTask {
 		$defaultChoice = count($this->_validations);
 		$validate = $alreadyChosen = array();
 
+		$prompt = __d('cake_console',
+			"or enter in a valid regex validation string.\nAlternatively [s] skip the rest of the fields.\n"
+		);
+		$methods = array_flip($this->_validations);
+
 		$anotherValidator = 'y';
 		while ($anotherValidator === 'y') {
 			if ($this->interactive) {
@@ -424,8 +438,6 @@ class ModelTask extends BakeTask {
 				$this->hr();
 			}
 
-			$prompt = __d('cake_console', "... or enter in a valid regex validation string.\n");
-			$methods = array_flip($this->_validations);
 			$guess = $defaultChoice;
 			if ($metaData['null'] != 1 && !in_array($fieldName, array($primaryKey, 'created', 'modified', 'updated'))) {
 				if ($fieldName === 'email') {
@@ -455,6 +467,10 @@ class ModelTask extends BakeTask {
 
 			if ($this->interactive === true) {
 				$choice = $this->in($prompt, null, $guess);
+				if ($choice === 's') {
+					$validate['_skipFields'] = true;
+					return $validate;
+				}
 				if (in_array($choice, $alreadyChosen)) {
 					$this->out(__d('cake_console', "You have already chosen that validation rule,\nplease choose again"));
 					continue;
@@ -482,7 +498,12 @@ class ModelTask extends BakeTask {
 			}
 			$anotherValidator = 'n';
 			if ($this->interactive && $choice != $defaultChoice) {
-				$anotherValidator = $this->in(__d('cake_console', 'Would you like to add another validation rule?'), array('y', 'n'), 'n');
+				$anotherValidator = $this->in(__d('cake_console', "Would you like to add another validation rule\n" .
+					"or skip the rest of the fields?"), array('y', 'n', 's'), 'n');
+				if ($anotherValidator === 's') {
+					$validate['_skipFields'] = true;
+					return $validate;
+				}
 			}
 		}
 		return $validate;

+ 128 - 30
lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php

@@ -32,6 +32,7 @@ App::uses('ModelTask', 'Console/Command/Task');
  * ModelTaskTest class
  *
  * @package	   Cake.Test.Case.Console.Command.Task
+ * @property   ModelTask $Task
  */
 class ModelTaskTest extends CakeTestCase {
 
@@ -361,46 +362,143 @@ class ModelTaskTest extends CakeTestCase {
 	}
 
 /**
- * test the validation Generation routine
+ * Test that skipping fields during rule choice works when doing interactive field validation.
  *
  * @return void
  */
-	public function testNonInteractiveDoValidation() {
+	public function testSkippingChoiceInteractiveFieldValidation() {
+		$this->Task->initValidations();
+		$this->Task->interactive = true;
+		$this->Task->expects($this->any())->method('in')
+			->will($this->onConsecutiveCalls('24', 'y', 's'));
+
+		$result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
+		$expected = array('notEmpty' => 'notEmpty', '_skipFields' => true);
+		$this->assertEquals($expected, $result);
+	}
+
+/**
+ * Test that skipping fields after rule choice works when doing interactive field validation.
+ *
+ * @return void
+ */
+	public function testSkippingAnotherInteractiveFieldValidation() {
+		$this->Task->initValidations();
+		$this->Task->interactive = true;
+		$this->Task->expects($this->any())->method('in')
+			->will($this->onConsecutiveCalls('24', 's'));
+
+		$result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
+		$expected = array('notEmpty' => 'notEmpty', '_skipFields' => true);
+		$this->assertEquals($expected, $result);
+	}
+
+/**
+ * Test the validation generation routine with skipping the rest of the fields
+ * when doing interactive field validation.
+ *
+ * @return void
+ */
+	public function testInteractiveDoValidationWithSkipping() {
+		$this->Task->expects($this->any())
+			->method('in')
+			->will($this->onConsecutiveCalls('35', '24', 'n', '11', 's'));
+		$this->Task->interactive = true;
 		$Model = $this->getMock('Model');
 		$Model->primaryKey = 'id';
-		$Model->expects($this->any())->method('schema')->will($this->returnValue(array(
-			'id' => array(
-				'type' => 'integer',
-				'length' => 11,
-				'null' => false,
-				'key' => 'primary',
-			),
+		$Model->expects($this->any())
+			->method('schema')
+			->will($this->returnValue(array(
+					'id' => array(
+						'type' => 'integer',
+						'length' => 11,
+						'null' => false,
+						'key' => 'primary',
+					),
+					'name' => array(
+						'type' => 'string',
+						'length' => 20,
+						'null' => false,
+					),
+					'email' => array(
+						'type' => 'string',
+						'length' => 255,
+						'null' => false,
+					),
+					'some_date' => array(
+						'type' => 'date',
+						'length' => '',
+						'null' => false,
+					),
+					'some_time' => array(
+						'type' => 'time',
+						'length' => '',
+						'null' => false,
+					),
+					'created' => array(
+						'type' => 'datetime',
+						'length' => '',
+						'null' => false,
+					)
+				)
+			));
+
+		$result = $this->Task->doValidation($Model);
+		$expected = array(
 			'name' => array(
-				'type' => 'string',
-				'length' => 20,
-				'null' => false,
+				'notEmpty' => 'notEmpty'
 			),
 			'email' => array(
-				'type' => 'string',
-				'length' => 255,
-				'null' => false,
-			),
-			'some_date' => array(
-				'type' => 'date',
-				'length' => '',
-				'null' => false,
-			),
-			'some_time' => array(
-				'type' => 'time',
-				'length' => '',
-				'null' => false,
+				'email' => 'email',
 			),
-			'created' => array(
-				'type' => 'datetime',
-				'length' => '',
-				'null' => false,
+		);
+		$this->assertEquals($expected, $result);
+	}
+
+/**
+ * test the validation Generation routine
+ *
+ * @return void
+ */
+	public function testNonInteractiveDoValidation() {
+		$Model = $this->getMock('Model');
+		$Model->primaryKey = 'id';
+		$Model->expects($this->any())
+			->method('schema')
+			->will($this->returnValue(array(
+				'id' => array(
+					'type' => 'integer',
+					'length' => 11,
+					'null' => false,
+					'key' => 'primary',
+				),
+				'name' => array(
+					'type' => 'string',
+					'length' => 20,
+					'null' => false,
+				),
+				'email' => array(
+					'type' => 'string',
+					'length' => 255,
+					'null' => false,
+				),
+				'some_date' => array(
+					'type' => 'date',
+					'length' => '',
+					'null' => false,
+				),
+				'some_time' => array(
+					'type' => 'time',
+					'length' => '',
+					'null' => false,
+				),
+				'created' => array(
+					'type' => 'datetime',
+					'length' => '',
+					'null' => false,
+				)
 			)
-		)));
+		));
 		$this->Task->interactive = false;
 
 		$result = $this->Task->doValidation($Model);