#!/usr/bin/env python
#
#  trans_tests.py:  testing eol conversion and keyword substitution
#
#  Subversion is a tool for revision control.
#  See http://subversion.apache.org for more information.
#
# ====================================================================
#    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.
######################################################################

# General modules
import os, re, logging, sys

logger = logging.getLogger()

# Our testing module
import svntest
from svntest import wc

# (abbreviation)
Skip = svntest.testcase.Skip_deco
SkipUnless = svntest.testcase.SkipUnless_deco
XFail = svntest.testcase.XFail_deco
Issues = svntest.testcase.Issues_deco
Issue = svntest.testcase.Issue_deco
Wimp = svntest.testcase.Wimp_deco
Item = svntest.wc.StateItem


######################################################################
# THINGS TO TEST
#
# *** Perhaps something like commit_tests.py:make_standard_slew_of_changes
#     is in order here in this file as well. ***
#
# status level 1:
#    enable translation, status
#    (now throw local text mods into the picture)
#
# commit level 1:
#    enable translation, commit
#    (now throw local text mods into the picture)
#
# checkout:
#    checkout stuff with translation enabled
#
# status level 2:
#    disable translation, status
#    change newline conversion to different style, status
#    (now throw local text mods into the picture)
#
# commit level 2:
#    disable translation, commit
#    change newline conversion to different style, commit
#    (now throw local text mods into the picture)
#    (now throw local text mods with tortured line endings into the picture)
#
# update:
#    update files from disabled translation to enabled translation
#    update files from enabled translation to disabled translation
#    update files with newline conversion style changes
#    (now throw local text mods into the picture)
#    (now throw conflicting local property mods into the picture)
#
####



# Paths that the tests test.
author_rev_unexp_path = ''
author_rev_exp_path = ''
bogus_keywords_path = ''
embd_author_rev_unexp_path = ''
embd_author_rev_exp_path = ''
embd_bogus_keywords_path = ''

def check_keywords(actual_kw, expected_kw, name):
  """A Helper function to compare two keyword lists"""

  if len(actual_kw) != len(expected_kw):
    logger.warn("Keyword lists are different by size")
    raise svntest.Failure

  for i in range(0,len(actual_kw)):
    if actual_kw[i] != expected_kw[i]:
      logger.warn('%s item %s, Expected: %s', name, i, expected_kw[i][:-1])
      logger.warn('%s item %s, Got:      %s', name, i, actual_kw[i][:-1])
      raise svntest.Failure

