blob: 77126dff381a9839f5e13b1b1f4f9abdc5bd3306 [file] [log] [blame]
Mike Frysingerf7c51602019-06-18 17:23:39 -04001# -*- coding:utf-8 -*-
2#
3# Copyright (C) 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Mike Frysinger87deaef2019-07-26 21:14:55 -040017"""Unittests for the project.py module."""
18
19from __future__ import print_function
20
Mike Frysinger6da17752019-09-11 18:43:17 -040021import contextlib
22import os
23import shutil
24import subprocess
25import tempfile
Mike Frysingerf7c51602019-06-18 17:23:39 -040026import unittest
27
Mike Frysinger6da17752019-09-11 18:43:17 -040028import git_config
Mike Frysingerf7c51602019-06-18 17:23:39 -040029import project
30
31
Mike Frysinger6da17752019-09-11 18:43:17 -040032@contextlib.contextmanager
33def TempGitTree():
34 """Create a new empty git checkout for testing."""
35 # TODO(vapier): Convert this to tempfile.TemporaryDirectory once we drop
36 # Python 2 support entirely.
37 try:
38 tempdir = tempfile.mkdtemp(prefix='repo-tests')
39 subprocess.check_call(['git', 'init'], cwd=tempdir)
40 yield tempdir
41 finally:
42 shutil.rmtree(tempdir)
43
44
Mike Frysingerf7c51602019-06-18 17:23:39 -040045class RepoHookShebang(unittest.TestCase):
46 """Check shebang parsing in RepoHook."""
47
48 def test_no_shebang(self):
49 """Lines w/out shebangs should be rejected."""
50 DATA = (
51 '',
52 '# -*- coding:utf-8 -*-\n',
53 '#\n# foo\n',
54 '# Bad shebang in script\n#!/foo\n'
55 )
56 for data in DATA:
57 self.assertIsNone(project.RepoHook._ExtractInterpFromShebang(data))
58
59 def test_direct_interp(self):
60 """Lines whose shebang points directly to the interpreter."""
61 DATA = (
62 ('#!/foo', '/foo'),
63 ('#! /foo', '/foo'),
64 ('#!/bin/foo ', '/bin/foo'),
65 ('#! /usr/foo ', '/usr/foo'),
66 ('#! /usr/foo -args', '/usr/foo'),
67 )
68 for shebang, interp in DATA:
69 self.assertEqual(project.RepoHook._ExtractInterpFromShebang(shebang),
70 interp)
71
72 def test_env_interp(self):
73 """Lines whose shebang launches through `env`."""
74 DATA = (
75 ('#!/usr/bin/env foo', 'foo'),
76 ('#!/bin/env foo', 'foo'),
77 ('#! /bin/env /bin/foo ', '/bin/foo'),
78 )
79 for shebang, interp in DATA:
80 self.assertEqual(project.RepoHook._ExtractInterpFromShebang(shebang),
81 interp)
Mike Frysinger6da17752019-09-11 18:43:17 -040082
83
84class FakeProject(object):
85 """A fake for Project for basic functionality."""
86
87 def __init__(self, worktree):
88 self.worktree = worktree
89 self.gitdir = os.path.join(worktree, '.git')
90 self.name = 'fakeproject'
91 self.work_git = project.Project._GitGetByExec(
92 self, bare=False, gitdir=self.gitdir)
93 self.bare_git = project.Project._GitGetByExec(
94 self, bare=True, gitdir=self.gitdir)
95 self.config = git_config.GitConfig.ForRepository(gitdir=self.gitdir)
96
97
98class ReviewableBranchTests(unittest.TestCase):
99 """Check ReviewableBranch behavior."""
100
101 def test_smoke(self):
102 """A quick run through everything."""
103 with TempGitTree() as tempdir:
104 fakeproj = FakeProject(tempdir)
105
106 # Generate some commits.
107 with open(os.path.join(tempdir, 'readme'), 'w') as fp:
108 fp.write('txt')
109 fakeproj.work_git.add('readme')
110 fakeproj.work_git.commit('-mAdd file')
111 fakeproj.work_git.checkout('-b', 'work')
112 fakeproj.work_git.rm('-f', 'readme')
113 fakeproj.work_git.commit('-mDel file')
114
115 # Start off with the normal details.
116 rb = project.ReviewableBranch(
117 fakeproj, fakeproj.config.GetBranch('work'), 'master')
118 self.assertEqual('work', rb.name)
119 self.assertEqual(1, len(rb.commits))
120 self.assertIn('Del file', rb.commits[0])
121 d = rb.unabbrev_commits
122 self.assertEqual(1, len(d))
123 short, long = next(iter(d.items()))
124 self.assertTrue(long.startswith(short))
125 self.assertTrue(rb.base_exists)
126 # Hard to assert anything useful about this.
127 self.assertTrue(rb.date)
128
129 # Now delete the tracking branch!
130 fakeproj.work_git.branch('-D', 'master')
131 rb = project.ReviewableBranch(
132 fakeproj, fakeproj.config.GetBranch('work'), 'master')
133 self.assertEqual(0, len(rb.commits))
134 self.assertFalse(rb.base_exists)
135 # Hard to assert anything useful about this.
136 self.assertTrue(rb.date)