Merge branch 'release-candidate' into stable
diff --git a/.jazzy.yaml b/.jazzy.yaml
index f9986df..06ebfdc 100644
--- a/.jazzy.yaml
+++ b/.jazzy.yaml
@@ -1,8 +1,8 @@
 module: MotionInterchange
-module_version: 1.6.0
+module_version: 2.0.0
 sdk: iphonesimulator
 umbrella_header: src/MotionInterchange.h
 objc: true
 github_url: https://github.com/material-motion/motion-interchange-objc
-github_file_prefix: https://github.com/material-motion/motion-interchange-objc/tree/v1.6.0
+github_file_prefix: https://github.com/material-motion/motion-interchange-objc/tree/v2.0.0
 
diff --git a/.kokoro b/.kokoro
index d820c6d..e4f49f0 100755
--- a/.kokoro
+++ b/.kokoro
@@ -20,7 +20,41 @@
 # Display commands to stderr.
 set -x
 
-KOKORO_RUNNER_VERSION="v3.*"
+KOKORO_RUNNER_VERSION="v4.*"
+BAZEL_VERSION="0.20.0"
+
+# xcode-select's the provided xcode version.
+# Usage example:
+#     select_xcode 9.2.0
+select_xcode() {
+  desired_version="$1"
+  if [ -z "$desired_version" ]; then
+    return # No Xcode version to select.
+  fi
+
+  xcodes=$(ls /Applications/ | grep "Xcode")
+  for xcode_path in $xcodes; do
+    xcode_version=$(cat /Applications/$xcode_path/Contents/version.plist \
+      | grep "CFBundleShortVersionString" -A1 \
+      | grep string \
+      | cut -d'>' -f2 \
+      | cut -d'<' -f1)
+    xcode_version_as_number="$(version_as_number $xcode_version)"
+
+    if [ "$xcode_version_as_number" -ne "$(version_as_number $desired_version)" ]; then
+      continue
+    fi
+
+    sudo xcode-select --switch /Applications/$xcode_path/Contents/Developer
+    xcodebuild -version
+
+    # Resolves the following crash when switching Xcode versions:
+    # "Failed to locate a valid instance of CoreSimulatorService in the bootstrap"
+    launchctl remove com.apple.CoreSimulator.CoreSimulatorService || true
+
+    break
+  done
+}
 
 fix_bazel_imports() {
   if [ -z "$KOKORO_BUILD_NUMBER" ]; then
@@ -39,18 +73,36 @@
   trap reset_imports EXIT
 }
 
-if [ ! -d .kokoro-ios-runner ]; then
-  git clone https://github.com/material-foundation/kokoro-ios-runner.git .kokoro-ios-runner
-fi
+run_bazel() {
+  echo "Running bazel builds..."
 
-pushd .kokoro-ios-runner
-git fetch > /dev/null
-TAG=$(git tag --sort=v:refname -l "$KOKORO_RUNNER_VERSION" | tail -n1)
-git checkout "$TAG" > /dev/null
-popd
+  fix_bazel_imports
 
-fix_bazel_imports
+  if [ -n "$KOKORO_BUILD_NUMBER" ]; then
+    bazel version
+    use_bazel.sh "$BAZEL_VERSION"
+    bazel version
 
-./.kokoro-ios-runner/bazel.sh test //:UnitTests 8.1.0
+    select_xcode "$XCODE_VERSION"
+
+    # Move into our cloned repo
+    cd github/repo
+  fi
+
+  # Run against whichever Xcode is currently selected.
+  selected_xcode_developer_path=$(xcode-select -p)
+  selected_xcode_contents_path=$(dirname "$selected_xcode_developer_path")
+
+  xcode_version=$(cat "$selected_xcode_contents_path/version.plist" \
+    | grep "CFBundleShortVersionString" -A1 \
+    | grep string \
+    | cut -d'>' -f2 \
+    | cut -d'<' -f1)
+
+  bazel clean
+  bazel test //... --xcode_version $xcode_version --ios_minimum_os=8.0 --ios_multi_cpus=i386,x86_64
+}
+
+run_bazel
 
 echo "Success!"
diff --git a/.travis.yml b/.travis.yml
index 549e7b8..0ea5ada 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,11 +1,31 @@
 language: objective-c
-osx_image: xcode8.3
+osx_image: xcode9.2
 sudo: false
+env:
+  global:
+  - LC_CTYPE=en_US.UTF-8
+  - LANG=en_US.UTF-8
+  - LANGUAGE=en_US.UTF-8
+matrix:
+  include:
+    - osx_image: xcode9.2
+      env: COVERAGE=code_coverage SDK="iphonesimulator11.2" DESTINATION="name=iPhone 6s,OS=11.2"
+    - osx_image: xcode9.2
+      env: SDK="iphonesimulator11.2" DESTINATION="name=iPhone 6s,OS=10.3.1"
+    - osx_image: xcode9.2
+      env: SDK="iphonesimulator11.2" DESTINATION="name=iPhone 6s,OS=9.3"
+    - osx_image: xcode9.2
+      env: SDK="iphonesimulator11.2" DESTINATION="name=iPhone 6,OS=8.4"
+    - osx_image: xcode8.3
+      env: SDK="iphonesimulator10.3" DESTINATION="name=iPhone 6,OS=8.1"
 before_install:
   - gem install cocoapods --no-rdoc --no-ri --no-document --quiet