def setup_working_copy(wc_dir, value_len):
  """Setup a standard test working copy, then create (but do not add)
  various files for testing translation."""

  global author_rev_unexp_path
  global author_rev_exp_path
  global url_unexp_path
  global url_exp_path
  global id_unexp_path
  global id_exp_path
  global header_unexp_path
  global header_exp_path
  global bogus_keywords_path
  global embd_author_rev_unexp_path
  global embd_author_rev_exp_path
  global embd_bogus_keywords_path
  global fixed_length_keywords_path
  global id_with_space_path
  global id_exp_with_dollar_path

  # NOTE: Only using author and revision keywords in tests for now,
  # since they return predictable substitutions.

  # Unexpanded, expanded, and bogus keywords; sometimes as the only
  # content of the files, sometimes embedded in non-keyword content.
  author_rev_unexp_path = os.path.join(wc_dir, 'author_rev_unexp')
  author_rev_exp_path = os.path.join(wc_dir, 'author_rev_exp')
  url_unexp_path = os.path.join(wc_dir, 'url_unexp')
  url_exp_path = os.path.join(wc_dir, 'url_exp')
  id_unexp_path = os.path.join(wc_dir, 'id_unexp')
  id_exp_path = os.path.join(wc_dir, 'id_exp')
  header_unexp_path = os.path.join(wc_dir, 'header_unexp')
  header_exp_path = os.path.join(wc_dir, 'header_exp')
  bogus_keywords_path = os.path.join(wc_dir, 'bogus_keywords')
  embd_author_rev_unexp_path = os.path.join(wc_dir, 'embd_author_rev_unexp')
  embd_author_rev_exp_path = os.path.join(wc_dir, 'embd_author_rev_exp')
  embd_bogus_keywords_path = os.path.join(wc_dir, 'embd_bogus_keywords')
  fixed_length_keywords_path = os.path.join(wc_dir, 'fixed_length_keywords')
  id_with_space_path = os.path.join(wc_dir, 'id with space')
  id_exp_with_dollar_path = os.path.join(wc_dir, 'id_exp with_$_sign')

  svntest.main.file_append(author_rev_unexp_path, "$Author$\n$Rev$")
  svntest.main.file_append(author_rev_exp_path, "$Author: blah $\n$Rev: 0 $")
  svntest.main.file_append(url_unexp_path, "$URL$")
  svntest.main.file_append(url_exp_path, "$URL: blah $")
  svntest.main.file_append(id_unexp_path, "$Id$")
  svntest.main.file_append(id_exp_path, "$Id: blah $")
  svntest.main.file_append(header_unexp_path, "$Header$")
  svntest.main.file_append(header_exp_path, "$Header: blah $")
  svntest.main.file_append(bogus_keywords_path, "$Arthur$\n$Rev0$")
  svntest.main.file_append(embd_author_rev_unexp_path,
                           "one\nfish\n$Author$ two fish\n red $Rev$\n fish")
  svntest.main.file_append(embd_author_rev_exp_path,
                           "blue $Author: blah $ fish$Rev: 0 $\nI fish")
  svntest.main.file_append(embd_bogus_keywords_path,
                           "you fish $Arthur$then\n we$Rev0$ \n\nchew fish")

  keyword_test_targets = [
    # User tries to shoot him or herself on the foot
    "$URL::$\n",
    "$URL:: $\n",
    "$URL::  $\n",
    # Following are valid entries
    "$URL::   $\n",
    "$URL:: %s $\n" % (' ' * (value_len-1)),
    "$URL:: %s $\n" % (' ' * value_len),
    # Check we will clean the truncate marker when the value fits exactly
    "$URL:: %s#$\n" % ('a' * value_len),
    "$URL:: %s $\n" % (' ' * (value_len+1)),
    # These are syntactically wrong
    "$URL::x%s $\n" % (' ' * value_len),
    "$URL:: %sx$\n" % (' ' * value_len),
    "$URL::x%sx$\n" % (' ' * value_len)
    ]

  for i in keyword_test_targets:
    svntest.main.file_append(fixed_length_keywords_path, i)

  svntest.main.file_append(id_with_space_path, "$Id$")
  svntest.main.file_append(id_exp_with_dollar_path,
                   "$Id: id_exp with_$_sign 1 2006-06-10 11:10:00Z jrandom $")


### Helper functions for setting/removing properties

# Set the property keyword for PATH.  Turn on all possible keywords.
### todo: Later, take list of keywords to set.
def keywords_on(path):
  svntest.actions.run_and_verify_svn(None, [], 'propset',
                                     "svn:keywords",
                                     "Author Rev Date URL Id Header",
                                     path)

# Delete property NAME from versioned PATH in the working copy.
### todo: Later, take list of keywords to remove from the propval?
def keywords_off(path):
  svntest.actions.run_and_verify_svn(None, [], 'propdel',
                                     "svn:keywords", path)


######################################################################
# Tests
#
#   Each test must return on success or raise on failure.

#----------------------------------------------------------------------

