diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2ed740692..67ac5955c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@
- Добавление типизированного значения в не типизированную коллекцию
#### Запросы
+- В запросе отсутствует проверка на NULL для поля, которое может потенциально содержать NULL
#### Права ролей
diff --git a/bundles/com.e1c.v8codestyle.ql/markdown/ql-query-field-isnull.md b/bundles/com.e1c.v8codestyle.ql/markdown/ql-query-field-isnull.md
new file mode 100644
index 000000000..25692c994
--- /dev/null
+++ b/bundles/com.e1c.v8codestyle.ql/markdown/ql-query-field-isnull.md
@@ -0,0 +1,50 @@
+# The query is missing a NULL check for a field that could potentially contain NULL.
+
+2. When you order a query result by fields that might contain NULL, take into account that the sorting priority of NULL varies in different DBMS.
+
+## Noncompliant Code Example
+
+```bsl
+SELECT
+ CatalogProducts.Ref AS ProductRef,
+ InventoryBalance.QuantityBalance AS QuantityBalance
+FROM
+ Catalog.Products AS CatalogProducts
+ LEFT JOIN AccumulationRegister.Inventory.Balance AS InventoryBalance
+ BY (InventoryBalance.Products = CatalogProducts.Ref)
+
+ORDER BY
+ QuantityBalance
+```
+
+## Compliant Solution
+
+```bsl
+SELECT
+ CatalogProducts.Ref AS ProductRef,
+ ISNULL(InventoryBalance.QuantityBalance, 0) AS QuantityBalance
+FROM
+ Catalog.Products AS CatalogProducts
+ LEFT JOIN AccumulationRegister.Inventory.Balance AS InventoryBalance
+ BY (InventoryBalance.Products = CatalogProducts.Ref)
+
+ORDER BY
+ QuantityBalance;
+
+SELECT
+ CatalogProducts.Ref AS ProductRef,
+ CASE WHEN InventoryBalance.QuantityBalance IS NOT NULL THEN 0 ELSE InventoryBalance.QuantityBalance AS QuantityBalance
+FROM
+ Catalog.Products AS CatalogProducts
+ LEFT JOIN AccumulationRegister.Inventory.Balance AS InventoryBalance
+ BY (InventoryBalance.Products = CatalogProducts.Ref)
+
+ORDER BY
+ QuantityBalance;
+```
+
+## See
+
+- [Ordering query results](https://support.1ci.com/hc/en-us/articles/360011120859-Ordering-query-results)
+- [Using the CASE operation](https://support.1ci.com/hc/en-us/articles/360007870794-Query-language#using_the_isnull___function)
+- [Appendix 8. Features of operating with different DBMS](https://support.1ci.com/hc/en-us/articles/6347699838098-8-3-IBM-Db2)
\ No newline at end of file
diff --git a/bundles/com.e1c.v8codestyle.ql/markdown/ru/ql-query-field-isnull.md b/bundles/com.e1c.v8codestyle.ql/markdown/ru/ql-query-field-isnull.md
new file mode 100644
index 000000000..e724ff629
--- /dev/null
+++ b/bundles/com.e1c.v8codestyle.ql/markdown/ru/ql-query-field-isnull.md
@@ -0,0 +1,55 @@
+# В запросе отсутствует проверка на NULL для поля, которое может потенциально содержать NULL.
+
+1.2. При сортировке по полю запроса, которое может потенциально содержать NULL, следует учитывать, что в разных СУБД порядок сортировки по этому полю может отличаться.
+
+## Неправильно
+
+```bsl
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ЗапасыОстатки.КоличествоОстаток КАК КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ КоличествоОстаток
+```
+
+## Правильно
+
+При использовании в тексте запроса оператора ПОДОБНО и СПЕЦСИМВОЛ допустимо использовать только константные строковые литералы или параметры запроса.
+
+```bsl
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ЕСТЬNULL(ЗапасыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ КоличествоОстаток;
+
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ВЫБОР КОГДА ЗапасыОстатки.КоличествоОстаток ЕСТЬ НЕ NULL ТОГДА 0 ИНАЧЕ ЗапасыОстатки.КоличествоОстаток КАК КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ КоличествоОстаток;
+```
+
+## См.
+
+- [Упорядочивание результатов запроса](https://its.1c.ru/db/v8std#content:412:hdoc:1.2)
+- [Использование операции ВЫБОР](https://its.1c.ru/db/metod8dev/content/2653/hdoc)
+- [Приложение 8. Особенности работы с различными СУБД.](http://its.1c.ru/db/v83doc#bookmark:dev:TI000001285)
\ No newline at end of file
diff --git a/bundles/com.e1c.v8codestyle.ql/plugin.xml b/bundles/com.e1c.v8codestyle.ql/plugin.xml
index 10134d432..b357d5fb9 100644
--- a/bundles/com.e1c.v8codestyle.ql/plugin.xml
+++ b/bundles/com.e1c.v8codestyle.ql/plugin.xml
@@ -54,6 +54,10 @@
category="com.e1c.v8codestyle.ql"
class="com.e1c.v8codestyle.ql.check.ConstantsInBinaryOperationCheck">
+
+
diff --git a/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/Messages.java b/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/Messages.java
index 354548dd4..f777804d8 100644
--- a/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/Messages.java
+++ b/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/Messages.java
@@ -41,6 +41,9 @@ final class Messages
public static String JoinToSubQuery_description;
public static String JoinToSubQuery_Query_join_to_sub_query_not_allowed;
public static String JoinToSubQuery_title;
+ public static String QueryFieldIsNullCheck_description;
+ public static String QueryFieldIsNullCheck_Query_missing_NULL_check_for_field_potentially_contain_NULL;
+ public static String QueryFieldIsNullCheck_title;
public static String TempTableHasIndex_description;
public static String TempTableHasIndex_Exclude_table_name_pattern;
public static String TempTableHasIndex_New_temporary_table_should_have_indexes;
diff --git a/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/QueryFieldIsNullCheck.java b/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/QueryFieldIsNullCheck.java
new file mode 100644
index 000000000..d5cfc60a4
--- /dev/null
+++ b/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/QueryFieldIsNullCheck.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (C) 2022, 1C-Soft LLC and others.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * 1C-Soft LLC - initial API and implementation
+ * Denis Maslennikov - issue #163
+ *******************************************************************************/
+package com.e1c.v8codestyle.ql.check;
+
+import static com._1c.g5.v8.dt.ql.model.QlPackage.Literals.COMMON_EXPRESSION__CONTENT;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.EcoreUtil2;
+
+import com._1c.g5.v8.dt.ql.model.AbstractExpression;
+import com._1c.g5.v8.dt.ql.model.CaseBody;
+import com._1c.g5.v8.dt.ql.model.CaseOperationExpression;
+import com._1c.g5.v8.dt.ql.model.CommonExpression;
+import com._1c.g5.v8.dt.ql.model.FunctionExpression;
+import com._1c.g5.v8.dt.ql.model.FunctionInvocationExpression;
+import com._1c.g5.v8.dt.ql.model.IsNullOperatorExpression;
+import com._1c.g5.v8.dt.ql.model.MultiPartCommonExpression;
+import com._1c.g5.v8.dt.ql.model.QuerySchemaExpression;
+import com._1c.g5.v8.dt.ql.model.QuerySchemaOperator;
+import com._1c.g5.v8.dt.ql.model.QuerySchemaOrderExpression;
+import com._1c.g5.v8.dt.ql.model.QuerySchemaSelectQuery;
+import com.e1c.g5.v8.dt.check.CheckComplexity;
+import com.e1c.g5.v8.dt.check.ICheckParameters;
+import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
+import com.e1c.g5.v8.dt.check.settings.IssueType;
+import com.e1c.g5.v8.dt.ql.check.QlBasicDelegateCheck;
+import com.e1c.v8codestyle.check.StandardCheckExtension;
+import com.e1c.v8codestyle.internal.ql.CorePlugin;
+
+/**
+ * This class checks if null is checked when sorting by query field.
+ *
+ * @author Denis Maslennikov
+ */
+public class QueryFieldIsNullCheck
+ extends QlBasicDelegateCheck
+{
+
+ private static final String CHECK_ID = "ql-query-field-isnull"; //$NON-NLS-1$
+ private static final String METHOD_DELIMITER = ","; //$NON-NLS-1$
+ private static final String ISNULL_METHODS = "ISNULL,ЕСТЬNULL"; //$NON-NLS-1$
+
+ @Override
+ public String getCheckId()
+ {
+ return CHECK_ID;
+ }
+
+ @Override
+ protected void configureCheck(CheckConfigurer builder)
+ {
+ builder.title(Messages.QueryFieldIsNullCheck_title)
+ .description(Messages.QueryFieldIsNullCheck_description)
+ .complexity(CheckComplexity.NORMAL)
+ .severity(IssueSeverity.MINOR)
+ .issueType(IssueType.PORTABILITY)
+ .extension(new StandardCheckExtension(412, getCheckId(), CorePlugin.PLUGIN_ID))
+ .delegate(QuerySchemaSelectQuery.class);
+ }
+
+ @Override
+ protected void checkQlObject(EObject object, QueryOwner owner, IQlResultAcceptor resultAceptor,
+ ICheckParameters parameters, IProgressMonitor monitor)
+ {
+ QuerySchemaSelectQuery sourceTable = (QuerySchemaSelectQuery)object;
+
+ if (monitor.isCanceled())
+ {
+ return;
+ }
+
+ List orderFields = getOrderFields(sourceTable);
+ List operators = sourceTable.getOperators();
+ for (QuerySchemaOperator operator : operators)
+ {
+ List fields = operator.getSelectFields();
+ for (QuerySchemaExpression field : fields)
+ {
+ AbstractExpression abstractExpression = field.getExpression();
+ String fieldName = field.getAlias();
+ if (abstractExpression instanceof FunctionInvocationExpression)
+ {
+ removeFieldsWithIsNullMethod((FunctionInvocationExpression)abstractExpression, orderFields,
+ fieldName);
+ }
+ if (abstractExpression instanceof CaseOperationExpression)
+ {
+ removeFieldsWithWhenExpression((CaseOperationExpression)abstractExpression, orderFields, fieldName);
+ }
+ }
+ }
+ for (CommonExpression orderField : orderFields)
+ {
+ String message = Messages.QueryFieldIsNullCheck_Query_missing_NULL_check_for_field_potentially_contain_NULL;
+ resultAceptor.addIssue(message, orderField, COMMON_EXPRESSION__CONTENT);
+ }
+ }
+
+ private void removeFieldsWithWhenExpression(CaseOperationExpression caseInvocationExpression,
+ List orderFields, String fieldName)
+ {
+ List caseBodies = caseInvocationExpression.getBody();
+ for (CaseBody caseBody : caseBodies)
+ {
+ AbstractExpression whenExpression = caseBody.getWhen();
+ if (whenExpression instanceof IsNullOperatorExpression)
+ {
+ IsNullOperatorExpression nullOperator = (IsNullOperatorExpression)whenExpression;
+ for (EObject operatorContent : nullOperator.eContents())
+ {
+ if (operatorContent instanceof CommonExpression)
+ {
+ removeFieldByName(orderFields, (CommonExpression)operatorContent, fieldName);
+ }
+ }
+ }
+ }
+ }
+
+ private void removeFieldsWithIsNullMethod(FunctionInvocationExpression functionInvocationExpression,
+ List orderFields, String fieldName)
+ {
+ FunctionExpression f = functionInvocationExpression.getFunctionType();
+ List isNullMethods = getIsNullMethods();
+
+ if (isNullMethods.contains(f.getName()))
+ {
+ List params = functionInvocationExpression.getParams();
+
+ if (params.get(0) instanceof CommonExpression)
+ {
+ removeFieldByName(orderFields, (CommonExpression)params.get(0), fieldName);
+ }
+
+ }
+ }
+
+ private void removeFieldByName(List orderFields, CommonExpression commonExpression,
+ String fieldName)
+ {
+ String paramName = commonExpression.getFullContent();
+ List unique = new ArrayList<>();
+ unique.addAll(orderFields);
+ for (CommonExpression orderField : unique)
+ {
+ String fieldFullName = orderField.getFullContent();
+ if (paramName.equals(fieldFullName) || fieldName.equals(fieldFullName))
+ {
+ orderFields.remove(orderField);
+ }
+ }
+ }
+
+ private List getOrderFields(QuerySchemaSelectQuery sourceTable)
+ {
+ List orderExpressions = sourceTable.getOrderExpressions();
+ List orderFields = new ArrayList<>();
+
+ for (QuerySchemaOrderExpression orderExpression : orderExpressions)
+ {
+ List commonExpressions =
+ EcoreUtil2.getAllContentsOfType(orderExpression, CommonExpression.class);
+ orderFields.addAll(commonExpressions);
+ for (CommonExpression commonExpression : commonExpressions)
+ {
+ if (commonExpression instanceof MultiPartCommonExpression)
+ {
+ orderFields.remove(((MultiPartCommonExpression)commonExpression).getSourceTable());
+ }
+ }
+ }
+ return orderFields;
+ }
+
+ private List getIsNullMethods()
+ {
+ List isNullMethods = Arrays.asList(ISNULL_METHODS.split(METHOD_DELIMITER));
+ isNullMethods.replaceAll(String::trim);
+ return isNullMethods;
+ }
+}
diff --git a/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/messages.properties b/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/messages.properties
index 59d8486cc..0c3a61845 100644
--- a/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/messages.properties
+++ b/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/messages.properties
@@ -50,6 +50,12 @@ JoinToSubQuery_description = Query join with sub query
JoinToSubQuery_title = Query join with sub query
+QueryFieldIsNullCheck_description = The query is missing a NULL check for a field that could potentially contain NULL
+
+QueryFieldIsNullCheck_Query_missing_NULL_check_for_field_potentially_contain_NULL = The query is missing a NULL check for a field that could potentially contain NULL
+
+QueryFieldIsNullCheck_title = The query is missing a NULL check for a field that could potentially contain NULL
+
TempTableHasIndex_Exclude_table_name_pattern = Exclude table name pattern
TempTableHasIndex_New_temporary_table_should_have_indexes = New temporary table should have indexes
diff --git a/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/messages_ru.properties b/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/messages_ru.properties
index d50972682..5b4e090a9 100644
--- a/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/messages_ru.properties
+++ b/bundles/com.e1c.v8codestyle.ql/src/com/e1c/v8codestyle/ql/check/messages_ru.properties
@@ -51,6 +51,12 @@ JoinToSubQuery_description = Соединение запроса с подзап
JoinToSubQuery_title = Соединение запроса с подзапросом
+QueryFieldIsNullCheck_description = В запросе отсутствует проверка на NULL для поля, которое может потенциально содержать NULL
+
+QueryFieldIsNullCheck_Query_missing_NULL_check_for_field_potentially_contain_NULL = В запросе отсутствует проверка на NULL для поля, которое может потенциально содержать NULL
+
+QueryFieldIsNullCheck_title = В запросе отсутствует проверка на NULL для поля, которое может потенциально содержать NULL
+
TempTableHasIndex_Exclude_table_name_pattern = Выражения исключения имени таблицы
TempTableHasIndex_New_temporary_table_should_have_indexes = Новая временная таблица должна содержать индексы
diff --git a/tests/com.e1c.v8codestyle.ql.itests/resources/ql-query-field-isnull/compliant.ql b/tests/com.e1c.v8codestyle.ql.itests/resources/ql-query-field-isnull/compliant.ql
new file mode 100644
index 000000000..47c2b7133
--- /dev/null
+++ b/tests/com.e1c.v8codestyle.ql.itests/resources/ql-query-field-isnull/compliant.ql
@@ -0,0 +1,35 @@
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ЕСТЬNULL(ЗапасыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ ЗапасыОстатки.КоличествоОстаток;
+
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ЕСТЬNULL(ЗапасыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ КоличествоОстаток;
+
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ВЫБОР КОГДА ЗапасыОстатки.КоличествоОстаток ЕСТЬ НЕ NULL ТОГДА 0 ИНАЧЕ ЗапасыОстатки.КоличествоОстаток КАК КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ КоличествоОстаток
\ No newline at end of file
diff --git a/tests/com.e1c.v8codestyle.ql.itests/resources/ql-query-field-isnull/non-compliant.ql b/tests/com.e1c.v8codestyle.ql.itests/resources/ql-query-field-isnull/non-compliant.ql
new file mode 100644
index 000000000..a4b7016ed
--- /dev/null
+++ b/tests/com.e1c.v8codestyle.ql.itests/resources/ql-query-field-isnull/non-compliant.ql
@@ -0,0 +1,36 @@
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ЗапасыОстатки.КоличествоОстаток КАК КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ ЗапасыОстатки.КоличествоОстаток;
+
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ЗапасыОстатки.КоличествоОстаток КАК КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ КоличествоОстаток;
+
+ВЫБРАТЬ
+ СправочникНоменклатура.Ссылка КАК НоменклатураСсылка,
+ ВЫБОР КОГДА ЗапасыОстатки.КоличествоОстаток ЕСТЬ НЕ NULL ТОГДА 0 ИНАЧЕ ЗапасыОстатки.КоличествоОстаток
+ИЗ
+ Справочник.Номенклатура КАК СправочникНоменклатура
+ ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Запасы.Остатки КАК
+ЗапасыОстатки
+ ПО (ЗапасыОстатки.Номенклатура = СправочникНоменклатура.Ссылка)
+
+УПОРЯДОЧИТЬ ПО
+ КоличествоОстаток;
+
\ No newline at end of file
diff --git a/tests/com.e1c.v8codestyle.ql.itests/src/com/e1c/v8codestyle/ql/check/itests/QueryFieldIsNullTest.java b/tests/com.e1c.v8codestyle.ql.itests/src/com/e1c/v8codestyle/ql/check/itests/QueryFieldIsNullTest.java
new file mode 100644
index 000000000..ba3648053
--- /dev/null
+++ b/tests/com.e1c.v8codestyle.ql.itests/src/com/e1c/v8codestyle/ql/check/itests/QueryFieldIsNullTest.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (C) 2022, 1C-Soft LLC and others.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * 1C-Soft LLC - initial API and implementation
+ * Denis Maslennikov - issue #163
+ *******************************************************************************/
+/**
+ *
+ */
+package com.e1c.v8codestyle.ql.check.itests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import com.e1c.v8codestyle.ql.check.QueryFieldIsNullCheck;
+import com.e1c.v8codestyle.ql.check.itests.TestingQlResultAcceptor.QueryMarker;
+
+/**
+ * The test for class {@link QueryFieldIsNullCheck}.
+ *
+ * @author Denis Maslennikov
+ */
+public class QueryFieldIsNullTest
+ extends AbstractQueryTestBase
+{
+ private static final String PROJECT_NAME = "QlFullDemo";
+ private static final String FOLDER = FOLDER_RESOURCE + "ql-query-field-isnull/";
+
+ public QueryFieldIsNullTest()
+ {
+ super(QueryFieldIsNullCheck.class);
+ }
+
+ @Override
+ protected String getTestConfigurationName()
+ {
+ return PROJECT_NAME;
+ }
+
+ /**
+ * Test correct ISNULL check for query field.
+ *
+ * @throws Exception the exception
+ */
+ @Test
+ public void testQueryFieldIsNullCompliant() throws Exception
+ {
+ loadQueryAndValidate(FOLDER + "compliant.ql");
+ List markers = getQueryMarkers();
+ assertEquals(0, markers.size());
+ }
+
+ /**
+ * Test if ISNULL check is absent for query field.
+ *
+ * @throws Exception the exception
+ */
+ @Test
+ public void testQueryFieldIsNullNonCompliant() throws Exception
+ {
+ loadQueryAndValidate(FOLDER + "non-compliant.ql");
+ List markers = getQueryMarkers();
+ assertEquals(3, markers.size());
+
+ QueryMarker marker = markers.get(0);
+ assertNotNull(marker.getTarget());
+ assertEquals(11, marker.getLineNumber());
+
+ marker = markers.get(1);
+ assertNotNull(marker.getTarget());
+ assertEquals(23, marker.getLineNumber());
+
+ marker = markers.get(2);
+ assertNotNull(marker.getTarget());
+ assertEquals(35, marker.getLineNumber());
+
+ }
+}