-  - pod install --repo-update
+  - pod install
 script:
   - set -o pipefail
-  - xcodebuild test -workspace MotionInterchange.xcworkspace -scheme MotionInterchangeCatalog -sdk "iphonesimulator10.3" -destination "name=iPhone SE,OS=10.3" -enableCodeCoverage YES ONLY_ACTIVE_ARCH=YES | xcpretty -c;
+  - xcodebuild test -workspace MotionInterchange.xcworkspace -scheme MotionInterchangeCatalog -sdk "$SDK" -destination "$DESTINATION" -enableCodeCoverage YES ONLY_ACTIVE_ARCH=YES | xcpretty -c;
 after_success:
+  - if [ "$COVERAGE" == "code_coverage" ]; then
+     bash <(curl -s https://codecov.io/bash);
+    fi
   - bash <(curl -s https://codecov.io/bash)
diff --git a/BUILD b/BUILD
index bef9c79..0dd0699 100644
--- a/BUILD
+++ b/BUILD
@@ -15,9 +15,9 @@
 # Description:
 # Motion interchange format.
 
+load("@build_bazel_rules_apple//apple:ios.bzl", "ios_ui_test")
+load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
 load("@bazel_ios_warnings//:strict_warnings_objc_library.bzl", "strict_warnings_objc_library")
-load("@build_bazel_rules_apple//apple:swift.bzl", "swift_library")
-load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
 
 licenses(["notice"])  # Apache 2.0
 
@@ -51,6 +51,7 @@
     ]),
     deps = [":MotionInterchange"],
     visibility = ["//visibility:private"],
+    copts = ["-swift-version", "3"],
 )
 
 objc_library(
@@ -62,12 +63,13 @@
     visibility = ["//visibility:private"],
 )
 