### This test is know to fail when Subversion is built in very deep
### directory structures, caused by SVN_KEYWORD_MAX_LEN being defined
### as 255.
def keywords_from_birth(sbox):
  "commit new files with keywords active from birth"

  sbox.build()
  wc_dir = sbox.wc_dir

  canonical_repo_url = svntest.main.canonicalize_url(sbox.repo_url)
  if canonical_repo_url[-1:] != '/':
    url_expand_test_data = canonical_repo_url + '/fixed_length_keywords'
  else:
    url_expand_test_data = canonical_repo_url + 'fixed_length_keywords'

  setup_working_copy(wc_dir, len(url_expand_test_data))

  # Add all the files
  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  expected_status.add({
    'author_rev_unexp' : Item(status='A ', wc_rev=0),
    'author_rev_exp' : Item(status='A ', wc_rev=0),
    'url_unexp' : Item(status='A ', wc_rev=0),
    'url_exp' : Item(status='A ', wc_rev=0),
    'id_unexp' : Item(status='A ', wc_rev=0),
    'id_exp' : Item(status='A ', wc_rev=0),
    'header_unexp' : Item(status='A ', wc_rev=0),
    'header_exp' : Item(status='A ', wc_rev=0),
    'bogus_keywords' : Item(status='A ', wc_rev=0),
    'embd_author_rev_unexp' : Item(status='A ', wc_rev=0),
    'embd_author_rev_exp' : Item(status='A ', wc_rev=0),
    'embd_bogus_keywords' : Item(status='A ', wc_rev=0),
    'fixed_length_keywords' : Item(status='A ', wc_rev=0),
    'id with space' : Item(status='A ', wc_rev=0),
    'id_exp with_$_sign' : Item(status='A ', wc_rev=0),
    })

  svntest.main.run_svn(None, 'add', author_rev_unexp_path)
  svntest.main.run_svn(None, 'add', author_rev_exp_path)
  svntest.main.run_svn(None, 'add', url_unexp_path)
  svntest.main.run_svn(None, 'add', url_exp_path)
  svntest.main.run_svn(None, 'add', id_unexp_path)
  svntest.main.run_svn(None, 'add', id_exp_path)
  svntest.main.run_svn(None, 'add', header_unexp_path)
  svntest.main.run_svn(None, 'add', header_exp_path)
  svntest.main.run_svn(None, 'add', bogus_keywords_path)
  svntest.main.run_svn(None, 'add', embd_author_rev_unexp_path)
  svntest.main.run_svn(None, 'add', embd_author_rev_exp_path)
  svntest.main.run_svn(None, 'add', embd_bogus_keywords_path)
  svntest.main.run_svn(None, 'add', fixed_length_keywords_path)
  svntest.main.run_svn(None, 'add', id_with_space_path)
  svntest.main.run_svn(None, 'add', id_exp_with_dollar_path)

  svntest.actions.run_and_verify_status(wc_dir, expected_status)

  # Add the keyword properties.
  keywords_on(author_rev_unexp_path)
  keywords_on(url_unexp_path)
  keywords_on(url_exp_path)
  keywords_on(id_unexp_path)
  keywords_on(id_exp_path)
  keywords_on(header_unexp_path)
  keywords_on(header_exp_path)
  keywords_on(embd_author_rev_exp_path)
  keywords_on(fixed_length_keywords_path)
  keywords_on(id_with_space_path)
  keywords_on(id_exp_with_dollar_path)

  # Commit.
  expected_output = svntest.wc.State(wc_dir, {
    'author_rev_unexp' : Item(verb='Adding'),
    'author_rev_exp' : Item(verb='Adding'),
    'url_unexp' : Item(verb='Adding'),
    'url_exp' : Item(verb='Adding'),
    'id_unexp' : Item(verb='Adding'),
    'id_exp' : Item(verb='Adding'),
    'header_unexp' : Item(verb='Adding'),
    'header_exp' : Item(verb='Adding'),
    'bogus_keywords' : Item(verb='Adding'),
    'embd_author_rev_unexp' : Item(verb='Adding'),
    'embd_author_rev_exp' : Item(verb='Adding'),
    'embd_bogus_keywords' : Item(verb='Adding'),
    'fixed_length_keywords' : Item(verb='Adding'),
    'id with space' : Item(verb='Adding'),
    'id_exp with_$_sign' : Item(verb='Adding'),
    })

  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                        None)

  # Make sure the unexpanded URL keyword got expanded correctly.
  fp = open(url_unexp_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$URL: (http|https|file|svn|svn\\+ssh)://",
                        lines[0]))):
    logger.warn("URL expansion failed for %s", url_unexp_path)
    raise svntest.Failure
  fp.close()

  # Make sure the preexpanded URL keyword got reexpanded correctly.
  fp = open(url_exp_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$URL: (http|https|file|svn|svn\\+ssh)://",
                        lines[0]))):
    logger.warn("URL expansion failed for %s", url_exp_path)
    raise svntest.Failure
  fp.close()

  # Make sure the unexpanded Id keyword got expanded correctly.
  fp = open(id_unexp_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$Id: id_unexp", lines[0]))):
    logger.warn("Id expansion failed for %s", id_exp_path)
    raise svntest.Failure
  fp.close()

  # Make sure the preexpanded Id keyword got reexpanded correctly.
  fp = open(id_exp_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$Id: id_exp", lines[0]))):
    logger.warn("Id expansion failed for %s", id_exp_path)
    raise svntest.Failure
  fp.close()

  # Make sure the unexpanded Header keyword got expanded correctly.
  fp = open(header_unexp_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$Header: (https?|file|svn|svn\\+ssh)://.* jrandom",
                        lines[0]))):
    logger.warn("Header expansion failed for %s", header_unexp_path)
    raise svntest.Failure
  fp.close()

  # Make sure the preexpanded Header keyword got reexpanded correctly.
  fp = open(header_exp_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$Header: (https?|file|svn|svn\\+ssh)://.* jrandom",
                        lines[0]))):
    logger.warn("Header expansion failed for %s", header_exp_path)
    raise svntest.Failure
  fp.close()

  # Check fixed length keywords.
  kw_workingcopy = [
    '$URL::$\n',
    '$URL:: $\n',
    '$URL::  $\n',
    '$URL:: %s#$\n' % url_expand_test_data[0:1],
    '$URL:: %s#$\n' % url_expand_test_data[:-1],
    '$URL:: %s $\n' % url_expand_test_data,
    '$URL:: %s $\n' % url_expand_test_data,
    '$URL:: %s  $\n'% url_expand_test_data,
    '$URL::x%s $\n' % (' ' * len(url_expand_test_data)),
    '$URL:: %sx$\n' % (' ' * len(url_expand_test_data)),
    '$URL::x%sx$\n' % (' ' * len(url_expand_test_data))
  ]

  fp = open(fixed_length_keywords_path, 'r')
  actual_workingcopy_kw = fp.readlines()
  fp.close()
  check_keywords(actual_workingcopy_kw, kw_workingcopy, "working copy")

  # Check text base for fixed length keywords.
  kw_textbase = [
    '$URL::$\n',
    '$URL:: $\n',
    '$URL::  $\n',
    '$URL::   $\n',
    '$URL:: %s $\n' % (' ' * len(url_expand_test_data[:-1])),
    '$URL:: %s $\n' % (' ' * len(url_expand_test_data)),
    '$URL:: %s $\n' % (' ' * len(url_expand_test_data)),
    '$URL:: %s  $\n'% (' ' * len(url_expand_test_data)),
    '$URL::x%s $\n' % (' ' * len(url_expand_test_data)),
    '$URL:: %sx$\n' % (' ' * len(url_expand_test_data)),
    '$URL::x%sx$\n' % (' ' * len(url_expand_test_data))
    ]

  fp = open(svntest.wc.text_base_path(fixed_length_keywords_path), 'r')
  actual_textbase_kw = fp.readlines()
  fp.close()
  check_keywords(actual_textbase_kw, kw_textbase, "text base")

  # Check the Id keyword for filename with spaces.
  fp = open(id_with_space_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$Id: .*id with space", lines[0]))):
    logger.warn("Id expansion failed for %s", id_with_space_path)
    raise svntest.Failure
  fp.close()

  # Check the Id keyword for filename with_$_signs.
  fp = open(id_exp_with_dollar_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$Id: .*id_exp with_\$_sign [^$]* jrandom \$",
                        lines[0]))):
    logger.warn("Id expansion failed for %s", id_exp_with_dollar_path)

    raise svntest.Failure
  fp.close()

