You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

615 lines
16 KiB

#!/usr/bin/env python
# Copyright 2008 The Closure Linter Authors. All Rights Reserved.
#
# Licensed 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.
"""Medium tests for the gpylint auto-fixer."""
__author__ = 'robbyw@google.com (Robby Walker)'
import StringIO
import gflags as flags
import unittest as googletest
from closure_linter import error_fixer
from closure_linter import runner
_RESOURCE_PREFIX = 'closure_linter/testdata'
flags.FLAGS.strict = True
flags.FLAGS.limited_doc_files = ('dummy.js', 'externs.js')
flags.FLAGS.closurized_namespaces = ('goog', 'dummy')
class FixJsStyleTest(googletest.TestCase):
"""Test case to for gjslint auto-fixing."""
def setUp(self):
flags.FLAGS.dot_on_next_line = True
def tearDown(self):
flags.FLAGS.dot_on_next_line = False
def testFixJsStyle(self):
test_cases = [
['fixjsstyle.in.js', 'fixjsstyle.out.js'],
['indentation.js', 'fixjsstyle.indentation.out.js'],
['fixjsstyle.html.in.html', 'fixjsstyle.html.out.html'],
['fixjsstyle.oplineend.in.js', 'fixjsstyle.oplineend.out.js']]
for [running_input_file, running_output_file] in test_cases:
print 'Checking %s vs %s' % (running_input_file, running_output_file)
input_filename = None
golden_filename = None
current_filename = None
try:
input_filename = '%s/%s' % (_RESOURCE_PREFIX, running_input_file)
current_filename = input_filename
golden_filename = '%s/%s' % (_RESOURCE_PREFIX, running_output_file)
current_filename = golden_filename
except IOError as ex:
raise IOError('Could not find testdata resource for %s: %s' %
(current_filename, ex))
if running_input_file == 'fixjsstyle.in.js':
with open(input_filename) as f:
for line in f:
# Go to last line.
pass
self.assertTrue(line == line.rstrip(), '%s file should not end '
'with a new line.' % (input_filename))
# Autofix the file, sending output to a fake file.
actual = StringIO.StringIO()
runner.Run(input_filename, error_fixer.ErrorFixer(actual))
# Now compare the files.
actual.seek(0)
expected = open(golden_filename, 'r')
# Uncomment to generate new golden files and run
# open('/'.join(golden_filename.split('/')[4:]), 'w').write(actual.read())
# actual.seek(0)
self.assertEqual(actual.readlines(), expected.readlines())
def testAddProvideFirstLine(self):
"""Tests handling of case where goog.provide is added."""
original = [
'dummy.bb.cc = 1;',
]
expected = [
'goog.provide(\'dummy.bb\');',
'',
'dummy.bb.cc = 1;',
]
self._AssertFixes(original, expected, include_header=False)
original = [
'',
'dummy.bb.cc = 1;',
]
self._AssertFixes(original, expected, include_header=False)
def testAddRequireFirstLine(self):
"""Tests handling of case where goog.require is added."""
original = [
'a = dummy.bb.cc;',
]
expected = [
'goog.require(\'dummy.bb\');',
'',
'a = dummy.bb.cc;',
]
self._AssertFixes(original, expected, include_header=False)
original = [
'',
'a = dummy.bb.cc;',
]
self._AssertFixes(original, expected, include_header=False)
def testDeleteProvideAndAddProvideFirstLine(self):
"""Tests handling of case where goog.provide is deleted and added.
Bug 14832597.
"""
original = [
'goog.provide(\'dummy.aa\');',
'',
'dummy.bb.cc = 1;',
]
expected = [
'goog.provide(\'dummy.bb\');',
'',
'dummy.bb.cc = 1;',
]
self._AssertFixes(original, expected, include_header=False)
original = [
'goog.provide(\'dummy.aa\');',
'dummy.bb.cc = 1;',
]
self._AssertFixes(original, expected, include_header=False)
def testDeleteProvideAndAddRequireFirstLine(self):
"""Tests handling where goog.provide is deleted and goog.require added.
Bug 14832597.
"""
original = [
'goog.provide(\'dummy.aa\');',
'',
'a = dummy.bb.cc;',
]
expected = [
'goog.require(\'dummy.bb\');',
'',
'a = dummy.bb.cc;',
]
self._AssertFixes(original, expected, include_header=False)
original = [
'goog.provide(\'dummy.aa\');',
'a = dummy.bb.cc;',
]
self._AssertFixes(original, expected, include_header=False)
def testDeleteRequireAndAddRequireFirstLine(self):
"""Tests handling of case where goog.require is deleted and added.
Bug 14832597.
"""
original = [
'goog.require(\'dummy.aa\');',
'',
'a = dummy.bb.cc;',
]
expected = [
'goog.require(\'dummy.bb\');',
'',
'a = dummy.bb.cc;',
]
self._AssertFixes(original, expected, include_header=False)
original = [
'goog.require(\'dummy.aa\');',
'a = dummy.bb.cc;',
]
self._AssertFixes(original, expected, include_header=False)
def testDeleteRequireAndAddProvideFirstLine(self):
"""Tests handling where goog.require is deleted and goog.provide added.
Bug 14832597.
"""
original = [
'goog.require(\'dummy.aa\');',
'',
'dummy.bb.cc = 1;',
]
expected = [
'goog.provide(\'dummy.bb\');',
'',
'dummy.bb.cc = 1;',
]
self._AssertFixes(original, expected, include_header=False)
original = [
'goog.require(\'dummy.aa\');',
'dummy.bb.cc = 1;',
]
self._AssertFixes(original, expected, include_header=False)
def testMultipleProvideInsert(self):
original = [
'goog.provide(\'dummy.bb\');',
'goog.provide(\'dummy.dd\');',
'',
'dummy.aa.ff = 1;',
'dummy.bb.ff = 1;',
'dummy.cc.ff = 1;',
'dummy.dd.ff = 1;',
'dummy.ee.ff = 1;',
]
expected = [
'goog.provide(\'dummy.aa\');',
'goog.provide(\'dummy.bb\');',
'goog.provide(\'dummy.cc\');',
'goog.provide(\'dummy.dd\');',
'goog.provide(\'dummy.ee\');',
'',
'dummy.aa.ff = 1;',
'dummy.bb.ff = 1;',
'dummy.cc.ff = 1;',
'dummy.dd.ff = 1;',
'dummy.ee.ff = 1;',
]
self._AssertFixes(original, expected, include_header=False)
def testMultipleRequireInsert(self):
original = [
'goog.require(\'dummy.bb\');',
'goog.require(\'dummy.dd\');',
'',
'a = dummy.aa.ff;',
'b = dummy.bb.ff;',
'c = dummy.cc.ff;',
'd = dummy.dd.ff;',
'e = dummy.ee.ff;',
]
expected = [
'goog.require(\'dummy.aa\');',
'goog.require(\'dummy.bb\');',
'goog.require(\'dummy.cc\');',
'goog.require(\'dummy.dd\');',
'goog.require(\'dummy.ee\');',
'',
'a = dummy.aa.ff;',
'b = dummy.bb.ff;',
'c = dummy.cc.ff;',
'd = dummy.dd.ff;',
'e = dummy.ee.ff;',
]
self._AssertFixes(original, expected, include_header=False)
def testUnsortedRequires(self):
"""Tests handling of unsorted goog.require statements without header.
Bug 8398202.
"""
original = [
'goog.require(\'dummy.aa\');',
'goog.require(\'dummy.Cc\');',
'goog.require(\'dummy.Dd\');',
'',
'function a() {',
' dummy.aa.i = 1;',
' dummy.Cc.i = 1;',
' dummy.Dd.i = 1;',
'}',
]
expected = [
'goog.require(\'dummy.Cc\');',
'goog.require(\'dummy.Dd\');',
'goog.require(\'dummy.aa\');',
'',
'function a() {',
' dummy.aa.i = 1;',
' dummy.Cc.i = 1;',
' dummy.Dd.i = 1;',
'}',
]
self._AssertFixes(original, expected, include_header=False)
def testMissingExtraAndUnsortedRequires(self):
"""Tests handling of missing extra and unsorted goog.require statements."""
original = [
'goog.require(\'dummy.aa\');',
'goog.require(\'dummy.Cc\');',
'goog.require(\'dummy.Dd\');',
'',
'var x = new dummy.Bb();',
'dummy.Cc.someMethod();',
'dummy.aa.someMethod();',
]
expected = [
'goog.require(\'dummy.Bb\');',
'goog.require(\'dummy.Cc\');',
'goog.require(\'dummy.aa\');',
'',
'var x = new dummy.Bb();',
'dummy.Cc.someMethod();',
'dummy.aa.someMethod();',
]
self._AssertFixes(original, expected)
def testExtraRequireOnFirstLine(self):
"""Tests handling of extra goog.require statement on the first line.
There was a bug when fixjsstyle quits with an exception. It happened if
- the first line of the file is an extra goog.require() statement,
- goog.require() statements are not sorted.
"""
original = [
'goog.require(\'dummy.aa\');',
'goog.require(\'dummy.cc\');',
'goog.require(\'dummy.bb\');',
'',
'var x = new dummy.bb();',
'var y = new dummy.cc();',
]
expected = [
'goog.require(\'dummy.bb\');',
'goog.require(\'dummy.cc\');',
'',
'var x = new dummy.bb();',
'var y = new dummy.cc();',
]
self._AssertFixes(original, expected, include_header=False)
def testUnsortedProvides(self):
"""Tests handling of unsorted goog.provide statements without header.
Bug 8398202.
"""
original = [
'goog.provide(\'dummy.aa\');',
'goog.provide(\'dummy.Cc\');',
'goog.provide(\'dummy.Dd\');',
'',
'dummy.aa = function() {};'
'dummy.Cc = function() {};'
'dummy.Dd = function() {};'
]
expected = [
'goog.provide(\'dummy.Cc\');',
'goog.provide(\'dummy.Dd\');',
'goog.provide(\'dummy.aa\');',
'',
'dummy.aa = function() {};'
'dummy.Cc = function() {};'
'dummy.Dd = function() {};'
]
self._AssertFixes(original, expected, include_header=False)
def testMissingExtraAndUnsortedProvides(self):
"""Tests handling of missing extra and unsorted goog.provide statements."""
original = [
'goog.provide(\'dummy.aa\');',
'goog.provide(\'dummy.Cc\');',
'goog.provide(\'dummy.Dd\');',
'',
'dummy.Cc = function() {};',
'dummy.Bb = function() {};',
'dummy.aa.someMethod = function();',
]
expected = [
'goog.provide(\'dummy.Bb\');',
'goog.provide(\'dummy.Cc\');',
'goog.provide(\'dummy.aa\');',
'',
'dummy.Cc = function() {};',
'dummy.Bb = function() {};',
'dummy.aa.someMethod = function();',
]
self._AssertFixes(original, expected)
def testNoRequires(self):
"""Tests positioning of missing requires without existing requires."""
original = [
'goog.provide(\'dummy.Something\');',
'',
'dummy.Something = function() {};',
'',
'var x = new dummy.Bb();',
]
expected = [
'goog.provide(\'dummy.Something\');',
'',
'goog.require(\'dummy.Bb\');',
'',
'dummy.Something = function() {};',
'',
'var x = new dummy.Bb();',
]
self._AssertFixes(original, expected)
def testNoProvides(self):
"""Tests positioning of missing provides without existing provides."""
original = [
'goog.require(\'dummy.Bb\');',
'',
'dummy.Something = function() {};',
'',
'var x = new dummy.Bb();',
]
expected = [
'goog.provide(\'dummy.Something\');',
'',
'goog.require(\'dummy.Bb\');',
'',
'dummy.Something = function() {};',
'',
'var x = new dummy.Bb();',
]
self._AssertFixes(original, expected)
def testOutputOkayWhenFirstTokenIsDeleted(self):
"""Tests that autofix output is is correct when first token is deleted.
Regression test for bug 4581567
"""
original = ['"use strict";']
expected = ["'use strict';"]
self._AssertFixes(original, expected, include_header=False)
def testGoogScopeIndentation(self):
"""Tests Handling a typical end-of-scope indentation fix."""
original = [
'goog.scope(function() {',
' // TODO(brain): Take over the world.',
'}); // goog.scope',
]
expected = [
'goog.scope(function() {',
'// TODO(brain): Take over the world.',
'}); // goog.scope',
]
self._AssertFixes(original, expected)
def testMissingEndOfScopeComment(self):
"""Tests Handling a missing comment at end of goog.scope."""
original = [
'goog.scope(function() {',
'});',
]
expected = [
'goog.scope(function() {',
'}); // goog.scope',
]
self._AssertFixes(original, expected)
def testMissingEndOfScopeCommentWithOtherComment(self):
"""Tests handling an irrelevant comment at end of goog.scope."""
original = [
'goog.scope(function() {',
"}); // I don't belong here!",
]
expected = [
'goog.scope(function() {',
'}); // goog.scope',
]
self._AssertFixes(original, expected)
def testMalformedEndOfScopeComment(self):
"""Tests Handling a malformed comment at end of goog.scope."""
original = [
'goog.scope(function() {',
'}); // goog.scope FTW',
]
expected = [
'goog.scope(function() {',
'}); // goog.scope',
]
self._AssertFixes(original, expected)
def testEndsWithIdentifier(self):
"""Tests Handling case where script ends with identifier. Bug 7643404."""
original = [
'goog.provide(\'xyz\');',
'',
'abc'
]
expected = [
'goog.provide(\'xyz\');',
'',
'abc;'
]
self._AssertFixes(original, expected)
def testFileStartsWithSemicolon(self):
"""Tests handling files starting with semicolon.
b/10062516
"""
original = [
';goog.provide(\'xyz\');',
'',
'abc;'
]
expected = [
'goog.provide(\'xyz\');',
'',
'abc;'
]
self._AssertFixes(original, expected, include_header=False)
def testCodeStartsWithSemicolon(self):
"""Tests handling code in starting with semicolon after comments.
b/10062516
"""
original = [
';goog.provide(\'xyz\');',
'',
'abc;'
]
expected = [
'goog.provide(\'xyz\');',
'',
'abc;'
]
self._AssertFixes(original, expected)
def _AssertFixes(self, original, expected, include_header=True):
"""Asserts that the error fixer corrects original to expected."""
if include_header:
original = self._GetHeader() + original
expected = self._GetHeader() + expected
actual = StringIO.StringIO()
runner.Run('testing.js', error_fixer.ErrorFixer(actual), original)
actual.seek(0)
expected = [x + '\n' for x in expected]
self.assertListEqual(actual.readlines(), expected)
def _GetHeader(self):
"""Returns a fake header for a JavaScript file."""
return [
'// Copyright 2011 Google Inc. All Rights Reserved.',
'',
'/**',
' * @fileoverview Fake file overview.',
' * @author fake@google.com (Fake Person)',
' */',
''
]
if __name__ == '__main__':
googletest.main()