/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * License); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Unit tests for Python 2
 */

plugins { id 'org.apache.beam.module' }
applyPythonNature()

task lint {}
check.dependsOn lint

toxTask "lintPy27", "py27-lint"
lint.dependsOn lintPy27

toxTask "lintPy27_3", "py27-lint3"
lint.dependsOn lintPy27_3

toxTask "testPy2Gcp", "py27-gcp"
test.dependsOn testPy2Gcp

toxTask "testPython2", "py27"
test.dependsOn testPython2

toxTask "testPy2Cython", "py27-cython"
test.dependsOn testPy2Cython
// Ensure that testPy2Cython runs exclusively to other tests. This line is not
// actually required, since gradle doesn't do parallel execution within a
// project.
testPy2Cython.mustRunAfter testPython2, testPy2Gcp

toxTask "docs", "docs"
assemble.dependsOn docs

toxTask "cover", "cover"

task preCommitPy2() {
  dependsOn "docs"
  dependsOn "testPy2Cython"
  dependsOn "testPython2"
  dependsOn "testPy2Gcp"
}