#----------------------------------------------------------------------

#def enable_translation(sbox):
#  "enable translation, check status, commit"

  # TODO: Turn on newline conversion and/or keyword substitution for all
  # sorts of files, with and without local mods, and verify that
  # status shows the right stuff.  The, commit those mods.

#----------------------------------------------------------------------

#def checkout_translated():
#  "checkout files that have translation enabled"

  # TODO: Checkout a tree which contains files with translation
  # enabled.

#----------------------------------------------------------------------

#def disable_translation():
#  "disable translation, check status, commit"

  # TODO: Disable translation on files which have had it enabled,
  # with and without local mods, check status, and commit.

#----------------------------------------------------------------------

# Regression test for bug discovered by Vladmir Prus <ghost@cs.msu.csu>.
# This is a slight rewrite of his test, to use the run_and_verify_* API.
# This is for issue #631.

@Issue(631)
def update_modified_with_translation(sbox):
  "update modified file with eol-style 'native'"

  sbox.build()
  wc_dir = sbox.wc_dir

  # Replace contents of rho and set eol translation to 'native'
  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
  svntest.main.file_write(rho_path, "1\n2\n3\n4\n5\n6\n7\n8\n9\n")
  svntest.actions.run_and_verify_svn(None, [],
                                     'propset', 'svn:eol-style', 'native',
                                     rho_path)

  # Create expected output and status trees of a commit.
  expected_output = svntest.wc.State(wc_dir, {
    'A/D/G/rho' : Item(verb='Sending'),
    })

  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  # rho has props
  expected_status.tweak('A/D/G/rho', wc_rev=2, status='  ')

  # Commit revision 2:  it has the new rho.
  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output,
                                        expected_status,
                                        [], rho_path)

  # Change rho again
  svntest.main.file_write(rho_path, "1\n2\n3\n4\n4.5\n5\n6\n7\n8\n9\n")

  # Commit revision 3
  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  expected_status.tweak('A/D/G/rho', wc_rev=3, status='  ')

  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output,
                                        expected_status,
                                        [], rho_path)

  # Locally modify rho again.
  svntest.main.file_write(rho_path, "1\n2\n3\n4\n4.5\n5\n6\n7\n8\n9\n10\n")

  # Prepare trees for an update to rev 1.
  expected_output = svntest.wc.State(wc_dir, {
    'A/D/G/rho' : Item(status='CU'),
    })

  expected_disk = svntest.main.greek_state.copy()
  expected_disk.tweak('A/D/G/rho',
                      contents="\n".join(["<<<<<<< .mine",
                                          "1",
                                          "2",
                                          "3",
                                          "4",
                                          "4.5",
                                          "5",
                                          "6",
                                          "7",
                                          "8",
                                          "9",
                                          "10",
                                          "||||||| .r3",
                                          "1",
                                          "2",
                                          "3",
                                          "4",
                                          "4.5",
                                          "5",
                                          "6",
                                          "7",
                                          "8",
                                          "9",
                                          "=======",
                                          "This is the file 'rho'.",
                                          ">>>>>>> .r1",
                                          ""]))

  # Updating back to revision 1 should not error; the merge should
  # work, with eol-translation turned on.
  extra_files = ['rho.r1', 'rho.r3', 'rho.mine']
  svntest.actions.run_and_verify_update(wc_dir,
                                        expected_output,
                                        expected_disk,
                                        None,
                                        [], False,
                                        '-r', '1', wc_dir,
                                        extra_files=extra_files)