-ios_unit_test(
+ios_ui_test(
     name = "UnitTests",
     deps = [
       ":UnitTestsLib",
       ":UnitTestsSwiftLib"
     ],
+    test_host = "@build_bazel_rules_apple//apple/testing/default_host/ios",
     minimum_os_version = "8.0",
     timeout = "short",
     visibility = ["//visibility:private"],
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a2299a..7580f91 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
+# 2.0.0
+
+This major release upgrades the bazel dependencies and workspace. This change is breaking for anyone
+using bazel to build this library. In order to use this library with bazel, you will also need to
+upgrade your workspace versions to match the ones now used in this library's `WORKSPACE` file.
+
+## Source changes
+
+* [Update .travis.yml (#35)](https://github.com/material-motion/motion-interchange-objc/commit/f9891a24b843edc004f86ee86f7477d6327957b1) (featherless)
+
+## Non-source changes
+
+* [Update bazel workspace to latest versions. (#40)](https://github.com/material-motion/motion-interchange-objc/commit/a9a1cab4354ce45d8a4548b28c708455ce93885a) (featherless)
+* [Update .kokoro](https://github.com/material-motion/motion-interchange-objc/commit/cfbd73021314ce24b0e0f2d37906b58b128e416c) (featherless)
+* [Update .kokoro](https://github.com/material-motion/motion-interchange-objc/commit/7e3af4ac83426ea8da8283211e09c0458ff24b81) (featherless)
+* [Update bazel workspace and version to latest (#38)](https://github.com/material-motion/motion-interchange-objc/commit/71aa2e4393574d2b4b5cf55695787b9a662165d1) (featherless)
+* [Update .kokoro to build against Xcode 9.1](https://github.com/material-motion/motion-interchange-objc/commit/816f52f4600b311f50dae7ef9aa3b9f9f1fb1b0e) (featherless)
+* [Update .travis.yml](https://github.com/material-motion/motion-interchange-objc/commit/ba7e0f0015b83eda35edf0144fb6fa3ebb52a81a) (featherless)
+
 # 1.6.0
 
 This patch release introduces a compatibility initializer for creating Objective-C animation traits from C-style motion timings.
diff --git a/MotionInterchange.podspec b/MotionInterchange.podspec
index 8779c48..00e8c5e 100644
--- a/MotionInterchange.podspec
+++ b/MotionInterchange.podspec
@@ -1,7 +1,7 @@
 Pod::Spec.new do |s|
   s.name         = "MotionInterchange"
   s.summary      = "Motion interchange format."
-  s.version      = "1.6.0"
+  s.version      = "2.0.0"
   s.authors      = "The Material Motion Authors"
   s.license      = "Apache 2.0"
   s.homepage     = "https://github.com/material-motion/motion-interchange-objc"
diff --git a/WORKSPACE b/WORKSPACE
index 5cadb37..7b1a5be 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -12,18 +12,43 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-http_archive(
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
+
+git_repository(
     name = "build_bazel_rules_apple",
-    url = "https://github.com/bazelbuild/rules_apple/archive/0.2.0.zip",
-    strip_prefix = "rules_apple-0.2.0",
-    # Generated by running: openssl sha -sha256 <path to zip>
-    sha256 = "4ae91e15243fbe39a02b7e9a1bba6de50c5554443a30c5587cfeff7404dfdd56"
+    remote = "https://github.com/bazelbuild/rules_apple.git",
+    tag = "0.9.0",
 )
 
-http_archive(
+load(
+    "@build_bazel_rules_apple//apple:repositories.bzl",
+    "apple_rules_dependencies",
+)
+
+apple_rules_dependencies()
+
+git_repository(
+    name = "build_bazel_rules_swift",
+    remote = "https://github.com/bazelbuild/rules_swift.git",
+    tag = "0.4.0",
+)
+
+load(
+    "@build_bazel_rules_swift//swift:repositories.bzl",
+    "swift_rules_dependencies",
+)
+
+swift_rules_dependencies()
+
+git_repository(
     name = "bazel_ios_warnings",
-    url = "https://github.com/material-foundation/bazel_ios_warnings/archive/v2.0.0.zip",
-    strip_prefix = "bazel_ios_warnings-2.0.0",
-    # Generated by running: openssl sha -sha256 <path to zip>
-    sha256 = "199f1b1726ca561d5dedcb3876094a9604f603dc8d737b0e6b8866a70dc8a90d"
+    remote = "https://github.com/material-foundation/bazel_ios_warnings.git",
+    tag = "v2.0.0",
+)
+
+http_file(
+    name = "xctestrunner",
+    executable = 1,
+    urls = ["https://github.com/google/xctestrunner/releases/download/0.2.5/ios_test_runner.par"],
 )
diff --git a/tests/unit/MDMModalMovementTimingTests.m b/tests/unit/MDMModalMovementTimingTests.m
index d5aa2b2..465f9de 100644
--- a/tests/unit/MDMModalMovementTimingTests.m
+++ b/tests/unit/MDMModalMovementTimingTests.m
@@ -83,7 +83,9 @@
     XCTAssertEqualWithAccuracy(spring.mass, springAnimation.mass, 0.001);
     XCTAssertEqualWithAccuracy(spring.tension, springAnimation.stiffness, 0.001);
     XCTAssertEqualWithAccuracy(spring.friction, springAnimation.damping, 0.001);
-    XCTAssertEqualWithAccuracy(spring.initialVelocity, springAnimation.initialVelocity, 0.001);
+    if ([springAnimation respondsToSelector:@selector(initialVelocity)]) {
+      XCTAssertEqualWithAccuracy(spring.initialVelocity, springAnimation.initialVelocity, 0.001);
+    }
   }
 }
 
diff --git a/tests/unit/MDMSpringTimingCurve.swift b/tests/unit/MDMSpringTimingCurve.swift
index 8d20f36..7a797ab 100644
--- a/tests/unit/MDMSpringTimingCurve.swift
+++ b/tests/unit/MDMSpringTimingCurve.swift
@@ -39,19 +39,19 @@
   func testInitializerValuesWithDampingCoefficient() {
     for duration in stride(from: TimeInterval(0.1), to: TimeInterval(3), by: TimeInterval(0.5)) {
       for dampingRatio in stride(from: CGFloat(0.1), to: CGFloat(2), by: CGFloat(0.4)) {
-        for initialVelocity in stride(from: CGFloat(-2), to: CGFloat(2), by: CGFloat(0.8)) {
+        for initialVel in stride(from: CGFloat(-2), to: CGFloat(2), by: CGFloat(0.8)) {
           let generator = MDMSpringTimingCurveGenerator(duration: duration,
                                                         dampingRatio: dampingRatio,
-                                                        initialVelocity: initialVelocity)
+                                                        initialVelocity: initialVel)
           let view = UIView()
 
           UIView.animate(withDuration: duration,
                          delay: 0,
                          usingSpringWithDamping: dampingRatio,
-                         initialSpringVelocity: initialVelocity,
+                         initialSpringVelocity: initialVel,
                          options: [],
                          animations: {
-                          view.center = CGPoint(x: initialVelocity * 5, y: dampingRatio * 10)
+                          view.center = CGPoint(x: initialVel * 5, y: dampingRatio * 10)
           }, completion: nil)
 
           if let animationKey = view.layer.animationKeys()?.first,
@@ -61,10 +61,16 @@
             XCTAssertEqualWithAccuracy(curve.mass, animation.mass, accuracy: 0.001)
             XCTAssertEqualWithAccuracy(curve.tension, animation.stiffness, accuracy: 0.001)
             XCTAssertEqualWithAccuracy(curve.friction, animation.damping, accuracy: 0.001)
-            XCTAssertEqualWithAccuracy(curve.initialVelocity, animation.initialVelocity, accuracy: 0.001)
+            if animation.responds(to: #selector(initialVelocity)) {
+              XCTAssertEqualWithAccuracy(curve.initialVelocity, animation.initialVelocity, accuracy: 0.001)
+            }
           }
         }
       }
     }
   }
+
+  // Dummy getter for #selector(initialVelocity) reference.
+  func initialVelocity() {
+  }
 }