// Copyright (c) 2015 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
// "Materials"), to deal in the Materials without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Materials, and to
// permit persons to whom the Materials are furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Materials.
//
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
//    https://www.khronos.org/registry/
//
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

#include "UnitSPIRV.h"

#include <string>

namespace {

using libspirv::AssemblyContext;
using spvtest::AutoText;

TEST(TextStartsWithOp, YesAtStart) {
  EXPECT_TRUE(AssemblyContext(AutoText("OpFoo"), nullptr).isStartOfNewInst());
  EXPECT_TRUE(AssemblyContext(AutoText("OpFoo"), nullptr).isStartOfNewInst());
  EXPECT_TRUE(AssemblyContext(AutoText("OpEnCL"), nullptr).isStartOfNewInst());
}

TEST(TextStartsWithOp, YesAtMiddle) {
  {
    AssemblyContext dat(AutoText("  OpFoo"), nullptr);
    dat.seekForward(2);
    EXPECT_TRUE(dat.isStartOfNewInst());
  }
  {
    AssemblyContext dat(AutoText("xx OpFoo"), nullptr);
    dat.seekForward(2);
    EXPECT_TRUE(dat.isStartOfNewInst());
  }
}

TEST(TextStartsWithOp, NoIfTooFar) {
  AssemblyContext dat(AutoText("  OpFoo"), nullptr);
  dat.seekForward(3);
  EXPECT_FALSE(dat.isStartOfNewInst());
}

TEST(TextStartsWithOp, NoRegular) {
  EXPECT_FALSE(
      AssemblyContext(AutoText("Fee Fi Fo Fum"), nullptr).isStartOfNewInst());
  EXPECT_FALSE(AssemblyContext(AutoText("123456"), nullptr).isStartOfNewInst());
  EXPECT_FALSE(AssemblyContext(AutoText("123456"), nullptr).isStartOfNewInst());
  EXPECT_FALSE(AssemblyContext(AutoText("OpenCL"), nullptr).isStartOfNewInst());
}

TEST(TextStartsWithOp, YesForValueGenerationForm) {
  EXPECT_TRUE(
      AssemblyContext(AutoText("%foo = OpAdd"), nullptr).isStartOfNewInst());
  EXPECT_TRUE(
      AssemblyContext(AutoText("%foo  =  OpAdd"), nullptr).isStartOfNewInst());
}

TEST(TextStartsWithOp, NoForNearlyValueGeneration) {
  EXPECT_FALSE(
      AssemblyContext(AutoText("%foo = "), nullptr).isStartOfNewInst());
  EXPECT_FALSE(AssemblyContext(AutoText("%foo "), nullptr).isStartOfNewInst());
  EXPECT_FALSE(AssemblyContext(AutoText("%foo"), nullptr).isStartOfNewInst());
}

}  // anonymous namespace