#----------------------------------------------------------------------

# Regression test for issue #1085, whereby setting the eol-style to a
# fixed platform-incorrect value on a file whose line endings are
# platform-correct causes repository insanity (the eol-style prop
# claims one line ending style, the file is in another).  This test
# assumes that this can be testing by verifying that a) new file
# contents are transmitted to the server during commit, and b) that
# after the commit, the file and its text-base have been changed to
# have the new line-ending style.
@Issue(1085)
def eol_change_is_text_mod(sbox):
  "committing eol-style change forces text send"

  sbox.build()

  wc_dir = sbox.wc_dir

  # add a new file to the working copy.
  foo_path = os.path.join(wc_dir, 'foo')
  f = open(foo_path, 'wb')
  if svntest.main.windows:
    f.write(b"1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n")
  else:
    f.write(b"1\n2\n3\n4\n5\n6\n7\n8\n9\n")
  f.close()

  # commit the file
  svntest.actions.run_and_verify_svn(None, [], 'add', foo_path)
  svntest.actions.run_and_verify_svn(None, [],
                                     'ci', '-m', 'log msg',
                                     foo_path)

  if svntest.main.windows:
    svntest.actions.run_and_verify_svn(None, [], 'propset',
                                       'svn:eol-style', 'LF', foo_path)
  else:
    svntest.actions.run_and_verify_svn(None, [], 'propset',
                                       'svn:eol-style', 'CRLF', foo_path)

  # check 1: did new contents get transmitted?
  expected_output = ["Sending        " + foo_path + "\n",
                     "Transmitting file data .done\n",
                     "Committing transaction...\n",
                     "Committed revision 3.\n"]
  svntest.actions.run_and_verify_svn(expected_output, [],
                                     'ci', '-m', 'log msg', foo_path)

  # check 2: do the files have the right contents now?
  contents = open(foo_path, 'rb').read()
  if svntest.main.windows:
    if contents != b"1\n2\n3\n4\n5\n6\n7\n8\n9\n":
      raise svntest.Failure
  else:
    if contents != b"1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n":
      raise svntest.Failure

  foo_base_path = svntest.wc.text_base_path(foo_path)
  base_contents = open(foo_base_path, 'rb').read()
  if contents != base_contents:
    raise svntest.Failure

#----------------------------------------------------------------------
# Regression test for issue #1151.  A single file in a directory
# didn't get keywords expanded on checkout.
@Issue(1151)
def keyword_expanded_on_checkout(sbox):
  "keyword expansion for lone file in directory"

  sbox.build()
  wc_dir = sbox.wc_dir

  # The bug didn't occur if there were multiple files in the
  # directory, so setup an empty directory.
  Z_path = os.path.join(wc_dir, 'Z')
  svntest.actions.run_and_verify_svn(None, [], 'mkdir', Z_path)

  # Add the file that has the keyword to be expanded
  url_path = os.path.join(Z_path, 'url')
  svntest.main.file_append(url_path, "$URL$")
  svntest.actions.run_and_verify_svn(None, [], 'add', url_path)
  keywords_on(url_path)

  svntest.actions.run_and_verify_svn(None, [],
                                     'ci', '-m', 'log msg', wc_dir)

  other_wc_dir = sbox.add_wc_path('other')
  other_url_path = os.path.join(other_wc_dir, 'Z', 'url')
  svntest.actions.run_and_verify_svn(None, [], 'checkout',
                                     sbox.repo_url,
                                     other_wc_dir)

  # Check keyword got expanded (and thus the mkdir, add, ps, commit
  # etc. worked)
  fp = open(other_url_path, 'r')
  lines = fp.readlines()
  if not ((len(lines) == 1)
          and (re.match("\$URL: (http|https|file|svn|svn\\+ssh)://",
                        lines[0]))):
    logger.warn("URL expansion failed for %s", other_url_path)
    raise svntest.Failure
  fp.close()


#----------------------------------------------------------------------
def cat_keyword_expansion(sbox):
  "keyword expanded on cat"

  sbox.build()
  wc_dir = sbox.wc_dir
  mu_path = os.path.join(wc_dir, 'A', 'mu')
  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')

  # Set up A/mu to do $Rev$ keyword expansion
  svntest.main.file_append(mu_path , "$Rev$\n$Author$")
  svntest.actions.run_and_verify_svn(None, [],
                                     'propset', 'svn:keywords', 'Rev Author',
                                     mu_path)

  expected_output = wc.State(wc_dir, {
    'A/mu' : Item(verb='Sending'),
    })
  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  expected_status.tweak('A/mu', wc_rev=2)
  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output, expected_status)

  # Change the author to value which will get truncated on expansion
  full_author = "x" * 400
  key_author = "x" * 244
  svntest.actions.enable_revprop_changes(sbox.repo_dir)
  svntest.actions.run_and_verify_svn(None, [],
                                     'propset', '--revprop', '-r2',
                                     'svn:author', full_author,
                                     sbox.wc_dir)
  svntest.actions.run_and_verify_svn([ full_author ], [],
                                     'propget', '--revprop', '-r2',
                                     'svn:author', '--no-newline',
                                     sbox.wc_dir)

  # Make another commit so that the last changed revision for A/mu is
  # not HEAD.
  svntest.actions.run_and_verify_svn(None, [],
                                     'propset', 'foo', 'bar', lambda_path)
  expected_output = wc.State(wc_dir, {
    'A/B/lambda' : Item(verb='Sending'),
    })
  expected_status.tweak('A/B/lambda', wc_rev=3)
  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output, expected_status)

  # At one stage the keywords were expanded to values for the requested
  # revision, not to those committed revision
  svntest.actions.run_and_verify_svn([ "This is the file 'mu'.\n",
                                       "$Rev: 2 $\n",
                                       "$Author: " + key_author + " $"], [],
                                     'cat', '-r', 'HEAD', mu_path)


#----------------------------------------------------------------------
def copy_propset_commit(sbox):
  "copy, propset svn:eol-style, commit"

  sbox.build()
  wc_dir = sbox.wc_dir
  mu_path = os.path.join(wc_dir, 'A', 'mu')
  mu2_path = os.path.join(wc_dir, 'A', 'mu2')

  # Copy and propset
  svntest.actions.run_and_verify_svn(None, [], 'copy', mu_path, mu2_path)
  svntest.actions.run_and_verify_svn(None, [],
                                     'propset', 'svn:eol-style', 'native',
                                     mu2_path)
  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  expected_status.add({
    'A/mu2' : Item(status='A ', wc_rev='-', copied='+')
    })
  svntest.actions.run_and_verify_status(wc_dir, expected_status)

  # Commit, at one stage this dumped core
  expected_output = wc.State(wc_dir, {
    'A/mu2' : Item(verb='Adding'),
    })
  expected_status.tweak('A/mu2', status='  ', wc_rev=2, copied=None)
  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output, expected_status)

#----------------------------------------------------------------------
#      Create a greek tree, commit a keyword into one file,
#      then commit a keyword property (i.e., turn on keywords), then
#      try to check out head somewhere else.
#      This should not cause seg fault
def propset_commit_checkout_nocrash(sbox):
  "propset, commit, check out into another wc"

  sbox.build()
  wc_dir = sbox.wc_dir
  mu_path = os.path.join(wc_dir, 'A', 'mu')

  # Put a keyword in A/mu, commit
  svntest.main.file_append(mu_path, "$Rev$")
  expected_output = wc.State(wc_dir, {
    'A/mu' : Item(verb='Sending'),
    })
  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  expected_status.tweak('A/mu', wc_rev=2)
  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output, expected_status)

  # Set property to do keyword expansion on A/mu, commit.
  svntest.actions.run_and_verify_svn(None, [],
                                     'propset', 'svn:keywords', 'Rev', mu_path)
  expected_output = wc.State(wc_dir, {
    'A/mu' : Item(verb='Sending'),
    })
  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  expected_status.tweak('A/mu', wc_rev=3)
  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output, expected_status)

  # Check out into another wc dir
  other_wc_dir = sbox.add_wc_path('other')
  mu_other_path = os.path.join(other_wc_dir, 'A', 'mu')

  svntest.actions.run_and_verify_svn(None, [], 'checkout',
                                     sbox.repo_url,
                                     other_wc_dir)

  mu_other_contents = open(mu_other_path).read()
  if mu_other_contents != "This is the file 'mu'.\n$Rev: 3 $":
    logger.warn("'%s' does not have the expected contents", mu_other_path)
    raise svntest.Failure


#----------------------------------------------------------------------
#      Add the keyword property to a file, svn revert the file
#      This should not display any error message
def propset_revert_noerror(sbox):
  "propset, revert"

  sbox.build()
  wc_dir = sbox.wc_dir
  mu_path = os.path.join(wc_dir, 'A', 'mu')

  # Set the Rev keyword for the mu file
  # could use the keywords_on()/keywords_off() functions to
  # set/del all svn:keywords
  svntest.actions.run_and_verify_svn(None, [],
                                     'propset', 'svn:keywords', 'Rev', mu_path)
  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  expected_status.tweak('A/mu', status=' M')
  svntest.actions.run_and_verify_status(wc_dir, expected_status)

  # Revert the propset
  svntest.actions.run_and_verify_svn(None, [], 'revert', mu_path)
  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  svntest.actions.run_and_verify_status(wc_dir, expected_status)


def props_only_file_update(sbox):
  "retranslation occurs on a props-only update"

  sbox.build()
  wc_dir = sbox.wc_dir

  iota_path = os.path.join(wc_dir, 'iota')
  content = ["This is the file 'iota'.\n",
             "$Author$\n",
             ]
  content_expanded = ["This is the file 'iota'.\n",
                      "$Author: jrandom $\n",
                      ]

  # Create r2 with iota's contents and svn:keywords modified
  with open(iota_path, 'w') as f:
    f.writelines(content)
  svntest.main.run_svn(None, 'propset', 'svn:keywords', 'Author', iota_path)

  expected_output = wc.State(wc_dir, {
    'iota' : Item(verb='Sending'),
    })

  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
  expected_status.tweak('iota', wc_rev=2)

  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output,
                                        expected_status)

  # Create r3 that drops svn:keywords

  # put the content back to its untranslated form
  with open(iota_path, 'w') as f:
    f.writelines(content)

  svntest.main.run_svn(None, 'propdel', 'svn:keywords', iota_path)

  expected_status.tweak('iota', wc_rev=3)

  svntest.actions.run_and_verify_commit(wc_dir,
                                        expected_output,
                                        expected_status)

  # Now, go back to r2. iota should have the Author keyword expanded.
  expected_disk = svntest.main.greek_state.copy()
  expected_disk.tweak('iota', contents=''.join(content_expanded))

  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)

  svntest.actions.run_and_verify_update(wc_dir,
                                        None, None, expected_status,
                                        [], False,
                                        wc_dir, '-r', '2')

  if open(iota_path).read() != ''.join(content_expanded):
    raise svntest.Failure("$Author$ is not expanded in 'iota'")

  # Update to r3. this should retranslate iota, dropping the keyword expansion
  expected_disk = svntest.main.greek_state.copy()
  expected_disk.tweak('iota', contents=''.join(content))

  expected_status = svntest.actions.get_virginal_state(wc_dir, 3)

  svntest.actions.run_and_verify_update(wc_dir,
                                        None, expected_disk, expected_status)

  if open(iota_path).read() != ''.join(content):
    raise svntest.Failure("$Author$ is not contracted in 'iota'")

  # We used to leave some temporary files around. Make sure that we don't.
  temps = os.listdir(os.path.join(wc_dir, svntest.main.get_admin_name(), 'tmp'))
  if os.path.exists(os.path.join(wc_dir, svntest.main.get_admin_name(),
                                 'tmp', 'props')):
    temps.remove('prop-base')
    temps.remove('props')
  if temps:
    logger.warn('Temporary files leftover: %s', (', '.join(temps),))
    raise svntest.Failure

@XFail()
@Issues(4327)
def autoprops_inconsistent_eol(sbox):
  "able to handle inconsistent eols on add"

  sbox.build(read_only = True)
  wc_dir = sbox.wc_dir

  text = 'line with NL\n' + \
         'line with CR\r' + \
         'line with CRLF\r\n' + \
         'line with LFCR (or is that not a line? ;-)\n\r'

  # Compensate for python smartness
  if sys.platform == 'win32':
    expected_text = text.replace('\r\n', '\n')
  else:
    expected_text = text

  sbox.simple_add_text(text, 'add.c')
  sbox.simple_add_text(text, 'add-force.c')

  svntest.actions.run_and_verify_svn(None, '.*inconsistent newlines.*',
                                     'ps', 'svn:eol-style', 'native',
                                     sbox.ospath('add.c'))

  svntest.actions.run_and_verify_svn(None, [],
                                     'ps', 'svn:eol-style', 'native', '--force',
                                     sbox.ospath('add.c'))

  expected_disk = svntest.main.greek_state.copy()

  expected_disk.add({
    'add-force.c'  : Item(contents=expected_text),
    'add.c'        : Item(contents=expected_text),
  })

  # Verify that both add and add-force haven't been changed
  svntest.actions.verify_disk(wc_dir, expected_disk)

  sbox.simple_propset('svn:auto-props', '*.c = svn:eol-style=native', '')


  svntest.main.file_write(sbox.ospath('auto.c'), text, mode='wb')

  expected_output = ['A         %s\n' % sbox.ospath('auto.c')]

  # Fails with svn: E200009: File '.*auto.c' has inconsistent newlines
  svntest.actions.run_and_verify_svn(expected_output,
                                     [], 'add', sbox.ospath('auto.c'))

@XFail()
@Issues(4327)
def autoprops_inconsistent_mime(sbox):
  "able to handle inconsistent mime on add"

  sbox.build(read_only = True)

  sbox.simple_propset('svn:auto-props',
                      '*.c = svn:eol-style=native\n'
                      'c.* = svn:mime-type=application/octet-stream', '')

  sbox.simple_append('c.iota.c', '')

  expected_output = ['A         %s\n' % sbox.ospath('c.iota.c')]

  # Fails with svn: E200009: File '.*c.iota.c' has binary mime type property
  svntest.actions.run_and_verify_svn(expected_output,
                                     [], 'add', sbox.ospath('c.iota.c'))


########################################################################
# Run the tests


# list all tests here, starting with None:
test_list = [ None,
              keywords_from_birth,
              # enable_translation,
              # checkout_translated,
              # disable_translation,
              update_modified_with_translation,
              eol_change_is_text_mod,
              keyword_expanded_on_checkout,
              cat_keyword_expansion,
              copy_propset_commit,
              propset_commit_checkout_nocrash,
              propset_revert_noerror,
              props_only_file_update,
              autoprops_inconsistent_eol,
              autoprops_inconsistent_mime,
             ]

if __name__ == '__main__':
  svntest.main.run_tests(test_list)
  # NOTREACHED


### End of file.
