You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by tv...@apache.org on 2013/07/15 23:03:57 UTC

[01/50] [abbrv] git commit: [#6211] remove commit widget template (was unused, and was a widget extending master template which is weird)

Updated Branches:
  refs/heads/tv/6355 d0eeaec35 -> dbfa5afd2 (forced update)


[#6211] remove commit widget template (was unused, and was a widget extending master template which is weird)


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/faf6a395
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/faf6a395
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/faf6a395

Branch: refs/heads/tv/6355
Commit: faf6a3950a498fb6cabe19e65ad791698d12b140
Parents: 673a6b7
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Jul 1 16:01:14 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Jul 1 16:35:40 2013 +0000

----------------------------------------------------------------------
 .../allura/templates/widgets/repo/commit.html   | 65 --------------------
 1 file changed, 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/faf6a395/Allura/allura/templates/widgets/repo/commit.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/repo/commit.html b/Allura/allura/templates/widgets/repo/commit.html
deleted file mode 100644
index 0858365..0000000
--- a/Allura/allura/templates/widgets/repo/commit.html
+++ /dev/null
@@ -1,65 +0,0 @@
-{#-
-       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.
--#}
-{% extends g.theme.master %}
-
-{% block title %}
-  {{c.project.name}} / {{c.app.config.options.mount_label}} / Commit {{commit.shorthand_id()}}
-{% endblock %}
-
-{% macro commit_link(commit) -%}
-<a href={{commit.url()}}>{{commit.shorthand_id}}</a>
-{%- endmacro %}
-
-{% block header %}Commit {{commit_link(commit)}}{% endblock %}
-
-{% block content %}
-{{c.revision_widget.display(value=commit, prev=prev, next=next)}}
-<table>
-  <tbody>
-    {% for diff in commit.diffs.added %}
-    <tr>
-      <td>add</td>
-      <td><a href="./tree/{{h.really_unicode(diff)}}">{{h.really_unicode(diff)}}</a></td>
-    </tr>
-    {% endfor %}{% for diff in commit.diffs.removed %}
-    <tr>
-      <td>remove</td>
-      <td><a href="{{prev[0].url()}}tree/{{h.really_unicode(diff)}}">{{h.really_unicode(diff)}}</a></td>
-    </tr>
-    {% endfor %}{% for diff in commit.diffs.changed %}
-    <tr>
-      <td>change</td>
-      <td>
-        <a href="./tree/{{h.really_unicode(diff)}}">{{h.really_unicode(diff)}}</a>
-        <a href="./tree/{{h.really_unicode(diff)}}?diff={{prev[0]._id}}">(diff)</a>
-      </td>
-    </tr>
-    {% endfor %}{% for diff in commit.diffs.copied %}
-    <tr>
-      <td>copy</td>
-      <td>
-        <a href="{{prev[0].url()}}tree/{{h.really_unicode(diff.old)}}">{{h.really_unicode(diff.old)}}</a>
-        <br/>to<br/>
-        <a href="./tree/{{h.really_unicode(diff)}}">{{h.really_unicode(diff)}}</a>
-      </td>
-    </tr>
-    {% endfor %}
-  </tbody>
-</table>
-{% endblock %}


[42/50] [abbrv] [#4122] rename AlluraTesting dir to AlluraTest, to match the module name below

Posted by tv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/jslint/rhino.js
----------------------------------------------------------------------
diff --git a/AlluraTest/jslint/rhino.js b/AlluraTest/jslint/rhino.js
new file mode 100644
index 0000000..04be512
--- /dev/null
+++ b/AlluraTest/jslint/rhino.js
@@ -0,0 +1,41 @@
+// rhino.js
+// 2009-09-11
+/*
+Copyright (c) 2002 Douglas Crockford  (www.JSLint.com) Rhino Edition
+*/
+
+// This is the Rhino companion to fulljslint.js.
+
+/*global JSLINT */
+/*jslint rhino: true, strict: false */
+
+(function (a) {
+    var e, i, input;
+    if (!a[0]) {
+        print("Usage: jslint.js file.js");
+        quit(1);
+    }
+    input = readFile(a[0]);
+    if (!input) {
+        print("jslint: Couldn't open file '" + a[0] + "'.");
+        quit(1);
+    }
+    if (!JSLINT(input, {bitwise: true, eqeqeq: true, immed: true,
+            newcap: true, nomen: true, onevar: true, plusplus: true,
+            regexp: true, rhino: true, undef: true, white: true})) {
+        for (i = 0; i < JSLINT.errors.length; i += 1) {
+            e = JSLINT.errors[i];
+            if (e) {
+                print('Lint at line ' + e.line + ' character ' +
+                        e.character + ': ' + e.reason);
+                print((e.evidence || '').
+                        replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"));
+                print('');
+            }
+        }
+        quit(2);
+    } else {
+        print("jslint: No problems found in " + a[0]);
+        quit();
+    }
+}(arguments));
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/setup.py
----------------------------------------------------------------------
diff --git a/AlluraTest/setup.py b/AlluraTest/setup.py
new file mode 100644
index 0000000..421cd39
--- /dev/null
+++ b/AlluraTest/setup.py
@@ -0,0 +1,39 @@
+#       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.
+
+from setuptools import setup, find_packages
+import sys, os
+
+setup(name='AlluraTest',
+      version='0.1',
+      description="Allura testing support",
+      long_description="""\
+""",
+      classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
+      keywords='',
+      author='',
+      author_email='',
+      url='',
+      license='',
+      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=[
+        "poster",
+          # -*- Extra requirements: -*-
+      ]
+      )

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/README
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/README b/AlluraTest/twill-tests/README
new file mode 100644
index 0000000..59e490e
--- /dev/null
+++ b/AlluraTest/twill-tests/README
@@ -0,0 +1,19 @@
+Twill Tests
+
+First, you'll need twill-sh:
+
+  sudo easy_install twill
+
+
+Files in this directory ending with '.twill' are tests to be run by twill-sh
+
+  twill-sh --url=http://url.of.forge.to.test/ twill-tests/*.twill
+
+e.g.,
+
+  twill-sh --url=http://re.sourceforge.net/ twill-tests/*.twill
+
+
+If you just want to run the quick "smoke tests":
+
+  twill-sh --url=... twill-tests/smoke*.twill

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/create_repo.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/create_repo.twill b/AlluraTest/twill-tests/create_repo.twill
new file mode 100644
index 0000000..17b9a3a
--- /dev/null
+++ b/AlluraTest/twill-tests/create_repo.twill
@@ -0,0 +1,47 @@
+#       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.
+
+setlocal username test_admin
+setlocal password foo
+
+clear_extra_headers
+go ./auth/
+formvalue 1 username $username
+formvalue 1 password $password
+submit
+
+code 200
+
+go ./p/test/admin/tools
+
+code 200
+
+formvalue 2 "new.ep_name" "Git"
+formvalue 2 "new.mount_point" "deleteme"
+submit
+
+code 200
+
+go ../deleteme/
+
+code 200
+
+find ready
+
+go ../admin/tools
+
+# Delete the repo :-(

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/edit_wiki_page.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/edit_wiki_page.twill b/AlluraTest/twill-tests/edit_wiki_page.twill
new file mode 100644
index 0000000..2b659ec
--- /dev/null
+++ b/AlluraTest/twill-tests/edit_wiki_page.twill
@@ -0,0 +1,36 @@
+#       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.
+
+setlocal username test_admin
+setlocal password foo
+
+clear_extra_headers
+go ./auth/
+formvalue 1 username $username
+formvalue 1 password $password
+submit
+
+code 200
+
+go ./p/test/wiki/TestWikiWord/edit
+
+code 200
+
+formvalue 3 text "This is just a test."
+submit
+
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/login.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/login.twill b/AlluraTest/twill-tests/login.twill
new file mode 100644
index 0000000..fbe6f67
--- /dev/null
+++ b/AlluraTest/twill-tests/login.twill
@@ -0,0 +1,27 @@
+#       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.
+
+setlocal username test_admin
+setlocal password foo
+
+clear_extra_headers
+go ./auth/
+formvalue 1 username $username
+formvalue 1 password $password
+submit
+
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/new_issue.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/new_issue.twill b/AlluraTest/twill-tests/new_issue.twill
new file mode 100644
index 0000000..7b05168
--- /dev/null
+++ b/AlluraTest/twill-tests/new_issue.twill
@@ -0,0 +1,36 @@
+#       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.
+
+setlocal username test_admin
+setlocal password foo
+
+clear_extra_headers
+go ./auth/
+formvalue 1 username $username
+formvalue 1 password $password
+submit
+
+code 200
+
+go ./p/test/bugs/new/
+
+code 200
+
+formvalue 2 "ticket_form.summary" "test create ticket"
+submit
+
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/smoke-front-page.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/smoke-front-page.twill b/AlluraTest/twill-tests/smoke-front-page.twill
new file mode 100644
index 0000000..a0f4852
--- /dev/null
+++ b/AlluraTest/twill-tests/smoke-front-page.twill
@@ -0,0 +1,20 @@
+#       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.
+
+clear_extra_headers
+go .
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/smoke-project-home.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/smoke-project-home.twill b/AlluraTest/twill-tests/smoke-project-home.twill
new file mode 100644
index 0000000..3d1e8bf
--- /dev/null
+++ b/AlluraTest/twill-tests/smoke-project-home.twill
@@ -0,0 +1,20 @@
+#       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.
+
+clear_extra_headers
+go ./p/test/home/
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/smoke-tracker-search.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/smoke-tracker-search.twill b/AlluraTest/twill-tests/smoke-tracker-search.twill
new file mode 100644
index 0000000..d8d03a3
--- /dev/null
+++ b/AlluraTest/twill-tests/smoke-tracker-search.twill
@@ -0,0 +1,20 @@
+#       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.
+
+clear_extra_headers
+go ./p/test/bugs/search/
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/smoke-tracker.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/smoke-tracker.twill b/AlluraTest/twill-tests/smoke-tracker.twill
new file mode 100644
index 0000000..1e9e0f7
--- /dev/null
+++ b/AlluraTest/twill-tests/smoke-tracker.twill
@@ -0,0 +1,20 @@
+#       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.
+
+clear_extra_headers
+go ./p/test/bugs/
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/smoke-user-profile.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/smoke-user-profile.twill b/AlluraTest/twill-tests/smoke-user-profile.twill
new file mode 100644
index 0000000..907f17d
--- /dev/null
+++ b/AlluraTest/twill-tests/smoke-user-profile.twill
@@ -0,0 +1,20 @@
+#       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.
+
+clear_extra_headers
+go ./u/test_admin/profile/
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/twill-tests/smoke-wiki.twill
----------------------------------------------------------------------
diff --git a/AlluraTest/twill-tests/smoke-wiki.twill b/AlluraTest/twill-tests/smoke-wiki.twill
new file mode 100644
index 0000000..03e2c56
--- /dev/null
+++ b/AlluraTest/twill-tests/smoke-wiki.twill
@@ -0,0 +1,20 @@
+#       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.
+
+clear_extra_headers
+go ./p/test/wiki/Home/
+code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/LICENSE
----------------------------------------------------------------------
diff --git a/AlluraTesting/LICENSE b/AlluraTesting/LICENSE
deleted file mode 100644
index 196ac43..0000000
--- a/AlluraTesting/LICENSE
+++ /dev/null
@@ -1,234 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   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.
-
-AlluraTesting SUBCOMPONENTS:
-
-AlluraTesting includes a number of subcomponents with
-separate copyright notices and license terms. Your use of the source code
-for the these subcomponents is subject to the terms and conditions of the
-following licenses.
-
-For jslint.js, in directory
-jslint/
-
-   Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy of
-   this software and associated documentation files (the "Software"), to deal in
-   the Software without restriction, including without limitation the rights to
-   use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-   of the Software, and to permit persons to whom the Software is 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 Software.
-
-   The Software shall be used for Good, not Evil.
-
-   THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/alluratest/__init__.py
----------------------------------------------------------------------
diff --git a/AlluraTesting/alluratest/__init__.py b/AlluraTesting/alluratest/__init__.py
deleted file mode 100644
index 144e298..0000000
--- a/AlluraTesting/alluratest/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#       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.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/alluratest/controller.py
----------------------------------------------------------------------
diff --git a/AlluraTesting/alluratest/controller.py b/AlluraTesting/alluratest/controller.py
deleted file mode 100644
index 95d9b4b..0000000
--- a/AlluraTesting/alluratest/controller.py
+++ /dev/null
@@ -1,183 +0,0 @@
-#       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.
-
-"""Unit and functional test suite for allura."""
-import os
-import urllib
-
-import mock
-import beaker.session
-from formencode import variabledecode
-from paste.deploy import loadapp
-from paste.deploy.converters import asbool
-from paste.script.appinstall import SetupCommand
-from pylons import tmpl_context as c, app_globals as g
-from pylons import url, request, response, session
-import tg
-from webtest import TestApp
-from webob import Request, Response
-import ew
-from ming.orm import ThreadLocalORMSession
-import ming.orm
-
-from allura import model as M
-import allura.lib.security
-from allura.lib.app_globals import Globals
-from allura.lib import helpers as h
-from allura.websetup.schema import REGISTRY
-#from allura.lib.custom_middleware import environ as ENV, MagicalC
-from .validation import ValidatingTestApp
-
-DFL_APP_NAME = 'main_without_authn'
-
-# these are all helpers & base classes, and should never
-# be considered test cases when imported into some test module
-__test__ = False
-
-
-def get_config_file(config=None):
-    if not config:
-        config = 'test.ini'
-
-    try:
-        conf_dir = tg.config.here
-    except AttributeError:
-        conf_dir = os.getcwd()
-    return os.path.join(conf_dir, config)
-
-
-def setup_basic_test(config=None, app_name=DFL_APP_NAME):
-    '''Create clean environment for running tests'''
-    try:
-        conf_dir = tg.config.here
-    except AttributeError:
-        conf_dir = os.getcwd()
-    ew.TemplateEngine.initialize({})
-    test_file = os.path.join(conf_dir, get_config_file(config))
-    cmd = SetupCommand('setup-app')
-    cmd.run([test_file])
-
-    # run all tasks, e.g. indexing from bootstrap operations
-    while M.MonQTask.run_ready('setup'):
-        ThreadLocalORMSession.flush_all()
-setup_basic_test.__test__ = False  # sometimes __test__ above isn't sufficient
-
-
-def setup_functional_test(config=None, app_name=DFL_APP_NAME):
-    '''Create clean environment for running tests.  Also return WSGI test app'''
-    config = get_config_file(config)
-    setup_basic_test(config, app_name)
-    conf_dir = tg.config.here
-    wsgiapp = loadapp('config:%s#%s' % (config, app_name),
-                      relative_to=conf_dir)
-    return wsgiapp
-setup_functional_test.__test__ = False  # sometimes __test__ above isn't sufficient
-
-
-def setup_unit_test():
-    try:
-        while True:
-            REGISTRY.cleanup()
-    except:
-        pass
-    REGISTRY.prepare()
-    REGISTRY.register(ew.widget_context, ew.core.WidgetContext('http', ew.ResourceManager()))
-    REGISTRY.register(g, Globals())
-    REGISTRY.register(c, mock.Mock())
-    REGISTRY.register(url, lambda:None)
-    REGISTRY.register(request, Request.blank('/', remote_addr='1.1.1.1'))
-    REGISTRY.register(response, Response())
-    REGISTRY.register(session, beaker.session.SessionObject({}))
-    REGISTRY.register(allura.credentials, allura.lib.security.Credentials())
-    c.memoize_cache = {}
-    c.queued_messages = None
-    c.model_cache = None
-    ThreadLocalORMSession.close_all()
-setup_unit_test.__test__ = False  # sometimes __test__ above isn't sufficient
-
-
-def setup_global_objects():
-    setup_unit_test()
-    h.set_context('test', 'wiki', neighborhood='Projects')
-    c.user = M.User.query.get(username='test-admin')
-
-
-class TestController(object):
-
-    application_under_test = 'main'
-    validate_skip = False
-
-    def setUp(self):
-        """Method called by nose before running each test"""
-        self.app = ValidatingTestApp(setup_functional_test(app_name=self.application_under_test))
-        if self.validate_skip:
-            self.app.validate_skip = self.validate_skip
-        if asbool(tg.config.get('smtp.mock')):
-            self.smtp_mock = mock.patch('allura.lib.mail_util.smtplib.SMTP')
-            self.smtp_mock.start()
-
-    def tearDown(self):
-        """Method called by nose after running each test"""
-        if asbool(tg.config.get('smtp.mock')):
-            self.smtp_mock.stop()
-
-    def webflash(self, response):
-        "Extract webflash content from response."
-        return urllib.unquote(response.cookies_set.get('webflash', ''))
-
-
-class TestRestApiBase(TestController):
-
-    def setUp(self):
-        super(TestRestApiBase, self).setUp()
-        setup_global_objects()
-#        h.set_context('test', 'home')
-        self.user = M.User.query.get(username='test-admin')
-        self.token = M.ApiToken(user_id=self.user._id)
-        ming.orm.session(self.token).flush()
-
-    def set_api_token(self, token):
-        self.token = token
-
-    def _api_getpost(self, method, path, api_key=None, api_timestamp=None, api_signature=None,
-                 wrap_args=None, **params):
-        if wrap_args:
-            params = {wrap_args: params}
-        params = variabledecode.variable_encode(params, add_repetitions=False)
-        if api_key: params['api_key'] = api_key
-        if api_timestamp: params['api_timestamp'] = api_timestamp
-        if api_signature: params['api_signature'] = api_signature
-        params = self.token.sign_request(path, params)
-
-        fn = self.app.post if method=='POST' else self.app.get
-
-        response = fn(
-            str(path),
-            params=params,
-            status=[200, 302, 400, 403, 404])
-        if response.status_int == 302:
-            return response.follow()
-        else:
-            return response
-
-    def api_get(self, path, api_key=None, api_timestamp=None, api_signature=None,
-                 wrap_args=None, **params):
-        return self._api_getpost('GET', path, api_key, api_timestamp, api_signature, wrap_args, **params)
-
-    def api_post(self, path, api_key=None, api_timestamp=None, api_signature=None,
-                 wrap_args=None, **params):
-        return self._api_getpost('POST', path, api_key, api_timestamp, api_signature, wrap_args, **params)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/alluratest/test_syntax.py
----------------------------------------------------------------------
diff --git a/AlluraTesting/alluratest/test_syntax.py b/AlluraTesting/alluratest/test_syntax.py
deleted file mode 100644
index b394798..0000000
--- a/AlluraTesting/alluratest/test_syntax.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#       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.
-
-import os.path
-from glob import glob
-from subprocess import Popen, PIPE
-import sys
-
-toplevel_dir = os.path.abspath(os.path.dirname(__file__) + "/../..")
-
-def run(cmd):
-    proc = Popen(cmd, shell=True, cwd=toplevel_dir, stdout=PIPE, stderr=PIPE)
-    # must capture & reprint stdount, so that nosetests can capture it
-    (stdout, stderr) = proc.communicate()
-    sys.stdout.write(stdout)
-    sys.stderr.write(stderr)
-    return proc.returncode
-
-find_py = "find Allura Forge* -name '*.py'"
-
-# a recepe from itertools doc
-from itertools import izip_longest
-def grouper(n, iterable, fillvalue=None):
-    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
-    args = [iter(iterable)] * n
-    return izip_longest(fillvalue=fillvalue, *args)
-
-def test_pyflakes():
-    # skip some that aren't critical errors
-    skips = [
-        'imported but unused',
-        'redefinition of unused',
-        'assigned to but never used',
-        '__version__',
-    ]
-    proc = Popen(find_py, shell=True, cwd=toplevel_dir, stdout=PIPE, stderr=PIPE)
-    (find_stdout, stderr) = proc.communicate()
-    sys.stderr.write(stderr)
-    assert proc.returncode == 0, proc.returncode
-
-    # run pyflakes in batches, so it doesn't take tons of memory
-    error = False
-    all_files = [f for f in find_stdout.split('\n')
-                 if '/migrations/' not in f and f.strip()]
-    for files in grouper(20, all_files, fillvalue=''):
-        cmd = "pyflakes " + ' '.join(files) + " | grep -v '" + "' | grep -v '".join(skips) + "'"
-        #print 'Command was: %s' % cmd
-        retval = run(cmd)
-        if retval != 1:
-            print
-            #print 'Command was: %s' % cmd
-            print 'Returned %s' % retval
-            error = True
-
-    if error:
-        raise Exception('pyflakes failure, see stdout')
-
-def test_no_now():
-    if run(find_py + " | xargs grep '\.now(' ") not in [1,123]:
-        raise Exception("These should use .utcnow()")
-    if run(find_py + " | xargs grep '\.fromtimestamp(' ") not in [1,123]:
-        raise Exception("These should use .utcfromtimestamp()")
-
-def test_no_prints():
-    skips = [
-        '/tests/',
-        'Allura/allura/command/',
-        'Allura/ldap-setup.py',
-        'Allura/ldap-userconfig.py',
-        'Allura/ez_setup/',
-        'Allura/allura/lib/AsciiDammit.py',
-        '/scripts/',
-        'Allura/allura/lib/import_api.py',
-        'ForgeSVN/setup.py',
-    ]
-    if run(find_py + " | grep -v '" + "' | grep -v '".join(skips) + "' | xargs grep -v '^ *#' | grep 'print ' | grep -E -v '(pprint|#pragma: ?printok)' ") != 1:
-        raise Exception("These should use logging instead of print")
-
-def test_no_tabs():
-    if run(find_py + " | xargs grep '	' ") not in [1,123]:
-        raise Exception('These should not use tab chars')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/alluratest/validation.py
----------------------------------------------------------------------
diff --git a/AlluraTesting/alluratest/validation.py b/AlluraTesting/alluratest/validation.py
deleted file mode 100644
index 235d7c0..0000000
--- a/AlluraTesting/alluratest/validation.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#       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.
-
-"""
-Functions to syntax-validate output content
-"""
-from os import path, environ, getcwd
-import os
-import sys
-import logging
-import tempfile
-import subprocess
-import json
-import urllib2
-import re
-
-import tg
-import mock
-import beaker.session
-from paste.deploy import loadapp
-from paste.script.appinstall import SetupCommand
-from pylons import tmpl_context as c, app_globals as g
-from pylons import url, request, response, session
-import webtest
-from webtest import TestApp
-from webob import Request, Response
-from nose.tools import ok_, assert_true, assert_false
-from poster.encode import multipart_encode
-from poster.streaminghttp import register_openers
-from ming.utils import LazyProperty
-
-from allura.lib import utils
-
-ENABLE_CONTENT_VALIDATION = False
-# By default we want to run only validations which are fast,
-# but on special test hosts - all.
-COMPLETE_TESTS_HOST = 'sb-forge-4039'
-
-log = logging.getLogger(__name__)
-
-class Config(object):
-    "Config to encapsulate flexible/complex test enabled/disabled rules."
-    _instance = None
-
-    def __init__(self):
-        self.ini_config = None
-        pass
-
-    @classmethod
-    def instance(cls):
-        if not cls._instance:
-            cls._instance = cls()
-        return cls._instance
-
-    @LazyProperty
-    def test_ini(self):
-        if not self.ini_config:
-            from . import controller
-            import ConfigParser
-            conf = ConfigParser.ConfigParser({'validate_html5': 'false', 'validate_inlinejs': 'false'})
-            conf.read(controller.get_config_file())
-            self.ini_config = conf
-        return self.ini_config
-
-    @LazyProperty
-    def hostname(self):
-        if os.path.exists('/etc/soghost'):
-            with open('/etc/soghost') as fp:
-                return fp.read().strip()
-
-    def validation_enabled(self, val_type):
-        env_var = os.getenv('ALLURA_VALIDATION')
-        if env_var == 'all':
-            return True
-        elif env_var == 'none':
-            return False
-        elif env_var is not None:
-            return val_type in env_var.split(',')
-
-        if self.hostname == COMPLETE_TESTS_HOST:
-            return True
-
-        enabled = self.test_ini.getboolean('validation', 'validate_' + val_type)
-        return enabled
-
-    def fail_on_validation(self, val_type):
-        env_var = os.getenv('ALLURA_VALIDATION')
-        if env_var == 'all':
-            return True
-        if self.hostname == COMPLETE_TESTS_HOST:
-            return True
-        return ENABLE_CONTENT_VALIDATION
-
-
-def report_validation_error(val_name, filename, message):
-    message = '%s Validation errors (%s):\n%s\n' % (val_name, filename, message)
-    if Config.instance().fail_on_validation(val_name):
-        ok_(False, message)
-    else:
-        sys.stderr.write('=' * 40 + '\n' + message)
-
-def dump_to_file(prefix, html):
-    f = tempfile.NamedTemporaryFile(prefix=prefix, delete=False)
-    f.write(html)
-    f.close()
-    return f.name
-
-def validate_html(html_or_response):
-        if hasattr(html_or_response, 'body'):
-            html = html_or_response.body
-        else:
-            html = html_or_response
-
-        html = html.lstrip()
-
-        if html.startswith('<!DOCTYPE html>'):
-            return validate_html5(html)
-        else:
-            assert False, 'Non-valid HTML: ' + html[:100] + '...'
-
-def validate_json(json_or_response):
-        if hasattr(json_or_response, 'body'):
-            j = json_or_response.body
-        else:
-            j = json_or_response
-
-        try:
-            obj = json.loads(j)
-        except Exception, e:
-            ok_(False, "Couldn't validate JSON: " + str(e) + ':' + j[:100] + '...')
-
-        return obj
-
-def validate_html5(html_or_response):
-        if hasattr(html_or_response, 'body'):
-            html = html_or_response.body
-        else:
-            html = html_or_response
-        register_openers()
-        params = [("out","text"),("content",html)]
-        datagen, headers = multipart_encode(params)
-        request = urllib2.Request("http://html5.validator.nu/", datagen, headers)
-        count = 3
-        while True:
-            try:
-                resp = urllib2.urlopen(request, timeout=3).read()
-                break
-            except:
-                resp = "Couldn't connect to validation service to check the HTML"
-                count -= 1
-                if count == 0:
-                    sys.stderr.write('WARNING: ' + resp + '\n')
-                    break
-
-        resp = resp.replace('“','"').replace('”','"').replace('–','-')
-
-        ignored_errors = [
-            'Required attributes missing on element "object"',
-            'Stray end tag "embed".',
-            'Stray end tag "param".',
-            r'Bad value .+? for attribute "onclick" on element "input": invalid return',
-        ]
-        for ignore in ignored_errors:
-            resp = re.sub('Error: ' + ignore, 'Ignoring: ' + ignore, resp)
-
-        if 'Error:' in resp:
-            fname = dump_to_file('html5-', html)
-            message = resp.decode('ascii','ignore')
-            report_validation_error('html5', fname, message)
-
-
-def validate_html5_chunk(html):
-        """ When you don't have a html & body tags - this adds it"""
-        # WebTest doesn't like HTML fragments without doctype,
-        # so we output them sometimes for fragments, which is hack.
-        # Unhack it here.
-        doctype = '<!DOCTYPE html>'
-        if html.startswith(doctype):
-            html = html[len(doctype):]
-
-        html = '''<!DOCTYPE html>
-        <html>
-        <head><title></title></head>
-        <body>
-        %s
-        </body></html>''' % html
-        return validate_html5(html)
-
-def validate_js(html_or_response):
-        if hasattr(html_or_response, 'body'):
-            if html_or_response.status_int != 200:
-                return
-            html = html_or_response.body
-        else:
-            html = html_or_response
-        basedir = path.dirname(path.abspath(__file__))
-        jslint_dir = basedir + '/../jslint'
-        fname = dump_to_file('jslint-', html)
-        cmd = 'java -jar ' + jslint_dir + '/js.jar '+ jslint_dir +'/jslint.js ' + fname
-        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-        stdout, stderr = p.communicate(html)
-        if stdout.startswith('jslint: No problems found'):
-            os.unlink(fname)
-            return
-        stdout = stdout.decode('UTF-8', 'replace')
-        msg = '\n'.join(repr(s) for s in stdout.split('\n') if s)
-        report_validation_error('js', fname, msg)
-
-def validate_page(html_or_response):
-    if Config.instance().validation_enabled('html5'):
-        validate_html(html_or_response)
-    if Config.instance().validation_enabled('inlinejs'):
-        validate_js(html_or_response)
-
-class AntiSpamTestApp(TestApp):
-
-    def post(self, *args, **kwargs):
-        if kwargs.pop('antispam', False):
-            antispam = utils.AntiSpam()
-            params = {
-                'timestamp': antispam.timestamp_text,
-                'spinner': antispam.spinner_text,
-                antispam.enc('honey0'): '',
-                antispam.enc('honey1'): '',
-            }
-            for k, v in kwargs['params'].iteritems():
-                params[antispam.enc(k)] = v
-            kwargs['params'] = params
-        return super(AntiSpamTestApp, self).post(*args, **kwargs)
-
-class PostParamCheckingTestApp(AntiSpamTestApp):
-
-    def _validate_params(self, params, method):
-        if not params:
-            return
-        # params can be a list or a dict
-        if hasattr(params, 'items'):
-            params = params.items()
-        for k, v in params:
-            if not isinstance(k, basestring):
-                raise TypeError('%s key %s is %s, not str' % (method, k, type(k)))
-            if not isinstance(v, (basestring, webtest.app.File)):
-                raise TypeError('%s key %s has value %s of type %s, not str. ' % (method, k, v, type(v)))
-
-    def get(self, *args, **kwargs):
-        self._validate_params(kwargs.get('params'), 'get')
-        return super(PostParamCheckingTestApp, self).get(*args, **kwargs)
-
-    def post(self, *args, **kwargs):
-        self._validate_params(kwargs.get('params'), 'post')
-        return super(PostParamCheckingTestApp, self).post(*args, **kwargs)
-
-class ValidatingTestApp(PostParamCheckingTestApp):
-
-    # Subclasses may set this to True to skip validation altogether
-    validate_skip = False
-
-    def _validate(self, resp, method, val_params):
-        """Perform validation on webapp response. This handles responses of
-        various types and forms."""
-        if resp.status_int != 200:
-            return
-
-        content = resp.body
-        content_type = resp.headers['Content-Type']
-        if content_type.startswith('text/html'):
-            if val_params['validate_chunk']:
-                validate_html5_chunk(content)
-            else:
-                validate_page(resp)
-        elif content_type.split(';', 1)[0] in ('text/plain', 'text/x-python', 'application/octet-stream'):
-            pass
-        elif content_type.startswith('application/json'):
-            validate_json(content)
-        elif content_type.startswith(('application/x-javascript','application/javascript', 'text/javascript')):
-            validate_js(content)
-        elif content_type.startswith('application/xml'):
-            import feedparser
-            d = feedparser.parse(content)
-            assert d.bozo == 0, 'Non-wellformed feed'
-        elif content_type.startswith('image/'):
-            pass
-        else:
-            assert False, 'Unexpected output content type: ' + content_type
-
-    def _get_validation_params(self, kw):
-        "Separate validation params from normal TestApp methods params."
-        params = {}
-        for k in ('validate_skip', 'validate_chunk'):
-            params[k] = kw.pop(k, False)
-        return params, kw
-
-    def get(self, *args, **kw):
-        val_params, kw = self._get_validation_params(kw)
-        resp = super(ValidatingTestApp, self).get(*args, **kw)
-        if not self.validate_skip and not val_params['validate_skip']:
-            self._validate(resp, 'get', val_params)
-        return resp
-
-    def post(self, *args, **kw):
-        val_params, kw = self._get_validation_params(kw)
-        resp = super(ValidatingTestApp, self).post(*args, **kw)
-        if not self.validate_skip and not val_params['validate_skip']:
-            self._validate(resp, 'post', val_params)
-        return resp

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/jslint/Makefile
----------------------------------------------------------------------
diff --git a/AlluraTesting/jslint/Makefile b/AlluraTesting/jslint/Makefile
deleted file mode 100644
index 7efd72e..0000000
--- a/AlluraTesting/jslint/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# Make single-file jslint script out of  main script (from jslint.com,
-# patched by us to tweak its behavior, as it configurability leaves much
-# to be desired) and Rhino support module. Needed because Rhino accepts
-# only single file as script.
-
-jslint.js: fulljslint.js rhino.js
-	cat $^ >$@

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/jslint/env-js.jar
----------------------------------------------------------------------
diff --git a/AlluraTesting/jslint/env-js.jar b/AlluraTesting/jslint/env-js.jar
deleted file mode 100644
index 072891a..0000000
Binary files a/AlluraTesting/jslint/env-js.jar and /dev/null differ


[37/50] [abbrv] git commit: [#4659] ticket:381 refactored multiple attachments

Posted by tv...@apache.org.
[#4659]  ticket:381 refactored multiple attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/779e7947
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/779e7947
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/779e7947

Branch: refs/heads/tv/6355
Commit: 779e7947e8a34d26e404ee93fd5a9eb0ff8f3074
Parents: 94026f2
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Jul 9 18:28:30 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 14:35:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py         | 8 ++++----
 Allura/allura/model/artifact.py              | 2 +-
 Allura/allura/model/discuss.py               | 2 +-
 Allura/allura/tests/model/test_discussion.py | 4 ++--
 ForgeTracker/forgetracker/model/ticket.py    | 8 +-------
 ForgeTracker/forgetracker/tracker_main.py    | 2 +-
 ForgeWiki/forgewiki/wiki_main.py             | 2 +-
 7 files changed, 11 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 45b0124..9f745a3 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -202,7 +202,7 @@ class ThreadController(BaseController, FeedController):
 
         file_info = kw.get('file_info', None)
         p = self.thread.add_post(**kw)
-        p.add_multiple_attach(file_info)
+        p.add_multiple_attachments(file_info)
         if self.thread.artifact:
             self.thread.artifact.mod_date = datetime.utcnow()
         flash('Message posted')
@@ -275,7 +275,7 @@ class PostController(BaseController):
             require_access(self.post, 'moderate')
             post_fields = self.W.edit_post.to_python(kw, None)
             file_info = post_fields.pop('file_info', None)
-            self.post.add_multiple_attach(file_info)
+            self.post.add_multiple_attachments(file_info)
             for k,v in post_fields.iteritems():
                 try:
                     setattr(self.post, k, v)
@@ -320,7 +320,7 @@ class PostController(BaseController):
         require_access(self.thread, 'post')
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
-        p.add_multiple_attach(file_info)
+        p.add_multiple_attachments(file_info)
         redirect(request.referer)
 
     @h.vardec
@@ -355,7 +355,7 @@ class PostController(BaseController):
     @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
-        self.post.add_multiple_attach(file_info)
+        self.post.add_multiple_attachments(file_info)
         redirect(request.referer)
 
     @expose()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 6fbe0f5..b41b103 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -386,7 +386,7 @@ class Artifact(MappedClass):
         """
         return self.get_discussion_thread()[0]
 
-    def add_multiple_attach(self, file_info):
+    def add_multiple_attachments(self, file_info):
         if not isinstance(file_info, list):
             file_info = [file_info]
         for attach in file_info:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index b15d03d..76cf615 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -527,7 +527,7 @@ class Post(Message, VersionedArtifact, ActivityObject):
         return self.attachment_class().query.find(dict(
             post_id=self._id, type='attachment'))
 
-    def add_multiple_attach(self, file_info):
+    def add_multiple_attachments(self, file_info):
         if isinstance(file_info, list):
             map(self.add_attachment, file_info)
         else:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 4ac1e37..34e550a 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -207,7 +207,7 @@ def test_attachment_methods():
     assert '\nAttachment: fake.txt (37 Bytes; text/plain)' in n.text
 
 @with_setup(setUp, tearDown())
-def test_multiple_attach():
+def test_multiple_attachments():
     test_file1 = FieldStorage()
     test_file1.name = 'file_info'
     test_file1.filename = 'test1.txt'
@@ -221,7 +221,7 @@ def test_multiple_attach():
     d = M.Discussion(shortname='test', name='test')
     t = M.Thread.new(discussion_id=d._id, subject='Test Thread')
     test_post = t.post('test post')
-    test_post.add_multiple_attach([test_file1, test_file2])
+    test_post.add_multiple_attachments([test_file1, test_file2])
     ThreadLocalORMSession.flush_all()
     assert test_post.attachments.count() == 2, test_post.attachments.count()
     attaches = test_post.attachments.all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 6679e2a..80ce102 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -833,13 +833,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
                     self.custom_fields[k] = v
         self.commit()
         if attachment is not None:
-            if isinstance(attachment, list):
-                for attach in attachment:
-                    self.attach(attach.filename, attach.file, content_type=attach.type)
-            else:
-                self.attach(
-                    attachment.filename, attachment.file,
-                    content_type=attachment.type)
+            self.add_multiple_attachments(attachment)
 
     def _move_attach(self, attachments, attach_metadata, app_config):
         for attach in attachments:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 9037c4d..b6af2ee 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1293,7 +1293,7 @@ class TicketController(BaseController, FeedController):
 
         if 'attachment' in post_data:
             attachment = post_data['attachment']
-            self.ticket.add_multiple_attach(attachment)
+            self.ticket.add_multiple_attachments(attachment)
         for cf in c.app.globals.custom_fields or []:
             if 'custom_fields.' + cf.name in post_data:
                 value = post_data['custom_fields.' + cf.name]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/779e7947/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 76f66f6..57e2bff 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -649,7 +649,7 @@ class PageController(BaseController, FeedController):
         if not self.page:
             raise exc.HTTPNotFound
         require_access(self.page, 'edit')
-        self.page.add_multiple_attach(file_info)
+        self.page.add_multiple_attachments(file_info)
         redirect(request.referer)
 
     @expose()


[20/50] [abbrv] git commit: [#3060] Removed unused repo models

Posted by tv...@apache.org.
[#3060] Removed unused repo models

These models are from a previous implementation of repo indexing and
haven't been used in some time.  With this, the following collections
can also be removed:

    * project-data.last_commit_for
    * pyforge.repo_object

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/33e7fea7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/33e7fea7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/33e7fea7

Branch: refs/heads/tv/6355
Commit: 33e7fea7547e901a28d9cf45b26821b5feca43e5
Parents: 7fc9b7d
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jul 2 20:18:56 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 05:24:21 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/repository.py | 586 +--------------------------------
 1 file changed, 1 insertion(+), 585 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/33e7fea7/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 32cea30..2904a39 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -533,8 +533,7 @@ class Repository(Artifact, ActivityObject):
             log.info('... %r analyzing', self)
             self.status = 'analyzing'
             session(self).flush(self)
-            if asbool(tg.config.get('scm.new_refresh')):
-                refresh_repo(self, all_commits, notify, new_clone)
+            refresh_repo(self, all_commits, notify, new_clone)
         finally:
             log.info('... %s ready', self)
             self.status = 'ready'
@@ -654,589 +653,6 @@ class MergeRequest(VersionedArtifact, ActivityObject):
                 self.request_number, self.project.name, self.app.repo.name))
         return result
 
-class LastCommitFor(MappedClass):
-    class __mongometa__:
-        session = project_orm_session
-        name='last_commit_for'
-        unique_indexes = [ ('repo_id', 'object_id') ]
-
-    _id = FieldProperty(S.ObjectId)
-    repo_id = FieldProperty(S.ObjectId)
-    object_id = FieldProperty(str)
-    last_commit = FieldProperty(dict(
-        date=datetime,
-        author=str,
-        author_email=str,
-        author_url=str,
-        id=str,
-        href=str,
-        shortlink=str,
-        summary=str))
-
-    @classmethod
-    def upsert(cls, repo_id, object_id):
-        isnew = False
-        r = cls.query.get(repo_id=repo_id, object_id=object_id)
-        if r is not None: return r, isnew
-        try:
-            r = cls(repo_id=repo_id, object_id=object_id)
-            session(r).flush(r)
-            isnew = True
-        except pymongo.errors.DuplicateKeyError: # pragma no cover
-            session(r).expunge(r)
-            r = cls.query.get(repo_id=repo_id, object_id=object_id)
-        return r, isnew
-
-class RepoObject(MappedClass):
-    class __mongometa__:
-        session = repository_orm_session
-        name='repo_object'
-        polymorphic_on = 'type'
-        polymorphic_identity=None
-        indexes = [
-            ('parent_ids',),
-            ('repo_id','type'),
-            ('type', 'object_ids.object_id'),
-            ('type', 'tree_id'),
-            ]
-        unique_indexes = [ 'object_id' ]
-
-    # ID Fields
-    _id = FieldProperty(S.ObjectId)
-    type = FieldProperty(str)
-    repo_id = FieldProperty(S.Deprecated)
-    object_id = FieldProperty(str)
-    last_commit=FieldProperty(S.Deprecated)
-
-    @classmethod
-    def upsert(cls, object_id):
-        isnew = False
-        r = cls.query.get(object_id=object_id)
-        if r is not None:
-            return r, isnew
-        try:
-            r = cls(
-                type=cls.__mongometa__.polymorphic_identity,
-                object_id=object_id)
-            session(r).flush(r)
-            isnew = True
-        except pymongo.errors.DuplicateKeyError: # pragma no cover
-            session(r).expunge(r)
-            r = cls.query.get(object_id=object_id)
-        return r, isnew
-
-    def set_last_commit(self, ci, repo=None):
-        '''Update the last_commit_for object based on the passed in commit &
-        repo'''
-        if repo is None: repo = c.app.repo
-        lc, isnew = LastCommitFor.upsert(repo_id=repo._id, object_id=self.object_id)
-        if not ci.authored.date:
-            repo._impl.refresh_commit(ci)
-        if isnew:
-            lc.last_commit.author = ci.authored.name
-            lc.last_commit.author_email = ci.authored.email
-            lc.last_commit.author_url = ci.author_url
-            lc.last_commit.date = ci.authored.date
-            lc.last_commit.id = ci.object_id
-            lc.last_commit.href = ci.url()
-            lc.last_commit.shortlink = ci.shorthand_id()
-            lc.last_commit.summary = ci.summary
-            assert lc.last_commit.date
-        return lc, isnew
-
-    def get_last_commit(self, repo=None):
-        if repo is None: repo = c.app.repo
-        return repo.get_last_commit(self)
-
-    def __repr__(self):
-        return '<%s %s>' % (
-            self.__class__.__name__, self.object_id)
-
-    def index_id(self):
-        app_config = self.repo.app_config
-        return '%s %s in %s %s' % (
-            self.type, self.object_id,
-            app_config.project.name,
-            app_config.options.mount_label)
-
-    def set_context(self, context): # pragma no cover
-        '''Set ephemeral (unsaved) attributes based on a context object'''
-        raise NotImplementedError, 'set_context'
-
-    def primary(self): return self
-
-class LogCache(RepoObject):
-    '''Class to store nothing but lists of commit IDs in topo sort order'''
-    class __mongometa__:
-        polymorphic_identity='log_cache'
-    type_s = 'LogCache'
-
-    type = FieldProperty(str, if_missing='log_cache')
-    object_ids = FieldProperty([str])
-    candidates = FieldProperty([str])
-
-    @classmethod
-    def get(cls, repo, object_id):
-        lc, new = cls.upsert('$' + object_id)
-        if not lc.object_ids:
-            lc.object_ids, lc.candidates = repo._impl.log(object_id, 0, 50)
-        return lc
-
-class Commit(RepoObject):
-    class __mongometa__:
-        polymorphic_identity='commit'
-    type_s = 'Commit'
-
-    # File data
-    type = FieldProperty(str, if_missing='commit')
-    tree_id = FieldProperty(str)
-    diffs = FieldProperty(dict(
-            added=[str],
-            removed=[str],
-            changed=[str],
-            copied=[dict(old=str, new=str)]))
-    # Commit metadata
-    committed = FieldProperty(
-        dict(name=str,
-             email=str,
-             date=datetime))
-    authored = FieldProperty(
-        dict(name=str,
-             email=str,
-             date=datetime))
-    message = FieldProperty(str)
-    parent_ids = FieldProperty([str])
-    extra = FieldProperty([dict(name=str, value=str)])
-     # All repos that potentially reference this commit
-    repositories=FieldProperty([S.ObjectId])
-
-    # Ephemeral attrs
-    repo=None
-
-    def set_context(self, repo):
-        self.repo = repo
-
-    @property
-    def diffs_computed(self):
-        if self.diffs.added: return True
-        if self.diffs.removed: return True
-        if self.diffs.changed: return True
-        if self.diffs.copied: return True
-
-    @LazyProperty
-    def author_url(self):
-        u = User.by_email_address(self.authored.email)
-        if u: return u.url()
-
-    @LazyProperty
-    def committer_url(self):
-        u = User.by_email_address(self.committed.email)
-        if u: return u.url()
-
-    @LazyProperty
-    def tree(self):
-        if self.tree_id is None:
-            self.tree_id = self.repo.compute_tree(self)
-        if self.tree_id is None:
-            return None
-        t = Tree.query.get(object_id=self.tree_id)
-        if t is None:
-            self.tree_id = self.repo.compute_tree(self)
-            t = Tree.query.get(object_id=self.tree_id)
-        if t is not None: t.set_context(self)
-        return t
-
-    @LazyProperty
-    def summary(self):
-        message = h.really_unicode(self.message)
-        first_line = message.split('\n')[0]
-        return h.text.truncate(first_line, 50)
-
-    def get_path(self, path):
-        '''Return the blob on the given path'''
-        if path.startswith('/'): path = path[1:]
-        path_parts = path.split('/')
-        return self.tree.get_blob(path_parts[-1], path_parts[:-1])
-
-    def shorthand_id(self):
-        return self.repo.shorthand_for_commit(self.object_id)
-
-    @LazyProperty
-    def symbolic_ids(self):
-        return self.repo.symbolics_for_commit(self)
-
-    def url(self):
-        return self.repo.url_for_commit(self)
-
-    def log(self, skip, count):
-        oids = list(self.log_iter(skip, count))
-        commits = self.query.find(dict(
-                type='commit',
-                object_id={'$in':oids}))
-        commits_by_oid = {}
-        for ci in commits:
-            ci.set_context(self.repo)
-            commits_by_oid[ci.object_id] = ci
-        return [ commits_by_oid[oid] for oid in oids ]
-
-    def log_iter(self, skip, count):
-        seen_oids = set()
-        candidates = [ self.object_id ]
-        while candidates and count:
-            candidate = candidates.pop()
-            if candidate in seen_oids: continue
-            lc = LogCache.get(self.repo, candidate)
-            oids = lc.object_ids
-            candidates += lc.candidates
-            for oid in oids:
-                if oid in seen_oids: continue
-                seen_oids.add(oid)
-                if count == 0:
-                    break
-                elif skip == 0:
-                    yield oid
-                    count -= 1
-                else:
-                    skip -= 1
-
-    def compute_diffs(self):
-        self.diffs.added = []
-        self.diffs.removed = []
-        self.diffs.changed = []
-        self.diffs.copied = []
-        if self.parent_ids:
-            parent = self.repo.commit(self.parent_ids[0])
-            for diff in Tree.diff(parent.tree, self.tree):
-                if diff.is_new:
-                    self.diffs.added.append(diff.b_path)
-                    obj = RepoObject.query.get(object_id=diff.b_object_id)
-                    obj.set_last_commit(self, self.repo)
-                elif diff.is_delete:
-                    self.diffs.removed.append(diff.a_path)
-                else:
-                    self.diffs.changed.append(diff.a_path)
-                    obj = RepoObject.query.get(object_id=diff.b_object_id)
-                    obj.set_last_commit(self, self.repo)
-        else:
-            # Parent-less, so the whole tree is additions
-            tree = self.tree
-            for x in tree.object_ids:
-                self.diffs.added.append('/'+x.name)
-                obj = RepoObject.query.get(object_id=x.object_id)
-                obj.set_last_commit(self, self.repo)
-
-    def context(self):
-        return self.repo.commit_context(self)
-
-class Tree(RepoObject):
-    '''
-    A representation of files & directories.  E.g. what is present at a single commit
-
-    :var object_ids: dict(object_id: name)  Set by refresh_tree in the scm implementation
-    '''
-    class __mongometa__:
-        polymorphic_identity='tree'
-    type_s = 'Tree'
-
-    type = FieldProperty(str, if_missing='tree')
-    object_ids = FieldProperty([dict(object_id=str,name=str)])
-
-    # Ephemeral attrs
-    repo=None
-    commit=None
-    parent=None
-    name=None
-
-    def compute_hash(self):
-        '''Compute a hash based on the contents of the tree.  Note that this
-        hash does not necessarily correspond to any actual DVCS hash.
-        '''
-        lines = []
-        for x in self.object_ids:
-            obj = RepoObject.query.get(x.object_id)
-            lines.append(obj.type[0] + x.object_id + x.name)
-        sha_obj = sha1()
-        for line in sorted(lines):
-            sha_obj.update(line)
-        return sha_obj.hexdigest()
-
-    def set_last_commit(self, ci, repo=None):
-        lc, isnew = super(Tree, self).set_last_commit(ci, repo)
-        if isnew:
-            for x in self.object_ids:
-                obj = RepoObject.query.get(object_id=x.object_id)
-                obj.set_last_commit(ci, repo)
-        return lc, isnew
-
-    @LazyProperty
-    def object_id_index(self):
-        return dict((x.name, x.object_id) for x in self.object_ids)
-
-    @LazyProperty
-    def object_name_index(self):
-        result = defaultdict(list)
-        for x in self.object_ids:
-            result[x.object_id].append(x.name)
-        return result
-
-    def get(self, name, default=None):
-        try:
-            return self[name]
-        except KeyError:
-            return default
-
-    def __getitem__(self, name):
-        oid = self.object_id_index[name]
-        obj = RepoObject.query.get(object_id=oid)
-        if obj is None:
-            oid = self.repo.compute_tree(self.commit, self.path() + name + '/')
-            obj = RepoObject.query.get(object_id=oid)
-        if obj is None: raise KeyError, name
-        obj.set_context(self, name)
-        return obj
-
-    @classmethod
-    def diff(cls, a, b):
-        '''Recursive diff of two tree objects, yielding DiffObjects'''
-        if not isinstance(a, Tree) or not isinstance(b, Tree):
-            yield DiffObject(a, b)
-        else:
-            for a_x in a.object_ids:
-                b_oid = b.object_id_index.get(a_x.name)
-                if a_x.object_id == b_oid: continue
-                a_obj = a.get(a_x.name)
-                b_obj = b.get(a_x.name)
-                if b_obj is None:
-                    yield DiffObject(a_obj, None)
-                else:
-                    for x in cls.diff(a_obj, b_obj): yield x
-            for b_x in b.object_ids:
-                if b_x.name in a.object_id_index: continue
-                b_obj = b.get(b_x.name)
-                yield DiffObject(None, b_obj)
-
-    def set_context(self, commit_or_tree, name=None):
-        assert commit_or_tree is not self
-        self.repo = commit_or_tree.repo
-        if name:
-            self.commit = commit_or_tree.commit
-            self.parent = commit_or_tree
-            self.name = name
-        else:
-            self.commit = commit_or_tree
-
-    def readme(self):
-        'returns (filename, unicode text) if a readme file is found'
-        for x in self.object_ids:
-            if README_RE.match(x.name):
-                obj = self[x.name]
-                if isinstance(obj, Blob):
-                    return (x.name, h.really_unicode(obj.text))
-        return (None, '')
-
-    def ls(self):
-        results = []
-        for x in self.object_ids:
-            obj = self[x.name]
-            ci = obj.get_last_commit()
-            d = dict(last_commit=ci, name=x.name)
-            if isinstance(obj, Tree):
-                results.append(dict(d, kind='DIR', href=x.name + '/'))
-            else:
-                results.append(dict(d, kind='FILE', href=x.name))
-        results.sort(key=lambda d:(d['kind'], d['name']))
-        return results
-
-    def index_id(self):
-        return repr(self)
-
-    def path(self):
-        if self.parent:
-            assert self.parent is not self
-            return self.parent.path() + self.name + '/'
-        else:
-            return '/'
-
-    def url(self):
-        return self.commit.url() + 'tree' + self.path()
-
-    def is_blob(self, name):
-        obj = RepoObject.query.get(
-            object_id=self.object_id_index[name])
-        return isinstance(obj, Blob)
-
-    def get_tree(self, name):
-        t = self.get(name)
-        if isinstance(t, Tree): return t
-        return None
-
-    def get_blob(self, name, path_parts=None):
-        if not path_parts:
-            t = self
-        else:
-            t = self.get_object(*path_parts)
-        if t is None: return None
-        b = t.get(name)
-        if isinstance(b, Blob): return b
-        return None
-
-    def get_object(self, *path_parts):
-        cur = self
-        for part in path_parts:
-            if not isinstance(cur, Tree): return None
-            cur = cur.get(part)
-        return cur
-
-class Blob(RepoObject):
-    class __mongometa__:
-        polymorphic_identity='blob'
-    type_s = 'Blob'
-
-    type = FieldProperty(str, if_missing='blob')
-
-    # Ephemeral attrs
-    repo=None
-    commit=None
-    tree=None
-    name=None
-
-    def set_context(self, tree, name):
-        self.repo = tree.repo
-        self.commit = tree.commit
-        self.tree = tree
-        self.name = name
-        fn, ext = os.path.splitext(self.name)
-        self.extension = ext or fn
-
-    @LazyProperty
-    def _content_type_encoding(self):
-        return self.repo.guess_type(self.name)
-
-    @LazyProperty
-    def content_type(self):
-        return self._content_type_encoding[0]
-
-    @LazyProperty
-    def content_encoding(self):
-        return self._content_type_encoding[1]
-
-    @LazyProperty
-    def next_commit(self):
-        try:
-            path = self.path()
-            cur = self.commit
-            next = cur.context()['next']
-            while next:
-                cur = next[0]
-                next = cur.context()['next']
-                other_blob = cur.get_path(path)
-                if other_blob is None or other_blob.object_id != self.object_id:
-                    return cur
-        except:
-            log.exception('Lookup prev_commit')
-            return None
-
-    @LazyProperty
-    def prev_commit(self):
-        lc = self.get_last_commit()
-        if lc['id']:
-            last_commit = self.repo.commit(lc.id)
-            if last_commit.parent_ids:
-                return self.repo.commit(last_commit.parent_ids[0])
-        return None
-
-    def url(self):
-        return self.tree.url() + h.really_unicode(self.name)
-
-    def path(self):
-        return self.tree.path() + h.really_unicode(self.name)
-
-    @property
-    def has_pypeline_view(self):
-        if README_RE.match(self.name) or self.extension in ['.md', '.rst']:
-            return True
-        return False
-
-    @property
-    def has_html_view(self):
-        if (self.content_type.startswith('text/') or
-            self.extension in VIEWABLE_EXTENSIONS or
-            self.extension in self.repo._additional_viewable_extensions or
-            utils.is_text_file(self.text)):
-            return True
-        return False
-
-    @property
-    def has_image_view(self):
-        return self.content_type.startswith('image/')
-
-    def context(self):
-        path = self.path()[1:]
-        prev = self.prev_commit
-        next = self.next_commit
-        if prev is not None: prev = prev.get_path(path)
-        if next is not None: next = next.get_path(path)
-        return dict(
-            prev=prev,
-            next=next)
-
-    def compute_hash(self):
-        '''Compute a hash based on the contents of the blob.  Note that this
-        hash does not necessarily correspond to any actual DVCS hash.
-        '''
-        fp = self.open()
-        sha_obj = sha1()
-        while True:
-            buffer = fp.read(4096)
-            if not buffer: break
-            sha_obj.update(buffer)
-        return sha_obj.hexdigest()
-
-    def open(self):
-        return self.repo.open_blob(self)
-
-    def __iter__(self):
-        return iter(self.open())
-
-    @LazyProperty
-    def size(self):
-        return self.repo.blob_size(self)
-
-    @LazyProperty
-    def text(self):
-        return self.open().read()
-
-    @classmethod
-    def diff(cls, v0, v1):
-        differ = SequenceMatcher(v0, v1)
-        return differ.get_opcodes()
-
-class DiffObject(object):
-    a_path = b_path = None
-    a_object_id = b_object_id = None
-    is_new = False
-    is_delete = False
-
-    def __init__(self, a, b):
-        if a:
-            self.a_path = a.path()
-            self.a_object_id = a.object_id
-        else:
-            self.is_new = True
-        if b:
-            self.b_path = b.path()
-            self.b_object_id = b.object_id
-        else:
-            self.is_delete = True
-
-    def __repr__(self):
-        if self.is_new:
-            return '<new %s>' % self.b_path
-        elif self.is_delete:
-            return '<remove %s>' % self.a_path
-        else:
-            return '<change %s>' % (self.a_path)
-
 
 class GitLikeTree(object):
     '''


[44/50] [abbrv] [#4122] rename AlluraTesting dir to AlluraTest, to match the module name below

Posted by tv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/jslint/fulljslint.js
----------------------------------------------------------------------
diff --git a/AlluraTest/jslint/fulljslint.js b/AlluraTest/jslint/fulljslint.js
new file mode 100644
index 0000000..0bf59bb
--- /dev/null
+++ b/AlluraTest/jslint/fulljslint.js
@@ -0,0 +1,5688 @@
+// jslint.js
+// 2010-08-05
+
+/*
+Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is 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 Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*
+    JSLINT is a global function. It takes two parameters.
+
+        var myResult = JSLINT(source, option);
+
+    The first parameter is either a string or an array of strings. If it is a
+    string, it will be split on '\n' or '\r'. If it is an array of strings, it
+    is assumed that each string represents one line. The source can be a
+    JavaScript text, or HTML text, or a Konfabulator text.
+
+    The second parameter is an optional object of options which control the
+    operation of JSLINT. Most of the options are booleans: They are all are
+    optional and have a default value of false.
+
+    If it checks out, JSLINT returns true. Otherwise, it returns false.
+
+    If false, you can inspect JSLINT.errors to find out the problems.
+    JSLINT.errors is an array of objects containing these members:
+
+    {
+        line      : The line (relative to 0) at which the lint was found
+        character : The character (relative to 0) at which the lint was found
+        reason    : The problem
+        evidence  : The text line in which the problem occurred
+        raw       : The raw message before the details were inserted
+        a         : The first detail
+        b         : The second detail
+        c         : The third detail
+        d         : The fourth detail
+    }
+
+    If a fatal error was found, a null will be the last element of the
+    JSLINT.errors array.
+
+    You can request a Function Report, which shows all of the functions
+    and the parameters and vars that they use. This can be used to find
+    implied global variables and other problems. The report is in HTML and
+    can be inserted in an HTML <body>.
+
+        var myReport = JSLINT.report(limited);
+
+    If limited is true, then the report will be limited to only errors.
+
+    You can request a data structure which contains JSLint's results.
+
+        var myData = JSLINT.data();
+
+    It returns a structure with this form:
+
+    {
+        errors: [
+            {
+                line: NUMBER,
+                character: NUMBER,
+                reason: STRING,
+                evidence: STRING
+            }
+        ],
+        functions: [
+            name: STRING,
+            line: NUMBER,
+            last: NUMBER,
+            param: [
+                STRING
+            ],
+            closure: [
+                STRING
+            ],
+            var: [
+                STRING
+            ],
+            exception: [
+                STRING
+            ],
+            outer: [
+                STRING
+            ],
+            unused: [
+                STRING
+            ],
+            global: [
+                STRING
+            ],
+            label: [
+                STRING
+            ]
+        ],
+        globals: [
+            STRING
+        ],
+        member: {
+            STRING: NUMBER
+        },
+        unuseds: [
+            {
+                name: STRING,
+                line: NUMBER
+            }
+        ],
+        implieds: [
+            {
+                name: STRING,
+                line: NUMBER
+            }
+        ],
+        urls: [
+            STRING
+        ],
+        json: BOOLEAN
+    }
+
+    Empty arrays will not be included.
+
+*/
+
+/*jslint
+    evil: true, nomen: false, onevar: false, regexp: false, strict: true
+*/
+
+/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
+    "(begin)", "(breakage)", "(context)", "(error)", "(global)",
+    "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
+    "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/",
+    "<", "<=", "==", "===", ">", ">=", ADSAFE, ActiveXObject,
+    Array, Boolean, COM, CScript, Canvas, CustomAnimation, Date, Debug, E,
+    Enumerator, Error, EvalError, FadeAnimation, Flash, FormField, Frame,
+    Function, HotKey, Image, JSON, LN10, LN2, LOG10E, LOG2E, MAX_VALUE,
+    MIN_VALUE, Math, MenuItem, MoveAnimation, NEGATIVE_INFINITY, Number,
+    Object, Option, PI, POSITIVE_INFINITY, Point, RangeError, Rectangle,
+    ReferenceError, RegExp, ResizeAnimation, RotateAnimation, SQRT1_2,
+    SQRT2, ScrollBar, String, Style, SyntaxError, System, Text, TextArea,
+    Timer, TypeError, URIError, URL, VBArray, WScript, Web, Window, XMLDOM,
+    XMLHttpRequest, "\\", a, abbr, acronym, addEventListener, address,
+    adsafe, alert, aliceblue, animator, antiquewhite, appleScript, applet,
+    apply, approved, aqua, aquamarine, area, arguments, arity, article,
+    aside, audio, autocomplete, azure, b, background,
+    "background-attachment", "background-color", "background-image",
+    "background-position", "background-repeat", base, bdo, beep, beige, big,
+    bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
+    blueviolet, blur, body, border, "border-bottom", "border-bottom-color",
+    "border-bottom-style", "border-bottom-width", "border-collapse",
+    "border-color", "border-left", "border-left-color", "border-left-style",
+    "border-left-width", "border-right", "border-right-color",
+    "border-right-style", "border-right-width", "border-spacing",
+    "border-style", "border-top", "border-top-color", "border-top-style",
+    "border-top-width", "border-width", bottom, br, brown, browser,
+    burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller,
+    canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt,
+    character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
+    cite, clear, clearInterval, clearTimeout, clip, close, closeWidget,
+    closed, closure, cm, code, col, colgroup, color, command, comment,
+    condition, confirm, console, constructor, content, convertPathToHFS,
+    convertPathToPlatform, coral, cornflowerblue, cornsilk,
+    "counter-increment", "counter-reset", create, crimson, css, cursor,
+    cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,
+    darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
+    darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
+    darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent,
+    deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize,
+    details, devel, dfn, dialog, dimension, dimgray, dir, direction,
+    display, div, dl, document, dodgerblue, dt, edition, else, em, embed,
+    empty, "empty-cells", encodeURI, encodeURIComponent, entityify, eqeqeq,
+    errors, es5, escape, eval, event, evidence, evil, ex, exception, exec, exps,
+    fieldset, figure, filesystem, firebrick, first, float, floor,
+    floralwhite, focus, focusWidget, font, "font-face", "font-family",
+    "font-size", "font-size-adjust", "font-stretch", "font-style",
+    "font-variant", "font-weight", footer, forestgreen, forin, form,
+    fragment, frame, frames, frameset, from, fromCharCode, fuchsia, fud,
+    funct, function, functions, g, gainsboro, gc, getComputedStyle,
+    ghostwhite, global, globals, gold, goldenrod, gray, green, greenyellow,
+    h1, h2, h3, h4, h5, h6, hasOwnProperty, head, header, height, help,
+    hgroup, history, honeydew, hotpink, hr, 'hta:application', html,
+    i, iTunes, id, identifier,
+    iframe, img, immed, implieds, in, include, indent, indexOf, indianred,
+    indigo, init, input, ins, isAlpha, isApplicationRunning, isDigit,
+    isFinite, isNaN, ivory, join, jslint, json, kbd, keygen, khaki,
+    konfabulatorVersion, label, labelled, lang, last, lavender,
+    lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
+    lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
+    lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
+    lightseagreen, lightskyblue, lightslategray, lightsteelblue,
+    lightyellow, lime, limegreen, line, "line-height", linen, link,
+    "list-style", "list-style-image", "list-style-position",
+    "list-style-type", load, loadClass, location, log, m, magenta, map,
+    margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
+    mark, "marker-offset", maroon, match, "max-height", "max-width", maxerr,
+    maxlen, md5, media, mediumaquamarine, mediumblue, mediumorchid,
+    mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen,
+    mediumturquoise, mediumvioletred, member, menu, message, meta, meter,
+    midnightblue, "min-height", "min-width", mintcream, mistyrose, mm,
+    moccasin, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new,
+    newcap, noframes, nomen, noscript, nud, object, ol, oldlace, olive,
+    olivedrab, on, onbeforeunload, onblur, onerror, onevar, onfocus, onload,
+    onresize, onunload, opacity, open, openURL, opener, opera, optgroup,
+    option, orange, orangered, orchid, outer, outline, "outline-color",
+    "outline-style", "outline-width", output, overflow, "overflow-x",
+    "overflow-y", p, padding, "padding-bottom", "padding-left",
+    "padding-right", "padding-top", page, "page-break-after",
+    "page-break-before", palegoldenrod, palegreen, paleturquoise,
+    palevioletred, papayawhip, param, parent, parseFloat, parseInt,
+    passfail, pc, peachpuff, peru, pink, play, plum, plusplus, pop,
+    popupMenu, position, powderblue, pre, predef, preferenceGroups,
+    preferences, print, progress, prompt, prototype, pt, purple, push, px,
+    q, quit, quotes, random, range, raw, reach, readFile, readUrl, reason,
+    red, regexp, reloadWidget, removeEventListener, replace, report,
+    reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, rhino, right,
+    rosybrown, royalblue, rp, rt, ruby, runCommand, runCommandInBg,
+    saddlebrown, safe, salmon, samp, sandybrown, saveAs, savePreferences,
+    screen, script, scroll, scrollBy, scrollTo, seagreen, seal, search,
+    seashell, section, select, serialize, setInterval, setTimeout, shift,
+    showWidgetPreferences, sienna, silver, skyblue, slateblue, slategray,
+    sleep, slice, small, snow, sort, source, span, spawn, speak, split,
+    springgreen, src, stack, status, steelblue, strict, strong, style,
+    styleproperty, sub, substr, sup, supplant, suppressUpdates, sync,
+    system, table, "table-layout", tan, tbody, td, teal, tellWidget, test,
+    "text-align", "text-decoration", "text-indent", "text-shadow",
+    "text-transform", textarea, tfoot, th, thead, thistle, time, title,
+    toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
+    turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused,
+    unwatch, updateNow, urls, value, valueOf, var, version,
+    "vertical-align", video, violet, visibility, watch, wheat, white,
+    "white-space", whitesmoke, widget, width, windows, "word-spacing",
+    "word-wrap", yahooCheckLogin, yahooLogin, yahooLogout, yellow,
+    yellowgreen, "z-index"
+*/
+
+// We build the application inside a function so that we produce only a single
+// global variable. The function will be invoked, its return value is the JSLINT
+// application itself.
+
+"use strict";
+
+var JSLINT = (function () {
+    var adsafe_id,      // The widget's ADsafe id.
+        adsafe_may,     // The widget may load approved scripts.
+        adsafe_went,    // ADSAFE.go has been called.
+        anonname,       // The guessed name for anonymous functions.
+        approved,       // ADsafe approved urls.
+
+        atrule = {
+            media      : true,
+            'font-face': true,
+            page       : true
+        },
+
+// These are operators that should not be used with the ! operator.
+
+        bang = {
+            '<': true,
+            '<=': true,
+            '==': true,
+            '===': true,
+            '!==': true,
+            '!=': true,
+            '>': true,
+            '>=': true,
+            '+': true,
+            '-': true,
+            '*': true,
+            '/': true,
+            '%': true
+        },
+
+// These are members that should not be permitted in the safe subset.
+
+        banned = {              // the member names that ADsafe prohibits.
+            'arguments'     : true,
+            callee          : true,
+            caller          : true,
+            constructor     : true,
+            'eval'          : true,
+            prototype       : true,
+            stack           : true,
+            unwatch         : true,
+            valueOf         : true,
+            watch           : true
+        },
+
+
+// These are the JSLint boolean options.
+
+        boolOptions = {
+            adsafe     : true, // if ADsafe should be enforced
+            bitwise    : true, // if bitwise operators should not be allowed
+            browser    : true, // if the standard browser globals should be predefined
+            cap        : true, // if upper case HTML should be allowed
+            css        : true, // if CSS workarounds should be tolerated
+            debug      : true, // if debugger statements should be allowed
+            devel      : true, // if logging should be allowed (console, alert, etc.)
+            eqeqeq     : true, // if === should be required
+            es5        : true, // if ES5 syntax should be allowed
+            evil       : true, // if eval should be allowed
+            forin      : true, // if for in statements must filter
+            fragment   : true, // if HTML fragments should be allowed
+            immed      : true, // if immediate invocations must be wrapped in parens
+            laxbreak   : true, // if line breaks should not be checked
+            newcap     : true, // if constructor names must be capitalized
+            nomen      : true, // if names should be checked
+            on         : true, // if HTML event handlers should be allowed
+            onevar     : true, // if only one var statement per function should be allowed
+            passfail   : true, // if the scan should stop on first error
+            plusplus   : true, // if increment/decrement should not be allowed
+            regexp     : true, // if the . should not be allowed in regexp literals
+            rhino      : true, // if the Rhino environment globals should be predefined
+            undef      : true, // if variables should be declared before used
+            safe       : true, // if use of some browser features should be restricted
+            windows    : true, // if MS Windows-specigic globals should be predefined
+            strict     : true, // require the "use strict"; pragma
+            sub        : true, // if all forms of subscript notation are tolerated
+            white      : true, // if strict whitespace rules apply
+            widget     : true  // if the Yahoo Widgets globals should be predefined
+        },
+
+// browser contains a set of global names which are commonly provided by a
+// web browser environment.
+
+        browser = {
+            addEventListener: false,
+            blur            : false,
+            clearInterval   : false,
+            clearTimeout    : false,
+            close           : false,
+            closed          : false,
+            defaultStatus   : false,
+            document        : false,
+            event           : false,
+            focus           : false,
+            frames          : false,
+            getComputedStyle: false,
+            history         : false,
+            Image           : false,
+            length          : false,
+            location        : false,
+            moveBy          : false,
+            moveTo          : false,
+            name            : false,
+            navigator       : false,
+            onbeforeunload  : true,
+            onblur          : true,
+            onerror         : true,
+            onfocus         : true,
+            onload          : true,
+            onresize        : true,
+            onunload        : true,
+            open            : false,
+            opener          : false,
+            Option          : false,
+            parent          : false,
+            print           : false,
+            removeEventListener: false,
+            resizeBy        : false,
+            resizeTo        : false,
+            screen          : false,
+            scroll          : false,
+            scrollBy        : false,
+            scrollTo        : false,
+            setInterval     : false,
+            setTimeout      : false,
+            status          : false,
+            top             : false,
+            XMLHttpRequest  : false
+        },
+
+        cssAttributeData,
+        cssAny,
+
+        cssColorData = {
+            "aliceblue"             : true,
+            "antiquewhite"          : true,
+            "aqua"                  : true,
+            "aquamarine"            : true,
+            "azure"                 : true,
+            "beige"                 : true,
+            "bisque"                : true,
+            "black"                 : true,
+            "blanchedalmond"        : true,
+            "blue"                  : true,
+            "blueviolet"            : true,
+            "brown"                 : true,
+            "burlywood"             : true,
+            "cadetblue"             : true,
+            "chartreuse"            : true,
+            "chocolate"             : true,
+            "coral"                 : true,
+            "cornflowerblue"        : true,
+            "cornsilk"              : true,
+            "crimson"               : true,
+            "cyan"                  : true,
+            "darkblue"              : true,
+            "darkcyan"              : true,
+            "darkgoldenrod"         : true,
+            "darkgray"              : true,
+            "darkgreen"             : true,
+            "darkkhaki"             : true,
+            "darkmagenta"           : true,
+            "darkolivegreen"        : true,
+            "darkorange"            : true,
+            "darkorchid"            : true,
+            "darkred"               : true,
+            "darksalmon"            : true,
+            "darkseagreen"          : true,
+            "darkslateblue"         : true,
+            "darkslategray"         : true,
+            "darkturquoise"         : true,
+            "darkviolet"            : true,
+            "deeppink"              : true,
+            "deepskyblue"           : true,
+            "dimgray"               : true,
+            "dodgerblue"            : true,
+            "firebrick"             : true,
+            "floralwhite"           : true,
+            "forestgreen"           : true,
+            "fuchsia"               : true,
+            "gainsboro"             : true,
+            "ghostwhite"            : true,
+            "gold"                  : true,
+            "goldenrod"             : true,
+            "gray"                  : true,
+            "green"                 : true,
+            "greenyellow"           : true,
+            "honeydew"              : true,
+            "hotpink"               : true,
+            "indianred"             : true,
+            "indigo"                : true,
+            "ivory"                 : true,
+            "khaki"                 : true,
+            "lavender"              : true,
+            "lavenderblush"         : true,
+            "lawngreen"             : true,
+            "lemonchiffon"          : true,
+            "lightblue"             : true,
+            "lightcoral"            : true,
+            "lightcyan"             : true,
+            "lightgoldenrodyellow"  : true,
+            "lightgreen"            : true,
+            "lightpink"             : true,
+            "lightsalmon"           : true,
+            "lightseagreen"         : true,
+            "lightskyblue"          : true,
+            "lightslategray"        : true,
+            "lightsteelblue"        : true,
+            "lightyellow"           : true,
+            "lime"                  : true,
+            "limegreen"             : true,
+            "linen"                 : true,
+            "magenta"               : true,
+            "maroon"                : true,
+            "mediumaquamarine"      : true,
+            "mediumblue"            : true,
+            "mediumorchid"          : true,
+            "mediumpurple"          : true,
+            "mediumseagreen"        : true,
+            "mediumslateblue"       : true,
+            "mediumspringgreen"     : true,
+            "mediumturquoise"       : true,
+            "mediumvioletred"       : true,
+            "midnightblue"          : true,
+            "mintcream"             : true,
+            "mistyrose"             : true,
+            "moccasin"              : true,
+            "navajowhite"           : true,
+            "navy"                  : true,
+            "oldlace"               : true,
+            "olive"                 : true,
+            "olivedrab"             : true,
+            "orange"                : true,
+            "orangered"             : true,
+            "orchid"                : true,
+            "palegoldenrod"         : true,
+            "palegreen"             : true,
+            "paleturquoise"         : true,
+            "palevioletred"         : true,
+            "papayawhip"            : true,
+            "peachpuff"             : true,
+            "peru"                  : true,
+            "pink"                  : true,
+            "plum"                  : true,
+            "powderblue"            : true,
+            "purple"                : true,
+            "red"                   : true,
+            "rosybrown"             : true,
+            "royalblue"             : true,
+            "saddlebrown"           : true,
+            "salmon"                : true,
+            "sandybrown"            : true,
+            "seagreen"              : true,
+            "seashell"              : true,
+            "sienna"                : true,
+            "silver"                : true,
+            "skyblue"               : true,
+            "slateblue"             : true,
+            "slategray"             : true,
+            "snow"                  : true,
+            "springgreen"           : true,
+            "steelblue"             : true,
+            "tan"                   : true,
+            "teal"                  : true,
+            "thistle"               : true,
+            "tomato"                : true,
+            "turquoise"             : true,
+            "violet"                : true,
+            "wheat"                 : true,
+            "white"                 : true,
+            "whitesmoke"            : true,
+            "yellow"                : true,
+            "yellowgreen"           : true
+        },
+
+        cssBorderStyle,
+        cssBreak,
+
+        cssLengthData = {
+            '%': true,
+            'cm': true,
+            'em': true,
+            'ex': true,
+            'in': true,
+            'mm': true,
+            'pc': true,
+            'pt': true,
+            'px': true
+        },
+
+        cssOverflow,
+
+        devel = {
+            alert           : false,
+            confirm         : false,
+            console         : false,
+            Debug           : false,
+            opera           : false,
+            prompt          : false
+        },
+
+        escapes = {
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '/' : '\\/',
+            '\\': '\\\\'
+        },
+
+        funct,          // The current function
+
+        functionicity = [
+            'closure', 'exception', 'global', 'label',
+            'outer', 'unused', 'var'
+        ],
+
+        functions,      // All of the functions
+
+        global,         // The global scope
+        htmltag = {
+            a:        {},
+            abbr:     {},
+            acronym:  {},
+            address:  {},
+            applet:   {},
+            area:     {empty: true, parent: ' map '},
+            article:  {},
+            aside:    {},
+            audio:    {},
+            b:        {},
+            base:     {empty: true, parent: ' head '},
+            bdo:      {},
+            big:      {},
+            blockquote: {},
+            body:     {parent: ' html noframes '},
+            br:       {empty: true},
+            button:   {},
+            canvas:   {parent: ' body p div th td '},
+            caption:  {parent: ' table '},
+            center:   {},
+            cite:     {},
+            code:     {},
+            col:      {empty: true, parent: ' table colgroup '},
+            colgroup: {parent: ' table '},
+            command:  {parent: ' menu '},
+            datalist: {},
+            dd:       {parent: ' dl '},
+            del:      {},
+            details:  {},
+            dialog:   {},
+            dfn:      {},
+            dir:      {},
+            div:      {},
+            dl:       {},
+            dt:       {parent: ' dl '},
+            em:       {},
+            embed:    {},
+            fieldset: {},
+            figure:   {},
+            font:     {},
+            footer:   {},
+            form:     {},
+            frame:    {empty: true, parent: ' frameset '},
+            frameset: {parent: ' html frameset '},
+            h1:       {},
+            h2:       {},
+            h3:       {},
+            h4:       {},
+            h5:       {},
+            h6:       {},
+            head:     {parent: ' html '},
+            header:   {},
+            hgroup:   {},
+            hr:       {empty: true},
+            'hta:application':
+                      {empty: true, parent: ' head '},
+            html:     {parent: '*'},
+            i:        {},
+            iframe:   {},
+            img:      {empty: true},
+            input:    {empty: true},
+            ins:      {},
+            kbd:      {},
+            keygen:   {},
+            label:    {},
+            legend:   {parent: ' details fieldset figure '},
+            li:       {parent: ' dir menu ol ul '},
+            link:     {empty: true, parent: ' head '},
+            map:      {},
+            mark:     {},
+            menu:     {},
+            meta:     {empty: true, parent: ' head noframes noscript '},
+            meter:    {},
+            nav:      {},
+            noframes: {parent: ' html body '},
+            noscript: {},
+            object:   {},
+            ol:       {},
+            optgroup: {parent: ' select '},
+            option:   {parent: ' optgroup select '},
+            output:   {},
+            p:        {},
+            param:    {parent: ' applet object '},
+            pre:      {},
+            progress: {},
+            q:        {},
+            rp:       {},
+            rt:       {},
+            ruby:     {},
+            s:        {},
+            samp:     {},
+            script:   {empty: true, parent: ' body div frame head iframe p pre span '},
+            section:  {},
+            select:   {},
+            small:    {},
+            span:     {},
+            source:   {},
+            strong:   {},
+            style:    {parent: ' head ', empty: true},
+            sub:      {},
+            sup:      {},
+            table:    {},
+            tbody:    {parent: ' table '},
+            td:       {parent: ' tr '},
+            textarea: {},
+            tfoot:    {parent: ' table '},
+            th:       {parent: ' tr '},
+            thead:    {parent: ' table '},
+            time:     {},
+            title:    {parent: ' head '},
+            tr:       {parent: ' table tbody thead tfoot '},
+            tt:       {},
+            u:        {},
+            ul:       {},
+            'var':    {},
+            video:    {}
+        },
+
+        ids,            // HTML ids
+        implied,        // Implied globals
+        inblock,
+        indent,
+        jsonmode,
+        lines,
+        lookahead,
+        member,
+        membersOnly,
+        nexttoken,
+        noreach,
+        option,
+        predefined,     // Global variables defined by option
+        prereg,
+        prevtoken,
+
+        rhino = {
+            defineClass : false,
+            deserialize : false,
+            gc          : false,
+            help        : false,
+            load        : false,
+            loadClass   : false,
+            print       : false,
+            quit        : false,
+            readFile    : false,
+            readUrl     : false,
+            runCommand  : false,
+            seal        : false,
+            serialize   : false,
+            spawn       : false,
+            sync        : false,
+            toint32     : false,
+            version     : false
+        },
+
+        scope,      // The current scope
+
+        windows = {
+            ActiveXObject: false,
+            CScript      : false,
+            Debug        : false,
+            Enumerator   : false,
+            System       : false,
+            VBArray      : false,
+            WScript      : false
+        },
+
+        src,
+        stack,
+
+// standard contains the global names that are provided by the
+// ECMAScript standard.
+
+        standard = {
+            'void'              : false,
+            Array               : false,
+            Boolean             : false,
+            Date                : false,
+            decodeURI           : false,
+            decodeURIComponent  : false,
+            encodeURI           : false,
+            encodeURIComponent  : false,
+            Error               : false,
+            'eval'              : false,
+            EvalError           : false,
+            Function            : false,
+            hasOwnProperty      : false,
+            isFinite            : false,
+            isNaN               : false,
+            JSON                : false,
+            Math                : false,
+            Number              : false,
+            Object              : false,
+            parseInt            : false,
+            parseFloat          : false,
+            RangeError          : false,
+            ReferenceError      : false,
+            RegExp              : false,
+            String              : false,
+            SyntaxError         : false,
+            TypeError           : false,
+            URIError            : false
+        },
+
+        standard_member = {
+            E                   : true,
+            LN2                 : true,
+            LN10                : true,
+            LOG2E               : true,
+            LOG10E              : true,
+            PI                  : true,
+            SQRT1_2             : true,
+            SQRT2               : true,
+            MAX_VALUE           : true,
+            MIN_VALUE           : true,
+            NEGATIVE_INFINITY   : true,
+            POSITIVE_INFINITY   : true
+        },
+
+        strict_mode,
+        syntax = {},
+        tab,
+        token,
+        urls,
+        warnings,
+
+// widget contains the global names which are provided to a Yahoo
+// (fna Konfabulator) widget.
+
+        widget = {
+            alert                   : true,
+            animator                : true,
+            appleScript             : true,
+            beep                    : true,
+            bytesToUIString         : true,
+            Canvas                  : true,
+            chooseColor             : true,
+            chooseFile              : true,
+            chooseFolder            : true,
+            closeWidget             : true,
+            COM                     : true,
+            convertPathToHFS        : true,
+            convertPathToPlatform   : true,
+            CustomAnimation         : true,
+            escape                  : true,
+            FadeAnimation           : true,
+            filesystem              : true,
+            Flash                   : true,
+            focusWidget             : true,
+            form                    : true,
+            FormField               : true,
+            Frame                   : true,
+            HotKey                  : true,
+            Image                   : true,
+            include                 : true,
+            isApplicationRunning    : true,
+            iTunes                  : true,
+            konfabulatorVersion     : true,
+            log                     : true,
+            md5                     : true,
+            MenuItem                : true,
+            MoveAnimation           : true,
+            openURL                 : true,
+            play                    : true,
+            Point                   : true,
+            popupMenu               : true,
+            preferenceGroups        : true,
+            preferences             : true,
+            print                   : true,
+            prompt                  : true,
+            random                  : true,
+            Rectangle               : true,
+            reloadWidget            : true,
+            ResizeAnimation         : true,
+            resolvePath             : true,
+            resumeUpdates           : true,
+            RotateAnimation         : true,
+            runCommand              : true,
+            runCommandInBg          : true,
+            saveAs                  : true,
+            savePreferences         : true,
+            screen                  : true,
+            ScrollBar               : true,
+            showWidgetPreferences   : true,
+            sleep                   : true,
+            speak                   : true,
+            Style                   : true,
+            suppressUpdates         : true,
+            system                  : true,
+            tellWidget              : true,
+            Text                    : true,
+            TextArea                : true,
+            Timer                   : true,
+            unescape                : true,
+            updateNow               : true,
+            URL                     : true,
+            Web                     : true,
+            widget                  : true,
+            Window                  : true,
+            XMLDOM                  : true,
+            XMLHttpRequest          : true,
+            yahooCheckLogin         : true,
+            yahooLogin              : true,
+            yahooLogout             : true
+        },
+
+//  xmode is used to adapt to the exceptions in html parsing.
+//  It can have these states:
+//      false   .js script file
+//      html
+//      outer
+//      script
+//      style
+//      scriptstring
+//      styleproperty
+
+        xmode,
+        xquote,
+
+// unsafe comment or string
+        ax = /@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,
+// unsafe characters that are silently deleted by one or more browsers
+// Whitelist Replacement Char, 0xfffd
+        cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\ufffc\ufffe-\uffff]/,
+// token
+        tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
+// html token
+        hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,
+// characters in strings that need escapement
+        nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
+        nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+// outer html token
+        ox = /[>&]|<[\/!]?|--/,
+// star slash
+        lx = /\*\/|\/\*/,
+// identifier
+        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
+// javascript url
+        jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
+// url badness
+        ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,
+// style
+        sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,
+        ssx = /^\s*(\.?\d+(?:\.\d+)?|[@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|<\/)/,
+// attributes characters
+        //qx = /[^a-zA-Z0-9+\-_\/ ]/,
+        qx = /[^a-zA-Z0-9+\-_\/ .#]/, // We want dots in names, period; and hashes for templating
+// query characters for ids
+        //dx = /[\[\]\/\\"'*<>.&:(){}+=#]/,
+        // allow . and /
+        dx = /[\[\]\\"'*<>&:(){}+=#]/,
+
+        rx = {
+            outer: hx,
+            html: hx,
+            style: sx,
+            styleproperty: ssx
+        };
+
+    function F() {}
+
+    if (typeof Object.create !== 'function') {
+        Object.create = function (o) {
+            F.prototype = o;
+            return new F();
+        };
+    }
+
+
+    function is_own(object, name) {
+        return Object.prototype.hasOwnProperty.call(object, name);
+    }
+
+
+    function combine(t, o) {
+        var n;
+        for (n in o) {
+            if (is_own(o, n)) {
+                t[n] = o[n];
+            }
+        }
+    }
+
+    String.prototype.entityify = function () {
+        return this.
+            replace(/&/g, '&amp;').
+            replace(/</g, '&lt;').
+            replace(/>/g, '&gt;');
+    };
+
+    String.prototype.isAlpha = function () {
+        return (this >= 'a' && this <= 'z\uffff') ||
+            (this >= 'A' && this <= 'Z\uffff');
+    };
+
+
+    String.prototype.isDigit = function () {
+        return (this >= '0' && this <= '9');
+    };
+
+
+    String.prototype.supplant = function (o) {
+        return this.replace(/\{([^{}]*)\}/g, function (a, b) {
+            var r = o[b];
+            return typeof r === 'string' || typeof r === 'number' ? r : a;
+        });
+    };
+
+    String.prototype.name = function () {
+
+// If the string looks like an identifier, then we can return it as is.
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can simply slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe
+// sequences.
+
+        if (ix.test(this)) {
+            return this;
+        }
+        if (nx.test(this)) {
+            return '"' + this.replace(nxg, function (a) {
+                var c = escapes[a];
+                if (c) {
+                    return c;
+                }
+                return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
+            }) + '"';
+        }
+        return '"' + this + '"';
+    };
+
+
+    function assume() {
+        if (!option.safe) {
+            if (option.rhino) {
+                combine(predefined, rhino);
+            }
+            if (option.devel) {
+                combine(predefined, devel);
+            }
+            if (option.browser) {
+                combine(predefined, browser);
+            }
+            if (option.windows) {
+                combine(predefined, windows);
+            }
+            if (option.widget) {
+                combine(predefined, widget);
+            }
+        }
+    }
+
+
+// Produce an error warning.
+
+    function quit(m, l, ch) {
+        throw {
+            name: 'JSLintError',
+            line: l,
+            character: ch,
+            message: m + " (" + Math.floor((l / lines.length) * 100) +
+                    "% scanned)."
+        };
+    }
+
+    function warning(m, t, a, b, c, d) {
+        var ch, l, w;
+        t = t || nexttoken;
+        if (t.id === '(end)') {  // `~
+            t = token;
+        }
+        l = t.line || 0;
+        ch = t.from || 0;
+        w = {
+            id: '(error)',
+            raw: m,
+            evidence: lines[l - 1] || '',
+            line: l,
+            character: ch,
+            a: a,
+            b: b,
+            c: c,
+            d: d
+        };
+        w.reason = m.supplant(w);
+        JSLINT.errors.push(w);
+        if (option.passfail) {
+            quit('Stopping. ', l, ch);
+        }
+        warnings += 1;
+        if (warnings >= option.maxerr) {
+            quit("Too many errors.", l, ch);
+        }
+        return w;
+    }
+
+    function warningAt(m, l, ch, a, b, c, d) {
+        return warning(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+    function error(m, t, a, b, c, d) {
+        var w = warning(m, t, a, b, c, d);
+        quit("Stopping, unable to continue.", w.line, w.character);
+    }
+
+    function errorAt(m, l, ch, a, b, c, d) {
+        return error(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+
+
+// lexical analysis
+
+    var lex = (function lex() {
+        var character, from, line, s;
+
+// Private lex methods
+
+        function nextLine() {
+            var at;
+            if (line >= lines.length) {
+                return false;
+            }
+            character = 1;
+            s = lines[line];
+            line += 1;
+            at = s.search(/ \t/);
+            if (at >= 0) {
+                warningAt("Mixed spaces and tabs.", line, at + 1);
+            }
+            s = s.replace(/\t/g, tab);
+            at = s.search(cx);
+            if (at >= 0) {
+                warningAt("Unsafe character.", line, at);
+            }
+            if (option.maxlen && option.maxlen < s.length) {
+                warningAt("Line too long.", line, s.length);
+            }
+            return true;
+        }
+
+// Produce a token object.  The token inherits from a syntax symbol.
+
+        function it(type, value) {
+            var i, t;
+            if (type === '(color)') {
+                t = {type: type};
+            } else if (type === '(punctuator)' ||
+                    (type === '(identifier)' && is_own(syntax, value))) {
+                t = syntax[value] || syntax['(error)'];
+            } else {
+                t = syntax[type];
+            }
+            t = Object.create(t);
+            if (type === '(string)' || type === '(range)') {
+                if (jx.test(value)) {
+                    warningAt("Script URL.", line, from);
+                }
+            }
+            if (type === '(identifier)') {
+                t.identifier = true;
+                if (value === '__iterator__' || value === '__proto__') {
+                    errorAt("Reserved name '{a}'.",
+                        line, from, value);
+                } else if (option.nomen &&
+                        (value.charAt(0) === '_' ||
+                         value.charAt(value.length - 1) === '_')) {
+                    warningAt("Unexpected {a} in '{b}'.", line, from,
+                        "dangling '_'", value);
+                }
+            }
+            t.value = value;
+            t.line = line;
+            t.character = character;
+            t.from = from;
+            i = t.id;
+            if (i !== '(endline)') {
+                prereg = i &&
+                    (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
+                    i === 'return');
+            }
+            return t;
+        }
+
+// Public lex methods
+
+        return {
+            init: function (source) {
+                if (typeof source === 'string') {
+                    lines = source.
+                        replace(/\r\n/g, '\n').
+                        replace(/\r/g, '\n').
+                        split('\n');
+                } else {
+                    lines = source;
+                }
+                line = 0;
+                nextLine();
+                from = 1;
+            },
+
+            range: function (begin, end) {
+                var c, value = '';
+                from = character;
+                if (s.charAt(0) !== begin) {
+                    errorAt("Expected '{a}' and instead saw '{b}'.",
+                            line, character, begin, s.charAt(0));
+                }
+                for (;;) {
+                    s = s.slice(1);
+                    character += 1;
+                    c = s.charAt(0);
+                    switch (c) {
+                    case '':
+                        errorAt("Missing '{a}'.", line, character, c);
+                        break;
+                    case end:
+                        s = s.slice(1);
+                        character += 1;
+                        return it('(range)', value);
+                    case xquote:
+                    case '\\':
+                        warningAt("Unexpected '{a}'.", line, character, c);
+                    }
+                    value += c;
+                }
+
+            },
+
+// skip all content up to marker
+
+            skip_till: function (end) {
+                            for (;;) {
+                                i = s.indexOf(end);
+                                if (i >= 0) {
+                                    break;
+                                }
+                                if (!nextLine()) {
+                                    errorAt("Unclosed {a} block.", line, character, end);
+                                }
+                            }
+                            character += i;
+                            s = s.substr(i);
+            },
+
+// token -- this is called by advance to get the next token.
+
+            token: function () {
+                var b, c, captures, d, depth, high, i, l, low, q, t;
+
+                function match(x) {
+                    var r = x.exec(s), r1;
+                    if (r) {
+                        l = r[0].length;
+                        r1 = r[1];
+                        c = r1.charAt(0);
+                        s = s.substr(l);
+                        from = character + l - r1.length;
+                        character += l;
+                        return r1;
+                    }
+                }
+
+                function string(x) {
+                    var c, j, r = '';
+
+                    if (jsonmode && x !== '"') {
+                        warningAt("Strings must use doublequote.",
+                                line, character);
+                    }
+
+                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
+                        return it('(punctuator)', x);
+                    }
+
+                    function esc(n) {
+                        var i = parseInt(s.substr(j + 1, n), 16);
+                        j += n;
+                        if (i >= 32 && i <= 126 &&
+                                i !== 34 && i !== 92 && i !== 39) {
+                            warningAt("Unnecessary escapement.", line, character);
+                        }
+                        character += n;
+                        c = String.fromCharCode(i);
+                    }
+                    j = 0;
+                    for (;;) {
+                        while (j >= s.length) {
+                            j = 0;
+                            if (xmode !== 'html' || !nextLine()) {
+                                errorAt("Unclosed string.", line, from);
+                            }
+                        }
+                        c = s.charAt(j);
+                        if (c === x) {
+                            character += 1;
+                            s = s.substr(j + 1);
+                            return it('(string)', r, x);
+                        }
+                        if (c < ' ') {
+                            if (c === '\n' || c === '\r') {
+                                break;
+                            }
+                            warningAt("Control character in string: {a}.",
+                                    line, character + j, s.slice(0, j));
+                        } else if (c === xquote) {
+                            warningAt("Bad HTML string", line, character + j);
+                        } else if (c === '<') {
+                            if (option.safe && xmode === 'html') {
+                                warningAt("ADsafe string violation.",
+                                        line, character + j);
+                            } else if (s.charAt(j + 1) === '/' && (xmode || option.safe) && s.substr(j + 2, 6) === 'script') {
+                                warningAt("Expected '<\\/' and instead saw '</'.", line, character);
+                            } else if (s.charAt(j + 1) === '!' && (xmode || option.safe)) {
+                                warningAt("Unexpected '<!' in a string.", line, character);
+                            }
+                        } else if (c === '\\') {
+                            if (xmode === 'html') {
+                                if (option.safe) {
+                                    warningAt("ADsafe string violation.",
+                                            line, character + j);
+                                }
+                            } else if (xmode === 'styleproperty') {
+                                j += 1;
+                                character += 1;
+                                c = s.charAt(j);
+                                if (c !== x) {
+                                    warningAt("Escapement in style string.",
+                                            line, character + j);
+                                }
+                            } else {
+                                j += 1;
+                                character += 1;
+                                c = s.charAt(j);
+                                switch (c) {
+                                case xquote:
+                                    warningAt("Bad HTML string", line,
+                                        character + j);
+                                    break;
+                                case '\\':
+                                case '\'':
+                                case '"':
+                                case '/':
+                                    break;
+                                case 'b':
+                                    c = '\b';
+                                    break;
+                                case 'f':
+                                    c = '\f';
+                                    break;
+                                case 'n':
+                                    c = '\n';
+                                    break;
+                                case 'r':
+                                    c = '\r';
+                                    break;
+                                case 't':
+                                    c = '\t';
+                                    break;
+                                case 'u':
+                                    esc(4);
+                                    break;
+                                case 'v':
+                                    c = '\v';
+                                    break;
+                                case 'x':
+                                    if (jsonmode) {
+                                        warningAt("Avoid \\x-.", line, character);
+                                    }
+                                    esc(2);
+                                    break;
+                                default:
+                                    warningAt("Bad escapement.", line, character);
+                                }
+                            }
+                        }
+                        r += c;
+                        character += 1;
+                        j += 1;
+                    }
+                }
+
+                for (;;) {
+                    if (!s) {
+                        return it(nextLine() ? '(endline)' : '(end)', '');
+                    }
+                    while (xmode === 'outer') {
+                        i = s.search(ox);
+                        if (i === 0) {
+                            break;
+                        } else if (i > 0) {
+                            character += 1;
+                            s = s.slice(i);
+                            break;
+                        } else {
+                            if (!nextLine()) {
+                                return it('(end)', '');
+                            }
+                        }
+                    }
+//                     t = match(rx[xmode] || tx);
+//                     if (!t) {
+//                         if (xmode === 'html') {
+//                             return it('(error)', s.charAt(0));
+//                         } else {
+//                             t = '';
+//                             c = '';
+//                             while (s && s < '!') {
+//                                 s = s.substr(1);
+//                             }
+//                             if (s) {
+//                                 errorAt("Unexpected '{a}'.",
+//                                         line, character, s.substr(0, 1));
+//                             }
+//                         }
+                    t = match(rx[xmode] || tx);
+                    if (!t) {
+                        t = '';
+                        c = '';
+                        while (s && s < '!') {
+                            s = s.substr(1);
+                        }
+                        if (s) {
+                            if (xmode === 'html') {
+                                return it('(error)', s.charAt(0));
+                            } else {
+                                errorAt("Unexpected '{a}'.",
+                                        line, character, s.substr(0, 1));
+                            }
+                        }
+                    } else {
+
+    //      identifier
+
+                        if (c.isAlpha() || c === '_' || c === '$') {
+                            return it('(identifier)', t);
+                        }
+
+    //      number
+
+                        if (c.isDigit() || (c === '.' && t.substr(1, 1).isDigit())) {
+                            if (c === '.') {
+                                t = '0' + t;
+                                c = '0';
+                            }
+                        
+                            if (xmode !== 'style' && !isFinite(Number(t))) {
+                                warningAt("Bad number '{a}'.",
+                                    line, character, t);
+                            }
+                            if (xmode !== 'style' &&
+                                     xmode !== 'styleproperty' &&
+                                     s.substr(0, 1).isAlpha()) {
+                                warningAt("Missing space after '{a}'.",
+                                        line, character, t);
+                            }
+                            if (c === '0') {
+                                d = t.substr(1, 1);
+                                if (d.isDigit()) {
+                                    if (token.id !== '.' && xmode !== 'styleproperty') {
+                                        warningAt("Don't use extra leading zeros '{a}'.",
+                                            line, character, t);
+                                    }
+                                } else if (jsonmode && (d === 'x' || d === 'X')) {
+                                    warningAt("Avoid 0x-. '{a}'.",
+                                            line, character, t);
+                                }
+                            }
+                            if (t.substr(t.length - 1) === '.') {
+                                warningAt(
+        "A trailing decimal point can be confused with a dot '{a}'.",
+                                        line, character, t);
+                            }
+                            return it('(number)', t);
+                        }
+                        switch (t) {
+
+    //      string
+
+                        case '"':
+                        case "'":
+                            return string(t);
+
+    //      // comment
+
+                        case '//':
+                            if (src || (xmode && xmode !== 'script')) {
+                                warningAt("Unexpected comment.", line, character);
+                            } else if (xmode === 'script' && /<\s*\//i.test(s)) {
+                                warningAt("Unexpected <\/ in comment.", line, character);
+                            } else if ((option.safe || xmode === 'script') && ax.test(s)) {
+                                warningAt("Dangerous comment.", line, character);
+                            }
+                            s = '';
+                            token.comment = true;
+                            break;
+
+    //      /* comment
+
+                        case '/*':
+                            if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) {
+                                warningAt("Unexpected comment.", line, character);
+                            }
+                            if (option.safe && ax.test(s)) {
+                                warningAt("ADsafe comment violation.", line, character);
+                            }
+                            for (;;) {
+                                i = s.search(lx);
+                                if (i >= 0) {
+                                    break;
+                                }
+                                if (!nextLine()) {
+                                    errorAt("Unclosed comment.", line, character);
+                                } else {
+                                    if (option.safe && ax.test(s)) {
+                                        warningAt("ADsafe comment violation.",
+                                                line, character);
+                                    }
+                                }
+                            }
+                            character += i + 2;
+                            if (s.substr(i, 1) === '/') {
+                                errorAt("Nested comment.", line, character);
+                            }
+                            s = s.substr(i + 2);
+                            token.comment = true;
+                            break;
+
+    //      /*members /*jslint /*global
+
+                        case '/*members':
+                        case '/*member':
+                        case '/*jslint':
+                        case '/*global':
+                        case '*/':
+                            return {
+                                value: t,
+                                type: 'special',
+                                line: line,
+                                character: character,
+                                from: from
+                            };
+
+                        case '':
+                            break;
+    //      /
+                        case '/':
+                            if (token.id === '/=') {
+                                errorAt(
+"A regular expression literal can be confused with '/='.", line, from);
+                            }
+                            if (prereg) {
+                                depth = 0;
+                                captures = 0;
+                                l = 0;
+                                for (;;) {
+                                    b = true;
+                                    c = s.charAt(l);
+                                    l += 1;
+                                    switch (c) {
+                                    case '':
+                                        errorAt("Unclosed regular expression.",
+                                                line, from);
+                                        return;
+                                    case '/':
+                                        if (depth > 0) {
+                                            warningAt("Unescaped '{a}'.",
+                                                    line, from + l, '/');
+                                        }
+                                        c = s.substr(0, l - 1);
+                                        q = {
+                                            g: true,
+                                            i: true,
+                                            m: true
+                                        };
+                                        while (q[s.charAt(l)] === true) {
+                                            q[s.charAt(l)] = false;
+                                            l += 1;
+                                        }
+                                        character += l;
+                                        s = s.substr(l);
+                                        q = s.charAt(0);
+                                        if (q === '/' || q === '*') {
+                                            errorAt("Confusing regular expression.",
+                                                    line, from);
+                                        }
+                                        return it('(regexp)', c);
+                                    case '\\':
+                                        c = s.charAt(l);
+                                        if (c < ' ') {
+                                            warningAt(
+"Unexpected control character in regular expression.", line, from + l);
+                                        } else if (c === '<') {
+                                            warningAt(
+"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
+                                        }
+                                        l += 1;
+                                        break;
+                                    case '(':
+                                        depth += 1;
+                                        b = false;
+                                        if (s.charAt(l) === '?') {
+                                            l += 1;
+                                            switch (s.charAt(l)) {
+                                            case ':':
+                                            case '=':
+                                            case '!':
+                                                l += 1;
+                                                break;
+                                            default:
+                                                warningAt(
+"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
+                                            }
+                                        } else {
+                                            captures += 1;
+                                        }
+                                        break;
+                                    case '|':
+                                        b = false;
+                                        break;
+                                    case ')':
+                                        if (depth === 0) {
+                                            warningAt("Unescaped '{a}'.",
+                                                    line, from + l, ')');
+                                        } else {
+                                            depth -= 1;
+                                        }
+                                        break;
+                                    case ' ':
+                                        q = 1;
+                                        while (s.charAt(l) === ' ') {
+                                            l += 1;
+                                            q += 1;
+                                        }
+                                        if (q > 1) {
+                                            warningAt(
+"Spaces are hard to count. Use {{a}}.", line, from + l, q);
+                                        }
+                                        break;
+                                    case '[':
+                                        c = s.charAt(l);
+                                        if (c === '^') {
+                                            l += 1;
+                                            if (option.regexp) {
+                                                warningAt("Insecure '{a}'.",
+                                                        line, from + l, c);
+                                            }
+                                        }
+                                        q = false;
+                                        if (c === ']') {
+                                            warningAt("Empty class.", line,
+                                                    from + l - 1);
+                                            q = true;
+                                        }
+klass:                                  do {
+                                            c = s.charAt(l);
+                                            l += 1;
+                                            switch (c) {
+                                            case '[':
+                                            case '^':
+                                                warningAt("Unescaped '{a}'.",
+                                                        line, from + l, c);
+                                                q = true;
+                                                break;
+                                            case '-':
+                                                if (q) {
+                                                    q = false;
+                                                } else {
+                                                    warningAt("Unescaped '{a}'.",
+                                                            line, from + l, '-');
+                                                    q = true;
+                                                }
+                                                break;
+                                            case ']':
+                                                if (!q) {
+                                                    warningAt("Unescaped '{a}'.",
+                                                            line, from + l - 1, '-');
+                                                }
+                                                break klass;
+                                            case '\\':
+                                                c = s.charAt(l);
+                                                if (c < ' ') {
+                                                    warningAt(
+"Unexpected control character in regular expression.", line, from + l);
+                                                } else if (c === '<') {
+                                                    warningAt(
+"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
+                                                }
+                                                l += 1;
+                                                q = true;
+                                                break;
+                                            case '/':
+                                                warningAt("Unescaped '{a}'.",
+                                                        line, from + l - 1, '/');
+                                                q = true;
+                                                break;
+                                            case '<':
+                                                if (xmode === 'script') {
+                                                    c = s.charAt(l);
+                                                    if (c === '!' || c === '/') {
+                                                        warningAt(
+"HTML confusion in regular expression '<{a}'.", line, from + l, c);
+                                                    }
+                                                }
+                                                q = true;
+                                                break;
+                                            default:
+                                                q = true;
+                                            }
+                                        } while (c);
+                                        break;
+                                    case '.':
+                                        if (option.regexp) {
+                                            warningAt("Insecure '{a}'.", line,
+                                                    from + l, c);
+                                        }
+                                        break;
+                                    case ']':
+                                    case '?':
+                                    case '{':
+                                    case '}':
+                                    case '+':
+                                    case '*':
+                                        warningAt("Unescaped '{a}'.", line,
+                                                from + l, c);
+                                        break;
+                                    case '<':
+                                        if (xmode === 'script') {
+                                            c = s.charAt(l);
+                                            if (c === '!' || c === '/') {
+                                                warningAt(
+"HTML confusion in regular expression '<{a}'.", line, from + l, c);
+                                            }
+                                        }
+                                    }
+                                    if (b) {
+                                        switch (s.charAt(l)) {
+                                        case '?':
+                                        case '+':
+                                        case '*':
+                                            l += 1;
+                                            if (s.charAt(l) === '?') {
+                                                l += 1;
+                                            }
+                                            break;
+                                        case '{':
+                                            l += 1;
+                                            c = s.charAt(l);
+                                            if (c < '0' || c > '9') {
+                                                warningAt(
+"Expected a number and instead saw '{a}'.", line, from + l, c);
+                                            }
+                                            l += 1;
+                                            low = +c;
+                                            for (;;) {
+                                                c = s.charAt(l);
+                                                if (c < '0' || c > '9') {
+                                                    break;
+                                                }
+                                                l += 1;
+                                                low = +c + (low * 10);
+                                            }
+                                            high = low;
+                                            if (c === ',') {
+                                                l += 1;
+                                                high = Infinity;
+                                                c = s.charAt(l);
+                                                if (c >= '0' && c <= '9') {
+                                                    l += 1;
+                                                    high = +c;
+                                                    for (;;) {
+                                                        c = s.charAt(l);
+                                                        if (c < '0' || c > '9') {
+                                                            break;
+                                                        }
+                                                        l += 1;
+                                                        high = +c + (high * 10);
+                                                    }
+                                                }
+                                            }
+                                            if (s.charAt(l) !== '}') {
+                                                warningAt(
+"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
+                                            } else {
+                                                l += 1;
+                                            }
+                                            if (s.charAt(l) === '?') {
+                                                l += 1;
+                                            }
+                                            if (low > high) {
+                                                warningAt(
+"'{a}' should not be greater than '{b}'.", line, from + l, low, high);
+                                            }
+                                        }
+                                    }
+                                }
+                                c = s.substr(0, l - 1);
+                                character += l;
+                                s = s.substr(l);
+                                return it('(regexp)', c);
+                            }
+                            return it('(punctuator)', t);
+
+    //      punctuator
+
+                        case '<!--':
+                            l = line;
+                            c = character;
+                            for (;;) {
+                                i = s.indexOf('--');
+                                if (i >= 0) {
+                                    break;
+                                }
+                                i = s.indexOf('<!-');
+                                if (i >= 0) {
+                                    errorAt("Nested HTML comment.",
+                                        line, character + i);
+                                }
+                                if (!nextLine()) {
+                                    errorAt("Unclosed HTML comment.", l, c);
+                                }
+                            }
+                            l = s.indexOf('<!-');
+                            if (l >= 0 && l < i) {
+                                errorAt("Nested HTML comment.",
+                                    line, character + l);
+                            }
+                            character += i;
+                            if (s[i + 2] !== '>') {
+                                errorAt("Expected -->.", line, character);
+                            }
+                            character += 3;
+                            s = s.slice(i + 3);
+                            break;
+                        case '#':
+                            if (xmode === 'html' || xmode === 'styleproperty') {
+                                for (;;) {
+                                    c = s.charAt(0);
+                                    if ((c < '0' || c > '9') &&
+                                            (c < 'a' || c > 'f') &&
+                                            (c < 'A' || c > 'F')) {
+                                        break;
+                                    }
+                                    character += 1;
+                                    s = s.substr(1);
+                                    t += c;
+                                }
+                                if (t.length !== 4 && t.length !== 7) {
+                                    warningAt("Bad hex color '{a}'.", line,
+                                        from + l, t);
+                                }
+                                return it('(color)', t);
+                            }
+                            return it('(punctuator)', t);
+                        default:
+                            if (xmode === 'outer' && c === '&') {
+                                character += 1;
+                                s = s.substr(1);
+                                for (;;) {
+                                    c = s.charAt(0);
+                                    character += 1;
+                                    s = s.substr(1);
+                                    if (c === ';') {
+                                        break;
+                                    }
+                                    if (!((c >= '0' && c <= '9') ||
+                                            (c >= 'a' && c <= 'z') ||
+                                            c === '#')) {
+                                        errorAt("Bad entity", line, from + l,
+                                        character);
+                                    }
+                                }
+                                break;
+                            }
+                            return it('(punctuator)', t);
+                        }
+                    }
+                }
+            }
+        };
+    }());
+
+
+    function addlabel(t, type) {
+
+        if (option.safe && funct['(global)'] &&
+                typeof predefined[t] !== 'boolean') {
+            warning('ADsafe global: ' + t + '.', token);
+        } else if (t === 'hasOwnProperty') {
+            warning("'hasOwnProperty' is a really bad name.");
+        }
+
+// Define t in the current function in the current scope.
+
+        if (is_own(funct, t) && !funct['(global)']) {
+            warning(funct[t] === true ?
+                "'{a}' was used before it was defined." :
+                "'{a}' is already defined.",
+                nexttoken, t);
+        }
+        funct[t] = type;
+        if (funct['(global)']) {
+            global[t] = funct;
+            if (is_own(implied, t)) {
+                warning("'{a}' was used before it was defined.", nexttoken, t);
+                delete implied[t];
+            }
+        } else {
+            scope[t] = funct;
+        }
+    }
+
+
+    function doOption() {
+        var b, obj, filter, o = nexttoken.value, t, v;
+        switch (o) {
+        case '*/':
+            error("Unbegun comment.");
+            break;
+        case '/*members':
+        case '/*member':
+            o = '/*members';
+            if (!membersOnly) {
+                membersOnly = {};
+            }
+            obj = membersOnly;
+            break;
+        case '/*jslint':
+            if (option.safe) {
+                warning("ADsafe restriction.");
+            }
+            obj = option;
+            filter = boolOptions;
+            break;
+        case '/*global':
+            if (option.safe) {
+                warning("ADsafe restriction.");
+            }
+            obj = predefined;
+            break;
+        default:
+        }
+        t = lex.token();
+loop:   for (;;) {
+            for (;;) {
+                if (t.type === 'special' && t.value === '*/') {
+                    break loop;
+                }
+                if (t.id !== '(endline)' && t.id !== ',') {
+                    break;
+                }
+                t = lex.token();
+            }
+            if (t.type !== '(string)' && t.type !== '(identifier)' &&
+                    o !== '/*members') {
+                error("Bad option.", t);
+            }
+            v = lex.token();
+            if (v.id === ':') {
+                v = lex.token();
+                if (obj === membersOnly) {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                            t, '*/', ':');
+                }
+                if (t.value === 'indent' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.white = true;
+                    obj.indent = b;
+                } else if (t.value === 'maxerr' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.maxerr = b;
+                } else if (t.value === 'maxlen' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.maxlen = b;
+                } else if (v.value === 'true') {
+                    obj[t.value] = true;
+                } else if (v.value === 'false') {
+                    obj[t.value] = false;
+                } else {
+                    error("Bad option value.", v);
+                }
+                t = lex.token();
+            } else {
+                if (o === '/*jslint') {
+                    error("Missing option value.", t);
+                }
+                obj[t.value] = false;
+                t = v;
+            }
+        }
+        if (filter) {
+            assume();
+        }
+    }
+
+
+// We need a peek function. If it has an argument, it peeks that much farther
+// ahead. It is used to distinguish
+//     for ( var i in ...
+// from
+//     for ( var i = ...
+
+    function peek(p) {
+        var i = p || 0, j = 0, t;
+
+        while (j <= i) {
+            t = lookahead[j];
+            if (!t) {
+                t = lookahead[j] = lex.token();
+            }
+            j += 1;
+        }
+        return t;
+    }
+
+
+
+// Produce the next token. It looks for programming errors.
+
+    function advance(id, t) {
+        switch (token.id) {
+        case '(number)':
+            if (nexttoken.id === '.') {
+                warning(
+"A dot following a number can be confused with a decimal point.", token);
+            }
+            break;
+        case '-':
+            if (nexttoken.id === '-' || nexttoken.id === '--') {
+                warning("Confusing minusses.");
+            }
+            break;
+        case '+':
+            if (nexttoken.id === '+' || nexttoken.id === '++') {
+                warning("Confusing plusses.");
+            }
+            break;
+        }
+        if (token.type === '(string)' || token.identifier) {
+            anonname = token.value;
+        }
+
+        if (id && nexttoken.id !== id) {
+            if (t) {
+                if (nexttoken.id === '(end)') {
+                    warning("Unmatched '{a}'.", t, t.id);
+                } else {
+                    warning(
+"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
+                            nexttoken, id, t.id, t.line, nexttoken.value);
+                }
+            } else if (nexttoken.type !== '(identifier)' ||
+                            nexttoken.value !== id) {
+                warning("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, id, nexttoken.value);
+            }
+        }
+        prevtoken = token;
+        token = nexttoken;
+        for (;;) {
+            nexttoken = lookahead.shift() || lex.token();
+            if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
+                return;
+            }
+            if (nexttoken.type === 'special') {
+                doOption();
+            } else {
+                if (nexttoken.id !== '(endline)') {
+                    break;
+                }
+            }
+        }
+    }
+
+
+// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
+// is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is
+// like nud except that it is only used on the first token of a statement.
+// Having .fud makes it much easier to define JavaScript. I retained Pratt's
+// nomenclature.
+
+// .nud     Null denotation
+// .fud     First null denotation
+// .led     Left denotation
+//  lbp     Left binding power
+//  rbp     Right binding power
+
+// They are key to the parsing method called Top Down Operator Precedence.
+
+    function parse(rbp, initial) {
+        var left;
+        if (nexttoken.id === '(end)') {
+            error("Unexpected early end of program.", token);
+        }
+        advance();
+        if (option.safe && typeof predefined[token.value] === 'boolean' &&
+                (nexttoken.id !== '(' && nexttoken.id !== '.')) {
+            warning('ADsafe violation.', token);
+        }
+        if (initial) {
+            anonname = 'anonymous';
+            funct['(verb)'] = token.value;
+        }
+        if (initial === true && token.fud) {
+            left = token.fud();
+        } else {
+            if (token.nud) {
+                left = token.nud();
+            } else {
+                if (nexttoken.type === '(number)' && token.id === '.') {
+                    warning(
+"A leading decimal point can be confused with a dot: '.{a}'.",
+                            token, nexttoken.value);
+                    advance();
+                    return token;
+                } else {
+                    error("Expected an identifier and instead saw '{a}'.",
+                            token, token.id);
+                }
+            }
+            while (rbp < nexttoken.lbp) {
+                advance();
+                if (token.led) {
+                    left = token.led(left);
+                } else {
+                    error("Expected an operator and instead saw '{a}'.",
+                        token, token.id);
+                }
+            }
+        }
+        return left;
+    }
+
+
+// Functions for conformance of style.
+
+    function adjacent(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white || xmode === 'styleproperty' || xmode === 'style') {
+            if (left.character !== right.from && left.line === right.line) {
+                warning("Unexpected space after '{a}'.", right, left.value);
+            }
+        }
+    }
+
+    function nospace(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white && !left.comment) {
+            if (left.line === right.line) {
+                adjacent(left, right);
+            }
+        }
+    }
+
+
+    function nonadjacent(left, right) {
+        if (option.white) {
+            left = left || token;
+            right = right || nexttoken;
+            if (left.line === right.line && left.character === right.from) {
+                warning("Missing space after '{a}'.",
+                

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/jslint/js.jar
----------------------------------------------------------------------
diff --git a/AlluraTest/jslint/js.jar b/AlluraTest/jslint/js.jar
new file mode 100644
index 0000000..2369f99
Binary files /dev/null and b/AlluraTest/jslint/js.jar differ


[10/50] [abbrv] git commit: [#6056] Improved loading of discussion post by slug

Posted by tv...@apache.org.
[#6056] Improved loading of discussion post by slug

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/9f0c8412
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/9f0c8412
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/9f0c8412

Branch: refs/heads/tv/6355
Commit: 9f0c841263e319cec004becc687b16703cb16951
Parents: fe6f4b2
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jul 2 02:02:54 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:48:41 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9f0c8412/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 4fa05c8..9ff5e6c 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -256,11 +256,12 @@ class PostController(BaseController):
 
     @LazyProperty
     def post(self):
-        result = self.M.Post.query.find(dict(slug=self._post_slug)).all()
-        for p in result:
-            if p.thread_id == self.thread._id: return p
-        if result:
-            redirect(result[0].url())
+        post = self.M.Post.query.get(slug=self._post_slug, thread_id=self.thread._id)
+        if post:
+            return post
+        post = self.M.Post.query.get(slug=self._post_slug)
+        if post:
+            return post
         else:
             redirect('..')
 


[29/50] [abbrv] git commit: [#4213] Don't stop export after first 100 tickets

Posted by tv...@apache.org.
[#4213] Don't stop export after first 100 tickets

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/584a7285
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/584a7285
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/584a7285

Branch: refs/heads/tv/6355
Commit: 584a728545c233ce5e36b3a59f20bdb77adacce7
Parents: 98cec90
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Mon Jul 8 16:49:33 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Mon Jul 8 16:49:33 2013 +0000

----------------------------------------------------------------------
 scripts/trac_export.py | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/584a7285/scripts/trac_export.py
----------------------------------------------------------------------
diff --git a/scripts/trac_export.py b/scripts/trac_export.py
index 4fcb27a..002a1e8 100755
--- a/scripts/trac_export.py
+++ b/scripts/trac_export.py
@@ -237,6 +237,10 @@ class TracExport(object):
 
     def next(self):
         while True:
+            # queue empty, try to fetch more
+            if len(self.ticket_queue) == 0:
+                self.ticket_queue = self.next_ticket_ids()
+            # there aren't any more, we're really done
             if len(self.ticket_queue) == 0:
                 raise StopIteration
             id, extra = self.ticket_queue.pop(0)


[50/50] [abbrv] git commit: [#6355] Handle dots in repo names

Posted by tv...@apache.org.
[#6355] Handle dots in repo names

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/dbfa5afd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/dbfa5afd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/dbfa5afd

Branch: refs/heads/tv/6355
Commit: dbfa5afd2849f9d33901aa4ac170bb5b9d8945f5
Parents: d2a60bb
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Jul 2 14:33:11 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Mon Jul 15 21:03:18 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/auth.py               | 7 ++++---
 ForgeGit/forgegit/tests/functional/test_auth.py | 7 +++++++
 2 files changed, 11 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dbfa5afd/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index 5b3acf3..4e197e6 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -309,12 +309,13 @@ class AuthController(BaseController):
                      project_path, repo_path)
             response.status = 404
             return dict(disallow, error='unknown project')
-        mount_point = os.path.splitext(rest[0])[0]
         c.project = project
-        c.app = project.app_instance(mount_point)
+        c.app = project.app_instance(rest[0])
+        if not c.app:
+            c.app = project.app_instance(rest[0])[0]
         if c.app is None:
             log.info("Can't find repo at %s on repo_path %s",
-                     mount_point, repo_path)
+                     rest[0], repo_path)
             return disallow
         return dict(allow_read=has_access(c.app, 'read')(user=user),
                     allow_write=has_access(c.app, 'write')(user=user),

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dbfa5afd/ForgeGit/forgegit/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_auth.py b/ForgeGit/forgegit/tests/functional/test_auth.py
index fcee919..4a16aab 100644
--- a/ForgeGit/forgegit/tests/functional/test_auth.py
+++ b/ForgeGit/forgegit/tests/functional/test_auth.py
@@ -21,8 +21,10 @@ import json
 from datadiff.tools import assert_equal
 
 from allura.tests import TestController
+from allura.tests.decorators import with_tool
 from forgegit.tests import with_git
 
+
 class TestGitUserPermissions(TestController):
     allow = dict(allow_read=True, allow_write=True, allow_create=True)
     read = dict(allow_read=True, allow_write=False, allow_create=False)
@@ -67,6 +69,11 @@ class TestGitUserPermissions(TestController):
             username='test-usera',
             status=404)
 
+    @with_tool('test', 'Git', 'src.c++.git', 'Git', type='git')
+    def test_dot_and_plus(self):
+        r = self._check_repo('/git/test.p/src.c++.git')
+        assert r == self.allow, r
+
     def _check_repo(self, path, username='test-admin', **kw):
         url = '/auth/repo_permissions'
         r = self.app.get(url, params=dict(


[16/50] [abbrv] git commit: [#5103] ticket:374 Fix indentation in template

Posted by tv...@apache.org.
[#5103] ticket:374 Fix indentation in template


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a5680c0e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a5680c0e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a5680c0e

Branch: refs/heads/tv/6355
Commit: a5680c0ea5112f6fadb14e56ccf2ec4781862f03
Parents: 806c3fe
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jun 20 06:52:07 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:57:49 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/repo/default_branch.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a5680c0e/Allura/allura/templates/repo/default_branch.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/default_branch.html b/Allura/allura/templates/repo/default_branch.html
index c524001..6c20021 100644
--- a/Allura/allura/templates/repo/default_branch.html
+++ b/Allura/allura/templates/repo/default_branch.html
@@ -19,8 +19,8 @@
 
 <form action="{{c.project.url()}}admin/{{app.config.options.mount_point}}/set_default_branch_name" method="POST">
     <label class="grid-13">Default branch name:</label>
-        <div class="grid-13">
-            <input type="text" name="branch_name" id="branch_name" {% if default_branch_name %} value="{{default_branch_name}}"{% endif %}/>
+    <div class="grid-13">
+        <input type="text" name="branch_name" id="branch_name" {% if default_branch_name %} value="{{default_branch_name}}"{% endif %}/>
     </div>
     <div class="grid-13">&nbsp;</div>
     <hr>


[41/50] [abbrv] [#4122] rename AlluraTesting dir to AlluraTest, to match the module name below

Posted by tv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/jslint/fulljslint.js
----------------------------------------------------------------------
diff --git a/AlluraTesting/jslint/fulljslint.js b/AlluraTesting/jslint/fulljslint.js
deleted file mode 100644
index 0bf59bb..0000000
--- a/AlluraTesting/jslint/fulljslint.js
+++ /dev/null
@@ -1,5688 +0,0 @@
-// jslint.js
-// 2010-08-05
-
-/*
-Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is 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 Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/*
-    JSLINT is a global function. It takes two parameters.
-
-        var myResult = JSLINT(source, option);
-
-    The first parameter is either a string or an array of strings. If it is a
-    string, it will be split on '\n' or '\r'. If it is an array of strings, it
-    is assumed that each string represents one line. The source can be a
-    JavaScript text, or HTML text, or a Konfabulator text.
-
-    The second parameter is an optional object of options which control the
-    operation of JSLINT. Most of the options are booleans: They are all are
-    optional and have a default value of false.
-
-    If it checks out, JSLINT returns true. Otherwise, it returns false.
-
-    If false, you can inspect JSLINT.errors to find out the problems.
-    JSLINT.errors is an array of objects containing these members:
-
-    {
-        line      : The line (relative to 0) at which the lint was found
-        character : The character (relative to 0) at which the lint was found
-        reason    : The problem
-        evidence  : The text line in which the problem occurred
-        raw       : The raw message before the details were inserted
-        a         : The first detail
-        b         : The second detail
-        c         : The third detail
-        d         : The fourth detail
-    }
-
-    If a fatal error was found, a null will be the last element of the
-    JSLINT.errors array.
-
-    You can request a Function Report, which shows all of the functions
-    and the parameters and vars that they use. This can be used to find
-    implied global variables and other problems. The report is in HTML and
-    can be inserted in an HTML <body>.
-
-        var myReport = JSLINT.report(limited);
-
-    If limited is true, then the report will be limited to only errors.
-
-    You can request a data structure which contains JSLint's results.
-
-        var myData = JSLINT.data();
-
-    It returns a structure with this form:
-
-    {
-        errors: [
-            {
-                line: NUMBER,
-                character: NUMBER,
-                reason: STRING,
-                evidence: STRING
-            }
-        ],
-        functions: [
-            name: STRING,
-            line: NUMBER,
-            last: NUMBER,
-            param: [
-                STRING
-            ],
-            closure: [
-                STRING
-            ],
-            var: [
-                STRING
-            ],
-            exception: [
-                STRING
-            ],
-            outer: [
-                STRING
-            ],
-            unused: [
-                STRING
-            ],
-            global: [
-                STRING
-            ],
-            label: [
-                STRING
-            ]
-        ],
-        globals: [
-            STRING
-        ],
-        member: {
-            STRING: NUMBER
-        },
-        unuseds: [
-            {
-                name: STRING,
-                line: NUMBER
-            }
-        ],
-        implieds: [
-            {
-                name: STRING,
-                line: NUMBER
-            }
-        ],
-        urls: [
-            STRING
-        ],
-        json: BOOLEAN
-    }
-
-    Empty arrays will not be included.
-
-*/
-
-/*jslint
-    evil: true, nomen: false, onevar: false, regexp: false, strict: true
-*/
-
-/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
-    "(begin)", "(breakage)", "(context)", "(error)", "(global)",
-    "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
-    "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/",
-    "<", "<=", "==", "===", ">", ">=", ADSAFE, ActiveXObject,
-    Array, Boolean, COM, CScript, Canvas, CustomAnimation, Date, Debug, E,
-    Enumerator, Error, EvalError, FadeAnimation, Flash, FormField, Frame,
-    Function, HotKey, Image, JSON, LN10, LN2, LOG10E, LOG2E, MAX_VALUE,
-    MIN_VALUE, Math, MenuItem, MoveAnimation, NEGATIVE_INFINITY, Number,
-    Object, Option, PI, POSITIVE_INFINITY, Point, RangeError, Rectangle,
-    ReferenceError, RegExp, ResizeAnimation, RotateAnimation, SQRT1_2,
-    SQRT2, ScrollBar, String, Style, SyntaxError, System, Text, TextArea,
-    Timer, TypeError, URIError, URL, VBArray, WScript, Web, Window, XMLDOM,
-    XMLHttpRequest, "\\", a, abbr, acronym, addEventListener, address,
-    adsafe, alert, aliceblue, animator, antiquewhite, appleScript, applet,
-    apply, approved, aqua, aquamarine, area, arguments, arity, article,
-    aside, audio, autocomplete, azure, b, background,
-    "background-attachment", "background-color", "background-image",
-    "background-position", "background-repeat", base, bdo, beep, beige, big,
-    bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
-    blueviolet, blur, body, border, "border-bottom", "border-bottom-color",
-    "border-bottom-style", "border-bottom-width", "border-collapse",
-    "border-color", "border-left", "border-left-color", "border-left-style",
-    "border-left-width", "border-right", "border-right-color",
-    "border-right-style", "border-right-width", "border-spacing",
-    "border-style", "border-top", "border-top-color", "border-top-style",
-    "border-top-width", "border-width", bottom, br, brown, browser,
-    burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller,
-    canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt,
-    character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
-    cite, clear, clearInterval, clearTimeout, clip, close, closeWidget,
-    closed, closure, cm, code, col, colgroup, color, command, comment,
-    condition, confirm, console, constructor, content, convertPathToHFS,
-    convertPathToPlatform, coral, cornflowerblue, cornsilk,
-    "counter-increment", "counter-reset", create, crimson, css, cursor,
-    cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,
-    darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
-    darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
-    darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent,
-    deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize,
-    details, devel, dfn, dialog, dimension, dimgray, dir, direction,
-    display, div, dl, document, dodgerblue, dt, edition, else, em, embed,
-    empty, "empty-cells", encodeURI, encodeURIComponent, entityify, eqeqeq,
-    errors, es5, escape, eval, event, evidence, evil, ex, exception, exec, exps,
-    fieldset, figure, filesystem, firebrick, first, float, floor,
-    floralwhite, focus, focusWidget, font, "font-face", "font-family",
-    "font-size", "font-size-adjust", "font-stretch", "font-style",
-    "font-variant", "font-weight", footer, forestgreen, forin, form,
-    fragment, frame, frames, frameset, from, fromCharCode, fuchsia, fud,
-    funct, function, functions, g, gainsboro, gc, getComputedStyle,
-    ghostwhite, global, globals, gold, goldenrod, gray, green, greenyellow,
-    h1, h2, h3, h4, h5, h6, hasOwnProperty, head, header, height, help,
-    hgroup, history, honeydew, hotpink, hr, 'hta:application', html,
-    i, iTunes, id, identifier,
-    iframe, img, immed, implieds, in, include, indent, indexOf, indianred,
-    indigo, init, input, ins, isAlpha, isApplicationRunning, isDigit,
-    isFinite, isNaN, ivory, join, jslint, json, kbd, keygen, khaki,
-    konfabulatorVersion, label, labelled, lang, last, lavender,
-    lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
-    lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
-    lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
-    lightseagreen, lightskyblue, lightslategray, lightsteelblue,
-    lightyellow, lime, limegreen, line, "line-height", linen, link,
-    "list-style", "list-style-image", "list-style-position",
-    "list-style-type", load, loadClass, location, log, m, magenta, map,
-    margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
-    mark, "marker-offset", maroon, match, "max-height", "max-width", maxerr,
-    maxlen, md5, media, mediumaquamarine, mediumblue, mediumorchid,
-    mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen,
-    mediumturquoise, mediumvioletred, member, menu, message, meta, meter,
-    midnightblue, "min-height", "min-width", mintcream, mistyrose, mm,
-    moccasin, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new,
-    newcap, noframes, nomen, noscript, nud, object, ol, oldlace, olive,
-    olivedrab, on, onbeforeunload, onblur, onerror, onevar, onfocus, onload,
-    onresize, onunload, opacity, open, openURL, opener, opera, optgroup,
-    option, orange, orangered, orchid, outer, outline, "outline-color",
-    "outline-style", "outline-width", output, overflow, "overflow-x",
-    "overflow-y", p, padding, "padding-bottom", "padding-left",
-    "padding-right", "padding-top", page, "page-break-after",
-    "page-break-before", palegoldenrod, palegreen, paleturquoise,
-    palevioletred, papayawhip, param, parent, parseFloat, parseInt,
-    passfail, pc, peachpuff, peru, pink, play, plum, plusplus, pop,
-    popupMenu, position, powderblue, pre, predef, preferenceGroups,
-    preferences, print, progress, prompt, prototype, pt, purple, push, px,
-    q, quit, quotes, random, range, raw, reach, readFile, readUrl, reason,
-    red, regexp, reloadWidget, removeEventListener, replace, report,
-    reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, rhino, right,
-    rosybrown, royalblue, rp, rt, ruby, runCommand, runCommandInBg,
-    saddlebrown, safe, salmon, samp, sandybrown, saveAs, savePreferences,
-    screen, script, scroll, scrollBy, scrollTo, seagreen, seal, search,
-    seashell, section, select, serialize, setInterval, setTimeout, shift,
-    showWidgetPreferences, sienna, silver, skyblue, slateblue, slategray,
-    sleep, slice, small, snow, sort, source, span, spawn, speak, split,
-    springgreen, src, stack, status, steelblue, strict, strong, style,
-    styleproperty, sub, substr, sup, supplant, suppressUpdates, sync,
-    system, table, "table-layout", tan, tbody, td, teal, tellWidget, test,
-    "text-align", "text-decoration", "text-indent", "text-shadow",
-    "text-transform", textarea, tfoot, th, thead, thistle, time, title,
-    toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
-    turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused,
-    unwatch, updateNow, urls, value, valueOf, var, version,
-    "vertical-align", video, violet, visibility, watch, wheat, white,
-    "white-space", whitesmoke, widget, width, windows, "word-spacing",
-    "word-wrap", yahooCheckLogin, yahooLogin, yahooLogout, yellow,
-    yellowgreen, "z-index"
-*/
-
-// We build the application inside a function so that we produce only a single
-// global variable. The function will be invoked, its return value is the JSLINT
-// application itself.
-
-"use strict";
-
-var JSLINT = (function () {
-    var adsafe_id,      // The widget's ADsafe id.
-        adsafe_may,     // The widget may load approved scripts.
-        adsafe_went,    // ADSAFE.go has been called.
-        anonname,       // The guessed name for anonymous functions.
-        approved,       // ADsafe approved urls.
-
-        atrule = {
-            media      : true,
-            'font-face': true,
-            page       : true
-        },
-
-// These are operators that should not be used with the ! operator.
-
-        bang = {
-            '<': true,
-            '<=': true,
-            '==': true,
-            '===': true,
-            '!==': true,
-            '!=': true,
-            '>': true,
-            '>=': true,
-            '+': true,
-            '-': true,
-            '*': true,
-            '/': true,
-            '%': true
-        },
-
-// These are members that should not be permitted in the safe subset.
-
-        banned = {              // the member names that ADsafe prohibits.
-            'arguments'     : true,
-            callee          : true,
-            caller          : true,
-            constructor     : true,
-            'eval'          : true,
-            prototype       : true,
-            stack           : true,
-            unwatch         : true,
-            valueOf         : true,
-            watch           : true
-        },
-
-
-// These are the JSLint boolean options.
-
-        boolOptions = {
-            adsafe     : true, // if ADsafe should be enforced
-            bitwise    : true, // if bitwise operators should not be allowed
-            browser    : true, // if the standard browser globals should be predefined
-            cap        : true, // if upper case HTML should be allowed
-            css        : true, // if CSS workarounds should be tolerated
-            debug      : true, // if debugger statements should be allowed
-            devel      : true, // if logging should be allowed (console, alert, etc.)
-            eqeqeq     : true, // if === should be required
-            es5        : true, // if ES5 syntax should be allowed
-            evil       : true, // if eval should be allowed
-            forin      : true, // if for in statements must filter
-            fragment   : true, // if HTML fragments should be allowed
-            immed      : true, // if immediate invocations must be wrapped in parens
-            laxbreak   : true, // if line breaks should not be checked
-            newcap     : true, // if constructor names must be capitalized
-            nomen      : true, // if names should be checked
-            on         : true, // if HTML event handlers should be allowed
-            onevar     : true, // if only one var statement per function should be allowed
-            passfail   : true, // if the scan should stop on first error
-            plusplus   : true, // if increment/decrement should not be allowed
-            regexp     : true, // if the . should not be allowed in regexp literals
-            rhino      : true, // if the Rhino environment globals should be predefined
-            undef      : true, // if variables should be declared before used
-            safe       : true, // if use of some browser features should be restricted
-            windows    : true, // if MS Windows-specigic globals should be predefined
-            strict     : true, // require the "use strict"; pragma
-            sub        : true, // if all forms of subscript notation are tolerated
-            white      : true, // if strict whitespace rules apply
-            widget     : true  // if the Yahoo Widgets globals should be predefined
-        },
-
-// browser contains a set of global names which are commonly provided by a
-// web browser environment.
-
-        browser = {
-            addEventListener: false,
-            blur            : false,
-            clearInterval   : false,
-            clearTimeout    : false,
-            close           : false,
-            closed          : false,
-            defaultStatus   : false,
-            document        : false,
-            event           : false,
-            focus           : false,
-            frames          : false,
-            getComputedStyle: false,
-            history         : false,
-            Image           : false,
-            length          : false,
-            location        : false,
-            moveBy          : false,
-            moveTo          : false,
-            name            : false,
-            navigator       : false,
-            onbeforeunload  : true,
-            onblur          : true,
-            onerror         : true,
-            onfocus         : true,
-            onload          : true,
-            onresize        : true,
-            onunload        : true,
-            open            : false,
-            opener          : false,
-            Option          : false,
-            parent          : false,
-            print           : false,
-            removeEventListener: false,
-            resizeBy        : false,
-            resizeTo        : false,
-            screen          : false,
-            scroll          : false,
-            scrollBy        : false,
-            scrollTo        : false,
-            setInterval     : false,
-            setTimeout      : false,
-            status          : false,
-            top             : false,
-            XMLHttpRequest  : false
-        },
-
-        cssAttributeData,
-        cssAny,
-
-        cssColorData = {
-            "aliceblue"             : true,
-            "antiquewhite"          : true,
-            "aqua"                  : true,
-            "aquamarine"            : true,
-            "azure"                 : true,
-            "beige"                 : true,
-            "bisque"                : true,
-            "black"                 : true,
-            "blanchedalmond"        : true,
-            "blue"                  : true,
-            "blueviolet"            : true,
-            "brown"                 : true,
-            "burlywood"             : true,
-            "cadetblue"             : true,
-            "chartreuse"            : true,
-            "chocolate"             : true,
-            "coral"                 : true,
-            "cornflowerblue"        : true,
-            "cornsilk"              : true,
-            "crimson"               : true,
-            "cyan"                  : true,
-            "darkblue"              : true,
-            "darkcyan"              : true,
-            "darkgoldenrod"         : true,
-            "darkgray"              : true,
-            "darkgreen"             : true,
-            "darkkhaki"             : true,
-            "darkmagenta"           : true,
-            "darkolivegreen"        : true,
-            "darkorange"            : true,
-            "darkorchid"            : true,
-            "darkred"               : true,
-            "darksalmon"            : true,
-            "darkseagreen"          : true,
-            "darkslateblue"         : true,
-            "darkslategray"         : true,
-            "darkturquoise"         : true,
-            "darkviolet"            : true,
-            "deeppink"              : true,
-            "deepskyblue"           : true,
-            "dimgray"               : true,
-            "dodgerblue"            : true,
-            "firebrick"             : true,
-            "floralwhite"           : true,
-            "forestgreen"           : true,
-            "fuchsia"               : true,
-            "gainsboro"             : true,
-            "ghostwhite"            : true,
-            "gold"                  : true,
-            "goldenrod"             : true,
-            "gray"                  : true,
-            "green"                 : true,
-            "greenyellow"           : true,
-            "honeydew"              : true,
-            "hotpink"               : true,
-            "indianred"             : true,
-            "indigo"                : true,
-            "ivory"                 : true,
-            "khaki"                 : true,
-            "lavender"              : true,
-            "lavenderblush"         : true,
-            "lawngreen"             : true,
-            "lemonchiffon"          : true,
-            "lightblue"             : true,
-            "lightcoral"            : true,
-            "lightcyan"             : true,
-            "lightgoldenrodyellow"  : true,
-            "lightgreen"            : true,
-            "lightpink"             : true,
-            "lightsalmon"           : true,
-            "lightseagreen"         : true,
-            "lightskyblue"          : true,
-            "lightslategray"        : true,
-            "lightsteelblue"        : true,
-            "lightyellow"           : true,
-            "lime"                  : true,
-            "limegreen"             : true,
-            "linen"                 : true,
-            "magenta"               : true,
-            "maroon"                : true,
-            "mediumaquamarine"      : true,
-            "mediumblue"            : true,
-            "mediumorchid"          : true,
-            "mediumpurple"          : true,
-            "mediumseagreen"        : true,
-            "mediumslateblue"       : true,
-            "mediumspringgreen"     : true,
-            "mediumturquoise"       : true,
-            "mediumvioletred"       : true,
-            "midnightblue"          : true,
-            "mintcream"             : true,
-            "mistyrose"             : true,
-            "moccasin"              : true,
-            "navajowhite"           : true,
-            "navy"                  : true,
-            "oldlace"               : true,
-            "olive"                 : true,
-            "olivedrab"             : true,
-            "orange"                : true,
-            "orangered"             : true,
-            "orchid"                : true,
-            "palegoldenrod"         : true,
-            "palegreen"             : true,
-            "paleturquoise"         : true,
-            "palevioletred"         : true,
-            "papayawhip"            : true,
-            "peachpuff"             : true,
-            "peru"                  : true,
-            "pink"                  : true,
-            "plum"                  : true,
-            "powderblue"            : true,
-            "purple"                : true,
-            "red"                   : true,
-            "rosybrown"             : true,
-            "royalblue"             : true,
-            "saddlebrown"           : true,
-            "salmon"                : true,
-            "sandybrown"            : true,
-            "seagreen"              : true,
-            "seashell"              : true,
-            "sienna"                : true,
-            "silver"                : true,
-            "skyblue"               : true,
-            "slateblue"             : true,
-            "slategray"             : true,
-            "snow"                  : true,
-            "springgreen"           : true,
-            "steelblue"             : true,
-            "tan"                   : true,
-            "teal"                  : true,
-            "thistle"               : true,
-            "tomato"                : true,
-            "turquoise"             : true,
-            "violet"                : true,
-            "wheat"                 : true,
-            "white"                 : true,
-            "whitesmoke"            : true,
-            "yellow"                : true,
-            "yellowgreen"           : true
-        },
-
-        cssBorderStyle,
-        cssBreak,
-
-        cssLengthData = {
-            '%': true,
-            'cm': true,
-            'em': true,
-            'ex': true,
-            'in': true,
-            'mm': true,
-            'pc': true,
-            'pt': true,
-            'px': true
-        },
-
-        cssOverflow,
-
-        devel = {
-            alert           : false,
-            confirm         : false,
-            console         : false,
-            Debug           : false,
-            opera           : false,
-            prompt          : false
-        },
-
-        escapes = {
-            '\b': '\\b',
-            '\t': '\\t',
-            '\n': '\\n',
-            '\f': '\\f',
-            '\r': '\\r',
-            '"' : '\\"',
-            '/' : '\\/',
-            '\\': '\\\\'
-        },
-
-        funct,          // The current function
-
-        functionicity = [
-            'closure', 'exception', 'global', 'label',
-            'outer', 'unused', 'var'
-        ],
-
-        functions,      // All of the functions
-
-        global,         // The global scope
-        htmltag = {
-            a:        {},
-            abbr:     {},
-            acronym:  {},
-            address:  {},
-            applet:   {},
-            area:     {empty: true, parent: ' map '},
-            article:  {},
-            aside:    {},
-            audio:    {},
-            b:        {},
-            base:     {empty: true, parent: ' head '},
-            bdo:      {},
-            big:      {},
-            blockquote: {},
-            body:     {parent: ' html noframes '},
-            br:       {empty: true},
-            button:   {},
-            canvas:   {parent: ' body p div th td '},
-            caption:  {parent: ' table '},
-            center:   {},
-            cite:     {},
-            code:     {},
-            col:      {empty: true, parent: ' table colgroup '},
-            colgroup: {parent: ' table '},
-            command:  {parent: ' menu '},
-            datalist: {},
-            dd:       {parent: ' dl '},
-            del:      {},
-            details:  {},
-            dialog:   {},
-            dfn:      {},
-            dir:      {},
-            div:      {},
-            dl:       {},
-            dt:       {parent: ' dl '},
-            em:       {},
-            embed:    {},
-            fieldset: {},
-            figure:   {},
-            font:     {},
-            footer:   {},
-            form:     {},
-            frame:    {empty: true, parent: ' frameset '},
-            frameset: {parent: ' html frameset '},
-            h1:       {},
-            h2:       {},
-            h3:       {},
-            h4:       {},
-            h5:       {},
-            h6:       {},
-            head:     {parent: ' html '},
-            header:   {},
-            hgroup:   {},
-            hr:       {empty: true},
-            'hta:application':
-                      {empty: true, parent: ' head '},
-            html:     {parent: '*'},
-            i:        {},
-            iframe:   {},
-            img:      {empty: true},
-            input:    {empty: true},
-            ins:      {},
-            kbd:      {},
-            keygen:   {},
-            label:    {},
-            legend:   {parent: ' details fieldset figure '},
-            li:       {parent: ' dir menu ol ul '},
-            link:     {empty: true, parent: ' head '},
-            map:      {},
-            mark:     {},
-            menu:     {},
-            meta:     {empty: true, parent: ' head noframes noscript '},
-            meter:    {},
-            nav:      {},
-            noframes: {parent: ' html body '},
-            noscript: {},
-            object:   {},
-            ol:       {},
-            optgroup: {parent: ' select '},
-            option:   {parent: ' optgroup select '},
-            output:   {},
-            p:        {},
-            param:    {parent: ' applet object '},
-            pre:      {},
-            progress: {},
-            q:        {},
-            rp:       {},
-            rt:       {},
-            ruby:     {},
-            s:        {},
-            samp:     {},
-            script:   {empty: true, parent: ' body div frame head iframe p pre span '},
-            section:  {},
-            select:   {},
-            small:    {},
-            span:     {},
-            source:   {},
-            strong:   {},
-            style:    {parent: ' head ', empty: true},
-            sub:      {},
-            sup:      {},
-            table:    {},
-            tbody:    {parent: ' table '},
-            td:       {parent: ' tr '},
-            textarea: {},
-            tfoot:    {parent: ' table '},
-            th:       {parent: ' tr '},
-            thead:    {parent: ' table '},
-            time:     {},
-            title:    {parent: ' head '},
-            tr:       {parent: ' table tbody thead tfoot '},
-            tt:       {},
-            u:        {},
-            ul:       {},
-            'var':    {},
-            video:    {}
-        },
-
-        ids,            // HTML ids
-        implied,        // Implied globals
-        inblock,
-        indent,
-        jsonmode,
-        lines,
-        lookahead,
-        member,
-        membersOnly,
-        nexttoken,
-        noreach,
-        option,
-        predefined,     // Global variables defined by option
-        prereg,
-        prevtoken,
-
-        rhino = {
-            defineClass : false,
-            deserialize : false,
-            gc          : false,
-            help        : false,
-            load        : false,
-            loadClass   : false,
-            print       : false,
-            quit        : false,
-            readFile    : false,
-            readUrl     : false,
-            runCommand  : false,
-            seal        : false,
-            serialize   : false,
-            spawn       : false,
-            sync        : false,
-            toint32     : false,
-            version     : false
-        },
-
-        scope,      // The current scope
-
-        windows = {
-            ActiveXObject: false,
-            CScript      : false,
-            Debug        : false,
-            Enumerator   : false,
-            System       : false,
-            VBArray      : false,
-            WScript      : false
-        },
-
-        src,
-        stack,
-
-// standard contains the global names that are provided by the
-// ECMAScript standard.
-
-        standard = {
-            'void'              : false,
-            Array               : false,
-            Boolean             : false,
-            Date                : false,
-            decodeURI           : false,
-            decodeURIComponent  : false,
-            encodeURI           : false,
-            encodeURIComponent  : false,
-            Error               : false,
-            'eval'              : false,
-            EvalError           : false,
-            Function            : false,
-            hasOwnProperty      : false,
-            isFinite            : false,
-            isNaN               : false,
-            JSON                : false,
-            Math                : false,
-            Number              : false,
-            Object              : false,
-            parseInt            : false,
-            parseFloat          : false,
-            RangeError          : false,
-            ReferenceError      : false,
-            RegExp              : false,
-            String              : false,
-            SyntaxError         : false,
-            TypeError           : false,
-            URIError            : false
-        },
-
-        standard_member = {
-            E                   : true,
-            LN2                 : true,
-            LN10                : true,
-            LOG2E               : true,
-            LOG10E              : true,
-            PI                  : true,
-            SQRT1_2             : true,
-            SQRT2               : true,
-            MAX_VALUE           : true,
-            MIN_VALUE           : true,
-            NEGATIVE_INFINITY   : true,
-            POSITIVE_INFINITY   : true
-        },
-
-        strict_mode,
-        syntax = {},
-        tab,
-        token,
-        urls,
-        warnings,
-
-// widget contains the global names which are provided to a Yahoo
-// (fna Konfabulator) widget.
-
-        widget = {
-            alert                   : true,
-            animator                : true,
-            appleScript             : true,
-            beep                    : true,
-            bytesToUIString         : true,
-            Canvas                  : true,
-            chooseColor             : true,
-            chooseFile              : true,
-            chooseFolder            : true,
-            closeWidget             : true,
-            COM                     : true,
-            convertPathToHFS        : true,
-            convertPathToPlatform   : true,
-            CustomAnimation         : true,
-            escape                  : true,
-            FadeAnimation           : true,
-            filesystem              : true,
-            Flash                   : true,
-            focusWidget             : true,
-            form                    : true,
-            FormField               : true,
-            Frame                   : true,
-            HotKey                  : true,
-            Image                   : true,
-            include                 : true,
-            isApplicationRunning    : true,
-            iTunes                  : true,
-            konfabulatorVersion     : true,
-            log                     : true,
-            md5                     : true,
-            MenuItem                : true,
-            MoveAnimation           : true,
-            openURL                 : true,
-            play                    : true,
-            Point                   : true,
-            popupMenu               : true,
-            preferenceGroups        : true,
-            preferences             : true,
-            print                   : true,
-            prompt                  : true,
-            random                  : true,
-            Rectangle               : true,
-            reloadWidget            : true,
-            ResizeAnimation         : true,
-            resolvePath             : true,
-            resumeUpdates           : true,
-            RotateAnimation         : true,
-            runCommand              : true,
-            runCommandInBg          : true,
-            saveAs                  : true,
-            savePreferences         : true,
-            screen                  : true,
-            ScrollBar               : true,
-            showWidgetPreferences   : true,
-            sleep                   : true,
-            speak                   : true,
-            Style                   : true,
-            suppressUpdates         : true,
-            system                  : true,
-            tellWidget              : true,
-            Text                    : true,
-            TextArea                : true,
-            Timer                   : true,
-            unescape                : true,
-            updateNow               : true,
-            URL                     : true,
-            Web                     : true,
-            widget                  : true,
-            Window                  : true,
-            XMLDOM                  : true,
-            XMLHttpRequest          : true,
-            yahooCheckLogin         : true,
-            yahooLogin              : true,
-            yahooLogout             : true
-        },
-
-//  xmode is used to adapt to the exceptions in html parsing.
-//  It can have these states:
-//      false   .js script file
-//      html
-//      outer
-//      script
-//      style
-//      scriptstring
-//      styleproperty
-
-        xmode,
-        xquote,
-
-// unsafe comment or string
-        ax = /@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,
-// unsafe characters that are silently deleted by one or more browsers
-// Whitelist Replacement Char, 0xfffd
-        cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\ufffc\ufffe-\uffff]/,
-// token
-        tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
-// html token
-        hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,
-// characters in strings that need escapement
-        nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
-        nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
-// outer html token
-        ox = /[>&]|<[\/!]?|--/,
-// star slash
-        lx = /\*\/|\/\*/,
-// identifier
-        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
-// javascript url
-        jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
-// url badness
-        ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,
-// style
-        sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,
-        ssx = /^\s*(\.?\d+(?:\.\d+)?|[@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|<\/)/,
-// attributes characters
-        //qx = /[^a-zA-Z0-9+\-_\/ ]/,
-        qx = /[^a-zA-Z0-9+\-_\/ .#]/, // We want dots in names, period; and hashes for templating
-// query characters for ids
-        //dx = /[\[\]\/\\"'*<>.&:(){}+=#]/,
-        // allow . and /
-        dx = /[\[\]\\"'*<>&:(){}+=#]/,
-
-        rx = {
-            outer: hx,
-            html: hx,
-            style: sx,
-            styleproperty: ssx
-        };
-
-    function F() {}
-
-    if (typeof Object.create !== 'function') {
-        Object.create = function (o) {
-            F.prototype = o;
-            return new F();
-        };
-    }
-
-
-    function is_own(object, name) {
-        return Object.prototype.hasOwnProperty.call(object, name);
-    }
-
-
-    function combine(t, o) {
-        var n;
-        for (n in o) {
-            if (is_own(o, n)) {
-                t[n] = o[n];
-            }
-        }
-    }
-
-    String.prototype.entityify = function () {
-        return this.
-            replace(/&/g, '&amp;').
-            replace(/</g, '&lt;').
-            replace(/>/g, '&gt;');
-    };
-
-    String.prototype.isAlpha = function () {
-        return (this >= 'a' && this <= 'z\uffff') ||
-            (this >= 'A' && this <= 'Z\uffff');
-    };
-
-
-    String.prototype.isDigit = function () {
-        return (this >= '0' && this <= '9');
-    };
-
-
-    String.prototype.supplant = function (o) {
-        return this.replace(/\{([^{}]*)\}/g, function (a, b) {
-            var r = o[b];
-            return typeof r === 'string' || typeof r === 'number' ? r : a;
-        });
-    };
-
-    String.prototype.name = function () {
-
-// If the string looks like an identifier, then we can return it as is.
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can simply slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe
-// sequences.
-
-        if (ix.test(this)) {
-            return this;
-        }
-        if (nx.test(this)) {
-            return '"' + this.replace(nxg, function (a) {
-                var c = escapes[a];
-                if (c) {
-                    return c;
-                }
-                return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
-            }) + '"';
-        }
-        return '"' + this + '"';
-    };
-
-
-    function assume() {
-        if (!option.safe) {
-            if (option.rhino) {
-                combine(predefined, rhino);
-            }
-            if (option.devel) {
-                combine(predefined, devel);
-            }
-            if (option.browser) {
-                combine(predefined, browser);
-            }
-            if (option.windows) {
-                combine(predefined, windows);
-            }
-            if (option.widget) {
-                combine(predefined, widget);
-            }
-        }
-    }
-
-
-// Produce an error warning.
-
-    function quit(m, l, ch) {
-        throw {
-            name: 'JSLintError',
-            line: l,
-            character: ch,
-            message: m + " (" + Math.floor((l / lines.length) * 100) +
-                    "% scanned)."
-        };
-    }
-
-    function warning(m, t, a, b, c, d) {
-        var ch, l, w;
-        t = t || nexttoken;
-        if (t.id === '(end)') {  // `~
-            t = token;
-        }
-        l = t.line || 0;
-        ch = t.from || 0;
-        w = {
-            id: '(error)',
-            raw: m,
-            evidence: lines[l - 1] || '',
-            line: l,
-            character: ch,
-            a: a,
-            b: b,
-            c: c,
-            d: d
-        };
-        w.reason = m.supplant(w);
-        JSLINT.errors.push(w);
-        if (option.passfail) {
-            quit('Stopping. ', l, ch);
-        }
-        warnings += 1;
-        if (warnings >= option.maxerr) {
-            quit("Too many errors.", l, ch);
-        }
-        return w;
-    }
-
-    function warningAt(m, l, ch, a, b, c, d) {
-        return warning(m, {
-            line: l,
-            from: ch
-        }, a, b, c, d);
-    }
-
-    function error(m, t, a, b, c, d) {
-        var w = warning(m, t, a, b, c, d);
-        quit("Stopping, unable to continue.", w.line, w.character);
-    }
-
-    function errorAt(m, l, ch, a, b, c, d) {
-        return error(m, {
-            line: l,
-            from: ch
-        }, a, b, c, d);
-    }
-
-
-
-// lexical analysis
-
-    var lex = (function lex() {
-        var character, from, line, s;
-
-// Private lex methods
-
-        function nextLine() {
-            var at;
-            if (line >= lines.length) {
-                return false;
-            }
-            character = 1;
-            s = lines[line];
-            line += 1;
-            at = s.search(/ \t/);
-            if (at >= 0) {
-                warningAt("Mixed spaces and tabs.", line, at + 1);
-            }
-            s = s.replace(/\t/g, tab);
-            at = s.search(cx);
-            if (at >= 0) {
-                warningAt("Unsafe character.", line, at);
-            }
-            if (option.maxlen && option.maxlen < s.length) {
-                warningAt("Line too long.", line, s.length);
-            }
-            return true;
-        }
-
-// Produce a token object.  The token inherits from a syntax symbol.
-
-        function it(type, value) {
-            var i, t;
-            if (type === '(color)') {
-                t = {type: type};
-            } else if (type === '(punctuator)' ||
-                    (type === '(identifier)' && is_own(syntax, value))) {
-                t = syntax[value] || syntax['(error)'];
-            } else {
-                t = syntax[type];
-            }
-            t = Object.create(t);
-            if (type === '(string)' || type === '(range)') {
-                if (jx.test(value)) {
-                    warningAt("Script URL.", line, from);
-                }
-            }
-            if (type === '(identifier)') {
-                t.identifier = true;
-                if (value === '__iterator__' || value === '__proto__') {
-                    errorAt("Reserved name '{a}'.",
-                        line, from, value);
-                } else if (option.nomen &&
-                        (value.charAt(0) === '_' ||
-                         value.charAt(value.length - 1) === '_')) {
-                    warningAt("Unexpected {a} in '{b}'.", line, from,
-                        "dangling '_'", value);
-                }
-            }
-            t.value = value;
-            t.line = line;
-            t.character = character;
-            t.from = from;
-            i = t.id;
-            if (i !== '(endline)') {
-                prereg = i &&
-                    (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
-                    i === 'return');
-            }
-            return t;
-        }
-
-// Public lex methods
-
-        return {
-            init: function (source) {
-                if (typeof source === 'string') {
-                    lines = source.
-                        replace(/\r\n/g, '\n').
-                        replace(/\r/g, '\n').
-                        split('\n');
-                } else {
-                    lines = source;
-                }
-                line = 0;
-                nextLine();
-                from = 1;
-            },
-
-            range: function (begin, end) {
-                var c, value = '';
-                from = character;
-                if (s.charAt(0) !== begin) {
-                    errorAt("Expected '{a}' and instead saw '{b}'.",
-                            line, character, begin, s.charAt(0));
-                }
-                for (;;) {
-                    s = s.slice(1);
-                    character += 1;
-                    c = s.charAt(0);
-                    switch (c) {
-                    case '':
-                        errorAt("Missing '{a}'.", line, character, c);
-                        break;
-                    case end:
-                        s = s.slice(1);
-                        character += 1;
-                        return it('(range)', value);
-                    case xquote:
-                    case '\\':
-                        warningAt("Unexpected '{a}'.", line, character, c);
-                    }
-                    value += c;
-                }
-
-            },
-
-// skip all content up to marker
-
-            skip_till: function (end) {
-                            for (;;) {
-                                i = s.indexOf(end);
-                                if (i >= 0) {
-                                    break;
-                                }
-                                if (!nextLine()) {
-                                    errorAt("Unclosed {a} block.", line, character, end);
-                                }
-                            }
-                            character += i;
-                            s = s.substr(i);
-            },
-
-// token -- this is called by advance to get the next token.
-
-            token: function () {
-                var b, c, captures, d, depth, high, i, l, low, q, t;
-
-                function match(x) {
-                    var r = x.exec(s), r1;
-                    if (r) {
-                        l = r[0].length;
-                        r1 = r[1];
-                        c = r1.charAt(0);
-                        s = s.substr(l);
-                        from = character + l - r1.length;
-                        character += l;
-                        return r1;
-                    }
-                }
-
-                function string(x) {
-                    var c, j, r = '';
-
-                    if (jsonmode && x !== '"') {
-                        warningAt("Strings must use doublequote.",
-                                line, character);
-                    }
-
-                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
-                        return it('(punctuator)', x);
-                    }
-
-                    function esc(n) {
-                        var i = parseInt(s.substr(j + 1, n), 16);
-                        j += n;
-                        if (i >= 32 && i <= 126 &&
-                                i !== 34 && i !== 92 && i !== 39) {
-                            warningAt("Unnecessary escapement.", line, character);
-                        }
-                        character += n;
-                        c = String.fromCharCode(i);
-                    }
-                    j = 0;
-                    for (;;) {
-                        while (j >= s.length) {
-                            j = 0;
-                            if (xmode !== 'html' || !nextLine()) {
-                                errorAt("Unclosed string.", line, from);
-                            }
-                        }
-                        c = s.charAt(j);
-                        if (c === x) {
-                            character += 1;
-                            s = s.substr(j + 1);
-                            return it('(string)', r, x);
-                        }
-                        if (c < ' ') {
-                            if (c === '\n' || c === '\r') {
-                                break;
-                            }
-                            warningAt("Control character in string: {a}.",
-                                    line, character + j, s.slice(0, j));
-                        } else if (c === xquote) {
-                            warningAt("Bad HTML string", line, character + j);
-                        } else if (c === '<') {
-                            if (option.safe && xmode === 'html') {
-                                warningAt("ADsafe string violation.",
-                                        line, character + j);
-                            } else if (s.charAt(j + 1) === '/' && (xmode || option.safe) && s.substr(j + 2, 6) === 'script') {
-                                warningAt("Expected '<\\/' and instead saw '</'.", line, character);
-                            } else if (s.charAt(j + 1) === '!' && (xmode || option.safe)) {
-                                warningAt("Unexpected '<!' in a string.", line, character);
-                            }
-                        } else if (c === '\\') {
-                            if (xmode === 'html') {
-                                if (option.safe) {
-                                    warningAt("ADsafe string violation.",
-                                            line, character + j);
-                                }
-                            } else if (xmode === 'styleproperty') {
-                                j += 1;
-                                character += 1;
-                                c = s.charAt(j);
-                                if (c !== x) {
-                                    warningAt("Escapement in style string.",
-                                            line, character + j);
-                                }
-                            } else {
-                                j += 1;
-                                character += 1;
-                                c = s.charAt(j);
-                                switch (c) {
-                                case xquote:
-                                    warningAt("Bad HTML string", line,
-                                        character + j);
-                                    break;
-                                case '\\':
-                                case '\'':
-                                case '"':
-                                case '/':
-                                    break;
-                                case 'b':
-                                    c = '\b';
-                                    break;
-                                case 'f':
-                                    c = '\f';
-                                    break;
-                                case 'n':
-                                    c = '\n';
-                                    break;
-                                case 'r':
-                                    c = '\r';
-                                    break;
-                                case 't':
-                                    c = '\t';
-                                    break;
-                                case 'u':
-                                    esc(4);
-                                    break;
-                                case 'v':
-                                    c = '\v';
-                                    break;
-                                case 'x':
-                                    if (jsonmode) {
-                                        warningAt("Avoid \\x-.", line, character);
-                                    }
-                                    esc(2);
-                                    break;
-                                default:
-                                    warningAt("Bad escapement.", line, character);
-                                }
-                            }
-                        }
-                        r += c;
-                        character += 1;
-                        j += 1;
-                    }
-                }
-
-                for (;;) {
-                    if (!s) {
-                        return it(nextLine() ? '(endline)' : '(end)', '');
-                    }
-                    while (xmode === 'outer') {
-                        i = s.search(ox);
-                        if (i === 0) {
-                            break;
-                        } else if (i > 0) {
-                            character += 1;
-                            s = s.slice(i);
-                            break;
-                        } else {
-                            if (!nextLine()) {
-                                return it('(end)', '');
-                            }
-                        }
-                    }
-//                     t = match(rx[xmode] || tx);
-//                     if (!t) {
-//                         if (xmode === 'html') {
-//                             return it('(error)', s.charAt(0));
-//                         } else {
-//                             t = '';
-//                             c = '';
-//                             while (s && s < '!') {
-//                                 s = s.substr(1);
-//                             }
-//                             if (s) {
-//                                 errorAt("Unexpected '{a}'.",
-//                                         line, character, s.substr(0, 1));
-//                             }
-//                         }
-                    t = match(rx[xmode] || tx);
-                    if (!t) {
-                        t = '';
-                        c = '';
-                        while (s && s < '!') {
-                            s = s.substr(1);
-                        }
-                        if (s) {
-                            if (xmode === 'html') {
-                                return it('(error)', s.charAt(0));
-                            } else {
-                                errorAt("Unexpected '{a}'.",
-                                        line, character, s.substr(0, 1));
-                            }
-                        }
-                    } else {
-
-    //      identifier
-
-                        if (c.isAlpha() || c === '_' || c === '$') {
-                            return it('(identifier)', t);
-                        }
-
-    //      number
-
-                        if (c.isDigit() || (c === '.' && t.substr(1, 1).isDigit())) {
-                            if (c === '.') {
-                                t = '0' + t;
-                                c = '0';
-                            }
-                        
-                            if (xmode !== 'style' && !isFinite(Number(t))) {
-                                warningAt("Bad number '{a}'.",
-                                    line, character, t);
-                            }
-                            if (xmode !== 'style' &&
-                                     xmode !== 'styleproperty' &&
-                                     s.substr(0, 1).isAlpha()) {
-                                warningAt("Missing space after '{a}'.",
-                                        line, character, t);
-                            }
-                            if (c === '0') {
-                                d = t.substr(1, 1);
-                                if (d.isDigit()) {
-                                    if (token.id !== '.' && xmode !== 'styleproperty') {
-                                        warningAt("Don't use extra leading zeros '{a}'.",
-                                            line, character, t);
-                                    }
-                                } else if (jsonmode && (d === 'x' || d === 'X')) {
-                                    warningAt("Avoid 0x-. '{a}'.",
-                                            line, character, t);
-                                }
-                            }
-                            if (t.substr(t.length - 1) === '.') {
-                                warningAt(
-        "A trailing decimal point can be confused with a dot '{a}'.",
-                                        line, character, t);
-                            }
-                            return it('(number)', t);
-                        }
-                        switch (t) {
-
-    //      string
-
-                        case '"':
-                        case "'":
-                            return string(t);
-
-    //      // comment
-
-                        case '//':
-                            if (src || (xmode && xmode !== 'script')) {
-                                warningAt("Unexpected comment.", line, character);
-                            } else if (xmode === 'script' && /<\s*\//i.test(s)) {
-                                warningAt("Unexpected <\/ in comment.", line, character);
-                            } else if ((option.safe || xmode === 'script') && ax.test(s)) {
-                                warningAt("Dangerous comment.", line, character);
-                            }
-                            s = '';
-                            token.comment = true;
-                            break;
-
-    //      /* comment
-
-                        case '/*':
-                            if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) {
-                                warningAt("Unexpected comment.", line, character);
-                            }
-                            if (option.safe && ax.test(s)) {
-                                warningAt("ADsafe comment violation.", line, character);
-                            }
-                            for (;;) {
-                                i = s.search(lx);
-                                if (i >= 0) {
-                                    break;
-                                }
-                                if (!nextLine()) {
-                                    errorAt("Unclosed comment.", line, character);
-                                } else {
-                                    if (option.safe && ax.test(s)) {
-                                        warningAt("ADsafe comment violation.",
-                                                line, character);
-                                    }
-                                }
-                            }
-                            character += i + 2;
-                            if (s.substr(i, 1) === '/') {
-                                errorAt("Nested comment.", line, character);
-                            }
-                            s = s.substr(i + 2);
-                            token.comment = true;
-                            break;
-
-    //      /*members /*jslint /*global
-
-                        case '/*members':
-                        case '/*member':
-                        case '/*jslint':
-                        case '/*global':
-                        case '*/':
-                            return {
-                                value: t,
-                                type: 'special',
-                                line: line,
-                                character: character,
-                                from: from
-                            };
-
-                        case '':
-                            break;
-    //      /
-                        case '/':
-                            if (token.id === '/=') {
-                                errorAt(
-"A regular expression literal can be confused with '/='.", line, from);
-                            }
-                            if (prereg) {
-                                depth = 0;
-                                captures = 0;
-                                l = 0;
-                                for (;;) {
-                                    b = true;
-                                    c = s.charAt(l);
-                                    l += 1;
-                                    switch (c) {
-                                    case '':
-                                        errorAt("Unclosed regular expression.",
-                                                line, from);
-                                        return;
-                                    case '/':
-                                        if (depth > 0) {
-                                            warningAt("Unescaped '{a}'.",
-                                                    line, from + l, '/');
-                                        }
-                                        c = s.substr(0, l - 1);
-                                        q = {
-                                            g: true,
-                                            i: true,
-                                            m: true
-                                        };
-                                        while (q[s.charAt(l)] === true) {
-                                            q[s.charAt(l)] = false;
-                                            l += 1;
-                                        }
-                                        character += l;
-                                        s = s.substr(l);
-                                        q = s.charAt(0);
-                                        if (q === '/' || q === '*') {
-                                            errorAt("Confusing regular expression.",
-                                                    line, from);
-                                        }
-                                        return it('(regexp)', c);
-                                    case '\\':
-                                        c = s.charAt(l);
-                                        if (c < ' ') {
-                                            warningAt(
-"Unexpected control character in regular expression.", line, from + l);
-                                        } else if (c === '<') {
-                                            warningAt(
-"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
-                                        }
-                                        l += 1;
-                                        break;
-                                    case '(':
-                                        depth += 1;
-                                        b = false;
-                                        if (s.charAt(l) === '?') {
-                                            l += 1;
-                                            switch (s.charAt(l)) {
-                                            case ':':
-                                            case '=':
-                                            case '!':
-                                                l += 1;
-                                                break;
-                                            default:
-                                                warningAt(
-"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
-                                            }
-                                        } else {
-                                            captures += 1;
-                                        }
-                                        break;
-                                    case '|':
-                                        b = false;
-                                        break;
-                                    case ')':
-                                        if (depth === 0) {
-                                            warningAt("Unescaped '{a}'.",
-                                                    line, from + l, ')');
-                                        } else {
-                                            depth -= 1;
-                                        }
-                                        break;
-                                    case ' ':
-                                        q = 1;
-                                        while (s.charAt(l) === ' ') {
-                                            l += 1;
-                                            q += 1;
-                                        }
-                                        if (q > 1) {
-                                            warningAt(
-"Spaces are hard to count. Use {{a}}.", line, from + l, q);
-                                        }
-                                        break;
-                                    case '[':
-                                        c = s.charAt(l);
-                                        if (c === '^') {
-                                            l += 1;
-                                            if (option.regexp) {
-                                                warningAt("Insecure '{a}'.",
-                                                        line, from + l, c);
-                                            }
-                                        }
-                                        q = false;
-                                        if (c === ']') {
-                                            warningAt("Empty class.", line,
-                                                    from + l - 1);
-                                            q = true;
-                                        }
-klass:                                  do {
-                                            c = s.charAt(l);
-                                            l += 1;
-                                            switch (c) {
-                                            case '[':
-                                            case '^':
-                                                warningAt("Unescaped '{a}'.",
-                                                        line, from + l, c);
-                                                q = true;
-                                                break;
-                                            case '-':
-                                                if (q) {
-                                                    q = false;
-                                                } else {
-                                                    warningAt("Unescaped '{a}'.",
-                                                            line, from + l, '-');
-                                                    q = true;
-                                                }
-                                                break;
-                                            case ']':
-                                                if (!q) {
-                                                    warningAt("Unescaped '{a}'.",
-                                                            line, from + l - 1, '-');
-                                                }
-                                                break klass;
-                                            case '\\':
-                                                c = s.charAt(l);
-                                                if (c < ' ') {
-                                                    warningAt(
-"Unexpected control character in regular expression.", line, from + l);
-                                                } else if (c === '<') {
-                                                    warningAt(
-"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
-                                                }
-                                                l += 1;
-                                                q = true;
-                                                break;
-                                            case '/':
-                                                warningAt("Unescaped '{a}'.",
-                                                        line, from + l - 1, '/');
-                                                q = true;
-                                                break;
-                                            case '<':
-                                                if (xmode === 'script') {
-                                                    c = s.charAt(l);
-                                                    if (c === '!' || c === '/') {
-                                                        warningAt(
-"HTML confusion in regular expression '<{a}'.", line, from + l, c);
-                                                    }
-                                                }
-                                                q = true;
-                                                break;
-                                            default:
-                                                q = true;
-                                            }
-                                        } while (c);
-                                        break;
-                                    case '.':
-                                        if (option.regexp) {
-                                            warningAt("Insecure '{a}'.", line,
-                                                    from + l, c);
-                                        }
-                                        break;
-                                    case ']':
-                                    case '?':
-                                    case '{':
-                                    case '}':
-                                    case '+':
-                                    case '*':
-                                        warningAt("Unescaped '{a}'.", line,
-                                                from + l, c);
-                                        break;
-                                    case '<':
-                                        if (xmode === 'script') {
-                                            c = s.charAt(l);
-                                            if (c === '!' || c === '/') {
-                                                warningAt(
-"HTML confusion in regular expression '<{a}'.", line, from + l, c);
-                                            }
-                                        }
-                                    }
-                                    if (b) {
-                                        switch (s.charAt(l)) {
-                                        case '?':
-                                        case '+':
-                                        case '*':
-                                            l += 1;
-                                            if (s.charAt(l) === '?') {
-                                                l += 1;
-                                            }
-                                            break;
-                                        case '{':
-                                            l += 1;
-                                            c = s.charAt(l);
-                                            if (c < '0' || c > '9') {
-                                                warningAt(
-"Expected a number and instead saw '{a}'.", line, from + l, c);
-                                            }
-                                            l += 1;
-                                            low = +c;
-                                            for (;;) {
-                                                c = s.charAt(l);
-                                                if (c < '0' || c > '9') {
-                                                    break;
-                                                }
-                                                l += 1;
-                                                low = +c + (low * 10);
-                                            }
-                                            high = low;
-                                            if (c === ',') {
-                                                l += 1;
-                                                high = Infinity;
-                                                c = s.charAt(l);
-                                                if (c >= '0' && c <= '9') {
-                                                    l += 1;
-                                                    high = +c;
-                                                    for (;;) {
-                                                        c = s.charAt(l);
-                                                        if (c < '0' || c > '9') {
-                                                            break;
-                                                        }
-                                                        l += 1;
-                                                        high = +c + (high * 10);
-                                                    }
-                                                }
-                                            }
-                                            if (s.charAt(l) !== '}') {
-                                                warningAt(
-"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
-                                            } else {
-                                                l += 1;
-                                            }
-                                            if (s.charAt(l) === '?') {
-                                                l += 1;
-                                            }
-                                            if (low > high) {
-                                                warningAt(
-"'{a}' should not be greater than '{b}'.", line, from + l, low, high);
-                                            }
-                                        }
-                                    }
-                                }
-                                c = s.substr(0, l - 1);
-                                character += l;
-                                s = s.substr(l);
-                                return it('(regexp)', c);
-                            }
-                            return it('(punctuator)', t);
-
-    //      punctuator
-
-                        case '<!--':
-                            l = line;
-                            c = character;
-                            for (;;) {
-                                i = s.indexOf('--');
-                                if (i >= 0) {
-                                    break;
-                                }
-                                i = s.indexOf('<!-');
-                                if (i >= 0) {
-                                    errorAt("Nested HTML comment.",
-                                        line, character + i);
-                                }
-                                if (!nextLine()) {
-                                    errorAt("Unclosed HTML comment.", l, c);
-                                }
-                            }
-                            l = s.indexOf('<!-');
-                            if (l >= 0 && l < i) {
-                                errorAt("Nested HTML comment.",
-                                    line, character + l);
-                            }
-                            character += i;
-                            if (s[i + 2] !== '>') {
-                                errorAt("Expected -->.", line, character);
-                            }
-                            character += 3;
-                            s = s.slice(i + 3);
-                            break;
-                        case '#':
-                            if (xmode === 'html' || xmode === 'styleproperty') {
-                                for (;;) {
-                                    c = s.charAt(0);
-                                    if ((c < '0' || c > '9') &&
-                                            (c < 'a' || c > 'f') &&
-                                            (c < 'A' || c > 'F')) {
-                                        break;
-                                    }
-                                    character += 1;
-                                    s = s.substr(1);
-                                    t += c;
-                                }
-                                if (t.length !== 4 && t.length !== 7) {
-                                    warningAt("Bad hex color '{a}'.", line,
-                                        from + l, t);
-                                }
-                                return it('(color)', t);
-                            }
-                            return it('(punctuator)', t);
-                        default:
-                            if (xmode === 'outer' && c === '&') {
-                                character += 1;
-                                s = s.substr(1);
-                                for (;;) {
-                                    c = s.charAt(0);
-                                    character += 1;
-                                    s = s.substr(1);
-                                    if (c === ';') {
-                                        break;
-                                    }
-                                    if (!((c >= '0' && c <= '9') ||
-                                            (c >= 'a' && c <= 'z') ||
-                                            c === '#')) {
-                                        errorAt("Bad entity", line, from + l,
-                                        character);
-                                    }
-                                }
-                                break;
-                            }
-                            return it('(punctuator)', t);
-                        }
-                    }
-                }
-            }
-        };
-    }());
-
-
-    function addlabel(t, type) {
-
-        if (option.safe && funct['(global)'] &&
-                typeof predefined[t] !== 'boolean') {
-            warning('ADsafe global: ' + t + '.', token);
-        } else if (t === 'hasOwnProperty') {
-            warning("'hasOwnProperty' is a really bad name.");
-        }
-
-// Define t in the current function in the current scope.
-
-        if (is_own(funct, t) && !funct['(global)']) {
-            warning(funct[t] === true ?
-                "'{a}' was used before it was defined." :
-                "'{a}' is already defined.",
-                nexttoken, t);
-        }
-        funct[t] = type;
-        if (funct['(global)']) {
-            global[t] = funct;
-            if (is_own(implied, t)) {
-                warning("'{a}' was used before it was defined.", nexttoken, t);
-                delete implied[t];
-            }
-        } else {
-            scope[t] = funct;
-        }
-    }
-
-
-    function doOption() {
-        var b, obj, filter, o = nexttoken.value, t, v;
-        switch (o) {
-        case '*/':
-            error("Unbegun comment.");
-            break;
-        case '/*members':
-        case '/*member':
-            o = '/*members';
-            if (!membersOnly) {
-                membersOnly = {};
-            }
-            obj = membersOnly;
-            break;
-        case '/*jslint':
-            if (option.safe) {
-                warning("ADsafe restriction.");
-            }
-            obj = option;
-            filter = boolOptions;
-            break;
-        case '/*global':
-            if (option.safe) {
-                warning("ADsafe restriction.");
-            }
-            obj = predefined;
-            break;
-        default:
-        }
-        t = lex.token();
-loop:   for (;;) {
-            for (;;) {
-                if (t.type === 'special' && t.value === '*/') {
-                    break loop;
-                }
-                if (t.id !== '(endline)' && t.id !== ',') {
-                    break;
-                }
-                t = lex.token();
-            }
-            if (t.type !== '(string)' && t.type !== '(identifier)' &&
-                    o !== '/*members') {
-                error("Bad option.", t);
-            }
-            v = lex.token();
-            if (v.id === ':') {
-                v = lex.token();
-                if (obj === membersOnly) {
-                    error("Expected '{a}' and instead saw '{b}'.",
-                            t, '*/', ':');
-                }
-                if (t.value === 'indent' && o === '/*jslint') {
-                    b = +v.value;
-                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
-                            Math.floor(b) !== b) {
-                        error("Expected a small integer and instead saw '{a}'.",
-                                v, v.value);
-                    }
-                    obj.white = true;
-                    obj.indent = b;
-                } else if (t.value === 'maxerr' && o === '/*jslint') {
-                    b = +v.value;
-                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
-                            Math.floor(b) !== b) {
-                        error("Expected a small integer and instead saw '{a}'.",
-                                v, v.value);
-                    }
-                    obj.maxerr = b;
-                } else if (t.value === 'maxlen' && o === '/*jslint') {
-                    b = +v.value;
-                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
-                            Math.floor(b) !== b) {
-                        error("Expected a small integer and instead saw '{a}'.",
-                                v, v.value);
-                    }
-                    obj.maxlen = b;
-                } else if (v.value === 'true') {
-                    obj[t.value] = true;
-                } else if (v.value === 'false') {
-                    obj[t.value] = false;
-                } else {
-                    error("Bad option value.", v);
-                }
-                t = lex.token();
-            } else {
-                if (o === '/*jslint') {
-                    error("Missing option value.", t);
-                }
-                obj[t.value] = false;
-                t = v;
-            }
-        }
-        if (filter) {
-            assume();
-        }
-    }
-
-
-// We need a peek function. If it has an argument, it peeks that much farther
-// ahead. It is used to distinguish
-//     for ( var i in ...
-// from
-//     for ( var i = ...
-
-    function peek(p) {
-        var i = p || 0, j = 0, t;
-
-        while (j <= i) {
-            t = lookahead[j];
-            if (!t) {
-                t = lookahead[j] = lex.token();
-            }
-            j += 1;
-        }
-        return t;
-    }
-
-
-
-// Produce the next token. It looks for programming errors.
-
-    function advance(id, t) {
-        switch (token.id) {
-        case '(number)':
-            if (nexttoken.id === '.') {
-                warning(
-"A dot following a number can be confused with a decimal point.", token);
-            }
-            break;
-        case '-':
-            if (nexttoken.id === '-' || nexttoken.id === '--') {
-                warning("Confusing minusses.");
-            }
-            break;
-        case '+':
-            if (nexttoken.id === '+' || nexttoken.id === '++') {
-                warning("Confusing plusses.");
-            }
-            break;
-        }
-        if (token.type === '(string)' || token.identifier) {
-            anonname = token.value;
-        }
-
-        if (id && nexttoken.id !== id) {
-            if (t) {
-                if (nexttoken.id === '(end)') {
-                    warning("Unmatched '{a}'.", t, t.id);
-                } else {
-                    warning(
-"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
-                            nexttoken, id, t.id, t.line, nexttoken.value);
-                }
-            } else if (nexttoken.type !== '(identifier)' ||
-                            nexttoken.value !== id) {
-                warning("Expected '{a}' and instead saw '{b}'.",
-                        nexttoken, id, nexttoken.value);
-            }
-        }
-        prevtoken = token;
-        token = nexttoken;
-        for (;;) {
-            nexttoken = lookahead.shift() || lex.token();
-            if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
-                return;
-            }
-            if (nexttoken.type === 'special') {
-                doOption();
-            } else {
-                if (nexttoken.id !== '(endline)') {
-                    break;
-                }
-            }
-        }
-    }
-
-
-// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
-// is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is
-// like nud except that it is only used on the first token of a statement.
-// Having .fud makes it much easier to define JavaScript. I retained Pratt's
-// nomenclature.
-
-// .nud     Null denotation
-// .fud     First null denotation
-// .led     Left denotation
-//  lbp     Left binding power
-//  rbp     Right binding power
-
-// They are key to the parsing method called Top Down Operator Precedence.
-
-    function parse(rbp, initial) {
-        var left;
-        if (nexttoken.id === '(end)') {
-            error("Unexpected early end of program.", token);
-        }
-        advance();
-        if (option.safe && typeof predefined[token.value] === 'boolean' &&
-                (nexttoken.id !== '(' && nexttoken.id !== '.')) {
-            warning('ADsafe violation.', token);
-        }
-        if (initial) {
-            anonname = 'anonymous';
-            funct['(verb)'] = token.value;
-        }
-        if (initial === true && token.fud) {
-            left = token.fud();
-        } else {
-            if (token.nud) {
-                left = token.nud();
-            } else {
-                if (nexttoken.type === '(number)' && token.id === '.') {
-                    warning(
-"A leading decimal point can be confused with a dot: '.{a}'.",
-                            token, nexttoken.value);
-                    advance();
-                    return token;
-                } else {
-                    error("Expected an identifier and instead saw '{a}'.",
-                            token, token.id);
-                }
-            }
-            while (rbp < nexttoken.lbp) {
-                advance();
-                if (token.led) {
-                    left = token.led(left);
-                } else {
-                    error("Expected an operator and instead saw '{a}'.",
-                        token, token.id);
-                }
-            }
-        }
-        return left;
-    }
-
-
-// Functions for conformance of style.
-
-    function adjacent(left, right) {
-        left = left || token;
-        right = right || nexttoken;
-        if (option.white || xmode === 'styleproperty' || xmode === 'style') {
-            if (left.character !== right.from && left.line === right.line) {
-                warning("Unexpected space after '{a}'.", right, left.value);
-            }
-        }
-    }
-
-    function nospace(left, right) {
-        left = left || token;
-        right = right || nexttoken;
-        if (option.white && !left.comment) {
-            if (left.line === right.line) {
-                adjacent(left, right);
-            }
-        }
-    }
-
-
-    function nonadjacent(left, right) {
-        if (option.white) {
-            left = left || token;
-            right = right || nexttoken;
-            if (left.line === right.line && left.character === right.from) {
-                warning("Missing space after '{a}'.",
-

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/jslint/js.jar
----------------------------------------------------------------------
diff --git a/AlluraTesting/jslint/js.jar b/AlluraTesting/jslint/js.jar
deleted file mode 100644
index 2369f99..0000000
Binary files a/AlluraTesting/jslint/js.jar and /dev/null differ


[31/50] [abbrv] git commit: [#3060] Bump ForgeHg version

Posted by tv...@apache.org.
[#3060] Bump ForgeHg version

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/885ef999
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/885ef999
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/885ef999

Branch: refs/heads/tv/6355
Commit: 885ef9995dafe227986d1dbd15ee3005c11562dd
Parents: b8d0e6a
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Jul 10 17:55:29 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jul 10 17:55:29 2013 +0000

----------------------------------------------------------------------
 requirements-sf.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/885ef999/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index c151bbf..7ce28ae 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -4,7 +4,7 @@ akismet==0.2.0
 amqplib==0.6.1
 kombu==1.0.4
 coverage==3.5a1-20110413
-ForgeHg==0.1.13
+ForgeHg==0.1.15
 ForgePastebin==0.2.7
 mechanize==0.2.4
 mercurial==1.4.3


[08/50] [abbrv] git commit: [#5693] ticket:382 added empty line in discussion footer because paragraph processed by Markdown as a header

Posted by tv...@apache.org.
[#5693]  ticket:382 added empty line in  discussion footer because paragraph processed by Markdown as a header


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/2b6444d4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/2b6444d4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/2b6444d4

Branch: refs/heads/tv/6355
Commit: 2b6444d4b22bf203fa5c88e49c043d0fd5ec8287
Parents: ebc7e43
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Jun 28 12:49:33 2013 +0400
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed Jul 3 16:46:33 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/mail_tasks.py               |  4 +++-
 Allura/allura/templates/mail/Discussion.txt     |  2 ++
 Allura/allura/templates/mail/Ticket.txt         |  2 +-
 .../tests/functional/test_forum.py              |  1 +
 .../forgetracker/tests/functional/test_root.py  | 25 ++++++++++++++++++++
 5 files changed, 32 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b6444d4/Allura/allura/tasks/mail_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/mail_tasks.py b/Allura/allura/tasks/mail_tasks.py
index 6526987..c949497 100644
--- a/Allura/allura/tasks/mail_tasks.py
+++ b/Allura/allura/tasks/mail_tasks.py
@@ -16,6 +16,7 @@
 #       under the License.
 
 import logging
+import HTMLParser
 
 from pylons import tmpl_context as c, app_globals as g
 from bson import ObjectId
@@ -118,7 +119,8 @@ def sendmail(fromaddr, destinations, text, reply_to, subject,
                 addrs_html.append(addr)
             else:
                 addrs_multi.append(addr)
-    plain_msg = mail_util.encode_email_part(text, 'plain')
+    htmlparser = HTMLParser.HTMLParser()
+    plain_msg = mail_util.encode_email_part(htmlparser.unescape(text), 'plain')
     html_text = g.forge_markdown(email=True).convert(text)
     html_msg = mail_util.encode_email_part(html_text, 'html')
     multi_msg = mail_util.make_multipart_message(plain_msg, html_msg)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b6444d4/Allura/allura/templates/mail/Discussion.txt
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/Discussion.txt b/Allura/allura/templates/mail/Discussion.txt
index cab33d2..4702f21 100644
--- a/Allura/allura/templates/mail/Discussion.txt
+++ b/Allura/allura/templates/mail/Discussion.txt
@@ -17,5 +17,7 @@
        under the License.
 #}
 
+
 ---
+
 [{{post.thread.subject}}]({{h.absurl(post.url_paginated())}})

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b6444d4/Allura/allura/templates/mail/Ticket.txt
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/Ticket.txt b/Allura/allura/templates/mail/Ticket.txt
index 78ffc00..7c4c4da 100644
--- a/Allura/allura/templates/mail/Ticket.txt
+++ b/Allura/allura/templates/mail/Ticket.txt
@@ -20,7 +20,7 @@
 
 ---
 
-** [{{data.app_config.options.mount_point}}:#{{data.ticket_num}}] {{data.summary}}**
+** [{{data.app_config.options.mount_point}}:#{{data.ticket_num}}] {{data.summary|e}}**
 
 **Status:** {{data.status}}
 {% if data.labels.__len__() -%}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b6444d4/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index c9f7196..ffa0ca1 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -403,6 +403,7 @@ class TestForum(TestController):
         n = M.Notification.query.get(subject='[test:discussion] Test Thread')
         post = FM.ForumPost.query.get(text='This is a *test thread*')
         assert post.url_paginated() in n.text
+        assert 'This is a *test thread*\n\n\n---\n\n[Test Thread]' in n.text
         assert '[Test Thread](' in n.text
         assert 'noreply' not in n.reply_to_address, n
         assert 'testforum@discussion.test.p' in n.reply_to_address, n

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b6444d4/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 2e14fff..77e0dc7 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -23,6 +23,7 @@ import time
 import json
 import StringIO
 import allura
+import mock
 
 import PIL
 from mock import patch
@@ -40,6 +41,7 @@ from allura.lib.security import has_access
 from allura.lib import helpers as h
 from allura.lib.search import SearchError
 from allura.tests import decorators as td
+from allura.tasks import  mail_tasks
 from ming.orm.ormsession import ThreadLocalORMSession
 
 class TrackerTestController(TestController):
@@ -1879,6 +1881,29 @@ class TestFunctionalController(TrackerTestController):
         r = json.loads(r.body)
         assert_equal(r['ticket']['attachments'][0]['url'], 'http://localhost:80/p/test/bugs/1/attachment/test_root.py')
 
+    def test_html_escaping(self):
+        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
+            self.new_ticket(summary='test <h2> ticket', status='open', _milestone='2.0')
+            ThreadLocalORMSession.flush_all()
+            M.MonQTask.run_ready()
+            ThreadLocalORMSession.flush_all()
+            email = M.MonQTask.query.find(dict(task_name='allura.tasks.mail_tasks.sendmail')).first()
+            assert_equal(email.kwargs.subject, '[test:bugs] #1 test <h2> ticket')
+            text = email.kwargs.text
+            assert '** [bugs:#1] test &lt;h2&gt; ticket**' in text
+            mail_tasks.sendmail(
+                fromaddr=str(c.user._id),
+                destinations=[ str(c.user._id) ],
+                text=text,
+                reply_to=u'noreply@sf.net',
+                subject=email.kwargs.subject,
+                message_id=h.gen_message_id())
+            assert_equal(_client.sendmail.call_count, 1)
+            return_path, rcpts, body = _client.sendmail.call_args[0]
+            body = body.split('\n')
+            assert 'Subject: [test:bugs] #1 test <h2> ticket' in body
+            assert '<p><strong> <a class="alink" href="http://localhost/p/test/bugs/1/">[bugs:#1]</a> test &lt;h2&gt; ticket</strong></p>' in body
+
 
 
 class TestMilestoneAdmin(TrackerTestController):


[32/50] [abbrv] git commit: [#6220] ticket:383 embed macro (youtube support only)

Posted by tv...@apache.org.
[#6220] ticket:383 embed macro (youtube support only)


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f1938c5e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f1938c5e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f1938c5e

Branch: refs/heads/tv/6355
Commit: f1938c5e421cc7f77f1c6c02c7bf18fbfbfdd912
Parents: 885ef99
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Jul 9 15:14:47 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jul 10 21:29:19 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/macro.py               | 11 +++++++++++
 Allura/allura/lib/markdown_extensions.py |  6 +++---
 Allura/allura/lib/utils.py               | 11 +++++++++++
 Allura/allura/tests/test_globals.py      |  7 +++++++
 Allura/allura/tests/test_utils.py        | 12 ++++++++++++
 requirements-common.txt                  |  1 +
 6 files changed, 45 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1938c5e/Allura/allura/lib/macro.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/macro.py b/Allura/allura/lib/macro.py
index 27c0d35..aac20ff 100644
--- a/Allura/allura/lib/macro.py
+++ b/Allura/allura/lib/macro.py
@@ -20,6 +20,8 @@ import random
 import shlex
 import logging
 import traceback
+import oembed
+import jinja2
 from operator import attrgetter
 
 import pymongo
@@ -374,3 +376,12 @@ def members(limit=20):
     response = users.display(users=output, over_limit=over_limit)
     return response
 
+@macro()
+def embed(url=None):
+    consumer = oembed.OEmbedConsumer()
+    endpoint = oembed.OEmbedEndpoint('http://www.youtube.com/oembed', ['http://*.youtube.com/*', 'https://*.youtube.com/*'])
+    consumer.addEndpoint(endpoint)
+    try:
+        return jinja2.Markup('<div class="grid-20">%s</div>' % consumer.embed(url)['html'])
+    except oembed.OEmbedNoEndpoint as e:
+        return '[[embed url=%s]]' % url

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1938c5e/Allura/allura/lib/markdown_extensions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/markdown_extensions.py b/Allura/allura/lib/markdown_extensions.py
index be2805a..4879bf4 100644
--- a/Allura/allura/lib/markdown_extensions.py
+++ b/Allura/allura/lib/markdown_extensions.py
@@ -24,11 +24,11 @@ from pylons import request
 from BeautifulSoup import BeautifulSoup
 
 import markdown
-import feedparser
 
 from . import macro
 from . import helpers as h
 from allura import model as M
+from allura.lib.utils import ForgeHTMLSanitizer
 
 log = logging.getLogger(__name__)
 
@@ -288,9 +288,9 @@ class HTMLSanitizer(markdown.postprocessors.Postprocessor):
 
     def run(self, text):
         try:
-            p = feedparser._HTMLSanitizer('utf-8')
+            p = ForgeHTMLSanitizer('utf-8')
         except TypeError: # $@%## pre-released versions from SOG
-            p = feedparser._HTMLSanitizer('utf-8', '')
+            p = ForgeHTMLSanitizer('utf-8', '')
         p.feed(text.encode('utf-8'))
         return unicode(p.output(), 'utf-8')
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1938c5e/Allura/allura/lib/utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index a88511c..d6796e5 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -43,6 +43,7 @@ from webhelpers.html import literal
 from webob import exc
 from pygments.formatters import HtmlFormatter
 from setproctitle import getproctitle
+from feedparser import _HTMLSanitizer
 
 from ew import jinja2_ew as ew
 from ming.utils import LazyProperty
@@ -494,3 +495,13 @@ def serve_file(fp, filename, content_type, last_modified=None, cache_expires=Non
         return tg.request.environ['wsgi.file_wrapper'](fp, block_size)
     else:
         return iter(lambda: fp.read(block_size), '')
+
+
+class ForgeHTMLSanitizer(_HTMLSanitizer):
+
+    def unknown_starttag(self, tag, attrs):
+        if 'iframe' in self.acceptable_elements:
+            self.acceptable_elements.remove('iframe')
+        if (tag == 'iframe') and (dict(attrs).get('src', '').startswith('http://www.youtube.com/embed/')):
+            self.acceptable_elements.append('iframe')
+        _HTMLSanitizer.unknown_starttag(self, tag, attrs)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1938c5e/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 429ca27..60860a5 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -256,6 +256,13 @@ def test_macro_include_extra_br():
     assert html.strip().replace('\n', '') == expected_html, html
 
 
+def test_macro_embed():
+    r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=kOLpSPEA72U]]')
+    assert '''<div class="grid-20"><iframe height="270" src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" width="480"></iframe></div>''' in r
+    r = g.markdown_wiki.convert('[[embed url=http://vimeo.com/46163090]]')
+    assert_equal(r, '<div class="markdown_content"><p>[[embed url=http://vimeo.com/46163090]]</p></div>')
+
+
 def test_markdown_toc():
     with h.push_context('test', neighborhood='Projects'):
         r = g.markdown_wiki.convert("""[TOC]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1938c5e/Allura/allura/tests/test_utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_utils.py b/Allura/allura/tests/test_utils.py
index bd44ca2..494e893 100644
--- a/Allura/allura/tests/test_utils.py
+++ b/Allura/allura/tests/test_utils.py
@@ -229,3 +229,15 @@ class TestCodeStats(unittest.TestCase):
         assert stats['line_count'] == 8
         assert stats['data_line_count'] == 5
         assert stats['code_size'] == len(blob.text)
+
+class TestHTMLSanitizer(unittest.TestCase):
+
+    def test_html_sanitizer_iframe(self):
+        p = utils.ForgeHTMLSanitizer('utf-8', '')
+        p.feed('<div><iframe></iframe></div>')
+        assert_equal(p.output(), '<div></div>')
+
+    def test_html_sanitizer_youtube_iframe(self):
+        p = utils.ForgeHTMLSanitizer('utf-8', '')
+        p.feed('<div><iframe src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed"></iframe></div>')
+        assert_equal(p.output(),'<div><iframe src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed"></iframe></div>')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1938c5e/requirements-common.txt
----------------------------------------------------------------------
diff --git a/requirements-common.txt b/requirements-common.txt
index 8dd3b5b..d496708 100644
--- a/requirements-common.txt
+++ b/requirements-common.txt
@@ -36,6 +36,7 @@ pysolr==2.1.0-beta
 python-dateutil==1.5
 python-magic==0.4.3
 python-openid==2.2.5
+python-oembed==0.2.1
 pytidylib==0.2.1
 # for taskd proc name switching
 setproctitle==1.1.7


[02/50] [abbrv] git commit: [#6412] ticket:385 Allow only [-_a-zA-Z0-9]+ in short urls

Posted by tv...@apache.org.
[#6412] ticket:385 Allow only [-_a-zA-Z0-9]+ in short urls


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/733c0b22
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/733c0b22
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/733c0b22

Branch: refs/heads/tv/6355
Commit: 733c0b2287f16dcd27b46933c216f082b78bdb6e
Parents: faf6a39
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jun 28 13:06:45 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Jul 1 16:46:28 2013 +0000

----------------------------------------------------------------------
 ForgeShortUrl/forgeshorturl/main.py                  | 12 +++++++++++-
 ForgeShortUrl/forgeshorturl/tests/functional/test.py | 10 ++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/733c0b22/ForgeShortUrl/forgeshorturl/main.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/main.py b/ForgeShortUrl/forgeshorturl/main.py
index d26c69e..3081e81 100644
--- a/ForgeShortUrl/forgeshorturl/main.py
+++ b/ForgeShortUrl/forgeshorturl/main.py
@@ -196,6 +196,16 @@ class RootController(BaseController):
 
 
 class ShortURLAdminController(DefaultAdminController):
+
+    shorturl_validators = All(
+        validators.NotEmpty(),
+        validators.Regex(
+            r'^[-_a-zA-Z0-9]+$',
+            messages={'invalid': 'must include only letters, numbers, dashes and underscores.'}
+        )
+    )
+
+
     def __init__(self, app):
         self.app = app
 
@@ -215,7 +225,7 @@ class ShortURLAdminController(DefaultAdminController):
     @expose('jinja:forgeshorturl:templates/form.html')
     @validate(dict(full_url=All(validators.URL(add_http=True),
                                 validators.NotEmpty()),
-                   short_url=validators.NotEmpty()))
+                   short_url=shorturl_validators))
     def add(self, short_url='', full_url='', description='', private='off',
             update=False, **kw):
         if update:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/733c0b22/ForgeShortUrl/forgeshorturl/tests/functional/test.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/tests/functional/test.py b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
index e162b38..8f0fc64 100644
--- a/ForgeShortUrl/forgeshorturl/tests/functional/test.py
+++ b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
@@ -97,6 +97,16 @@ class TestRootController(TestController):
         r = self.app.post('/admin/url/add', params=d)
         assert 'exists' in self.webflash(r)
 
+    def test_shorturl_chars_restrictions(self):
+        d = dict(short_url='', full_url='http://sf.net/')
+        r = self.app.post('/admin/url/add', params=d)
+        assert ShortUrl.query.find(dict(app_config_id=c.app.config._id)).count() == 0
+        assert 'Please enter a value' in self.webflash(r)
+        d = dict(short_url='g*', full_url='http://sf.net/')
+        r = self.app.post('/admin/url/add', params=d)
+        assert ShortUrl.query.find(dict(app_config_id=c.app.config._id)).count() == 0
+        assert 'Short url: must include only letters, numbers, dashes and underscores.' in self.webflash(r)
+
     def test_shorturl_remove(self):
         self.app.post('/admin/url/add',
                 params=dict(short_url='g', full_url='http://google.com/'))


[12/50] [abbrv] git commit: [#6056] Catch IndexError on invalid wiki page version

Posted by tv...@apache.org.
[#6056] Catch IndexError on invalid wiki page version

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/fe6f4b26
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/fe6f4b26
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/fe6f4b26

Branch: refs/heads/tv/6355
Commit: fe6f4b26fe5b35f4daf0aba6a293e1a81d0445eb
Parents: 8516efb
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jul 2 00:49:06 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:48:41 2013 +0000

----------------------------------------------------------------------
 ForgeWiki/forgewiki/wiki_main.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/fe6f4b26/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 650d271..9cc0ffc 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -439,7 +439,7 @@ class PageController(BaseController, FeedController):
         if not version: return self.page
         try:
             return self.page.get_version(version)
-        except ValueError:
+        except (ValueError, IndexError):
             return None
 
     @expose()


[07/50] [abbrv] git commit: [#5693] ticket:382 unescape text email for sendsimplemail

Posted by tv...@apache.org.
[#5693]  ticket:382 unescape text email for sendsimplemail


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a20153ca
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a20153ca
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a20153ca

Branch: refs/heads/tv/6355
Commit: a20153caa3a23dfd0f903afd5805208170926b90
Parents: 2b6444d
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Jun 28 15:11:01 2013 +0400
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed Jul 3 16:46:33 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/mail_tasks.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a20153ca/Allura/allura/tasks/mail_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/mail_tasks.py b/Allura/allura/tasks/mail_tasks.py
index c949497..8e7eb97 100644
--- a/Allura/allura/tasks/mail_tasks.py
+++ b/Allura/allura/tasks/mail_tasks.py
@@ -154,7 +154,8 @@ def sendsimplemail(
             fromaddr = u'noreply@in.sf.net'
         else:
             fromaddr = user.email_address_header()
-    plain_msg = mail_util.encode_email_part(text, 'plain')
+    htmlparser = HTMLParser.HTMLParser()
+    plain_msg = mail_util.encode_email_part(htmlparser.unescape(text), 'plain')
     html_text = g.forge_markdown(email=True).convert(text)
     html_msg = mail_util.encode_email_part(html_text, 'html')
     multi_msg = mail_util.make_multipart_message(plain_msg, html_msg)


[04/50] [abbrv] git commit: [#6317] Fixed nav menu dropdown style

Posted by tv...@apache.org.
[#6317] Fixed nav menu dropdown style

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ff0459c9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ff0459c9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ff0459c9

Branch: refs/heads/tv/6355
Commit: ff0459c97101348e5487ae5e908d89d3a3678ad0
Parents: 7b386c7
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 1 20:48:20 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jul 2 14:00:08 2013 +0000

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css | 55 +++++++++++++++++++------
 1 file changed, 42 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ff0459c9/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index b08330b..91c6fb5 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -982,7 +982,7 @@ a.btn:active {
 .btn-bar, #top_nav {
   display: block;
   clear: both;
-  padding: 10px;
+  padding: 0px 10px 0 10px;
   -moz-border-radius: 4px;
   -webkit-border-radius: 4px;
   -o-border-radius: 4px;
@@ -2967,6 +2967,8 @@ ul.dropdown li {
     float: left;
     vertical-align: middle;
     zoom: 1;
+    padding-top: 10px;
+    padding-bottom: 10px;
 }
 
 ul.dropdown li.hover,
@@ -2979,35 +2981,62 @@ ul.dropdown li:hover {
 ul.dropdown ul {
     visibility: hidden;
     position: absolute;
-    top:50px;
-    left: 0;
+    top:70px;
     z-index: 598;
     background-color: #ffffff;
-    -moz-border-radius: 5px;
-    -webkit-border-radius: 5px;
-    -o-border-radius: 5px;
-    -ms-border-radius: 5px;
-    -khtml-border-radius: 5px;
-    border-radius: 5px;
     border-width: 1px;
     border-style: solid;
-    border-color: #E6EFC2;
+    border-color: #dddddd;
+    -moz-border-bottom-left-radius: 5px;
+    -webkit-border-bottom-left-radius: 5px;
+    -o-border-bottom-left-radius: 5px;
+    -ms-border-bottom-left-radius: 5px;
+    -khtml-border-bottom-left-radius: 5px;
+    border-bottom-left-radius: 5px;
+    -moz-border-bottom-right-radius: 5px;
+    -webkit-border-bottom-right-radius: 5px;
+    -o-border-bottom-right-radius: 5px;
+    -ms-border-bottom-right-radius: 5px;
+    -khtml-border-bottom-right-radius: 5px;
+    border-bottom-right-radius: 5px;
+    border-top: 0;
+    -moz-box-shadow: 2px 2px 5px rgba(0,0,0,0.4);
+    -webkit-box-shadow: 2px 2px 5px rgba(0,0,0,0.4);
+    -o-box-shadow: 2px 2px 5px rgba(0,0,0,0.4);
+    box-shadow: 2px 2px 5px rgba(0,0,0,0.4)
 }
 
 ul.dropdown ul li {
     float: left;
-    margin: 5px;
-    min-width: 100px;
+    margin: 0;
+    padding: 0;
 }
 
 ul.dropdown li:hover > ul {
     visibility: visible;
 }
 ul.dropdown ul li a {
-    height: 20px !important;
+    white-space: nowrap;
+    height: auto !important;
     font-weight:normal;
+    padding: 5px;
+    border-top: 1px solid #eee;
+}
+ul.dropdown ul li:first-child a {
+    border-top: 0;
 }
 li.selected,
 ul.dropdown ul li.selected a{
     font-weight:bold;
 }
+ul.dropdown ul li a:hover {
+    background-color: #09c;
+    color: white !important;
+}
+#top_nav ul.dropdown ul li,
+#top_nav ul.dropdown ul li a {
+    float: none;
+    display: block;
+    text-align: left;
+    margin-right: 0;
+}


[24/50] [abbrv] git commit: [#4213] ticket:344 refactored and fixed tests

Posted by tv...@apache.org.
[#4213]  ticket:344 refactored and fixed tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/d8ed95c4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/d8ed95c4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/d8ed95c4

Branch: refs/heads/tv/6355
Commit: d8ed95c4df193ee74e288140749ac785916f0a55
Parents: 3439474
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri May 31 14:23:40 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 06:08:00 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/import_support.py           | 14 ++++++--------
 .../forgetracker/tests/unit/test_ticket_model.py      |  6 +++---
 2 files changed, 9 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d8ed95c4/ForgeTracker/forgetracker/import_support.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/import_support.py b/ForgeTracker/forgetracker/import_support.py
index 1ea391b..6970004 100644
--- a/ForgeTracker/forgetracker/import_support.py
+++ b/ForgeTracker/forgetracker/import_support.py
@@ -50,14 +50,16 @@ class ResettableStream(object):
         self.buf_size = header_size if header_size >= 0 else self.HEADER_BUF_SIZE
         self.buf_pos = 0
         self.stream_pos = 0
-        
-    def read(self, size=-1):
+
+    def _read_header(self):
         if self.buf is None:
             data = self.fp.read(self.buf_size)
             self.buf = StringIO(data)
             self.buf_len = len(data)
             self.stream_pos = self.buf_len
-        
+
+    def read(self, size=-1):
+        self._read_header()
         data = ''
         if self.buf_pos < self.stream_pos:
             data = self.buf.read(size)
@@ -71,11 +73,7 @@ class ResettableStream(object):
         return data
 
     def seek(self, pos):
-        if self.buf is None:
-            data = self.fp.read(self.buf_size)
-            self.buf = StringIO(data)
-            self.buf_len = len(data)
-
+        self._read_header()
         if self.stream_pos > self.buf_len:
             assert False, 'Started reading stream body, cannot reset pos'
         self.buf.seek(pos)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d8ed95c4/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
index c53afad..145bc7c 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
@@ -271,9 +271,9 @@ class TestTicketModel(TrackerTestWithModel):
             ticket.summary = 'test ticket'
             ticket.description = 'test description'
         assert_equal(len(ticket.attachments), 0)
-        f = urllib2.urlopen('http://sourceforge.net/apps/trac/sourceforge/raw-attachment/ticket/204/SF%20display%20error.JPG')
-        TicketAttachment.save_attachment('filename.txt', ResettableStream(f),
+        f = urllib2.urlopen('file://%s' % __file__)
+        TicketAttachment.save_attachment('test_ticket_model.py', ResettableStream(f),
                                             artifact_id=ticket._id)
         ThreadLocalORMSession.flush_all()
         assert_equal(len(ticket.attachments), 1)
-        assert_equal(ticket.attachments.first().filename, 'filename.txt')
+        assert_equal(ticket.attachments.first().filename, 'test_ticket_model.py')


[35/50] [abbrv] git commit: [#4659] ticket:381 refactored multiple attachments

Posted by tv...@apache.org.
[#4659]  ticket:381 refactored multiple attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/870f5aad
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/870f5aad
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/870f5aad

Branch: refs/heads/tv/6355
Commit: 870f5aad4b4c2c5680429d6f649df47a6bb7adc1
Parents: 087b9ec
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Jul 5 21:03:24 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 14:35:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            | 20 ++++----------------
 Allura/allura/lib/widgets/discuss.py            |  2 +-
 Allura/allura/model/artifact.py                 |  7 +++++++
 Allura/allura/model/discuss.py                  |  6 ++++++
 Allura/allura/model/notification.py             | 18 +++++++-----------
 Allura/allura/templates/widgets/edit_post.html  |  4 +---
 ForgeTracker/forgetracker/tracker_main.py       |  8 +-------
 .../forgetracker/widgets/ticket_form.py         |  2 +-
 .../forgewiki/tests/functional/test_root.py     |  2 +-
 ForgeWiki/forgewiki/wiki_main.py                |  8 +-------
 10 files changed, 30 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 97a08e5..45b0124 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -202,10 +202,7 @@ class ThreadController(BaseController, FeedController):
 
         file_info = kw.get('file_info', None)
         p = self.thread.add_post(**kw)
-        if isinstance(file_info, list):
-            map(p.add_attachment, file_info)
-        else:
-            p.add_attachment(file_info)
+        p.add_multiple_attach(file_info)
         if self.thread.artifact:
             self.thread.artifact.mod_date = datetime.utcnow()
         flash('Message posted')
@@ -278,10 +275,7 @@ class PostController(BaseController):
             require_access(self.post, 'moderate')
             post_fields = self.W.edit_post.to_python(kw, None)
             file_info = post_fields.pop('file_info', None)
-            if isinstance(file_info, list):
-                map(self.post.add_attachment, file_info)
-            else:
-                self.post.add_attachment(file_info)
+            self.post.add_multiple_attach(file_info)
             for k,v in post_fields.iteritems():
                 try:
                     setattr(self.post, k, v)
@@ -326,10 +320,7 @@ class PostController(BaseController):
         require_access(self.thread, 'post')
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
-        if isinstance(file_info, list):
-            map(p.add_attachment, file_info)
-        else:
-            p.add_attachment(file_info)
+        p.add_multiple_attach(file_info)
         redirect(request.referer)
 
     @h.vardec
@@ -364,10 +355,7 @@ class PostController(BaseController):
     @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
-        if isinstance(file_info, list):
-            map(self.post.add_attachment, file_info)
-        else:
-            self.post.add_attachment(file_info)
+        self.post.add_multiple_attach(file_info)
         redirect(request.referer)
 
     @expose()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index 96a48b3..e62a993 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -160,9 +160,9 @@ class EditPost(ff.ForgeForm):
         for r in ffw.MarkdownEdit(name='text').resources(): yield r
         yield ew.JSScript('''$(document).ready(function () {
             $("a.attachment_form_add_button").click(function(evt){
-                evt.preventDefault();
                 $(this).hide();
                 $(".attachment_form_fields", this.parentNode).show();
+                evt.preventDefault();
             });
             $("a.cancel_edit_post").click(function(evt){
                 $("textarea", this.parentNode).val($("input.original_value", this.parentNode).val());

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 05d7c14..6fbe0f5 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -386,6 +386,13 @@ class Artifact(MappedClass):
         """
         return self.get_discussion_thread()[0]
 
+    def add_multiple_attach(self, file_info):
+        if not isinstance(file_info, list):
+            file_info = [file_info]
+        for attach in file_info:
+            if hasattr(attach, 'file'):
+                self.attach(attach.filename, attach.file, content_type=attach.type)
+
     def attach(self, filename, fp, **kw):
         """Attach a file to this Artifact.
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 7699d33..b15d03d 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -527,6 +527,12 @@ class Post(Message, VersionedArtifact, ActivityObject):
         return self.attachment_class().query.find(dict(
             post_id=self._id, type='attachment'))
 
+    def add_multiple_attach(self, file_info):
+        if isinstance(file_info, list):
+            map(self.add_attachment, file_info)
+        else:
+            self.add_attachment(file_info)
+
     def add_attachment(self, file_info):
         if hasattr(file_info, 'file'):
             mime_type = file_info.type

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 1d03eef..d4b0755 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -148,17 +148,13 @@ class Notification(MappedClass):
             file_info = kwargs.pop('file_info', None)
             if file_info is not None:
                 text = "%s\n\n\nAttachment:" % text
-                if isinstance(file_info, list):
-                    for attach in file_info:
-                        attach.file.seek(0, 2)
-                        bytecount = attach.file.tell()
-                        attach.file.seek(0)
-                        text = "%s %s (%s; %s) " % (text, attach.filename, h.do_filesizeformat(bytecount), attach.type)
-                else:
-                    file_info.file.seek(0, 2)
-                    bytecount = file_info.file.tell()
-                    file_info.file.seek(0)
-                    text = "%s %s (%s; %s) " % (text, file_info.filename, h.do_filesizeformat(bytecount), file_info.type)
+                if not isinstance(file_info, list):
+                    file_info = [file_info]
+                for attach in file_info:
+                    attach.file.seek(0, 2)
+                    bytecount = attach.file.tell()
+                    attach.file.seek(0)
+                    text = "%s %s (%s; %s) " % (text, attach.filename, h.do_filesizeformat(bytecount), attach.type)
 
             subject = post.subject or ''
             if post.parent_id and not subject.lower().startswith('re:'):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/Allura/allura/templates/widgets/edit_post.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/edit_post.html b/Allura/allura/templates/widgets/edit_post.html
index 0fe22a7..38ad0b3 100644
--- a/Allura/allura/templates/widgets/edit_post.html
+++ b/Allura/allura/templates/widgets/edit_post.html
@@ -26,13 +26,11 @@
     {{widget.display_field(widget.fields.text)}}
     <input type="hidden" class="original_value" value="{{value.text}}">
     <span class="arw"><span></span></span><br/>
-    <div class="attachment_form_fields" style="display:none; padding: 5px 0;">
-      <input type="file" class="text" multiple="True" name="{{att_name}}" {% if att_id %}id="{{att_id}}"{% endif %}/>
-    </div>
     <div style="clear:both"></div>
     <input type="submit" value="{{submit_text}}"/>
     <a href="#" class="btn link cancel_edit_post">Cancel</a> &nbsp;
     <a href="#" class="btn link attachment_form_add_button">Add attachments</a>
+    <input type="file" class="text attachment_form_fields" style="display:none" multiple="True" name="{{att_name}}" {% if att_id %}id="{{att_id}}"{% endif %}/>
   {% if widget.antispam %}{% for fld in g.antispam.extra_fields() %}
   {{fld}}{% endfor %}{% endif %}
   </form>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 3d2d02d..9037c4d 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1293,13 +1293,7 @@ class TicketController(BaseController, FeedController):
 
         if 'attachment' in post_data:
             attachment = post_data['attachment']
-            if isinstance(attachment, list):
-                for attach in attachment:
-                    self.ticket.attach(attach.filename, attach.file, content_type=attach.type)
-            else:
-                if hasattr(attachment, 'file'):
-                    self.ticket.attach(
-                        attachment.filename, attachment.file, content_type=attachment.type)
+            self.ticket.add_multiple_attach(attachment)
         for cf in c.app.globals.custom_fields or []:
             if 'custom_fields.' + cf.name in post_data:
                 value = post_data['custom_fields.' + cf.name]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/ForgeTracker/forgetracker/widgets/ticket_form.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/ticket_form.py b/ForgeTracker/forgetracker/widgets/ticket_form.py
index edee7e5..f022177 100644
--- a/ForgeTracker/forgetracker/widgets/ticket_form.py
+++ b/ForgeTracker/forgetracker/widgets/ticket_form.py
@@ -136,9 +136,9 @@ class TicketForm(GenericTicketForm):
         yield ew.JSScript('''
         $(function(){
             $('#show_attach').click(function(evt) {
-                evt.preventDefault();
                 $('#view_attach').show();
                 $('#show_attach').hide();
+                evt.preventDefault();
             });
             $('form').submit(function() {
                 var value = $('div.tagsinput div input').val();

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 05c0dd1..3312ed7 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -348,7 +348,7 @@ class TestRootController(TestController):
         response = self.app.get('/wiki/tést/')
         assert 'test_root.py' in response
 
-    def test_attach_two_fiels(self):
+    def test_attach_two_files(self):
         self.app.post(
             '/wiki/tést/update',
             params={

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/870f5aad/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 88f1102..76f66f6 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -649,13 +649,7 @@ class PageController(BaseController, FeedController):
         if not self.page:
             raise exc.HTTPNotFound
         require_access(self.page, 'edit')
-        if isinstance(file_info, list):
-            for attach in file_info:
-                if hasattr(attach, 'file'):
-                    self.page.attach(attach.filename, attach.file, content_type=attach.type)
-        else:
-            if hasattr(file_info, 'file'):
-                self.page.attach(file_info.filename, file_info.file, content_type=file_info.type)
+        self.page.add_multiple_attach(file_info)
         redirect(request.referer)
 
     @expose()


[03/50] [abbrv] git commit: [#6411] ticket:384 Don't restrict URL shortener urls to HTTP GET only

Posted by tv...@apache.org.
[#6411] ticket:384 Don't restrict URL shortener urls to HTTP GET only


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7b386c7b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7b386c7b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7b386c7b

Branch: refs/heads/tv/6355
Commit: 7b386c7bfef275bbc90faa902c324d0094245fb4
Parents: 733c0b2
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jun 28 09:39:29 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Jul 1 21:46:05 2013 +0000

----------------------------------------------------------------------
 ForgeShortUrl/forgeshorturl/main.py               | 18 +++++++-----------
 .../forgeshorturl/tests/functional/test.py        |  9 +++++++++
 2 files changed, 16 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7b386c7b/ForgeShortUrl/forgeshorturl/main.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/main.py b/ForgeShortUrl/forgeshorturl/main.py
index 3081e81..c8e16c0 100644
--- a/ForgeShortUrl/forgeshorturl/main.py
+++ b/ForgeShortUrl/forgeshorturl/main.py
@@ -181,17 +181,13 @@ class RootController(BaseController):
 
     @expose()
     def _lookup(self, pname, *remainder):
-        if request.method == 'GET':
-            query = {'app_config_id': c.app.config._id,
-                     'short_name': pname}
-            if not has_access(c.app, 'view_private'):
-                query['private'] = False
-            short_url = ShortUrl.query.find(query).first()
-            if short_url:
-                redirect(short_url.full_url)
-
-        flash("We're sorry but we weren't able "
-              "to process this request.", "error")
+        query = {'app_config_id': c.app.config._id,
+                 'short_name': pname}
+        if not has_access(c.app, 'view_private'):
+            query['private'] = False
+        short_url = ShortUrl.query.find(query).first()
+        if short_url:
+            redirect(short_url.full_url)
         raise exc.HTTPNotFound()
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7b386c7b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/tests/functional/test.py b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
index 8f0fc64..997050f 100644
--- a/ForgeShortUrl/forgeshorturl/tests/functional/test.py
+++ b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
@@ -44,6 +44,15 @@ class TestRootController(TestController):
         redirected = self.app.get('/url/test').follow()
         assert redirected.request.url == 'http://www.google.com/'
 
+    def test_shorturl_http_head(self):
+        response = self.app.get('/admin/url/add')
+        response.form['short_url'] = 'test'
+        response.form['full_url'] = 'http://www.google.com/'
+        response.form.submit()
+        r = self.app.head('/url/test')
+        assert r.status_int == 302
+        assert r.headers['Location'] == 'http://www.google.com/'
+
     def test_shorturl_update(self):
         response = self.app.get('/admin/url/add')
         response.form['short_url'] = 'g'


[45/50] [abbrv] git commit: [#4122] rename AlluraTesting dir to AlluraTest, to match the module name below

Posted by tv...@apache.org.
[#4122] rename AlluraTesting dir to AlluraTest, to match the module name below

This makes the coverage output from ./run_tests better


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/37e91c91
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/37e91c91
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/37e91c91

Branch: refs/heads/tv/6355
Commit: 37e91c9136b973d84eb7309858ddb1e20f05c586
Parents: c2ac016
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon May 6 18:24:09 2013 -0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Jul 11 21:30:45 2013 +0000

----------------------------------------------------------------------
 AlluraTest/LICENSE                              |  234 +
 AlluraTest/alluratest/__init__.py               |   16 +
 AlluraTest/alluratest/controller.py             |  183 +
 AlluraTest/alluratest/test_syntax.py            |   95 +
 AlluraTest/alluratest/validation.py             |  321 +
 AlluraTest/jslint/Makefile                      |    7 +
 AlluraTest/jslint/env-js.jar                    |  Bin 0 -> 1110999 bytes
 AlluraTest/jslint/fulljslint.js                 | 5688 +++++++++++++++++
 AlluraTest/jslint/js.jar                        |  Bin 0 -> 871260 bytes
 AlluraTest/jslint/jslint.js                     | 5729 ++++++++++++++++++
 AlluraTest/jslint/rhino.js                      |   41 +
 AlluraTest/setup.py                             |   39 +
 AlluraTest/twill-tests/README                   |   19 +
 AlluraTest/twill-tests/create_repo.twill        |   47 +
 AlluraTest/twill-tests/edit_wiki_page.twill     |   36 +
 AlluraTest/twill-tests/login.twill              |   27 +
 AlluraTest/twill-tests/new_issue.twill          |   36 +
 AlluraTest/twill-tests/smoke-front-page.twill   |   20 +
 AlluraTest/twill-tests/smoke-project-home.twill |   20 +
 .../twill-tests/smoke-tracker-search.twill      |   20 +
 AlluraTest/twill-tests/smoke-tracker.twill      |   20 +
 AlluraTest/twill-tests/smoke-user-profile.twill |   20 +
 AlluraTest/twill-tests/smoke-wiki.twill         |   20 +
 AlluraTesting/LICENSE                           |  234 -
 AlluraTesting/alluratest/__init__.py            |   16 -
 AlluraTesting/alluratest/controller.py          |  183 -
 AlluraTesting/alluratest/test_syntax.py         |   95 -
 AlluraTesting/alluratest/validation.py          |  321 -
 AlluraTesting/jslint/Makefile                   |    7 -
 AlluraTesting/jslint/env-js.jar                 |  Bin 1110999 -> 0 bytes
 AlluraTesting/jslint/fulljslint.js              | 5688 -----------------
 AlluraTesting/jslint/js.jar                     |  Bin 871260 -> 0 bytes
 AlluraTesting/jslint/jslint.js                  | 5729 ------------------
 AlluraTesting/jslint/rhino.js                   |   41 -
 AlluraTesting/setup.py                          |   39 -
 AlluraTesting/twill-tests/README                |   19 -
 AlluraTesting/twill-tests/create_repo.twill     |   47 -
 AlluraTesting/twill-tests/edit_wiki_page.twill  |   36 -
 AlluraTesting/twill-tests/login.twill           |   27 -
 AlluraTesting/twill-tests/new_issue.twill       |   36 -
 .../twill-tests/smoke-front-page.twill          |   20 -
 .../twill-tests/smoke-project-home.twill        |   20 -
 .../twill-tests/smoke-tracker-search.twill      |   20 -
 AlluraTesting/twill-tests/smoke-tracker.twill   |   20 -
 .../twill-tests/smoke-user-profile.twill        |   20 -
 AlluraTesting/twill-tests/smoke-wiki.twill      |   20 -
 rat-excludes.txt                                |    2 +-
 run_clonedigger                                 |    2 +-
 run_tests                                       |    2 +-
 49 files changed, 12641 insertions(+), 12641 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/LICENSE
----------------------------------------------------------------------
diff --git a/AlluraTest/LICENSE b/AlluraTest/LICENSE
new file mode 100644
index 0000000..15f71ee
--- /dev/null
+++ b/AlluraTest/LICENSE
@@ -0,0 +1,234 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
+
+AlluraTest SUBCOMPONENTS:
+
+AlluraTest includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source code
+for the these subcomponents is subject to the terms and conditions of the
+following licenses.
+
+For jslint.js, in directory
+jslint/
+
+   Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
+
+   Permission is hereby granted, free of charge, to any person obtaining a copy of
+   this software and associated documentation files (the "Software"), to deal in
+   the Software without restriction, including without limitation the rights to
+   use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+   of the Software, and to permit persons to whom the Software is 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 Software.
+
+   The Software shall be used for Good, not Evil.
+
+   THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+   SOFTWARE.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/alluratest/__init__.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/__init__.py b/AlluraTest/alluratest/__init__.py
new file mode 100644
index 0000000..144e298
--- /dev/null
+++ b/AlluraTest/alluratest/__init__.py
@@ -0,0 +1,16 @@
+#       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.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/alluratest/controller.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/controller.py b/AlluraTest/alluratest/controller.py
new file mode 100644
index 0000000..95d9b4b
--- /dev/null
+++ b/AlluraTest/alluratest/controller.py
@@ -0,0 +1,183 @@
+#       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.
+
+"""Unit and functional test suite for allura."""
+import os
+import urllib
+
+import mock
+import beaker.session
+from formencode import variabledecode
+from paste.deploy import loadapp
+from paste.deploy.converters import asbool
+from paste.script.appinstall import SetupCommand
+from pylons import tmpl_context as c, app_globals as g
+from pylons import url, request, response, session
+import tg
+from webtest import TestApp
+from webob import Request, Response
+import ew
+from ming.orm import ThreadLocalORMSession
+import ming.orm
+
+from allura import model as M
+import allura.lib.security
+from allura.lib.app_globals import Globals
+from allura.lib import helpers as h
+from allura.websetup.schema import REGISTRY
+#from allura.lib.custom_middleware import environ as ENV, MagicalC
+from .validation import ValidatingTestApp
+
+DFL_APP_NAME = 'main_without_authn'
+
+# these are all helpers & base classes, and should never
+# be considered test cases when imported into some test module
+__test__ = False
+
+
+def get_config_file(config=None):
+    if not config:
+        config = 'test.ini'
+
+    try:
+        conf_dir = tg.config.here
+    except AttributeError:
+        conf_dir = os.getcwd()
+    return os.path.join(conf_dir, config)
+
+
+def setup_basic_test(config=None, app_name=DFL_APP_NAME):
+    '''Create clean environment for running tests'''
+    try:
+        conf_dir = tg.config.here
+    except AttributeError:
+        conf_dir = os.getcwd()
+    ew.TemplateEngine.initialize({})
+    test_file = os.path.join(conf_dir, get_config_file(config))
+    cmd = SetupCommand('setup-app')
+    cmd.run([test_file])
+
+    # run all tasks, e.g. indexing from bootstrap operations
+    while M.MonQTask.run_ready('setup'):
+        ThreadLocalORMSession.flush_all()
+setup_basic_test.__test__ = False  # sometimes __test__ above isn't sufficient
+
+
+def setup_functional_test(config=None, app_name=DFL_APP_NAME):
+    '''Create clean environment for running tests.  Also return WSGI test app'''
+    config = get_config_file(config)
+    setup_basic_test(config, app_name)
+    conf_dir = tg.config.here
+    wsgiapp = loadapp('config:%s#%s' % (config, app_name),
+                      relative_to=conf_dir)
+    return wsgiapp
+setup_functional_test.__test__ = False  # sometimes __test__ above isn't sufficient
+
+
+def setup_unit_test():
+    try:
+        while True:
+            REGISTRY.cleanup()
+    except:
+        pass
+    REGISTRY.prepare()
+    REGISTRY.register(ew.widget_context, ew.core.WidgetContext('http', ew.ResourceManager()))
+    REGISTRY.register(g, Globals())
+    REGISTRY.register(c, mock.Mock())
+    REGISTRY.register(url, lambda:None)
+    REGISTRY.register(request, Request.blank('/', remote_addr='1.1.1.1'))
+    REGISTRY.register(response, Response())
+    REGISTRY.register(session, beaker.session.SessionObject({}))
+    REGISTRY.register(allura.credentials, allura.lib.security.Credentials())
+    c.memoize_cache = {}
+    c.queued_messages = None
+    c.model_cache = None
+    ThreadLocalORMSession.close_all()
+setup_unit_test.__test__ = False  # sometimes __test__ above isn't sufficient
+
+
+def setup_global_objects():
+    setup_unit_test()
+    h.set_context('test', 'wiki', neighborhood='Projects')
+    c.user = M.User.query.get(username='test-admin')
+
+
+class TestController(object):
+
+    application_under_test = 'main'
+    validate_skip = False
+
+    def setUp(self):
+        """Method called by nose before running each test"""
+        self.app = ValidatingTestApp(setup_functional_test(app_name=self.application_under_test))
+        if self.validate_skip:
+            self.app.validate_skip = self.validate_skip
+        if asbool(tg.config.get('smtp.mock')):
+            self.smtp_mock = mock.patch('allura.lib.mail_util.smtplib.SMTP')
+            self.smtp_mock.start()
+
+    def tearDown(self):
+        """Method called by nose after running each test"""
+        if asbool(tg.config.get('smtp.mock')):
+            self.smtp_mock.stop()
+
+    def webflash(self, response):
+        "Extract webflash content from response."
+        return urllib.unquote(response.cookies_set.get('webflash', ''))
+
+
+class TestRestApiBase(TestController):
+
+    def setUp(self):
+        super(TestRestApiBase, self).setUp()
+        setup_global_objects()
+#        h.set_context('test', 'home')
+        self.user = M.User.query.get(username='test-admin')
+        self.token = M.ApiToken(user_id=self.user._id)
+        ming.orm.session(self.token).flush()
+
+    def set_api_token(self, token):
+        self.token = token
+
+    def _api_getpost(self, method, path, api_key=None, api_timestamp=None, api_signature=None,
+                 wrap_args=None, **params):
+        if wrap_args:
+            params = {wrap_args: params}
+        params = variabledecode.variable_encode(params, add_repetitions=False)
+        if api_key: params['api_key'] = api_key
+        if api_timestamp: params['api_timestamp'] = api_timestamp
+        if api_signature: params['api_signature'] = api_signature
+        params = self.token.sign_request(path, params)
+
+        fn = self.app.post if method=='POST' else self.app.get
+
+        response = fn(
+            str(path),
+            params=params,
+            status=[200, 302, 400, 403, 404])
+        if response.status_int == 302:
+            return response.follow()
+        else:
+            return response
+
+    def api_get(self, path, api_key=None, api_timestamp=None, api_signature=None,
+                 wrap_args=None, **params):
+        return self._api_getpost('GET', path, api_key, api_timestamp, api_signature, wrap_args, **params)
+
+    def api_post(self, path, api_key=None, api_timestamp=None, api_signature=None,
+                 wrap_args=None, **params):
+        return self._api_getpost('POST', path, api_key, api_timestamp, api_signature, wrap_args, **params)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/alluratest/test_syntax.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/test_syntax.py b/AlluraTest/alluratest/test_syntax.py
new file mode 100644
index 0000000..b394798
--- /dev/null
+++ b/AlluraTest/alluratest/test_syntax.py
@@ -0,0 +1,95 @@
+#       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.
+
+import os.path
+from glob import glob
+from subprocess import Popen, PIPE
+import sys
+
+toplevel_dir = os.path.abspath(os.path.dirname(__file__) + "/../..")
+
+def run(cmd):
+    proc = Popen(cmd, shell=True, cwd=toplevel_dir, stdout=PIPE, stderr=PIPE)
+    # must capture & reprint stdount, so that nosetests can capture it
+    (stdout, stderr) = proc.communicate()
+    sys.stdout.write(stdout)
+    sys.stderr.write(stderr)
+    return proc.returncode
+
+find_py = "find Allura Forge* -name '*.py'"
+
+# a recepe from itertools doc
+from itertools import izip_longest
+def grouper(n, iterable, fillvalue=None):
+    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
+    args = [iter(iterable)] * n
+    return izip_longest(fillvalue=fillvalue, *args)
+
+def test_pyflakes():
+    # skip some that aren't critical errors
+    skips = [
+        'imported but unused',
+        'redefinition of unused',
+        'assigned to but never used',
+        '__version__',
+    ]
+    proc = Popen(find_py, shell=True, cwd=toplevel_dir, stdout=PIPE, stderr=PIPE)
+    (find_stdout, stderr) = proc.communicate()
+    sys.stderr.write(stderr)
+    assert proc.returncode == 0, proc.returncode
+
+    # run pyflakes in batches, so it doesn't take tons of memory
+    error = False
+    all_files = [f for f in find_stdout.split('\n')
+                 if '/migrations/' not in f and f.strip()]
+    for files in grouper(20, all_files, fillvalue=''):
+        cmd = "pyflakes " + ' '.join(files) + " | grep -v '" + "' | grep -v '".join(skips) + "'"
+        #print 'Command was: %s' % cmd
+        retval = run(cmd)
+        if retval != 1:
+            print
+            #print 'Command was: %s' % cmd
+            print 'Returned %s' % retval
+            error = True
+
+    if error:
+        raise Exception('pyflakes failure, see stdout')
+
+def test_no_now():
+    if run(find_py + " | xargs grep '\.now(' ") not in [1,123]:
+        raise Exception("These should use .utcnow()")
+    if run(find_py + " | xargs grep '\.fromtimestamp(' ") not in [1,123]:
+        raise Exception("These should use .utcfromtimestamp()")
+
+def test_no_prints():
+    skips = [
+        '/tests/',
+        'Allura/allura/command/',
+        'Allura/ldap-setup.py',
+        'Allura/ldap-userconfig.py',
+        'Allura/ez_setup/',
+        'Allura/allura/lib/AsciiDammit.py',
+        '/scripts/',
+        'Allura/allura/lib/import_api.py',
+        'ForgeSVN/setup.py',
+    ]
+    if run(find_py + " | grep -v '" + "' | grep -v '".join(skips) + "' | xargs grep -v '^ *#' | grep 'print ' | grep -E -v '(pprint|#pragma: ?printok)' ") != 1:
+        raise Exception("These should use logging instead of print")
+
+def test_no_tabs():
+    if run(find_py + " | xargs grep '	' ") not in [1,123]:
+        raise Exception('These should not use tab chars')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/alluratest/validation.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/validation.py b/AlluraTest/alluratest/validation.py
new file mode 100644
index 0000000..235d7c0
--- /dev/null
+++ b/AlluraTest/alluratest/validation.py
@@ -0,0 +1,321 @@
+# -*- coding: utf-8 -*-
+
+#       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.
+
+"""
+Functions to syntax-validate output content
+"""
+from os import path, environ, getcwd
+import os
+import sys
+import logging
+import tempfile
+import subprocess
+import json
+import urllib2
+import re
+
+import tg
+import mock
+import beaker.session
+from paste.deploy import loadapp
+from paste.script.appinstall import SetupCommand
+from pylons import tmpl_context as c, app_globals as g
+from pylons import url, request, response, session
+import webtest
+from webtest import TestApp
+from webob import Request, Response
+from nose.tools import ok_, assert_true, assert_false
+from poster.encode import multipart_encode
+from poster.streaminghttp import register_openers
+from ming.utils import LazyProperty
+
+from allura.lib import utils
+
+ENABLE_CONTENT_VALIDATION = False
+# By default we want to run only validations which are fast,
+# but on special test hosts - all.
+COMPLETE_TESTS_HOST = 'sb-forge-4039'
+
+log = logging.getLogger(__name__)
+
+class Config(object):
+    "Config to encapsulate flexible/complex test enabled/disabled rules."
+    _instance = None
+
+    def __init__(self):
+        self.ini_config = None
+        pass
+
+    @classmethod
+    def instance(cls):
+        if not cls._instance:
+            cls._instance = cls()
+        return cls._instance
+
+    @LazyProperty
+    def test_ini(self):
+        if not self.ini_config:
+            from . import controller
+            import ConfigParser
+            conf = ConfigParser.ConfigParser({'validate_html5': 'false', 'validate_inlinejs': 'false'})
+            conf.read(controller.get_config_file())
+            self.ini_config = conf
+        return self.ini_config
+
+    @LazyProperty
+    def hostname(self):
+        if os.path.exists('/etc/soghost'):
+            with open('/etc/soghost') as fp:
+                return fp.read().strip()
+
+    def validation_enabled(self, val_type):
+        env_var = os.getenv('ALLURA_VALIDATION')
+        if env_var == 'all':
+            return True
+        elif env_var == 'none':
+            return False
+        elif env_var is not None:
+            return val_type in env_var.split(',')
+
+        if self.hostname == COMPLETE_TESTS_HOST:
+            return True
+
+        enabled = self.test_ini.getboolean('validation', 'validate_' + val_type)
+        return enabled
+
+    def fail_on_validation(self, val_type):
+        env_var = os.getenv('ALLURA_VALIDATION')
+        if env_var == 'all':
+            return True
+        if self.hostname == COMPLETE_TESTS_HOST:
+            return True
+        return ENABLE_CONTENT_VALIDATION
+
+
+def report_validation_error(val_name, filename, message):
+    message = '%s Validation errors (%s):\n%s\n' % (val_name, filename, message)
+    if Config.instance().fail_on_validation(val_name):
+        ok_(False, message)
+    else:
+        sys.stderr.write('=' * 40 + '\n' + message)
+
+def dump_to_file(prefix, html):
+    f = tempfile.NamedTemporaryFile(prefix=prefix, delete=False)
+    f.write(html)
+    f.close()
+    return f.name
+
+def validate_html(html_or_response):
+        if hasattr(html_or_response, 'body'):
+            html = html_or_response.body
+        else:
+            html = html_or_response
+
+        html = html.lstrip()
+
+        if html.startswith('<!DOCTYPE html>'):
+            return validate_html5(html)
+        else:
+            assert False, 'Non-valid HTML: ' + html[:100] + '...'
+
+def validate_json(json_or_response):
+        if hasattr(json_or_response, 'body'):
+            j = json_or_response.body
+        else:
+            j = json_or_response
+
+        try:
+            obj = json.loads(j)
+        except Exception, e:
+            ok_(False, "Couldn't validate JSON: " + str(e) + ':' + j[:100] + '...')
+
+        return obj
+
+def validate_html5(html_or_response):
+        if hasattr(html_or_response, 'body'):
+            html = html_or_response.body
+        else:
+            html = html_or_response
+        register_openers()
+        params = [("out","text"),("content",html)]
+        datagen, headers = multipart_encode(params)
+        request = urllib2.Request("http://html5.validator.nu/", datagen, headers)
+        count = 3
+        while True:
+            try:
+                resp = urllib2.urlopen(request, timeout=3).read()
+                break
+            except:
+                resp = "Couldn't connect to validation service to check the HTML"
+                count -= 1
+                if count == 0:
+                    sys.stderr.write('WARNING: ' + resp + '\n')
+                    break
+
+        resp = resp.replace('“','"').replace('”','"').replace('–','-')
+
+        ignored_errors = [
+            'Required attributes missing on element "object"',
+            'Stray end tag "embed".',
+            'Stray end tag "param".',
+            r'Bad value .+? for attribute "onclick" on element "input": invalid return',
+        ]
+        for ignore in ignored_errors:
+            resp = re.sub('Error: ' + ignore, 'Ignoring: ' + ignore, resp)
+
+        if 'Error:' in resp:
+            fname = dump_to_file('html5-', html)
+            message = resp.decode('ascii','ignore')
+            report_validation_error('html5', fname, message)
+
+
+def validate_html5_chunk(html):
+        """ When you don't have a html & body tags - this adds it"""
+        # WebTest doesn't like HTML fragments without doctype,
+        # so we output them sometimes for fragments, which is hack.
+        # Unhack it here.
+        doctype = '<!DOCTYPE html>'
+        if html.startswith(doctype):
+            html = html[len(doctype):]
+
+        html = '''<!DOCTYPE html>
+        <html>
+        <head><title></title></head>
+        <body>
+        %s
+        </body></html>''' % html
+        return validate_html5(html)
+
+def validate_js(html_or_response):
+        if hasattr(html_or_response, 'body'):
+            if html_or_response.status_int != 200:
+                return
+            html = html_or_response.body
+        else:
+            html = html_or_response
+        basedir = path.dirname(path.abspath(__file__))
+        jslint_dir = basedir + '/../jslint'
+        fname = dump_to_file('jslint-', html)
+        cmd = 'java -jar ' + jslint_dir + '/js.jar '+ jslint_dir +'/jslint.js ' + fname
+        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        stdout, stderr = p.communicate(html)
+        if stdout.startswith('jslint: No problems found'):
+            os.unlink(fname)
+            return
+        stdout = stdout.decode('UTF-8', 'replace')
+        msg = '\n'.join(repr(s) for s in stdout.split('\n') if s)
+        report_validation_error('js', fname, msg)
+
+def validate_page(html_or_response):
+    if Config.instance().validation_enabled('html5'):
+        validate_html(html_or_response)
+    if Config.instance().validation_enabled('inlinejs'):
+        validate_js(html_or_response)
+
+class AntiSpamTestApp(TestApp):
+
+    def post(self, *args, **kwargs):
+        if kwargs.pop('antispam', False):
+            antispam = utils.AntiSpam()
+            params = {
+                'timestamp': antispam.timestamp_text,
+                'spinner': antispam.spinner_text,
+                antispam.enc('honey0'): '',
+                antispam.enc('honey1'): '',
+            }
+            for k, v in kwargs['params'].iteritems():
+                params[antispam.enc(k)] = v
+            kwargs['params'] = params
+        return super(AntiSpamTestApp, self).post(*args, **kwargs)
+
+class PostParamCheckingTestApp(AntiSpamTestApp):
+
+    def _validate_params(self, params, method):
+        if not params:
+            return
+        # params can be a list or a dict
+        if hasattr(params, 'items'):
+            params = params.items()
+        for k, v in params:
+            if not isinstance(k, basestring):
+                raise TypeError('%s key %s is %s, not str' % (method, k, type(k)))
+            if not isinstance(v, (basestring, webtest.app.File)):
+                raise TypeError('%s key %s has value %s of type %s, not str. ' % (method, k, v, type(v)))
+
+    def get(self, *args, **kwargs):
+        self._validate_params(kwargs.get('params'), 'get')
+        return super(PostParamCheckingTestApp, self).get(*args, **kwargs)
+
+    def post(self, *args, **kwargs):
+        self._validate_params(kwargs.get('params'), 'post')
+        return super(PostParamCheckingTestApp, self).post(*args, **kwargs)
+
+class ValidatingTestApp(PostParamCheckingTestApp):
+
+    # Subclasses may set this to True to skip validation altogether
+    validate_skip = False
+
+    def _validate(self, resp, method, val_params):
+        """Perform validation on webapp response. This handles responses of
+        various types and forms."""
+        if resp.status_int != 200:
+            return
+
+        content = resp.body
+        content_type = resp.headers['Content-Type']
+        if content_type.startswith('text/html'):
+            if val_params['validate_chunk']:
+                validate_html5_chunk(content)
+            else:
+                validate_page(resp)
+        elif content_type.split(';', 1)[0] in ('text/plain', 'text/x-python', 'application/octet-stream'):
+            pass
+        elif content_type.startswith('application/json'):
+            validate_json(content)
+        elif content_type.startswith(('application/x-javascript','application/javascript', 'text/javascript')):
+            validate_js(content)
+        elif content_type.startswith('application/xml'):
+            import feedparser
+            d = feedparser.parse(content)
+            assert d.bozo == 0, 'Non-wellformed feed'
+        elif content_type.startswith('image/'):
+            pass
+        else:
+            assert False, 'Unexpected output content type: ' + content_type
+
+    def _get_validation_params(self, kw):
+        "Separate validation params from normal TestApp methods params."
+        params = {}
+        for k in ('validate_skip', 'validate_chunk'):
+            params[k] = kw.pop(k, False)
+        return params, kw
+
+    def get(self, *args, **kw):
+        val_params, kw = self._get_validation_params(kw)
+        resp = super(ValidatingTestApp, self).get(*args, **kw)
+        if not self.validate_skip and not val_params['validate_skip']:
+            self._validate(resp, 'get', val_params)
+        return resp
+
+    def post(self, *args, **kw):
+        val_params, kw = self._get_validation_params(kw)
+        resp = super(ValidatingTestApp, self).post(*args, **kw)
+        if not self.validate_skip and not val_params['validate_skip']:
+            self._validate(resp, 'post', val_params)
+        return resp

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/jslint/Makefile
----------------------------------------------------------------------
diff --git a/AlluraTest/jslint/Makefile b/AlluraTest/jslint/Makefile
new file mode 100644
index 0000000..7efd72e
--- /dev/null
+++ b/AlluraTest/jslint/Makefile
@@ -0,0 +1,7 @@
+# Make single-file jslint script out of  main script (from jslint.com,
+# patched by us to tweak its behavior, as it configurability leaves much
+# to be desired) and Rhino support module. Needed because Rhino accepts
+# only single file as script.
+
+jslint.js: fulljslint.js rhino.js
+	cat $^ >$@

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/jslint/env-js.jar
----------------------------------------------------------------------
diff --git a/AlluraTest/jslint/env-js.jar b/AlluraTest/jslint/env-js.jar
new file mode 100644
index 0000000..072891a
Binary files /dev/null and b/AlluraTest/jslint/env-js.jar differ


[13/50] [abbrv] git commit: [#6056] Fixed "unexpected keyword arguments" from repo controllers

Posted by tv...@apache.org.
[#6056] Fixed "unexpected keyword arguments" from repo controllers

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/8516efb1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/8516efb1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/8516efb1

Branch: refs/heads/tv/6355
Commit: 8516efb1d9392f92e17c947251f9898051962aa9
Parents: 96df73a
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jul 2 00:13:07 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:48:41 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8516efb1/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index c8d852b..d9331c7 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -86,7 +86,7 @@ class RepoRootController(BaseController, FeedController):
 
     @with_trailing_slash
     @expose('jinja:allura:templates/repo/forks.html')
-    def forks(self):
+    def forks(self, **kw):
 
         links = []
         if c.app.repo.forks:
@@ -99,7 +99,7 @@ class RepoRootController(BaseController, FeedController):
         return dict(links=links)
 
     @expose()
-    def refresh(self):
+    def refresh(self, **kw):
         allura.tasks.repo_tasks.refresh.post()
         if request.referer:
             flash('Repository is being refreshed')
@@ -109,7 +109,7 @@ class RepoRootController(BaseController, FeedController):
 
     @with_trailing_slash
     @expose('jinja:allura:templates/repo/fork.html')
-    def fork(self, project_id=None, mount_point=None, mount_label=None):
+    def fork(self, project_id=None, mount_point=None, mount_label=None, **kw):
         # this shows the form and handles the submission
         security.require_authenticated()
         if not c.app.forkable: raise exc.HTTPNotFound
@@ -159,7 +159,7 @@ class RepoRootController(BaseController, FeedController):
 
     @without_trailing_slash
     @expose('jinja:allura:templates/repo/request_merge.html')
-    def request_merge(self, branch=None):
+    def request_merge(self, branch=None, **kw):
         security.require(security.has_access(c.app.repo, 'admin'))
         c.form = self.mr_widget
         if branch is None:
@@ -193,7 +193,7 @@ class RepoRootController(BaseController, FeedController):
 
     @without_trailing_slash
     @expose('jinja:allura:templates/repo/commit_browser.html')
-    def commit_browser(self):
+    def commit_browser(self, **kw):
         if not c.app.repo or c.app.repo.status != 'ready':
             return dict(status='not_ready')
         # if c.app.repo.count() > 2000:
@@ -205,7 +205,7 @@ class RepoRootController(BaseController, FeedController):
 
     @without_trailing_slash
     @expose('json:')
-    def commit_browser_data(self):
+    def commit_browser_data(self, **kw):
         head_ids = [ head.object_id for head in c.app.repo.get_heads() ]
         commit_ids = [c.app.repo.rev_to_commit_id(r) for r in c.app.repo.log(head_ids, id_only=True)]
         log.info('Grab %d commit objects by ID', len(commit_ids))
@@ -307,7 +307,7 @@ class MergeRequestsController(object):
 
     @expose('jinja:allura:templates/repo/merge_requests.html')
     @validate(mr_filter)
-    def index(self, status=None):
+    def index(self, status=None, **kw):
         status = status or ['open']
         requests = c.app.repo.merge_requests_by_statuses(*status)
         c.mr_filter = self.mr_filter
@@ -333,7 +333,7 @@ class MergeRequestController(object):
         if self.req is None: raise exc.HTTPNotFound
 
     @expose('jinja:allura:templates/repo/merge_request.html')
-    def index(self, page=0, limit=250):
+    def index(self, page=0, limit=250, **kw):
         c.thread = self.thread_widget
         c.log_widget = self.log_widget
         c.mr_dispose_form = self.mr_dispose_form
@@ -349,7 +349,7 @@ class MergeRequestController(object):
     @expose()
     @require_post()
     @validate(mr_dispose_form)
-    def save(self, status=None):
+    def save(self, status=None, **kw):
         security.require(
             security.has_access(self.req, 'write'), 'Write access required')
         self.req.status = status
@@ -423,7 +423,7 @@ class CommitBrowser(BaseController):
     @expose('jinja:allura:templates/repo/commit.html')
     @validate(dict(page=validators.Int(if_empty=0),
                    limit=validators.Int(if_empty=DEFAULT_PAGE_LIMIT)))
-    def index(self, page=0, limit=DEFAULT_PAGE_LIMIT):
+    def index(self, page=0, limit=DEFAULT_PAGE_LIMIT, **kw):
         c.revision_widget = self.revision_widget
         c.page_list = self.page_list
         result = dict(commit=self._commit)
@@ -442,7 +442,7 @@ class CommitBrowser(BaseController):
         return result
 
     @expose('jinja:allura:templates/repo/commit_basic.html')
-    def basic(self):
+    def basic(self, **kw):
         c.revision_widget = self.revision_widget
         result = dict(commit=self._commit)
         if self._commit:
@@ -560,7 +560,7 @@ class TreeBrowser(BaseController, DispatchIndex):
 
     @expose()
     @validate(subscribe_form)
-    def subscribe(self, subscribe=None, unsubscribe=None):
+    def subscribe(self, subscribe=None, unsubscribe=None, **kw):
         if subscribe:
             M.Mailbox.subscribe()
         elif unsubscribe:
@@ -599,7 +599,7 @@ class FileBrowser(BaseController):
                 )
 
     @expose()
-    def raw(self):
+    def raw(self, **kw):
         content_type = self._blob.content_type.encode('utf-8')
         filename = self._blob.name.encode('utf-8')
         response.headers['Content-Type'] = ''
@@ -612,7 +612,7 @@ class FileBrowser(BaseController):
             'Content-Disposition', 'attachment;filename=' + filename)
         return iter(self._blob)
 
-    def diff(self, commit, fmt=None):
+    def diff(self, commit, fmt=None, **kw):
         try:
             path, filename = os.path.split(self._blob.path())
             a_ci = c.app.repo.commit(commit)


[06/50] [abbrv] git commit: [#5693] ticket:397 Escape forum topic in notifications

Posted by tv...@apache.org.
[#5693] ticket:397 Escape forum topic in notifications


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ff44014a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ff44014a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ff44014a

Branch: refs/heads/tv/6355
Commit: ff44014a528b069e10cbfe51d2bc1981d924d455
Parents: a20153c
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jul 3 09:39:26 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed Jul 3 16:46:33 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/mail/Discussion.txt        |  2 +-
 .../forgediscussion/tests/functional/test_forum.py | 17 ++++++++++++++++-
 2 files changed, 17 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ff44014a/Allura/allura/templates/mail/Discussion.txt
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/Discussion.txt b/Allura/allura/templates/mail/Discussion.txt
index 4702f21..21bfb51 100644
--- a/Allura/allura/templates/mail/Discussion.txt
+++ b/Allura/allura/templates/mail/Discussion.txt
@@ -20,4 +20,4 @@
 
 ---
 
-[{{post.thread.subject}}]({{h.absurl(post.url_paginated())}})
+[{{post.thread.subject|e}}]({{h.absurl(post.url_paginated())}})

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ff44014a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index ffa0ca1..a9288c8 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -26,7 +26,7 @@ from email.mime.multipart import MIMEMultipart
 
 import pkg_resources
 from pylons import tmpl_context as c, app_globals as g
-from nose.tools import assert_equal
+from nose.tools import assert_equal, assert_in
 
 from allura import model as M
 from allura.tasks import mail_tasks
@@ -408,6 +408,21 @@ class TestForum(TestController):
         assert 'noreply' not in n.reply_to_address, n
         assert 'testforum@discussion.test.p' in n.reply_to_address, n
 
+    def test_notifications_escaping(self):
+        r = self.app.get('/discussion/create_topic/')
+        f = r.html.find('form', {'action':'/p/test/discussion/save_new_topic'})
+        params = dict()
+        inputs = f.findAll('input')
+        for field in inputs:
+            if field.has_key('name'):
+                params[field['name']] = field.has_key('value') and field['value'] or ''
+        params[f.find('textarea')['name']] = 'Post text'
+        params[f.find('select')['name']] = 'testforum'
+        params[f.find('input', {'style':'width: 90%'})['name']] = "this is <h2> o'clock"
+        r = self.app.post('/discussion/save_new_topic', params=params)
+        n = M.Notification.query.find(dict(subject="[test:discussion] this is <h2> o'clock")).first()
+        assert_in('---\n\n[this is &lt;h2&gt; o&#39;clock]', n.text)
+
     @mock.patch('allura.model.discuss.g.spam_checker')
     def test_anonymous_post(self, spam_checker):
         spam_checker.check.return_value = True


[11/50] [abbrv] git commit: [#6056] Bump ForgePastebin version

Posted by tv...@apache.org.
[#6056] Bump ForgePastebin version

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/6901e8ae
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/6901e8ae
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/6901e8ae

Branch: refs/heads/tv/6355
Commit: 6901e8ae77d01250faab1436fa9b1c062e5cbb68
Parents: 9f0c841
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Jul 3 14:36:32 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:48:41 2013 +0000

----------------------------------------------------------------------
 requirements-sf.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6901e8ae/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index 6c052c6..c151bbf 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -5,7 +5,7 @@ amqplib==0.6.1
 kombu==1.0.4
 coverage==3.5a1-20110413
 ForgeHg==0.1.13
-ForgePastebin==0.2.6
+ForgePastebin==0.2.7
 mechanize==0.2.4
 mercurial==1.4.3
 MySQL-python==1.2.3c1


[17/50] [abbrv] git commit: [#5103] ticket:374 default branch option for git

Posted by tv...@apache.org.
[#5103]  ticket:374 default branch option for git


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/806c3feb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/806c3feb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/806c3feb

Branch: refs/heads/tv/6355
Commit: 806c3febfa5d6ee7ae83d2505cdf6b5b8da06bab
Parents: 4358701
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Wed Jun 19 13:33:01 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:57:49 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/repository.py                 | 12 ++++++++
 Allura/allura/model/repository.py               |  1 +
 .../allura/templates/repo/default_branch.html   | 31 ++++++++++++++++++++
 ForgeGit/forgegit/git_main.py                   | 18 +++++++++++-
 .../tests/functional/test_controllers.py        | 16 ++++++++++
 ForgeGit/forgegit/tests/test_git_app.py         |  7 ++++-
 6 files changed, 83 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/806c3feb/Allura/allura/lib/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/repository.py b/Allura/allura/lib/repository.py
index 5798b21..7aa7399 100644
--- a/Allura/allura/lib/repository.py
+++ b/Allura/allura/lib/repository.py
@@ -20,6 +20,7 @@ import shutil
 from urllib import quote
 
 from pylons import tmpl_context as c, app_globals as g
+from pylons import request
 from tg import expose, redirect, url
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from bson import ObjectId
@@ -215,3 +216,14 @@ class RepoAdminController(DefaultAdminController):
     @require_post()
     def set_extensions(self, **post_data):
         self.repo.additional_viewable_extensions = post_data['additional_viewable_extensions']
+
+    @without_trailing_slash
+    @expose('jinja:allura:templates/repo/default_branch.html')
+    def set_default_branch_name(self, branch_name=None, **kw):
+        if (request.method == 'POST') and branch_name:
+            self.repo.default_branch_name = branch_name
+            redirect(request.referer)
+        else:
+            return dict(app=self.app,
+                        default_branch_name=self.app.default_branch_name)
+

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/806c3feb/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 3431e41..5492ef3 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -262,6 +262,7 @@ class Repository(Artifact, ActivityObject):
     branches = FieldProperty(S.Deprecated)
     repo_tags = FieldProperty(S.Deprecated)
     upstream_repo = FieldProperty(dict(name=str,url=str))
+    default_branch_name = FieldProperty(str)
 
     def __init__(self, **kw):
         if 'name' in kw and 'tool' in kw:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/806c3feb/Allura/allura/templates/repo/default_branch.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/default_branch.html b/Allura/allura/templates/repo/default_branch.html
new file mode 100644
index 0000000..c524001
--- /dev/null
+++ b/Allura/allura/templates/repo/default_branch.html
@@ -0,0 +1,31 @@
+{#-
+       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.
+-#}
+
+<form action="{{c.project.url()}}admin/{{app.config.options.mount_point}}/set_default_branch_name" method="POST">
+    <label class="grid-13">Default branch name:</label>
+        <div class="grid-13">
+            <input type="text" name="branch_name" id="branch_name" {% if default_branch_name %} value="{{default_branch_name}}"{% endif %}/>
+    </div>
+    <div class="grid-13">&nbsp;</div>
+    <hr>
+    <div class="grid-13">&nbsp;</div>
+    <div class="grid-13">
+        <input type="submit" value="Save">
+    </div>
+</form>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/806c3feb/ForgeGit/forgegit/git_main.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/git_main.py b/ForgeGit/forgegit/git_main.py
index 85219f8..2ba63bc 100644
--- a/ForgeGit/forgegit/git_main.py
+++ b/ForgeGit/forgegit/git_main.py
@@ -31,6 +31,7 @@ from allura import model as M
 from allura.controllers.repository import RepoRootController, RefsController, CommitsController
 from allura.controllers.repository import MergeRequestsController, RepoRestController
 from allura.lib.repository import RepositoryApp
+from allura.app import SitemapEntry
 
 # Local imports
 from . import model as GM
@@ -50,7 +51,6 @@ class ForgeGitApp(RepositoryApp):
     """
     ordinal=2
     forkable=True
-    default_branch_name='master'
 
     def __init__(self, project, config):
         super(ForgeGitApp, self).__init__(project, config)
@@ -64,6 +64,22 @@ class ForgeGitApp(RepositoryApp):
     def repo(self):
         return GM.Repository.query.get(app_config_id=self.config._id)
 
+    @property
+    def default_branch_name(self):
+        default_branch_name = getattr(self.repo, 'default_branch_name', 'master')
+        if not default_branch_name:
+            default_branch_name = 'master'
+        return default_branch_name
+
+    def admin_menu(self):
+        links = []
+        links.append(SitemapEntry(
+                'Set default branch',
+                c.project.url()+'admin/'+self.config.options.mount_point+'/' + 'set_default_branch_name',
+                className='admin_modal'))
+        links += super(ForgeGitApp, self).admin_menu()
+        return links
+
     def install(self, project):
         '''Create repo object for this tool'''
         super(ForgeGitApp, self).install(project)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/806c3feb/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index c4ac325..841d0fb 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -354,6 +354,22 @@ class TestRootController(_TestCase):
         download_link = [a for a in links if a.text == 'Download Snapshot'][0]
         assert_equal(download_link.get('href'), '/p/test/testgit-index/ci/master/tarball?path=/index')
 
+    def test_default_branch(self):
+        assert_equal(c.app.default_branch_name, 'master')
+        c.app.repo.default_branch_name = 'zz'
+        assert_equal(c.app.default_branch_name, 'zz')
+        r = self.app.get('/p/test/src-git/').follow().follow()
+        assert '<span class="scm-branch-label">zz</span>' in r
+
+    def test_set_default_branch(self):
+        r = self.app.get('/p/test/admin/src-git/set_default_branch_name')
+        assert '<input type="text" name="branch_name" id="branch_name"  value="master"/>' in r
+        self.app.post('/p/test/admin/src-git/set_default_branch_name', params={'branch_name':'zz'})
+        r = self.app.get('/p/test/admin/src-git/set_default_branch_name')
+        assert '<input type="text" name="branch_name" id="branch_name"  value="zz"/>' in r
+        r = self.app.get('/p/test/src-git/').follow().follow()
+        assert '<span class="scm-branch-label">zz</span>' in r
+
 
 class TestRestController(_TestCase):
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/806c3feb/ForgeGit/forgegit/tests/test_git_app.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/test_git_app.py b/ForgeGit/forgegit/tests/test_git_app.py
index f315600..5d745b4 100644
--- a/ForgeGit/forgegit/tests/test_git_app.py
+++ b/ForgeGit/forgegit/tests/test_git_app.py
@@ -39,7 +39,12 @@ class TestGitApp(unittest.TestCase):
         ThreadLocalORMSession.close_all()
 
     def test_admin_menu(self):
-        assert_equals(len(c.app.admin_menu()), 4)
+        assert_equals(len(c.app.admin_menu()), 5)
+
+    def test_default_branch(self):
+        assert c.app.default_branch_name == 'master'
+        c.app.repo.default_branch_name = 'zz'
+        assert c.app.default_branch_name == 'zz'
 
     def test_uninstall(self):
         from allura import model as M


[40/50] [abbrv] [#4122] rename AlluraTesting dir to AlluraTest, to match the module name below

Posted by tv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/jslint/jslint.js
----------------------------------------------------------------------
diff --git a/AlluraTesting/jslint/jslint.js b/AlluraTesting/jslint/jslint.js
deleted file mode 100644
index 4b2ddcc..0000000
--- a/AlluraTesting/jslint/jslint.js
+++ /dev/null
@@ -1,5729 +0,0 @@
-// jslint.js
-// 2010-08-05
-
-/*
-Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is 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 Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/*
-    JSLINT is a global function. It takes two parameters.
-
-        var myResult = JSLINT(source, option);
-
-    The first parameter is either a string or an array of strings. If it is a
-    string, it will be split on '\n' or '\r'. If it is an array of strings, it
-    is assumed that each string represents one line. The source can be a
-    JavaScript text, or HTML text, or a Konfabulator text.
-
-    The second parameter is an optional object of options which control the
-    operation of JSLINT. Most of the options are booleans: They are all are
-    optional and have a default value of false.
-
-    If it checks out, JSLINT returns true. Otherwise, it returns false.
-
-    If false, you can inspect JSLINT.errors to find out the problems.
-    JSLINT.errors is an array of objects containing these members:
-
-    {
-        line      : The line (relative to 0) at which the lint was found
-        character : The character (relative to 0) at which the lint was found
-        reason    : The problem
-        evidence  : The text line in which the problem occurred
-        raw       : The raw message before the details were inserted
-        a         : The first detail
-        b         : The second detail
-        c         : The third detail
-        d         : The fourth detail
-    }
-
-    If a fatal error was found, a null will be the last element of the
-    JSLINT.errors array.
-
-    You can request a Function Report, which shows all of the functions
-    and the parameters and vars that they use. This can be used to find
-    implied global variables and other problems. The report is in HTML and
-    can be inserted in an HTML <body>.
-
-        var myReport = JSLINT.report(limited);
-
-    If limited is true, then the report will be limited to only errors.
-
-    You can request a data structure which contains JSLint's results.
-
-        var myData = JSLINT.data();
-
-    It returns a structure with this form:
-
-    {
-        errors: [
-            {
-                line: NUMBER,
-                character: NUMBER,
-                reason: STRING,
-                evidence: STRING
-            }
-        ],
-        functions: [
-            name: STRING,
-            line: NUMBER,
-            last: NUMBER,
-            param: [
-                STRING
-            ],
-            closure: [
-                STRING
-            ],
-            var: [
-                STRING
-            ],
-            exception: [
-                STRING
-            ],
-            outer: [
-                STRING
-            ],
-            unused: [
-                STRING
-            ],
-            global: [
-                STRING
-            ],
-            label: [
-                STRING
-            ]
-        ],
-        globals: [
-            STRING
-        ],
-        member: {
-            STRING: NUMBER
-        },
-        unuseds: [
-            {
-                name: STRING,
-                line: NUMBER
-            }
-        ],
-        implieds: [
-            {
-                name: STRING,
-                line: NUMBER
-            }
-        ],
-        urls: [
-            STRING
-        ],
-        json: BOOLEAN
-    }
-
-    Empty arrays will not be included.
-
-*/
-
-/*jslint
-    evil: true, nomen: false, onevar: false, regexp: false, strict: true
-*/
-
-/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
-    "(begin)", "(breakage)", "(context)", "(error)", "(global)",
-    "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
-    "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/",
-    "<", "<=", "==", "===", ">", ">=", ADSAFE, ActiveXObject,
-    Array, Boolean, COM, CScript, Canvas, CustomAnimation, Date, Debug, E,
-    Enumerator, Error, EvalError, FadeAnimation, Flash, FormField, Frame,
-    Function, HotKey, Image, JSON, LN10, LN2, LOG10E, LOG2E, MAX_VALUE,
-    MIN_VALUE, Math, MenuItem, MoveAnimation, NEGATIVE_INFINITY, Number,
-    Object, Option, PI, POSITIVE_INFINITY, Point, RangeError, Rectangle,
-    ReferenceError, RegExp, ResizeAnimation, RotateAnimation, SQRT1_2,
-    SQRT2, ScrollBar, String, Style, SyntaxError, System, Text, TextArea,
-    Timer, TypeError, URIError, URL, VBArray, WScript, Web, Window, XMLDOM,
-    XMLHttpRequest, "\\", a, abbr, acronym, addEventListener, address,
-    adsafe, alert, aliceblue, animator, antiquewhite, appleScript, applet,
-    apply, approved, aqua, aquamarine, area, arguments, arity, article,
-    aside, audio, autocomplete, azure, b, background,
-    "background-attachment", "background-color", "background-image",
-    "background-position", "background-repeat", base, bdo, beep, beige, big,
-    bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
-    blueviolet, blur, body, border, "border-bottom", "border-bottom-color",
-    "border-bottom-style", "border-bottom-width", "border-collapse",
-    "border-color", "border-left", "border-left-color", "border-left-style",
-    "border-left-width", "border-right", "border-right-color",
-    "border-right-style", "border-right-width", "border-spacing",
-    "border-style", "border-top", "border-top-color", "border-top-style",
-    "border-top-width", "border-width", bottom, br, brown, browser,
-    burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller,
-    canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt,
-    character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
-    cite, clear, clearInterval, clearTimeout, clip, close, closeWidget,
-    closed, closure, cm, code, col, colgroup, color, command, comment,
-    condition, confirm, console, constructor, content, convertPathToHFS,
-    convertPathToPlatform, coral, cornflowerblue, cornsilk,
-    "counter-increment", "counter-reset", create, crimson, css, cursor,
-    cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,
-    darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
-    darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
-    darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent,
-    deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize,
-    details, devel, dfn, dialog, dimension, dimgray, dir, direction,
-    display, div, dl, document, dodgerblue, dt, edition, else, em, embed,
-    empty, "empty-cells", encodeURI, encodeURIComponent, entityify, eqeqeq,
-    errors, es5, escape, eval, event, evidence, evil, ex, exception, exec, exps,
-    fieldset, figure, filesystem, firebrick, first, float, floor,
-    floralwhite, focus, focusWidget, font, "font-face", "font-family",
-    "font-size", "font-size-adjust", "font-stretch", "font-style",
-    "font-variant", "font-weight", footer, forestgreen, forin, form,
-    fragment, frame, frames, frameset, from, fromCharCode, fuchsia, fud,
-    funct, function, functions, g, gainsboro, gc, getComputedStyle,
-    ghostwhite, global, globals, gold, goldenrod, gray, green, greenyellow,
-    h1, h2, h3, h4, h5, h6, hasOwnProperty, head, header, height, help,
-    hgroup, history, honeydew, hotpink, hr, 'hta:application', html,
-    i, iTunes, id, identifier,
-    iframe, img, immed, implieds, in, include, indent, indexOf, indianred,
-    indigo, init, input, ins, isAlpha, isApplicationRunning, isDigit,
-    isFinite, isNaN, ivory, join, jslint, json, kbd, keygen, khaki,
-    konfabulatorVersion, label, labelled, lang, last, lavender,
-    lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
-    lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
-    lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
-    lightseagreen, lightskyblue, lightslategray, lightsteelblue,
-    lightyellow, lime, limegreen, line, "line-height", linen, link,
-    "list-style", "list-style-image", "list-style-position",
-    "list-style-type", load, loadClass, location, log, m, magenta, map,
-    margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
-    mark, "marker-offset", maroon, match, "max-height", "max-width", maxerr,
-    maxlen, md5, media, mediumaquamarine, mediumblue, mediumorchid,
-    mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen,
-    mediumturquoise, mediumvioletred, member, menu, message, meta, meter,
-    midnightblue, "min-height", "min-width", mintcream, mistyrose, mm,
-    moccasin, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new,
-    newcap, noframes, nomen, noscript, nud, object, ol, oldlace, olive,
-    olivedrab, on, onbeforeunload, onblur, onerror, onevar, onfocus, onload,
-    onresize, onunload, opacity, open, openURL, opener, opera, optgroup,
-    option, orange, orangered, orchid, outer, outline, "outline-color",
-    "outline-style", "outline-width", output, overflow, "overflow-x",
-    "overflow-y", p, padding, "padding-bottom", "padding-left",
-    "padding-right", "padding-top", page, "page-break-after",
-    "page-break-before", palegoldenrod, palegreen, paleturquoise,
-    palevioletred, papayawhip, param, parent, parseFloat, parseInt,
-    passfail, pc, peachpuff, peru, pink, play, plum, plusplus, pop,
-    popupMenu, position, powderblue, pre, predef, preferenceGroups,
-    preferences, print, progress, prompt, prototype, pt, purple, push, px,
-    q, quit, quotes, random, range, raw, reach, readFile, readUrl, reason,
-    red, regexp, reloadWidget, removeEventListener, replace, report,
-    reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, rhino, right,
-    rosybrown, royalblue, rp, rt, ruby, runCommand, runCommandInBg,
-    saddlebrown, safe, salmon, samp, sandybrown, saveAs, savePreferences,
-    screen, script, scroll, scrollBy, scrollTo, seagreen, seal, search,
-    seashell, section, select, serialize, setInterval, setTimeout, shift,
-    showWidgetPreferences, sienna, silver, skyblue, slateblue, slategray,
-    sleep, slice, small, snow, sort, source, span, spawn, speak, split,
-    springgreen, src, stack, status, steelblue, strict, strong, style,
-    styleproperty, sub, substr, sup, supplant, suppressUpdates, sync,
-    system, table, "table-layout", tan, tbody, td, teal, tellWidget, test,
-    "text-align", "text-decoration", "text-indent", "text-shadow",
-    "text-transform", textarea, tfoot, th, thead, thistle, time, title,
-    toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
-    turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused,
-    unwatch, updateNow, urls, value, valueOf, var, version,
-    "vertical-align", video, violet, visibility, watch, wheat, white,
-    "white-space", whitesmoke, widget, width, windows, "word-spacing",
-    "word-wrap", yahooCheckLogin, yahooLogin, yahooLogout, yellow,
-    yellowgreen, "z-index"
-*/
-
-// We build the application inside a function so that we produce only a single
-// global variable. The function will be invoked, its return value is the JSLINT
-// application itself.
-
-"use strict";
-
-var JSLINT = (function () {
-    var adsafe_id,      // The widget's ADsafe id.
-        adsafe_may,     // The widget may load approved scripts.
-        adsafe_went,    // ADSAFE.go has been called.
-        anonname,       // The guessed name for anonymous functions.
-        approved,       // ADsafe approved urls.
-
-        atrule = {
-            media      : true,
-            'font-face': true,
-            page       : true
-        },
-
-// These are operators that should not be used with the ! operator.
-
-        bang = {
-            '<': true,
-            '<=': true,
-            '==': true,
-            '===': true,
-            '!==': true,
-            '!=': true,
-            '>': true,
-            '>=': true,
-            '+': true,
-            '-': true,
-            '*': true,
-            '/': true,
-            '%': true
-        },
-
-// These are members that should not be permitted in the safe subset.
-
-        banned = {              // the member names that ADsafe prohibits.
-            'arguments'     : true,
-            callee          : true,
-            caller          : true,
-            constructor     : true,
-            'eval'          : true,
-            prototype       : true,
-            stack           : true,
-            unwatch         : true,
-            valueOf         : true,
-            watch           : true
-        },
-
-
-// These are the JSLint boolean options.
-
-        boolOptions = {
-            adsafe     : true, // if ADsafe should be enforced
-            bitwise    : true, // if bitwise operators should not be allowed
-            browser    : true, // if the standard browser globals should be predefined
-            cap        : true, // if upper case HTML should be allowed
-            css        : true, // if CSS workarounds should be tolerated
-            debug      : true, // if debugger statements should be allowed
-            devel      : true, // if logging should be allowed (console, alert, etc.)
-            eqeqeq     : true, // if === should be required
-            es5        : true, // if ES5 syntax should be allowed
-            evil       : true, // if eval should be allowed
-            forin      : true, // if for in statements must filter
-            fragment   : true, // if HTML fragments should be allowed
-            immed      : true, // if immediate invocations must be wrapped in parens
-            laxbreak   : true, // if line breaks should not be checked
-            newcap     : true, // if constructor names must be capitalized
-            nomen      : true, // if names should be checked
-            on         : true, // if HTML event handlers should be allowed
-            onevar     : true, // if only one var statement per function should be allowed
-            passfail   : true, // if the scan should stop on first error
-            plusplus   : true, // if increment/decrement should not be allowed
-            regexp     : true, // if the . should not be allowed in regexp literals
-            rhino      : true, // if the Rhino environment globals should be predefined
-            undef      : true, // if variables should be declared before used
-            safe       : true, // if use of some browser features should be restricted
-            windows    : true, // if MS Windows-specigic globals should be predefined
-            strict     : true, // require the "use strict"; pragma
-            sub        : true, // if all forms of subscript notation are tolerated
-            white      : true, // if strict whitespace rules apply
-            widget     : true  // if the Yahoo Widgets globals should be predefined
-        },
-
-// browser contains a set of global names which are commonly provided by a
-// web browser environment.
-
-        browser = {
-            addEventListener: false,
-            blur            : false,
-            clearInterval   : false,
-            clearTimeout    : false,
-            close           : false,
-            closed          : false,
-            defaultStatus   : false,
-            document        : false,
-            event           : false,
-            focus           : false,
-            frames          : false,
-            getComputedStyle: false,
-            history         : false,
-            Image           : false,
-            length          : false,
-            location        : false,
-            moveBy          : false,
-            moveTo          : false,
-            name            : false,
-            navigator       : false,
-            onbeforeunload  : true,
-            onblur          : true,
-            onerror         : true,
-            onfocus         : true,
-            onload          : true,
-            onresize        : true,
-            onunload        : true,
-            open            : false,
-            opener          : false,
-            Option          : false,
-            parent          : false,
-            print           : false,
-            removeEventListener: false,
-            resizeBy        : false,
-            resizeTo        : false,
-            screen          : false,
-            scroll          : false,
-            scrollBy        : false,
-            scrollTo        : false,
-            setInterval     : false,
-            setTimeout      : false,
-            status          : false,
-            top             : false,
-            XMLHttpRequest  : false
-        },
-
-        cssAttributeData,
-        cssAny,
-
-        cssColorData = {
-            "aliceblue"             : true,
-            "antiquewhite"          : true,
-            "aqua"                  : true,
-            "aquamarine"            : true,
-            "azure"                 : true,
-            "beige"                 : true,
-            "bisque"                : true,
-            "black"                 : true,
-            "blanchedalmond"        : true,
-            "blue"                  : true,
-            "blueviolet"            : true,
-            "brown"                 : true,
-            "burlywood"             : true,
-            "cadetblue"             : true,
-            "chartreuse"            : true,
-            "chocolate"             : true,
-            "coral"                 : true,
-            "cornflowerblue"        : true,
-            "cornsilk"              : true,
-            "crimson"               : true,
-            "cyan"                  : true,
-            "darkblue"              : true,
-            "darkcyan"              : true,
-            "darkgoldenrod"         : true,
-            "darkgray"              : true,
-            "darkgreen"             : true,
-            "darkkhaki"             : true,
-            "darkmagenta"           : true,
-            "darkolivegreen"        : true,
-            "darkorange"            : true,
-            "darkorchid"            : true,
-            "darkred"               : true,
-            "darksalmon"            : true,
-            "darkseagreen"          : true,
-            "darkslateblue"         : true,
-            "darkslategray"         : true,
-            "darkturquoise"         : true,
-            "darkviolet"            : true,
-            "deeppink"              : true,
-            "deepskyblue"           : true,
-            "dimgray"               : true,
-            "dodgerblue"            : true,
-            "firebrick"             : true,
-            "floralwhite"           : true,
-            "forestgreen"           : true,
-            "fuchsia"               : true,
-            "gainsboro"             : true,
-            "ghostwhite"            : true,
-            "gold"                  : true,
-            "goldenrod"             : true,
-            "gray"                  : true,
-            "green"                 : true,
-            "greenyellow"           : true,
-            "honeydew"              : true,
-            "hotpink"               : true,
-            "indianred"             : true,
-            "indigo"                : true,
-            "ivory"                 : true,
-            "khaki"                 : true,
-            "lavender"              : true,
-            "lavenderblush"         : true,
-            "lawngreen"             : true,
-            "lemonchiffon"          : true,
-            "lightblue"             : true,
-            "lightcoral"            : true,
-            "lightcyan"             : true,
-            "lightgoldenrodyellow"  : true,
-            "lightgreen"            : true,
-            "lightpink"             : true,
-            "lightsalmon"           : true,
-            "lightseagreen"         : true,
-            "lightskyblue"          : true,
-            "lightslategray"        : true,
-            "lightsteelblue"        : true,
-            "lightyellow"           : true,
-            "lime"                  : true,
-            "limegreen"             : true,
-            "linen"                 : true,
-            "magenta"               : true,
-            "maroon"                : true,
-            "mediumaquamarine"      : true,
-            "mediumblue"            : true,
-            "mediumorchid"          : true,
-            "mediumpurple"          : true,
-            "mediumseagreen"        : true,
-            "mediumslateblue"       : true,
-            "mediumspringgreen"     : true,
-            "mediumturquoise"       : true,
-            "mediumvioletred"       : true,
-            "midnightblue"          : true,
-            "mintcream"             : true,
-            "mistyrose"             : true,
-            "moccasin"              : true,
-            "navajowhite"           : true,
-            "navy"                  : true,
-            "oldlace"               : true,
-            "olive"                 : true,
-            "olivedrab"             : true,
-            "orange"                : true,
-            "orangered"             : true,
-            "orchid"                : true,
-            "palegoldenrod"         : true,
-            "palegreen"             : true,
-            "paleturquoise"         : true,
-            "palevioletred"         : true,
-            "papayawhip"            : true,
-            "peachpuff"             : true,
-            "peru"                  : true,
-            "pink"                  : true,
-            "plum"                  : true,
-            "powderblue"            : true,
-            "purple"                : true,
-            "red"                   : true,
-            "rosybrown"             : true,
-            "royalblue"             : true,
-            "saddlebrown"           : true,
-            "salmon"                : true,
-            "sandybrown"            : true,
-            "seagreen"              : true,
-            "seashell"              : true,
-            "sienna"                : true,
-            "silver"                : true,
-            "skyblue"               : true,
-            "slateblue"             : true,
-            "slategray"             : true,
-            "snow"                  : true,
-            "springgreen"           : true,
-            "steelblue"             : true,
-            "tan"                   : true,
-            "teal"                  : true,
-            "thistle"               : true,
-            "tomato"                : true,
-            "turquoise"             : true,
-            "violet"                : true,
-            "wheat"                 : true,
-            "white"                 : true,
-            "whitesmoke"            : true,
-            "yellow"                : true,
-            "yellowgreen"           : true
-        },
-
-        cssBorderStyle,
-        cssBreak,
-
-        cssLengthData = {
-            '%': true,
-            'cm': true,
-            'em': true,
-            'ex': true,
-            'in': true,
-            'mm': true,
-            'pc': true,
-            'pt': true,
-            'px': true
-        },
-
-        cssOverflow,
-
-        devel = {
-            alert           : false,
-            confirm         : false,
-            console         : false,
-            Debug           : false,
-            opera           : false,
-            prompt          : false
-        },
-
-        escapes = {
-            '\b': '\\b',
-            '\t': '\\t',
-            '\n': '\\n',
-            '\f': '\\f',
-            '\r': '\\r',
-            '"' : '\\"',
-            '/' : '\\/',
-            '\\': '\\\\'
-        },
-
-        funct,          // The current function
-
-        functionicity = [
-            'closure', 'exception', 'global', 'label',
-            'outer', 'unused', 'var'
-        ],
-
-        functions,      // All of the functions
-
-        global,         // The global scope
-        htmltag = {
-            a:        {},
-            abbr:     {},
-            acronym:  {},
-            address:  {},
-            applet:   {},
-            area:     {empty: true, parent: ' map '},
-            article:  {},
-            aside:    {},
-            audio:    {},
-            b:        {},
-            base:     {empty: true, parent: ' head '},
-            bdo:      {},
-            big:      {},
-            blockquote: {},
-            body:     {parent: ' html noframes '},
-            br:       {empty: true},
-            button:   {},
-            canvas:   {parent: ' body p div th td '},
-            caption:  {parent: ' table '},
-            center:   {},
-            cite:     {},
-            code:     {},
-            col:      {empty: true, parent: ' table colgroup '},
-            colgroup: {parent: ' table '},
-            command:  {parent: ' menu '},
-            datalist: {},
-            dd:       {parent: ' dl '},
-            del:      {},
-            details:  {},
-            dialog:   {},
-            dfn:      {},
-            dir:      {},
-            div:      {},
-            dl:       {},
-            dt:       {parent: ' dl '},
-            em:       {},
-            embed:    {},
-            fieldset: {},
-            figure:   {},
-            font:     {},
-            footer:   {},
-            form:     {},
-            frame:    {empty: true, parent: ' frameset '},
-            frameset: {parent: ' html frameset '},
-            h1:       {},
-            h2:       {},
-            h3:       {},
-            h4:       {},
-            h5:       {},
-            h6:       {},
-            head:     {parent: ' html '},
-            header:   {},
-            hgroup:   {},
-            hr:       {empty: true},
-            'hta:application':
-                      {empty: true, parent: ' head '},
-            html:     {parent: '*'},
-            i:        {},
-            iframe:   {},
-            img:      {empty: true},
-            input:    {empty: true},
-            ins:      {},
-            kbd:      {},
-            keygen:   {},
-            label:    {},
-            legend:   {parent: ' details fieldset figure '},
-            li:       {parent: ' dir menu ol ul '},
-            link:     {empty: true, parent: ' head '},
-            map:      {},
-            mark:     {},
-            menu:     {},
-            meta:     {empty: true, parent: ' head noframes noscript '},
-            meter:    {},
-            nav:      {},
-            noframes: {parent: ' html body '},
-            noscript: {},
-            object:   {},
-            ol:       {},
-            optgroup: {parent: ' select '},
-            option:   {parent: ' optgroup select '},
-            output:   {},
-            p:        {},
-            param:    {parent: ' applet object '},
-            pre:      {},
-            progress: {},
-            q:        {},
-            rp:       {},
-            rt:       {},
-            ruby:     {},
-            s:        {},
-            samp:     {},
-            script:   {empty: true, parent: ' body div frame head iframe p pre span '},
-            section:  {},
-            select:   {},
-            small:    {},
-            span:     {},
-            source:   {},
-            strong:   {},
-            style:    {parent: ' head ', empty: true},
-            sub:      {},
-            sup:      {},
-            table:    {},
-            tbody:    {parent: ' table '},
-            td:       {parent: ' tr '},
-            textarea: {},
-            tfoot:    {parent: ' table '},
-            th:       {parent: ' tr '},
-            thead:    {parent: ' table '},
-            time:     {},
-            title:    {parent: ' head '},
-            tr:       {parent: ' table tbody thead tfoot '},
-            tt:       {},
-            u:        {},
-            ul:       {},
-            'var':    {},
-            video:    {}
-        },
-
-        ids,            // HTML ids
-        implied,        // Implied globals
-        inblock,
-        indent,
-        jsonmode,
-        lines,
-        lookahead,
-        member,
-        membersOnly,
-        nexttoken,
-        noreach,
-        option,
-        predefined,     // Global variables defined by option
-        prereg,
-        prevtoken,
-
-        rhino = {
-            defineClass : false,
-            deserialize : false,
-            gc          : false,
-            help        : false,
-            load        : false,
-            loadClass   : false,
-            print       : false,
-            quit        : false,
-            readFile    : false,
-            readUrl     : false,
-            runCommand  : false,
-            seal        : false,
-            serialize   : false,
-            spawn       : false,
-            sync        : false,
-            toint32     : false,
-            version     : false
-        },
-
-        scope,      // The current scope
-
-        windows = {
-            ActiveXObject: false,
-            CScript      : false,
-            Debug        : false,
-            Enumerator   : false,
-            System       : false,
-            VBArray      : false,
-            WScript      : false
-        },
-
-        src,
-        stack,
-
-// standard contains the global names that are provided by the
-// ECMAScript standard.
-
-        standard = {
-            'void'              : false,
-            Array               : false,
-            Boolean             : false,
-            Date                : false,
-            decodeURI           : false,
-            decodeURIComponent  : false,
-            encodeURI           : false,
-            encodeURIComponent  : false,
-            Error               : false,
-            'eval'              : false,
-            EvalError           : false,
-            Function            : false,
-            hasOwnProperty      : false,
-            isFinite            : false,
-            isNaN               : false,
-            JSON                : false,
-            Math                : false,
-            Number              : false,
-            Object              : false,
-            parseInt            : false,
-            parseFloat          : false,
-            RangeError          : false,
-            ReferenceError      : false,
-            RegExp              : false,
-            String              : false,
-            SyntaxError         : false,
-            TypeError           : false,
-            URIError            : false
-        },
-
-        standard_member = {
-            E                   : true,
-            LN2                 : true,
-            LN10                : true,
-            LOG2E               : true,
-            LOG10E              : true,
-            PI                  : true,
-            SQRT1_2             : true,
-            SQRT2               : true,
-            MAX_VALUE           : true,
-            MIN_VALUE           : true,
-            NEGATIVE_INFINITY   : true,
-            POSITIVE_INFINITY   : true
-        },
-
-        strict_mode,
-        syntax = {},
-        tab,
-        token,
-        urls,
-        warnings,
-
-// widget contains the global names which are provided to a Yahoo
-// (fna Konfabulator) widget.
-
-        widget = {
-            alert                   : true,
-            animator                : true,
-            appleScript             : true,
-            beep                    : true,
-            bytesToUIString         : true,
-            Canvas                  : true,
-            chooseColor             : true,
-            chooseFile              : true,
-            chooseFolder            : true,
-            closeWidget             : true,
-            COM                     : true,
-            convertPathToHFS        : true,
-            convertPathToPlatform   : true,
-            CustomAnimation         : true,
-            escape                  : true,
-            FadeAnimation           : true,
-            filesystem              : true,
-            Flash                   : true,
-            focusWidget             : true,
-            form                    : true,
-            FormField               : true,
-            Frame                   : true,
-            HotKey                  : true,
-            Image                   : true,
-            include                 : true,
-            isApplicationRunning    : true,
-            iTunes                  : true,
-            konfabulatorVersion     : true,
-            log                     : true,
-            md5                     : true,
-            MenuItem                : true,
-            MoveAnimation           : true,
-            openURL                 : true,
-            play                    : true,
-            Point                   : true,
-            popupMenu               : true,
-            preferenceGroups        : true,
-            preferences             : true,
-            print                   : true,
-            prompt                  : true,
-            random                  : true,
-            Rectangle               : true,
-            reloadWidget            : true,
-            ResizeAnimation         : true,
-            resolvePath             : true,
-            resumeUpdates           : true,
-            RotateAnimation         : true,
-            runCommand              : true,
-            runCommandInBg          : true,
-            saveAs                  : true,
-            savePreferences         : true,
-            screen                  : true,
-            ScrollBar               : true,
-            showWidgetPreferences   : true,
-            sleep                   : true,
-            speak                   : true,
-            Style                   : true,
-            suppressUpdates         : true,
-            system                  : true,
-            tellWidget              : true,
-            Text                    : true,
-            TextArea                : true,
-            Timer                   : true,
-            unescape                : true,
-            updateNow               : true,
-            URL                     : true,
-            Web                     : true,
-            widget                  : true,
-            Window                  : true,
-            XMLDOM                  : true,
-            XMLHttpRequest          : true,
-            yahooCheckLogin         : true,
-            yahooLogin              : true,
-            yahooLogout             : true
-        },
-
-//  xmode is used to adapt to the exceptions in html parsing.
-//  It can have these states:
-//      false   .js script file
-//      html
-//      outer
-//      script
-//      style
-//      scriptstring
-//      styleproperty
-
-        xmode,
-        xquote,
-
-// unsafe comment or string
-        ax = /@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,
-// unsafe characters that are silently deleted by one or more browsers
-// Whitelist Replacement Char, 0xfffd
-        cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\ufffc\ufffe-\uffff]/,
-// token
-        tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
-// html token
-        hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,
-// characters in strings that need escapement
-        nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
-        nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
-// outer html token
-        ox = /[>&]|<[\/!]?|--/,
-// star slash
-        lx = /\*\/|\/\*/,
-// identifier
-        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
-// javascript url
-        jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
-// url badness
-        ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,
-// style
-        sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,
-        ssx = /^\s*(\.?\d+(?:\.\d+)?|[@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|<\/)/,
-// attributes characters
-        //qx = /[^a-zA-Z0-9+\-_\/ ]/,
-        qx = /[^a-zA-Z0-9+\-_\/ .#]/, // We want dots in names, period; and hashes for templating
-// query characters for ids
-        //dx = /[\[\]\/\\"'*<>.&:(){}+=#]/,
-        // allow . and /
-        dx = /[\[\]\\"'*<>&:(){}+=#]/,
-
-        rx = {
-            outer: hx,
-            html: hx,
-            style: sx,
-            styleproperty: ssx
-        };
-
-    function F() {}
-
-    if (typeof Object.create !== 'function') {
-        Object.create = function (o) {
-            F.prototype = o;
-            return new F();
-        };
-    }
-
-
-    function is_own(object, name) {
-        return Object.prototype.hasOwnProperty.call(object, name);
-    }
-
-
-    function combine(t, o) {
-        var n;
-        for (n in o) {
-            if (is_own(o, n)) {
-                t[n] = o[n];
-            }
-        }
-    }
-
-    String.prototype.entityify = function () {
-        return this.
-            replace(/&/g, '&amp;').
-            replace(/</g, '&lt;').
-            replace(/>/g, '&gt;');
-    };
-
-    String.prototype.isAlpha = function () {
-        return (this >= 'a' && this <= 'z\uffff') ||
-            (this >= 'A' && this <= 'Z\uffff');
-    };
-
-
-    String.prototype.isDigit = function () {
-        return (this >= '0' && this <= '9');
-    };
-
-
-    String.prototype.supplant = function (o) {
-        return this.replace(/\{([^{}]*)\}/g, function (a, b) {
-            var r = o[b];
-            return typeof r === 'string' || typeof r === 'number' ? r : a;
-        });
-    };
-
-    String.prototype.name = function () {
-
-// If the string looks like an identifier, then we can return it as is.
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can simply slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe
-// sequences.
-
-        if (ix.test(this)) {
-            return this;
-        }
-        if (nx.test(this)) {
-            return '"' + this.replace(nxg, function (a) {
-                var c = escapes[a];
-                if (c) {
-                    return c;
-                }
-                return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
-            }) + '"';
-        }
-        return '"' + this + '"';
-    };
-
-
-    function assume() {
-        if (!option.safe) {
-            if (option.rhino) {
-                combine(predefined, rhino);
-            }
-            if (option.devel) {
-                combine(predefined, devel);
-            }
-            if (option.browser) {
-                combine(predefined, browser);
-            }
-            if (option.windows) {
-                combine(predefined, windows);
-            }
-            if (option.widget) {
-                combine(predefined, widget);
-            }
-        }
-    }
-
-
-// Produce an error warning.
-
-    function quit(m, l, ch) {
-        throw {
-            name: 'JSLintError',
-            line: l,
-            character: ch,
-            message: m + " (" + Math.floor((l / lines.length) * 100) +
-                    "% scanned)."
-        };
-    }
-
-    function warning(m, t, a, b, c, d) {
-        var ch, l, w;
-        t = t || nexttoken;
-        if (t.id === '(end)') {  // `~
-            t = token;
-        }
-        l = t.line || 0;
-        ch = t.from || 0;
-        w = {
-            id: '(error)',
-            raw: m,
-            evidence: lines[l - 1] || '',
-            line: l,
-            character: ch,
-            a: a,
-            b: b,
-            c: c,
-            d: d
-        };
-        w.reason = m.supplant(w);
-        JSLINT.errors.push(w);
-        if (option.passfail) {
-            quit('Stopping. ', l, ch);
-        }
-        warnings += 1;
-        if (warnings >= option.maxerr) {
-            quit("Too many errors.", l, ch);
-        }
-        return w;
-    }
-
-    function warningAt(m, l, ch, a, b, c, d) {
-        return warning(m, {
-            line: l,
-            from: ch
-        }, a, b, c, d);
-    }
-
-    function error(m, t, a, b, c, d) {
-        var w = warning(m, t, a, b, c, d);
-        quit("Stopping, unable to continue.", w.line, w.character);
-    }
-
-    function errorAt(m, l, ch, a, b, c, d) {
-        return error(m, {
-            line: l,
-            from: ch
-        }, a, b, c, d);
-    }
-
-
-
-// lexical analysis
-
-    var lex = (function lex() {
-        var character, from, line, s;
-
-// Private lex methods
-
-        function nextLine() {
-            var at;
-            if (line >= lines.length) {
-                return false;
-            }
-            character = 1;
-            s = lines[line];
-            line += 1;
-            at = s.search(/ \t/);
-            if (at >= 0) {
-                warningAt("Mixed spaces and tabs.", line, at + 1);
-            }
-            s = s.replace(/\t/g, tab);
-            at = s.search(cx);
-            if (at >= 0) {
-                warningAt("Unsafe character.", line, at);
-            }
-            if (option.maxlen && option.maxlen < s.length) {
-                warningAt("Line too long.", line, s.length);
-            }
-            return true;
-        }
-
-// Produce a token object.  The token inherits from a syntax symbol.
-
-        function it(type, value) {
-            var i, t;
-            if (type === '(color)') {
-                t = {type: type};
-            } else if (type === '(punctuator)' ||
-                    (type === '(identifier)' && is_own(syntax, value))) {
-                t = syntax[value] || syntax['(error)'];
-            } else {
-                t = syntax[type];
-            }
-            t = Object.create(t);
-            if (type === '(string)' || type === '(range)') {
-                if (jx.test(value)) {
-                    warningAt("Script URL.", line, from);
-                }
-            }
-            if (type === '(identifier)') {
-                t.identifier = true;
-                if (value === '__iterator__' || value === '__proto__') {
-                    errorAt("Reserved name '{a}'.",
-                        line, from, value);
-                } else if (option.nomen &&
-                        (value.charAt(0) === '_' ||
-                         value.charAt(value.length - 1) === '_')) {
-                    warningAt("Unexpected {a} in '{b}'.", line, from,
-                        "dangling '_'", value);
-                }
-            }
-            t.value = value;
-            t.line = line;
-            t.character = character;
-            t.from = from;
-            i = t.id;
-            if (i !== '(endline)') {
-                prereg = i &&
-                    (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
-                    i === 'return');
-            }
-            return t;
-        }
-
-// Public lex methods
-
-        return {
-            init: function (source) {
-                if (typeof source === 'string') {
-                    lines = source.
-                        replace(/\r\n/g, '\n').
-                        replace(/\r/g, '\n').
-                        split('\n');
-                } else {
-                    lines = source;
-                }
-                line = 0;
-                nextLine();
-                from = 1;
-            },
-
-            range: function (begin, end) {
-                var c, value = '';
-                from = character;
-                if (s.charAt(0) !== begin) {
-                    errorAt("Expected '{a}' and instead saw '{b}'.",
-                            line, character, begin, s.charAt(0));
-                }
-                for (;;) {
-                    s = s.slice(1);
-                    character += 1;
-                    c = s.charAt(0);
-                    switch (c) {
-                    case '':
-                        errorAt("Missing '{a}'.", line, character, c);
-                        break;
-                    case end:
-                        s = s.slice(1);
-                        character += 1;
-                        return it('(range)', value);
-                    case xquote:
-                    case '\\':
-                        warningAt("Unexpected '{a}'.", line, character, c);
-                    }
-                    value += c;
-                }
-
-            },
-
-// skip all content up to marker
-
-            skip_till: function (end) {
-                            for (;;) {
-                                i = s.indexOf(end);
-                                if (i >= 0) {
-                                    break;
-                                }
-                                if (!nextLine()) {
-                                    errorAt("Unclosed {a} block.", line, character, end);
-                                }
-                            }
-                            character += i;
-                            s = s.substr(i);
-            },
-
-// token -- this is called by advance to get the next token.
-
-            token: function () {
-                var b, c, captures, d, depth, high, i, l, low, q, t;
-
-                function match(x) {
-                    var r = x.exec(s), r1;
-                    if (r) {
-                        l = r[0].length;
-                        r1 = r[1];
-                        c = r1.charAt(0);
-                        s = s.substr(l);
-                        from = character + l - r1.length;
-                        character += l;
-                        return r1;
-                    }
-                }
-
-                function string(x) {
-                    var c, j, r = '';
-
-                    if (jsonmode && x !== '"') {
-                        warningAt("Strings must use doublequote.",
-                                line, character);
-                    }
-
-                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
-                        return it('(punctuator)', x);
-                    }
-
-                    function esc(n) {
-                        var i = parseInt(s.substr(j + 1, n), 16);
-                        j += n;
-                        if (i >= 32 && i <= 126 &&
-                                i !== 34 && i !== 92 && i !== 39) {
-                            warningAt("Unnecessary escapement.", line, character);
-                        }
-                        character += n;
-                        c = String.fromCharCode(i);
-                    }
-                    j = 0;
-                    for (;;) {
-                        while (j >= s.length) {
-                            j = 0;
-                            if (xmode !== 'html' || !nextLine()) {
-                                errorAt("Unclosed string.", line, from);
-                            }
-                        }
-                        c = s.charAt(j);
-                        if (c === x) {
-                            character += 1;
-                            s = s.substr(j + 1);
-                            return it('(string)', r, x);
-                        }
-                        if (c < ' ') {
-                            if (c === '\n' || c === '\r') {
-                                break;
-                            }
-                            warningAt("Control character in string: {a}.",
-                                    line, character + j, s.slice(0, j));
-                        } else if (c === xquote) {
-                            warningAt("Bad HTML string", line, character + j);
-                        } else if (c === '<') {
-                            if (option.safe && xmode === 'html') {
-                                warningAt("ADsafe string violation.",
-                                        line, character + j);
-                            } else if (s.charAt(j + 1) === '/' && (xmode || option.safe) && s.substr(j + 2, 6) === 'script') {
-                                warningAt("Expected '<\\/' and instead saw '</'.", line, character);
-                            } else if (s.charAt(j + 1) === '!' && (xmode || option.safe)) {
-                                warningAt("Unexpected '<!' in a string.", line, character);
-                            }
-                        } else if (c === '\\') {
-                            if (xmode === 'html') {
-                                if (option.safe) {
-                                    warningAt("ADsafe string violation.",
-                                            line, character + j);
-                                }
-                            } else if (xmode === 'styleproperty') {
-                                j += 1;
-                                character += 1;
-                                c = s.charAt(j);
-                                if (c !== x) {
-                                    warningAt("Escapement in style string.",
-                                            line, character + j);
-                                }
-                            } else {
-                                j += 1;
-                                character += 1;
-                                c = s.charAt(j);
-                                switch (c) {
-                                case xquote:
-                                    warningAt("Bad HTML string", line,
-                                        character + j);
-                                    break;
-                                case '\\':
-                                case '\'':
-                                case '"':
-                                case '/':
-                                    break;
-                                case 'b':
-                                    c = '\b';
-                                    break;
-                                case 'f':
-                                    c = '\f';
-                                    break;
-                                case 'n':
-                                    c = '\n';
-                                    break;
-                                case 'r':
-                                    c = '\r';
-                                    break;
-                                case 't':
-                                    c = '\t';
-                                    break;
-                                case 'u':
-                                    esc(4);
-                                    break;
-                                case 'v':
-                                    c = '\v';
-                                    break;
-                                case 'x':
-                                    if (jsonmode) {
-                                        warningAt("Avoid \\x-.", line, character);
-                                    }
-                                    esc(2);
-                                    break;
-                                default:
-                                    warningAt("Bad escapement.", line, character);
-                                }
-                            }
-                        }
-                        r += c;
-                        character += 1;
-                        j += 1;
-                    }
-                }
-
-                for (;;) {
-                    if (!s) {
-                        return it(nextLine() ? '(endline)' : '(end)', '');
-                    }
-                    while (xmode === 'outer') {
-                        i = s.search(ox);
-                        if (i === 0) {
-                            break;
-                        } else if (i > 0) {
-                            character += 1;
-                            s = s.slice(i);
-                            break;
-                        } else {
-                            if (!nextLine()) {
-                                return it('(end)', '');
-                            }
-                        }
-                    }
-//                     t = match(rx[xmode] || tx);
-//                     if (!t) {
-//                         if (xmode === 'html') {
-//                             return it('(error)', s.charAt(0));
-//                         } else {
-//                             t = '';
-//                             c = '';
-//                             while (s && s < '!') {
-//                                 s = s.substr(1);
-//                             }
-//                             if (s) {
-//                                 errorAt("Unexpected '{a}'.",
-//                                         line, character, s.substr(0, 1));
-//                             }
-//                         }
-                    t = match(rx[xmode] || tx);
-                    if (!t) {
-                        t = '';
-                        c = '';
-                        while (s && s < '!') {
-                            s = s.substr(1);
-                        }
-                        if (s) {
-                            if (xmode === 'html') {
-                                return it('(error)', s.charAt(0));
-                            } else {
-                                errorAt("Unexpected '{a}'.",
-                                        line, character, s.substr(0, 1));
-                            }
-                        }
-                    } else {
-
-    //      identifier
-
-                        if (c.isAlpha() || c === '_' || c === '$') {
-                            return it('(identifier)', t);
-                        }
-
-    //      number
-
-                        if (c.isDigit() || (c === '.' && t.substr(1, 1).isDigit())) {
-                            if (c === '.') {
-                                t = '0' + t;
-                                c = '0';
-                            }
-                        
-                            if (xmode !== 'style' && !isFinite(Number(t))) {
-                                warningAt("Bad number '{a}'.",
-                                    line, character, t);
-                            }
-                            if (xmode !== 'style' &&
-                                     xmode !== 'styleproperty' &&
-                                     s.substr(0, 1).isAlpha()) {
-                                warningAt("Missing space after '{a}'.",
-                                        line, character, t);
-                            }
-                            if (c === '0') {
-                                d = t.substr(1, 1);
-                                if (d.isDigit()) {
-                                    if (token.id !== '.' && xmode !== 'styleproperty') {
-                                        warningAt("Don't use extra leading zeros '{a}'.",
-                                            line, character, t);
-                                    }
-                                } else if (jsonmode && (d === 'x' || d === 'X')) {
-                                    warningAt("Avoid 0x-. '{a}'.",
-                                            line, character, t);
-                                }
-                            }
-                            if (t.substr(t.length - 1) === '.') {
-                                warningAt(
-        "A trailing decimal point can be confused with a dot '{a}'.",
-                                        line, character, t);
-                            }
-                            return it('(number)', t);
-                        }
-                        switch (t) {
-
-    //      string
-
-                        case '"':
-                        case "'":
-                            return string(t);
-
-    //      // comment
-
-                        case '//':
-                            if (src || (xmode && xmode !== 'script')) {
-                                warningAt("Unexpected comment.", line, character);
-                            } else if (xmode === 'script' && /<\s*\//i.test(s)) {
-                                warningAt("Unexpected <\/ in comment.", line, character);
-                            } else if ((option.safe || xmode === 'script') && ax.test(s)) {
-                                warningAt("Dangerous comment.", line, character);
-                            }
-                            s = '';
-                            token.comment = true;
-                            break;
-
-    //      /* comment
-
-                        case '/*':
-                            if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) {
-                                warningAt("Unexpected comment.", line, character);
-                            }
-                            if (option.safe && ax.test(s)) {
-                                warningAt("ADsafe comment violation.", line, character);
-                            }
-                            for (;;) {
-                                i = s.search(lx);
-                                if (i >= 0) {
-                                    break;
-                                }
-                                if (!nextLine()) {
-                                    errorAt("Unclosed comment.", line, character);
-                                } else {
-                                    if (option.safe && ax.test(s)) {
-                                        warningAt("ADsafe comment violation.",
-                                                line, character);
-                                    }
-                                }
-                            }
-                            character += i + 2;
-                            if (s.substr(i, 1) === '/') {
-                                errorAt("Nested comment.", line, character);
-                            }
-                            s = s.substr(i + 2);
-                            token.comment = true;
-                            break;
-
-    //      /*members /*jslint /*global
-
-                        case '/*members':
-                        case '/*member':
-                        case '/*jslint':
-                        case '/*global':
-                        case '*/':
-                            return {
-                                value: t,
-                                type: 'special',
-                                line: line,
-                                character: character,
-                                from: from
-                            };
-
-                        case '':
-                            break;
-    //      /
-                        case '/':
-                            if (token.id === '/=') {
-                                errorAt(
-"A regular expression literal can be confused with '/='.", line, from);
-                            }
-                            if (prereg) {
-                                depth = 0;
-                                captures = 0;
-                                l = 0;
-                                for (;;) {
-                                    b = true;
-                                    c = s.charAt(l);
-                                    l += 1;
-                                    switch (c) {
-                                    case '':
-                                        errorAt("Unclosed regular expression.",
-                                                line, from);
-                                        return;
-                                    case '/':
-                                        if (depth > 0) {
-                                            warningAt("Unescaped '{a}'.",
-                                                    line, from + l, '/');
-                                        }
-                                        c = s.substr(0, l - 1);
-                                        q = {
-                                            g: true,
-                                            i: true,
-                                            m: true
-                                        };
-                                        while (q[s.charAt(l)] === true) {
-                                            q[s.charAt(l)] = false;
-                                            l += 1;
-                                        }
-                                        character += l;
-                                        s = s.substr(l);
-                                        q = s.charAt(0);
-                                        if (q === '/' || q === '*') {
-                                            errorAt("Confusing regular expression.",
-                                                    line, from);
-                                        }
-                                        return it('(regexp)', c);
-                                    case '\\':
-                                        c = s.charAt(l);
-                                        if (c < ' ') {
-                                            warningAt(
-"Unexpected control character in regular expression.", line, from + l);
-                                        } else if (c === '<') {
-                                            warningAt(
-"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
-                                        }
-                                        l += 1;
-                                        break;
-                                    case '(':
-                                        depth += 1;
-                                        b = false;
-                                        if (s.charAt(l) === '?') {
-                                            l += 1;
-                                            switch (s.charAt(l)) {
-                                            case ':':
-                                            case '=':
-                                            case '!':
-                                                l += 1;
-                                                break;
-                                            default:
-                                                warningAt(
-"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
-                                            }
-                                        } else {
-                                            captures += 1;
-                                        }
-                                        break;
-                                    case '|':
-                                        b = false;
-                                        break;
-                                    case ')':
-                                        if (depth === 0) {
-                                            warningAt("Unescaped '{a}'.",
-                                                    line, from + l, ')');
-                                        } else {
-                                            depth -= 1;
-                                        }
-                                        break;
-                                    case ' ':
-                                        q = 1;
-                                        while (s.charAt(l) === ' ') {
-                                            l += 1;
-                                            q += 1;
-                                        }
-                                        if (q > 1) {
-                                            warningAt(
-"Spaces are hard to count. Use {{a}}.", line, from + l, q);
-                                        }
-                                        break;
-                                    case '[':
-                                        c = s.charAt(l);
-                                        if (c === '^') {
-                                            l += 1;
-                                            if (option.regexp) {
-                                                warningAt("Insecure '{a}'.",
-                                                        line, from + l, c);
-                                            }
-                                        }
-                                        q = false;
-                                        if (c === ']') {
-                                            warningAt("Empty class.", line,
-                                                    from + l - 1);
-                                            q = true;
-                                        }
-klass:                                  do {
-                                            c = s.charAt(l);
-                                            l += 1;
-                                            switch (c) {
-                                            case '[':
-                                            case '^':
-                                                warningAt("Unescaped '{a}'.",
-                                                        line, from + l, c);
-                                                q = true;
-                                                break;
-                                            case '-':
-                                                if (q) {
-                                                    q = false;
-                                                } else {
-                                                    warningAt("Unescaped '{a}'.",
-                                                            line, from + l, '-');
-                                                    q = true;
-                                                }
-                                                break;
-                                            case ']':
-                                                if (!q) {
-                                                    warningAt("Unescaped '{a}'.",
-                                                            line, from + l - 1, '-');
-                                                }
-                                                break klass;
-                                            case '\\':
-                                                c = s.charAt(l);
-                                                if (c < ' ') {
-                                                    warningAt(
-"Unexpected control character in regular expression.", line, from + l);
-                                                } else if (c === '<') {
-                                                    warningAt(
-"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
-                                                }
-                                                l += 1;
-                                                q = true;
-                                                break;
-                                            case '/':
-                                                warningAt("Unescaped '{a}'.",
-                                                        line, from + l - 1, '/');
-                                                q = true;
-                                                break;
-                                            case '<':
-                                                if (xmode === 'script') {
-                                                    c = s.charAt(l);
-                                                    if (c === '!' || c === '/') {
-                                                        warningAt(
-"HTML confusion in regular expression '<{a}'.", line, from + l, c);
-                                                    }
-                                                }
-                                                q = true;
-                                                break;
-                                            default:
-                                                q = true;
-                                            }
-                                        } while (c);
-                                        break;
-                                    case '.':
-                                        if (option.regexp) {
-                                            warningAt("Insecure '{a}'.", line,
-                                                    from + l, c);
-                                        }
-                                        break;
-                                    case ']':
-                                    case '?':
-                                    case '{':
-                                    case '}':
-                                    case '+':
-                                    case '*':
-                                        warningAt("Unescaped '{a}'.", line,
-                                                from + l, c);
-                                        break;
-                                    case '<':
-                                        if (xmode === 'script') {
-                                            c = s.charAt(l);
-                                            if (c === '!' || c === '/') {
-                                                warningAt(
-"HTML confusion in regular expression '<{a}'.", line, from + l, c);
-                                            }
-                                        }
-                                    }
-                                    if (b) {
-                                        switch (s.charAt(l)) {
-                                        case '?':
-                                        case '+':
-                                        case '*':
-                                            l += 1;
-                                            if (s.charAt(l) === '?') {
-                                                l += 1;
-                                            }
-                                            break;
-                                        case '{':
-                                            l += 1;
-                                            c = s.charAt(l);
-                                            if (c < '0' || c > '9') {
-                                                warningAt(
-"Expected a number and instead saw '{a}'.", line, from + l, c);
-                                            }
-                                            l += 1;
-                                            low = +c;
-                                            for (;;) {
-                                                c = s.charAt(l);
-                                                if (c < '0' || c > '9') {
-                                                    break;
-                                                }
-                                                l += 1;
-                                                low = +c + (low * 10);
-                                            }
-                                            high = low;
-                                            if (c === ',') {
-                                                l += 1;
-                                                high = Infinity;
-                                                c = s.charAt(l);
-                                                if (c >= '0' && c <= '9') {
-                                                    l += 1;
-                                                    high = +c;
-                                                    for (;;) {
-                                                        c = s.charAt(l);
-                                                        if (c < '0' || c > '9') {
-                                                            break;
-                                                        }
-                                                        l += 1;
-                                                        high = +c + (high * 10);
-                                                    }
-                                                }
-                                            }
-                                            if (s.charAt(l) !== '}') {
-                                                warningAt(
-"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
-                                            } else {
-                                                l += 1;
-                                            }
-                                            if (s.charAt(l) === '?') {
-                                                l += 1;
-                                            }
-                                            if (low > high) {
-                                                warningAt(
-"'{a}' should not be greater than '{b}'.", line, from + l, low, high);
-                                            }
-                                        }
-                                    }
-                                }
-                                c = s.substr(0, l - 1);
-                                character += l;
-                                s = s.substr(l);
-                                return it('(regexp)', c);
-                            }
-                            return it('(punctuator)', t);
-
-    //      punctuator
-
-                        case '<!--':
-                            l = line;
-                            c = character;
-                            for (;;) {
-                                i = s.indexOf('--');
-                                if (i >= 0) {
-                                    break;
-                                }
-                                i = s.indexOf('<!-');
-                                if (i >= 0) {
-                                    errorAt("Nested HTML comment.",
-                                        line, character + i);
-                                }
-                                if (!nextLine()) {
-                                    errorAt("Unclosed HTML comment.", l, c);
-                                }
-                            }
-                            l = s.indexOf('<!-');
-                            if (l >= 0 && l < i) {
-                                errorAt("Nested HTML comment.",
-                                    line, character + l);
-                            }
-                            character += i;
-                            if (s[i + 2] !== '>') {
-                                errorAt("Expected -->.", line, character);
-                            }
-                            character += 3;
-                            s = s.slice(i + 3);
-                            break;
-                        case '#':
-                            if (xmode === 'html' || xmode === 'styleproperty') {
-                                for (;;) {
-                                    c = s.charAt(0);
-                                    if ((c < '0' || c > '9') &&
-                                            (c < 'a' || c > 'f') &&
-                                            (c < 'A' || c > 'F')) {
-                                        break;
-                                    }
-                                    character += 1;
-                                    s = s.substr(1);
-                                    t += c;
-                                }
-                                if (t.length !== 4 && t.length !== 7) {
-                                    warningAt("Bad hex color '{a}'.", line,
-                                        from + l, t);
-                                }
-                                return it('(color)', t);
-                            }
-                            return it('(punctuator)', t);
-                        default:
-                            if (xmode === 'outer' && c === '&') {
-                                character += 1;
-                                s = s.substr(1);
-                                for (;;) {
-                                    c = s.charAt(0);
-                                    character += 1;
-                                    s = s.substr(1);
-                                    if (c === ';') {
-                                        break;
-                                    }
-                                    if (!((c >= '0' && c <= '9') ||
-                                            (c >= 'a' && c <= 'z') ||
-                                            c === '#')) {
-                                        errorAt("Bad entity", line, from + l,
-                                        character);
-                                    }
-                                }
-                                break;
-                            }
-                            return it('(punctuator)', t);
-                        }
-                    }
-                }
-            }
-        };
-    }());
-
-
-    function addlabel(t, type) {
-
-        if (option.safe && funct['(global)'] &&
-                typeof predefined[t] !== 'boolean') {
-            warning('ADsafe global: ' + t + '.', token);
-        } else if (t === 'hasOwnProperty') {
-            warning("'hasOwnProperty' is a really bad name.");
-        }
-
-// Define t in the current function in the current scope.
-
-        if (is_own(funct, t) && !funct['(global)']) {
-            warning(funct[t] === true ?
-                "'{a}' was used before it was defined." :
-                "'{a}' is already defined.",
-                nexttoken, t);
-        }
-        funct[t] = type;
-        if (funct['(global)']) {
-            global[t] = funct;
-            if (is_own(implied, t)) {
-                warning("'{a}' was used before it was defined.", nexttoken, t);
-                delete implied[t];
-            }
-        } else {
-            scope[t] = funct;
-        }
-    }
-
-
-    function doOption() {
-        var b, obj, filter, o = nexttoken.value, t, v;
-        switch (o) {
-        case '*/':
-            error("Unbegun comment.");
-            break;
-        case '/*members':
-        case '/*member':
-            o = '/*members';
-            if (!membersOnly) {
-                membersOnly = {};
-            }
-            obj = membersOnly;
-            break;
-        case '/*jslint':
-            if (option.safe) {
-                warning("ADsafe restriction.");
-            }
-            obj = option;
-            filter = boolOptions;
-            break;
-        case '/*global':
-            if (option.safe) {
-                warning("ADsafe restriction.");
-            }
-            obj = predefined;
-            break;
-        default:
-        }
-        t = lex.token();
-loop:   for (;;) {
-            for (;;) {
-                if (t.type === 'special' && t.value === '*/') {
-                    break loop;
-                }
-                if (t.id !== '(endline)' && t.id !== ',') {
-                    break;
-                }
-                t = lex.token();
-            }
-            if (t.type !== '(string)' && t.type !== '(identifier)' &&
-                    o !== '/*members') {
-                error("Bad option.", t);
-            }
-            v = lex.token();
-            if (v.id === ':') {
-                v = lex.token();
-                if (obj === membersOnly) {
-                    error("Expected '{a}' and instead saw '{b}'.",
-                            t, '*/', ':');
-                }
-                if (t.value === 'indent' && o === '/*jslint') {
-                    b = +v.value;
-                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
-                            Math.floor(b) !== b) {
-                        error("Expected a small integer and instead saw '{a}'.",
-                                v, v.value);
-                    }
-                    obj.white = true;
-                    obj.indent = b;
-                } else if (t.value === 'maxerr' && o === '/*jslint') {
-                    b = +v.value;
-                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
-                            Math.floor(b) !== b) {
-                        error("Expected a small integer and instead saw '{a}'.",
-                                v, v.value);
-                    }
-                    obj.maxerr = b;
-                } else if (t.value === 'maxlen' && o === '/*jslint') {
-                    b = +v.value;
-                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
-                            Math.floor(b) !== b) {
-                        error("Expected a small integer and instead saw '{a}'.",
-                                v, v.value);
-                    }
-                    obj.maxlen = b;
-                } else if (v.value === 'true') {
-                    obj[t.value] = true;
-                } else if (v.value === 'false') {
-                    obj[t.value] = false;
-                } else {
-                    error("Bad option value.", v);
-                }
-                t = lex.token();
-            } else {
-                if (o === '/*jslint') {
-                    error("Missing option value.", t);
-                }
-                obj[t.value] = false;
-                t = v;
-            }
-        }
-        if (filter) {
-            assume();
-        }
-    }
-
-
-// We need a peek function. If it has an argument, it peeks that much farther
-// ahead. It is used to distinguish
-//     for ( var i in ...
-// from
-//     for ( var i = ...
-
-    function peek(p) {
-        var i = p || 0, j = 0, t;
-
-        while (j <= i) {
-            t = lookahead[j];
-            if (!t) {
-                t = lookahead[j] = lex.token();
-            }
-            j += 1;
-        }
-        return t;
-    }
-
-
-
-// Produce the next token. It looks for programming errors.
-
-    function advance(id, t) {
-        switch (token.id) {
-        case '(number)':
-            if (nexttoken.id === '.') {
-                warning(
-"A dot following a number can be confused with a decimal point.", token);
-            }
-            break;
-        case '-':
-            if (nexttoken.id === '-' || nexttoken.id === '--') {
-                warning("Confusing minusses.");
-            }
-            break;
-        case '+':
-            if (nexttoken.id === '+' || nexttoken.id === '++') {
-                warning("Confusing plusses.");
-            }
-            break;
-        }
-        if (token.type === '(string)' || token.identifier) {
-            anonname = token.value;
-        }
-
-        if (id && nexttoken.id !== id) {
-            if (t) {
-                if (nexttoken.id === '(end)') {
-                    warning("Unmatched '{a}'.", t, t.id);
-                } else {
-                    warning(
-"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
-                            nexttoken, id, t.id, t.line, nexttoken.value);
-                }
-            } else if (nexttoken.type !== '(identifier)' ||
-                            nexttoken.value !== id) {
-                warning("Expected '{a}' and instead saw '{b}'.",
-                        nexttoken, id, nexttoken.value);
-            }
-        }
-        prevtoken = token;
-        token = nexttoken;
-        for (;;) {
-            nexttoken = lookahead.shift() || lex.token();
-            if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
-                return;
-            }
-            if (nexttoken.type === 'special') {
-                doOption();
-            } else {
-                if (nexttoken.id !== '(endline)') {
-                    break;
-                }
-            }
-        }
-    }
-
-
-// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
-// is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is
-// like nud except that it is only used on the first token of a statement.
-// Having .fud makes it much easier to define JavaScript. I retained Pratt's
-// nomenclature.
-
-// .nud     Null denotation
-// .fud     First null denotation
-// .led     Left denotation
-//  lbp     Left binding power
-//  rbp     Right binding power
-
-// They are key to the parsing method called Top Down Operator Precedence.
-
-    function parse(rbp, initial) {
-        var left;
-        if (nexttoken.id === '(end)') {
-            error("Unexpected early end of program.", token);
-        }
-        advance();
-        if (option.safe && typeof predefined[token.value] === 'boolean' &&
-                (nexttoken.id !== '(' && nexttoken.id !== '.')) {
-            warning('ADsafe violation.', token);
-        }
-        if (initial) {
-            anonname = 'anonymous';
-            funct['(verb)'] = token.value;
-        }
-        if (initial === true && token.fud) {
-            left = token.fud();
-        } else {
-            if (token.nud) {
-                left = token.nud();
-            } else {
-                if (nexttoken.type === '(number)' && token.id === '.') {
-                    warning(
-"A leading decimal point can be confused with a dot: '.{a}'.",
-                            token, nexttoken.value);
-                    advance();
-                    return token;
-                } else {
-                    error("Expected an identifier and instead saw '{a}'.",
-                            token, token.id);
-                }
-            }
-            while (rbp < nexttoken.lbp) {
-                advance();
-                if (token.led) {
-                    left = token.led(left);
-                } else {
-                    error("Expected an operator and instead saw '{a}'.",
-                        token, token.id);
-                }
-            }
-        }
-        return left;
-    }
-
-
-// Functions for conformance of style.
-
-    function adjacent(left, right) {
-        left = left || token;
-        right = right || nexttoken;
-        if (option.white || xmode === 'styleproperty' || xmode === 'style') {
-            if (left.character !== right.from && left.line === right.line) {
-                warning("Unexpected space after '{a}'.", right, left.value);
-            }
-        }
-    }
-
-    function nospace(left, right) {
-        left = left || token;
-        right = right || nexttoken;
-        if (option.white && !left.comment) {
-            if (left.line === right.line) {
-                adjacent(left, right);
-            }
-        }
-    }
-
-
-    function nonadjacent(left, right) {
-        if (option.white) {
-            left = left || token;
-            right = right || nexttoken;
-            if (left.line === right.line && left.character === right.from) {
-                warning("Missing space after '{a}'.",
-                

<TRUNCATED>

[36/50] [abbrv] git commit: [#4659] ticket:381 test for multiple attachments

Posted by tv...@apache.org.
[#4659]  ticket:381 test for multiple attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/94026f29
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/94026f29
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/94026f29

Branch: refs/heads/tv/6355
Commit: 94026f295048ff34325d51ea420ebdc5d71f567a
Parents: 870f5aa
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Jul 8 08:47:11 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 14:35:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/model/test_discussion.py | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/94026f29/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 72920e6..4ac1e37 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -206,6 +206,28 @@ def test_attachment_methods():
     n = M.Notification.query.get(subject=u'[test:wiki] Test comment notification')
     assert '\nAttachment: fake.txt (37 Bytes; text/plain)' in n.text
 
+@with_setup(setUp, tearDown())
+def test_multiple_attach():
+    test_file1 = FieldStorage()
+    test_file1.name = 'file_info'
+    test_file1.filename = 'test1.txt'
+    test_file1.type = 'text/plain'
+    test_file1.file=StringIO('test file1\n')
+    test_file2 = FieldStorage()
+    test_file2.name = 'file_info'
+    test_file2.filename = 'test2.txt'
+    test_file2.type = 'text/plain'
+    test_file2.file=StringIO('test file2\n')
+    d = M.Discussion(shortname='test', name='test')
+    t = M.Thread.new(discussion_id=d._id, subject='Test Thread')
+    test_post = t.post('test post')
+    test_post.add_multiple_attach([test_file1, test_file2])
+    ThreadLocalORMSession.flush_all()
+    assert test_post.attachments.count() == 2, test_post.attachments.count()
+    attaches = test_post.attachments.all()
+    assert 'test1.txt' in [attaches[0].filename, attaches[1].filename]
+    assert 'test2.txt' in [attaches[0].filename, attaches[1].filename]
+
 @with_setup(setUp, tearDown)
 def test_add_attachment():
     test_file = FieldStorage()


[26/50] [abbrv] git commit: [#4213] ticket:347 Import from trac: ScriptTask to run import

Posted by tv...@apache.org.
[#4213]  ticket:347 Import from trac: ScriptTask to run import


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/98cec904
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/98cec904
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/98cec904

Branch: refs/heads/tv/6355
Commit: 98cec9044dbed1fa4db3aac256110feecfaed136
Parents: 964c3d1
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Jun 10 14:55:24 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 06:09:58 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/import_support.py     |   1 -
 ForgeTracker/forgetracker/scripts/__init__.py   |  16 +++
 .../forgetracker/scripts/import_tracker.py      | 120 +++++++++++++++++++
 scripts/allura_import.py                        |  50 +-------
 4 files changed, 138 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/98cec904/ForgeTracker/forgetracker/import_support.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/import_support.py b/ForgeTracker/forgetracker/import_support.py
index d23cf94..a94e70c 100644
--- a/ForgeTracker/forgetracker/import_support.py
+++ b/ForgeTracker/forgetracker/import_support.py
@@ -316,7 +316,6 @@ option user_map to avoid losing username information. Unknown users: %s''' % unk
         for a in artifacts:
             comments = a.pop('comments', [])
             attachments = a.pop('attachments', [])
-#            log.info(a)
             t = self.make_artifact(a)
             for c_entry in comments:
                 self.make_comment(t.discussion_thread, c_entry)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/98cec904/ForgeTracker/forgetracker/scripts/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/scripts/__init__.py b/ForgeTracker/forgetracker/scripts/__init__.py
new file mode 100644
index 0000000..144e298
--- /dev/null
+++ b/ForgeTracker/forgetracker/scripts/__init__.py
@@ -0,0 +1,16 @@
+#       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.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/98cec904/ForgeTracker/forgetracker/scripts/import_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/scripts/import_tracker.py b/ForgeTracker/forgetracker/scripts/import_tracker.py
new file mode 100644
index 0000000..a84bede
--- /dev/null
+++ b/ForgeTracker/forgetracker/scripts/import_tracker.py
@@ -0,0 +1,120 @@
+#       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.
+
+
+import argparse
+import json
+import logging
+
+from allura.scripts import ScriptTask
+from allura.lib.import_api import AlluraImportApiClient
+
+log = logging.getLogger(__name__)
+
+def import_tracker(cli, project, tool, import_options, options, doc_txt, validate=True, verbose=False):
+    url = '/rest/p/' + project + '/' + tool
+    if validate:
+        url += '/validate_import'
+    else:
+        url += '/perform_import'
+
+    existing_map = {}
+    if options.cont:
+        existing_tickets = cli.call('/rest/p/' + options.project + '/' + options.tracker + '/')['tickets']
+        for t in existing_tickets:
+            existing_map[t['ticket_num']] = t['summary']
+
+    doc = json.loads(doc_txt)
+
+    if 'trackers' in doc and 'default' in doc['trackers'] and 'artifacts' in doc['trackers']['default']:
+        tickets_in = doc['trackers']['default']['artifacts']
+        doc['trackers']['default']['artifacts'] = []
+    else:
+        tickets_in = doc
+
+    if options.verbose:
+        print "Processing %d tickets" % len(tickets_in)
+
+    for cnt, ticket_in in enumerate(tickets_in):
+        if ticket_in['id'] in existing_map:
+            if options.verbose:
+                print 'Ticket id %d already exists, skipping' % ticket_in['id']
+            continue
+        doc_import={}
+        doc_import['trackers'] = {}
+        doc_import['trackers']['default'] = {}
+        doc_import['trackers']['default']['artifacts'] = [ticket_in]
+        res = cli.call(url, doc=json.dumps(doc_import), options=json.dumps(import_options))
+        assert res['status'] and not res['errors']
+        if options.validate:
+            if res['warnings']:
+                print "Ticket id %s warnings: %s" % (ticket_in['id'], res['warnings'])
+        else:
+            print "Imported ticket id %s" % (ticket_in['id'])
+
+class ImportTracker(ScriptTask):
+    @classmethod
+    def execute(cls, options):
+        user_map = {}
+        import_options = {}
+        for s in options.import_opts:
+            k, v = s.split('=', 1)
+            if v == 'false':
+                v = False
+            import_options[k] = v
+
+        if options.user_map_file:
+            f = open(options.user_map_file)
+            try:
+                user_map = json.load(f)
+                if type(user_map) is not type({}):
+                    raise ValueError
+                for k, v in user_map.iteritems():
+                    if not isinstance(k, basestring) or not isinstance(v, basestring):
+                        raise ValueError
+            except ValueError:
+                raise '--user-map should specify JSON file with format {"original_user": "sf_user", ...}'
+            finally:
+                f.close()
+        import_options['user_map'] = user_map
+        cli = AlluraImportApiClient(options.base_url, options.api_key, options.secret_key, options.verbose)
+        doc_txt = open(options.file_data).read()
+        import_tracker(cli, options.project, options.tracker, import_options, options, doc_txt,
+                       validate=options.validate,
+                       verbose=options.verbose)
+
+    @classmethod
+    def parser(cls):
+        parser = argparse.ArgumentParser(description='import tickets from json')
+        parser.add_argument('--nbhd', action='store', default='', dest='nbhd',
+                help='Restrict update to a particular neighborhood, e.g. /p/.')
+        parser.add_argument('-a', '--api-ticket', action='store', dest='api_key', help='API ticket')
+        parser.add_argument('-s', '--secret-key', action='store', dest='secret_key', help='Secret key')
+        parser.add_argument('-p', '--project', action='store', dest='project', help='Project to import to')
+        parser.add_argument('-t', '--tracker', action='store', dest='tracker', help='Tracker to import to')
+        parser.add_argument('-u', '--base-url', dest='base_url', default='https://sourceforge.net', help='Base Allura URL (%default)')
+        parser.add_argument('-o', dest='import_opts', default=[], action='store',  help='Specify import option(s)', metavar='opt=val')
+        parser.add_argument('--user-map', dest='user_map_file', help='Map original users to SF.net users', metavar='JSON_FILE')
+        parser.add_argument('--file_data', dest='file_data', help='json file', metavar='JSON_FILE')
+        parser.add_argument('--validate', dest='validate', action='store_true', help='Validate import data')
+        parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='Verbose operation')
+        parser.add_argument('-c', '--continue', dest='cont', action='store_true', help='Continue import into existing tracker')
+        return parser
+
+
+if __name__ == '__main__':
+    ImportTracker.main()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/98cec904/scripts/allura_import.py
----------------------------------------------------------------------
diff --git a/scripts/allura_import.py b/scripts/allura_import.py
index ba250e3..ddcd588 100644
--- a/scripts/allura_import.py
+++ b/scripts/allura_import.py
@@ -15,19 +15,12 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-import os
-import sys
-import urllib
-import urllib2
-import urlparse
-import hmac
-import hashlib
 import json
 from optparse import OptionParser
-from pprint import pprint
 from datetime import datetime
 
 from allura.lib.import_api import AlluraImportApiClient
+from forgetracker.scripts.import_tracker import import_tracker
 
 
 def main():
@@ -69,46 +62,6 @@ def main():
     elif options.forum:
         import_forum(cli, options.project, options.forum, user_map, doc_txt, validate=options.validate)
 
-def import_tracker(cli, project, tool, import_options, options, doc_txt, validate=True, verbose=False):
-    url = '/rest/p/' + project + '/' + tool
-    if validate:
-        url += '/validate_import'
-    else:
-        url += '/perform_import'
-
-    existing_map = {}
-    if options.cont:
-        existing_tickets = cli.call('/rest/p/' + options.project + '/' + options.tracker + '/')['tickets']
-        for t in existing_tickets:
-            existing_map[t['ticket_num']] = t['summary']
-
-    doc = json.loads(doc_txt)
-
-    if 'trackers' in doc and 'default' in doc['trackers'] and 'artifacts' in doc['trackers']['default']:
-        tickets_in = doc['trackers']['default']['artifacts']
-        doc['trackers']['default']['artifacts'] = []
-    else:
-        tickets_in = doc
-        
-    if options.verbose:
-        print "Processing %d tickets" % len(tickets_in)
-
-    for cnt, ticket_in in enumerate(tickets_in):
-            if ticket_in['id'] in existing_map:
-                if options.verbose:
-                    print 'Ticket id %d already exists, skipping' % ticket_in['id']
-                continue
-            doc_import={}
-            doc_import['trackers'] = {}
-            doc_import['trackers']['default'] = {}
-            doc_import['trackers']['default']['artifacts'] = [ticket_in]
-            res = cli.call(url, doc=json.dumps(doc_import), options=json.dumps(import_options))
-            assert res['status'] and not res['errors']
-            if options.validate:
-                if res['warnings']:
-                    print "Ticket id %s warnings: %s" % (ticket_in['id'], res['warnings'])
-            else:
-                print "Imported ticket id %s" % (ticket_in['id'])
 
 def import_forum(cli, project, tool, user_map, doc_txt, validate=True):
     url = '/rest/p/' + project + '/' + tool
@@ -119,6 +72,7 @@ def import_forum(cli, project, tool, user_map, doc_txt, validate=True):
         url += '/perform_import'
         print cli.call(url, doc=doc_txt, user_map=json.dumps(user_map))
 
+
 def parse_options():
     optparser = OptionParser(usage='''%prog [options] <JSON dump>
 


[09/50] [abbrv] git commit: [#4657] refactor File.serve to a general helper method

Posted by tv...@apache.org.
[#4657] refactor File.serve to a general helper method


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/43587016
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/43587016
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/43587016

Branch: refs/heads/tv/6355
Commit: 435870162a56a4b05d35a66865f34c4ebbdccf04
Parents: ff44014
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Jun 10 22:31:12 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Jul 3 21:35:16 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/utils.py        | 25 ++++++++++++++++++++++++-
 Allura/allura/model/filesystem.py | 20 +++++---------------
 2 files changed, 29 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/43587016/Allura/allura/lib/utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index 7c490e2..a88511c 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -37,7 +37,7 @@ from formencode import Invalid
 from tg.decorators import before_validate
 from pylons import response
 from pylons import tmpl_context as c
-from paste.deploy.converters import asbool
+from paste.deploy.converters import asbool, asint
 from paste.httpheaders import CACHE_CONTROL, EXPIRES
 from webhelpers.html import literal
 from webob import exc
@@ -471,3 +471,26 @@ def take_while_true(source):
         yield x
         x = source()
 
+
+def serve_file(fp, filename, content_type, last_modified=None, cache_expires=None, size=None, embed=True):
+    '''Sets the response headers and serves as a wsgi iter'''
+    pylons.response.headers['Content-Type'] = ''
+    pylons.response.content_type = content_type.encode('utf-8')
+    pylons.response.cache_expires = cache_expires or asint(tg.config.get('files_expires_header_secs', 60 * 60))
+    pylons.response.last_modified = last_modified
+    if size:
+        pylons.response.content_length = size
+    if 'Pragma' in pylons.response.headers:
+        del pylons.response.headers['Pragma']
+    if 'Cache-Control' in pylons.response.headers:
+        del pylons.response.headers['Cache-Control']
+    if not embed:
+        pylons.response.headers.add(
+            'Content-Disposition',
+            'attachment;filename="%s"' % filename.encode('utf-8'))
+    # http://code.google.com/p/modwsgi/wiki/FileWrapperExtension
+    block_size = 4096
+    if 'wsgi.file_wrapper' in tg.request.environ:
+        return tg.request.environ['wsgi.file_wrapper'](fp, block_size)
+    else:
+        return iter(lambda: fp.read(block_size), '')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/43587016/Allura/allura/model/filesystem.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/filesystem.py b/Allura/allura/model/filesystem.py
index c56e595..1bb0087 100644
--- a/Allura/allura/model/filesystem.py
+++ b/Allura/allura/model/filesystem.py
@@ -23,7 +23,6 @@ import pylons
 import PIL
 from gridfs import GridFS
 from tg import config
-from paste.deploy.converters import asint
 
 from ming import schema
 from ming.orm import session, FieldProperty
@@ -109,20 +108,11 @@ class File(MappedClass):
 
     def serve(self, embed=True):
         '''Sets the response headers and serves as a wsgi iter'''
-        fp = self.rfile()
-        pylons.response.headers['Content-Type'] = ''
-        pylons.response.content_type = self.content_type.encode('utf-8')
-        pylons.response.cache_expires = asint(config.get('files_expires_header_secs', 60 * 60))
-        pylons.response.last_modified = self._id.generation_time
-        if 'Pragma' in pylons.response.headers:
-            del pylons.response.headers['Pragma']
-        if 'Cache-Control' in pylons.response.headers:
-            del pylons.response.headers['Cache-Control']
-        if not embed:
-            pylons.response.headers.add(
-                'Content-Disposition',
-                'attachment;filename="%s"' % self.filename.encode('utf-8'))
-        return iter(fp)
+        gridfs_file = self.rfile()
+        return utils.serve_file(gridfs_file, self.filename, self.content_type,
+                                last_modified=self._id.generation_time,
+                                size=gridfs_file.length,
+                                embed=embed)
 
     @classmethod
     def save_thumbnail(cls, filename, image,


[30/50] [abbrv] git commit: Exclude non-builtin apps from this test

Posted by tv...@apache.org.
Exclude non-builtin apps from this test

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/b8d0e6ac
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/b8d0e6ac
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/b8d0e6ac

Branch: refs/heads/tv/6355
Commit: b8d0e6ac000e6face2d8b5003be0635e896c3f5d
Parents: 584a728
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Jul 10 17:49:31 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jul 10 17:49:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_admin.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b8d0e6ac/Allura/allura/tests/functional/test_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 9535c36..8b1d703 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -155,10 +155,13 @@ class TestProjectAdmin(TestController):
         assert "uninstall tool test-tool" in r.body, r.body
 
     def test_tool_permissions(self):
+        BUILTIN_APPS = ['activity', 'blog', 'discussion', 'git', 'link',
+                'shorturl', 'svn', 'tickets', 'userstats', 'wiki']
         self.app.get('/admin/')
         for i, ep in enumerate(pkg_resources.iter_entry_points('allura')):
             app = ep.load()
-            if not app.installable: continue
+            if not app.installable or ep.name.lower() not in BUILTIN_APPS:
+                continue
             tool = ep.name
             with audits('install tool test-%d' % i):
                 self.app.post('/admin/update_mounts', params={


[25/50] [abbrv] git commit: [#4213] ticket:345 import from trac: set milestone options

Posted by tv...@apache.org.
[#4213]  ticket:345 import from trac: set milestone options


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/0efd308a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/0efd308a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/0efd308a

Branch: refs/heads/tv/6355
Commit: 0efd308af702c9b0f0b39511a0db093d8aa9060c
Parents: d8ed95c
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon May 27 10:55:43 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 06:08:00 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/import_support.py     | 30 ++++++++++++++++
 .../forgetracker/tests/functional/data/sf.json  |  3 +-
 .../tests/functional/test_import.py             | 37 ++++++++++++++++++++
 3 files changed, 69 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0efd308a/ForgeTracker/forgetracker/import_support.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/import_support.py b/ForgeTracker/forgetracker/import_support.py
index 6970004..56c6947 100644
--- a/ForgeTracker/forgetracker/import_support.py
+++ b/ForgeTracker/forgetracker/import_support.py
@@ -18,11 +18,13 @@
 #-*- python -*-
 import logging
 import json
+import shlex
 from datetime import datetime
 from cStringIO import StringIO
 
 # Non-stdlib imports
 from pylons import tmpl_context as c
+from allura.lib import helpers as h
 
 from ming.orm.ormsession import ThreadLocalORMSession
 
@@ -140,6 +142,33 @@ class ImportSupport(object):
             return u._id
         return None
 
+    def check_suctom_field(self, field, value):
+        field = c.app.globals.get_custom_field(field)
+        if (field['type'] == 'select') and (value != ''):
+            field_options = h.really_unicode(field['options'])
+            try:
+                field_options = shlex.split(field_options.encode('utf-8'))
+                field_options = map(h.really_unicode, field_options)
+            except ValueError:
+                field_options = field_options.split()
+            field_options = [o.replace('"', '') for o in field_options]
+            if value not in field_options:
+                field['options'] = ' '.join([field['options'], value])
+        elif (field['type'] == 'milestone') and (value != ''):
+            milestones = field['milestones']
+            is_exists = False
+            for milestone in milestones:
+                if milestone['name'] == value:
+                    is_exists = True
+            if not is_exists:
+                milestone = {'due_date': '',
+                             'complete': False,
+                             'description': '',
+                             'name': value,
+                             'old_name': value}
+                field['milestones'].append(milestone)
+        ThreadLocalORMSession.flush_all()
+
     def custom(self, ticket, field, value):
         field = '_' + field
         if not c.app.has_custom_field(field):
@@ -148,6 +177,7 @@ class ImportSupport(object):
             ThreadLocalORMSession.flush_all()
         if 'custom_fields' not in ticket:
             ticket['custom_fields'] = {}
+        self.check_suctom_field(field, value)
         ticket['custom_fields'][field] = value
 
     #

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0efd308a/ForgeTracker/forgetracker/tests/functional/data/sf.json
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/data/sf.json b/ForgeTracker/forgetracker/tests/functional/data/sf.json
index 93632fd..58e322c 100644
--- a/ForgeTracker/forgetracker/tests/functional/data/sf.json
+++ b/ForgeTracker/forgetracker/tests/functional/data/sf.json
@@ -47,7 +47,8 @@
           "date_updated": "2009-07-20T15:44:32Z", 
           "description": "This problem occurs with IE 7, Windows Vista:\r\nOn the project's public info page (for example:\r\nhttps://sourceforge.net/project/admin/public_info.php?group_id=258655), the text boxes next to \"Descriptive Name\" and \"Project Description\" are not aligned properly; see the screenshot attached. ", 
           "id": 204, 
-          "keywords": "ENGR", 
+          "keywords": "ENGR",
+          "milestone": "test_milestone",
           "private": false, 
           "resolution": "fixed", 
           "status": "open", 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0efd308a/ForgeTracker/forgetracker/tests/functional/test_import.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_import.py b/ForgeTracker/forgetracker/tests/functional/test_import.py
index 7df19f7..06fde25 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_import.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_import.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #       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
@@ -17,6 +18,7 @@
 
 import os
 import json
+from formencode.variabledecode import variable_encode
 from datetime import datetime, timedelta
 from nose.tools import assert_equal
 
@@ -89,6 +91,39 @@ class TestImportController(TestRestApiBase):
         assert not r.json['errors']
 
     @td.with_tracker
+    def test_import_custom_field(self):
+        params = dict(
+            custom_fields=[
+                dict(name='_resolution', label='Resolution', type='select',
+                     options='oné "one and á half" two'),
+               ],
+            open_status_names='aa bb',
+            closed_status_names='cc',
+            )
+        self.app.post(
+            '/admin/bugs/set_custom_fields',
+            params=variable_encode(params))
+        here_dir = os.path.dirname(__file__)
+        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects','test']},
+                                 expires=datetime.utcnow() + timedelta(days=1))
+        ming.orm.session(api_ticket).flush()
+        self.set_api_token(api_ticket)
+
+        doc_text = open(here_dir + '/data/sf.json').read()
+        doc_json = json.loads(doc_text)
+        ticket_json = doc_json['trackers']['default']['artifacts'][0]
+        self.api_post('/rest/p/test/bugs/perform_import',
+            doc=doc_text, options='{"user_map": {"hinojosa4": "test-admin", "ma_boehm": "test-user"}}')
+
+        ming.orm.ThreadLocalORMSession.flush_all()
+        M.MonQTask.run_ready()
+        ming.orm.ThreadLocalORMSession.flush_all()
+
+        r = self.app.get('/p/test/bugs/204/')
+        assert '<option selected value="fixed">fixed</option>' in r
+        assert '<option value="one and á half">one and á half</option>' in r
+
+    @td.with_tracker
     def test_import(self):
         here_dir = os.path.dirname(__file__)
         api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects','test']},
@@ -124,6 +159,8 @@ class TestImportController(TestRestApiBase):
         assert_equal(r.json['tickets'][0]['summary'], ticket_json['summary'])
 
         r = self.app.get('/p/test/bugs/204/')
+        assert '<option value="2.0">2.0</option>' in r
+        assert '<option selected value="test_milestone">test_milestone</option>' in r
         assert ticket_json['summary'] in r
         r = self.app.get('/p/test/bugs/')
         assert ticket_json['summary'] in r


[23/50] [abbrv] git commit: [#4213] ticket:344 set buf_len for ResettableStream().seek

Posted by tv...@apache.org.
[#4213]  ticket:344 set buf_len for ResettableStream().seek


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/34394746
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/34394746
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/34394746

Branch: refs/heads/tv/6355
Commit: 34394746fdf7d6fa324c8987f2d5c9938e897118
Parents: 3ae3c36
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Wed May 22 15:38:03 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 06:08:00 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/import_support.py       |  9 +++++++--
 .../forgetracker/tests/unit/test_ticket_model.py  | 18 +++++++++++++++++-
 2 files changed, 24 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/34394746/ForgeTracker/forgetracker/import_support.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/import_support.py b/ForgeTracker/forgetracker/import_support.py
index 4c0f72f..1ea391b 100644
--- a/ForgeTracker/forgetracker/import_support.py
+++ b/ForgeTracker/forgetracker/import_support.py
@@ -69,13 +69,18 @@ class ResettableStream(object):
         data += self.fp.read(size)
         self.stream_pos += len(data)
         return data
-        
+
     def seek(self, pos):
+        if self.buf is None:
+            data = self.fp.read(self.buf_size)
+            self.buf = StringIO(data)
+            self.buf_len = len(data)
+
         if self.stream_pos > self.buf_len:
             assert False, 'Started reading stream body, cannot reset pos'
         self.buf.seek(pos)
         self.buf_pos = pos
-        
+
     def tell(self):
         if self.buf_pos < self.stream_pos:
             return self.buf_pos

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/34394746/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
index 9cca6df..c53afad 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
@@ -17,13 +17,15 @@
 
 from pylons import tmpl_context as c
 from datetime import datetime
+import urllib2
 
 from ming.orm.ormsession import ThreadLocalORMSession
 from ming import schema
 from nose.tools import raises, assert_raises, assert_equal
 
-from forgetracker.model import Ticket
+from forgetracker.model import Ticket, TicketAttachment
 from forgetracker.tests.unit import TrackerTestWithModel
+from forgetracker.import_support import ResettableStream
 from allura.model import Feed, Post, User
 from allura.lib import helpers as h
 from allura.tests import decorators as td
@@ -261,3 +263,17 @@ class TestTicketModel(TrackerTestWithModel):
         message += '\n- **_user_field_2**: test-user-0 (user not in project)'
         message += '\n- **assigned_to**: test-user-0 (user not in project)'
         assert_equal(post.text, message)
+
+    @td.with_tool('test', 'Tickets', 'bugs', username='test-user')
+    def test_attach_with_resettable_stream(self):
+        with h.push_context(c.project._id, app_config_id=c.app.config._id):
+            ticket = Ticket.new()
+            ticket.summary = 'test ticket'
+            ticket.description = 'test description'
+        assert_equal(len(ticket.attachments), 0)
+        f = urllib2.urlopen('http://sourceforge.net/apps/trac/sourceforge/raw-attachment/ticket/204/SF%20display%20error.JPG')
+        TicketAttachment.save_attachment('filename.txt', ResettableStream(f),
+                                            artifact_id=ticket._id)
+        ThreadLocalORMSession.flush_all()
+        assert_equal(len(ticket.attachments), 1)
+        assert_equal(ticket.attachments.first().filename, 'filename.txt')


[21/50] [abbrv] git commit: [#3060] Removed redundant commit log iteration and updated tests to new method

Posted by tv...@apache.org.
[#3060] Removed redundant commit log iteration and updated tests to new method

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/1e27f3d8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/1e27f3d8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/1e27f3d8

Branch: refs/heads/tv/6355
Commit: 1e27f3d88ef9ef696e1e8a72600905247320f507
Parents: 33e7fea
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jul 3 15:10:25 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 05:25:12 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/repo.py                     | 20 ++---
 Allura/allura/model/repository.py               | 22 ------
 Allura/allura/tests/model/test_repo.py          |  9 ++-
 ForgeGit/forgegit/model/git_repo.py             | 14 ----
 .../forgegit/tests/model/test_repository.py     | 80 +++++++-------------
 ForgeSVN/forgesvn/model/svn.py                  | 39 ----------
 .../forgesvn/tests/model/test_repository.py     | 54 ++++---------
 7 files changed, 58 insertions(+), 180 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e27f3d8/Allura/allura/model/repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repo.py b/Allura/allura/model/repo.py
index f683490..06a0853 100644
--- a/Allura/allura/model/repo.py
+++ b/Allura/allura/model/repo.py
@@ -783,13 +783,12 @@ class LastCommit(RepoObject):
 
     @classmethod
     def _last_commit_id(cls, commit, path):
-        commit_id = list(commit.repo.commits(path, commit._id, limit=1))
-        if commit_id:
-            commit_id = commit_id[0]
-        else:
+        try:
+            rev = commit.repo.log(commit._id, path, id_only=True).next()
+            return commit.repo.rev_to_commit_id(rev)
+        except StopIteration:
             log.error('Tree node not recognized by SCM: %s @ %s', path, commit._id)
-            commit_id = commit._id
-        return commit_id
+            return commit._id
 
     @classmethod
     def _prev_commit_id(cls, commit, path):
@@ -798,10 +797,13 @@ class LastCommit(RepoObject):
         lcid_cache = getattr(c, 'lcid_cache', '')
         if lcid_cache != '' and path in lcid_cache:
             return lcid_cache[path]
-        commit_id = list(commit.repo.commits(path, commit._id, skip=1, limit=1))
-        if not commit_id:
+        try:
+            log_iter = commit.repo.log(commit._id, path, id_only=True)
+            log_iter.next()
+            rev = log_iter.next()
+            return commit.repo.rev_to_commit_id(rev)
+        except StopIteration:
             return None
-        return commit_id[0]
 
     @classmethod
     def get(cls, tree, create=True):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e27f3d8/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 2904a39..3d893cc 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -135,14 +135,6 @@ class RepositoryImplementation(object):
         '''Return a blob size in bytes'''
         raise NotImplementedError, 'blob_size'
 
-    def commits(self, path=None, rev=None, skip=None, limit=None):
-        '''Return a list of the commits related to path'''
-        raise NotImplementedError, 'commits'
-
-    def commits_count(self, path=None, rev=None):
-        '''Return count of the commits related to path'''
-        raise NotImplementedError, 'commits_count'
-
     def tarball(self, revision, path=None):
         '''Create a tarball for the revision'''
         raise NotImplementedError, 'tarball'
@@ -346,10 +338,6 @@ class Repository(Artifact, ActivityObject):
         return self._impl.url_for_commit(commit, url_type)
     def compute_tree_new(self, commit, path='/'):
         return self._impl.compute_tree_new(commit, path)
-    def commits(self, path=None, rev=None, skip=None, limit=None):
-        return self._impl.commits(path, rev, skip, limit)
-    def commits_count(self, path=None, rev=None):
-        return self._impl.commits_count(path, rev)
     def last_commit_ids(self, commit, paths):
         return self._impl.last_commit_ids(commit, paths)
     def is_empty(self):
@@ -433,16 +421,6 @@ class Repository(Artifact, ActivityObject):
             exclude = [exclude]
         return self._impl.log(revs, path, exclude=exclude, id_only=id_only, **kw)
 
-    def commitlog(self, revs):
-        """
-        Return a generator that returns Commit model instances reachable by
-        the commits specified by revs.
-        """
-        for ci_id in self.log(revs, id_only=True):
-            commit = self.commit(ci_id)
-            commit.set_context(self)
-            yield commit
-
     def latest(self, branch=None):
         if self._impl is None:
             return None

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e27f3d8/Allura/allura/tests/model/test_repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_repo.py b/Allura/allura/tests/model/test_repo.py
index 3880629..5d9e95e 100644
--- a/Allura/allura/tests/model/test_repo.py
+++ b/Allura/allura/tests/model/test_repo.py
@@ -98,7 +98,8 @@ class TestLastCommit(unittest.TestCase):
         setup_global_objects()
         self.repo = mock.Mock('repo', _commits=OrderedDict(), _last_commit=None)
         self.repo.shorthand_for_commit = lambda _id: _id[:6]
-        self.repo.commits = self._commits
+        self.repo.rev_to_commit_id = lambda rev: rev
+        self.repo.log = self._log
         lcids = M.repository.RepositoryImplementation.last_commit_ids.__func__
         self.repo.last_commit_ids = lambda *a, **k: lcids(self.repo, *a, **k)
         c.lcid_cache = {}
@@ -155,8 +156,10 @@ class TestLastCommit(unittest.TestCase):
         self.repo._commits[commit._id] = commit
         return commit
 
-    def _commits(self, path, commit_id, skip=0, limit=-1):
-        return [c._id for c in reversed(self.repo._commits.values()) if path in c.changed_paths][skip:limit]
+    def _log(self, revs, path, id_only=True):
+        for commit_id, commit in reversed(self.repo._commits.items()):
+            if path in commit.changed_paths:
+                yield commit_id
 
     def test_single_commit(self):
         commit1 = self._add_commit('Commit 1', [

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e27f3d8/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 0da371d..9906c0b 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -266,20 +266,6 @@ class GitImplementation(M.RepositoryImplementation):
         doc.m.save(safe=False)
         return doc
 
-    def commits(self, path=None, rev=None, skip=None, limit=None):
-        params = dict(paths=path)
-        if rev is not None:
-            params['rev'] = rev
-        if skip is not None:
-            params['skip'] = skip
-        if limit is not None:
-            params['max_count'] = limit
-        return (c.hexsha for c in self._git.iter_commits(**params))
-
-    def commits_count(self, path=None, rev=None):
-        commit = self._git.commit(rev)
-        return commit.count(path)
-
     def log(self, revs=None, path=None, exclude=None, id_only=True, **kw):
         """
         Returns a generator that returns information about commits reachable

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e27f3d8/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index dba95ae..85777e2 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -471,59 +471,35 @@ class TestGitCommit(unittest.TestCase):
         for d in diffs:
             print d
 
-    def test_commits(self):
+    def test_log(self):
         # path only
-        commits = list(self.repo.commits())
-        assert len(commits) == 4, 'Returned %s commits' % len(commits)
-        assert "9a7df788cf800241e3bb5a849c8870f2f8259d98" in commits, commits
-        commits = list(self.repo.commits('README'))
-        assert len(commits) == 2, 'Returned %s README commits' % len(commits)
-        assert "1e146e67985dcd71c74de79613719bef7bddca4a" in commits, commits
-        assert "df30427c488aeab84b2352bdf88a3b19223f9d7a" in commits, commits
-        assert list(self.repo.commits('does/not/exist')) == []
-        # with path and start rev
-        commits = list(self.repo.commits('README', 'df30427c488aeab84b2352bdf88a3b19223f9d7a'))
-        assert_equal(commits, ['df30427c488aeab84b2352bdf88a3b19223f9d7a'])
-        # skip and limit
-        commits = list(self.repo.commits(None, rev=None, skip=1, limit=2))
-        assert_equal(commits, ['df30427c488aeab84b2352bdf88a3b19223f9d7a', '6a45885ae7347f1cac5103b0050cc1be6a1496c8'])
-        commits = list(self.repo.commits(None, '6a45885ae7347f1cac5103b0050cc1be6a1496c8', skip=1))
-        assert_equal(commits, ['9a7df788cf800241e3bb5a849c8870f2f8259d98'])
-        commits = list(self.repo.commits('README', 'df30427c488aeab84b2352bdf88a3b19223f9d7a', skip=1))
-        assert commits == []
-        # path to dir
-        commits = list(self.repo.commits('a/b/c/'))
-        assert commits == ['6a45885ae7347f1cac5103b0050cc1be6a1496c8', '9a7df788cf800241e3bb5a849c8870f2f8259d98']
-        commits = list(self.repo.commits('a/b/c/', skip=1))
-        assert commits == ['9a7df788cf800241e3bb5a849c8870f2f8259d98']
-        commits = list(self.repo.commits('a/b/c/', limit=1))
-        assert commits == ['6a45885ae7347f1cac5103b0050cc1be6a1496c8']
-        commits = list(self.repo.commits('not/exist/'))
-        assert commits == []
-        # with missing add record
-        commit = M.repo.Commit.query.get(_id='df30427c488aeab84b2352bdf88a3b19223f9d7a')
-        commit.changed_paths = []
-        commits = list(self.repo.commits('README', 'df30427c488aeab84b2352bdf88a3b19223f9d7a'))
-        assert_equal(commits, ['df30427c488aeab84b2352bdf88a3b19223f9d7a'])
-        # with missing add record & no parent
-        commit = M.repo.Commit.query.get(_id='9a7df788cf800241e3bb5a849c8870f2f8259d98')
-        commit.changed_paths = ['a']
-        commits = list(self.repo.commits('a/b/c/hello.txt', '9a7df788cf800241e3bb5a849c8870f2f8259d98'))
-        assert_equal(commits, ['9a7df788cf800241e3bb5a849c8870f2f8259d98'])
-
-    def test_commits_count(self):
-        commits = self.repo.commits_count()
-        assert commits == 4, commits
-        commits = self.repo.commits_count('README')
-        assert commits == 2, commits
-        commits = self.repo.commits_count(None, 'df30427c488aeab84b2352bdf88a3b19223f9d7a')
-        assert commits == 3, commits
-        commits = self.repo.commits_count('a/b/c/hello.txt', '6a45885ae7347f1cac5103b0050cc1be6a1496c8')
-        assert commits == 2, commits
-        commits = self.repo.commits_count('a/b/c/')
-        assert commits == 2, commits
-        commits = self.repo.commits_count('not/exist/')
-        assert commits == 0, commits
+        commits = list(self.repo.log(id_only=True))
+        assert_equal(commits, [
+                "1e146e67985dcd71c74de79613719bef7bddca4a",
+                "df30427c488aeab84b2352bdf88a3b19223f9d7a",
+                "6a45885ae7347f1cac5103b0050cc1be6a1496c8",
+                "9a7df788cf800241e3bb5a849c8870f2f8259d98",
+            ])
+        commits = list(self.repo.log(self.repo.head, 'README', id_only=True))
+        assert_equal(commits, [
+                "1e146e67985dcd71c74de79613719bef7bddca4a",
+                "df30427c488aeab84b2352bdf88a3b19223f9d7a",
+            ])
+        commits = list(self.repo.log("df30427c488aeab84b2352bdf88a3b19223f9d7a", 'README', id_only=True))
+        assert_equal(commits, [
+                "df30427c488aeab84b2352bdf88a3b19223f9d7a",
+            ])
+        commits = list(self.repo.log(self.repo.head, '/a/b/c/', id_only=True))
+        assert_equal(commits, [
+                "6a45885ae7347f1cac5103b0050cc1be6a1496c8",
+                "9a7df788cf800241e3bb5a849c8870f2f8259d98",
+            ])
+        commits = list(self.repo.log("9a7df788cf800241e3bb5a849c8870f2f8259d98", '/a/b/c/', id_only=True))
+        assert_equal(commits, [
+                "9a7df788cf800241e3bb5a849c8870f2f8259d98",
+            ])
+        commits = list(self.repo.log(self.repo.head, '/does/not/exist/', id_only=True))
+        assert_equal(commits, [])
 
 
 class TestGitHtmlView(unittest.TestCase):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e27f3d8/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index e348850..1ff9564 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -620,45 +620,6 @@ class SVNImplementation(M.RepositoryImplementation):
     def _oid(self, revno):
         return '%s:%s' % (self._repo._id, revno)
 
-    def commits(self, path=None, rev=None, skip=None, limit=None):
-        if path is not None:
-            path = '%s/%s' % (self._url, path)
-        else:
-            path = self._url
-        opts = {}
-        if rev is not None:
-            opts['revision_start'] = pysvn.Revision(pysvn.opt_revision_kind.number, self._revno(rev))
-            opts['revision_end'] = pysvn.Revision(pysvn.opt_revision_kind.number, 0)
-        if skip is None: skip = 0
-        if limit:
-            # we need to expand limit to include skipped revs (pysvn doesn't support skip)
-            opts['limit'] = skip + limit
-        try:
-            revs = self._svn.log(path, **opts)
-        except pysvn.ClientError as e:
-            log.exception('ClientError processing commits for SVN: path %s, rev %s, skip=%s, limit=%s, treating as empty',
-                    path, rev, skip, limit)
-            return []
-        if skip:
-            # pysvn has already limited result for us, we just need to skip
-            revs = revs[skip:]
-        return [self._oid(r.revision.number) for r in revs]
-
-    def commits_count(self, path=None, rev=None):
-        if path is not None:
-            path = '%s/%s' % (self._url, path)
-        else:
-            path = self._url
-        opts = {}
-        if rev is not None:
-            opts['revision_start'] = pysvn.Revision(pysvn.opt_revision_kind.number, self._revno(rev))
-            opts['revision_end'] = pysvn.Revision(pysvn.opt_revision_kind.number, 0)
-        try:
-            return len(self._svn.log(path, **opts))
-        except pysvn.ClientError as e:
-            log.exception('ClientError processing commits for SVN: path %s, rev %s, treating as empty', path, rev)
-            return 0
-
     def last_commit_ids(self, commit, paths):
         '''
         Return a mapping {path: commit_id} of the _id of the last

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e27f3d8/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 3f5182a..e47158f 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -559,46 +559,19 @@ class TestSVNRev(unittest.TestCase):
     def _oid(self, rev_id):
         return '%s:%s' % (self.repo._id, rev_id)
 
-    def test_commits(self):
+    def test_log(self):
         # path only
-        commits = self.repo.commits()
-        assert len(commits) == 5, 'Returned %s commits' % len(commits)
-        assert self._oid(5) in commits, commits
-        assert self._oid(1) in commits, commits
-        commits = self.repo.commits('README')
-        assert commits == [self._oid(3), self._oid(1)]
-        assert self.repo.commits('does/not/exist') == []
-        # with path and start rev
-        commits = self.repo.commits('README', self._oid(1))
-        assert commits == [self._oid(1)], commits
-        # skip and limit
-        commits = self.repo.commits(None, rev=None, skip=1, limit=2)
-        assert commits == [self._oid(4), self._oid(3)]
-        commits = self.repo.commits(None, self._oid(2), skip=1)
-        assert commits == [self._oid(1)], commits
-        commits = self.repo.commits('README', self._oid(1), skip=1)
-        assert commits == []
-        # path to dir
-        commits = self.repo.commits('a/b/c/')
-        assert commits == [self._oid(4), self._oid(2)]
-        commits = self.repo.commits('a/b/c/', skip=1)
-        assert commits == [self._oid(2)]
-        commits = self.repo.commits('a/b/c/', limit=1)
-        assert commits == [self._oid(4)]
-        commits = self.repo.commits('not/exist/')
-        assert commits == []
-
-    def test_commits_count(self):
-        commits = self.repo.commits_count()
-        assert commits == 5, commits
-        commits = self.repo.commits_count('a/b/c/')
-        assert commits == 2, commits
-        commits = self.repo.commits_count(None, self._oid(3))
-        assert commits == 3, commits
-        commits = self.repo.commits_count('README', self._oid(1))
-        assert commits == 1, commits
-        commits = self.repo.commits_count('not/exist/')
-        assert commits == 0, commits
+        commits = list(self.repo.log(self.repo.head, id_only=True))
+        assert_equal(commits, [5, 4, 3, 2, 1])
+        commits = list(self.repo.log(self.repo.head, 'README', id_only=True))
+        assert_equal(commits, [3, 1])
+        commits = list(self.repo.log(1, 'README', id_only=True))
+        assert_equal(commits, [1])
+        commits = list(self.repo.log(self.repo.head, 'a/b/c/', id_only=True))
+        assert_equal(commits, [4, 2])
+        commits = list(self.repo.log(3, 'a/b/c/', id_only=True))
+        assert_equal(commits, [2])
+        assert_equal(list(self.repo.log(self.repo.head, 'does/not/exist', id_only=True)), [])
 
     def test_notification_email(self):
         setup_global_objects()
@@ -613,8 +586,7 @@ class TestSVNRev(unittest.TestCase):
             status = 'creating')
         self.repo.refresh()
         ThreadLocalORMSession.flush_all()
-        commits = self.repo.commits()
-        send_notifications(self.repo, [commits[4], ])
+        send_notifications(self.repo, [self.repo.rev_to_commit_id(1)])
         ThreadLocalORMSession.flush_all()
         n = M.Notification.query.find(
             dict(subject='[test:src] [r1] - rick446: Create readme')).first()


[34/50] [abbrv] git commit: [#4659] ticket:381 upload multiple attachments

Posted by tv...@apache.org.
[#4659]  ticket:381 upload multiple attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/087b9ec5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/087b9ec5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/087b9ec5

Branch: refs/heads/tv/6355
Commit: 087b9ec58400c9ebe7ab4c41cd8581ff12195820
Parents: 8fd2f6f
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Jul 5 15:44:48 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 14:35:12 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            | 20 ++++++++++++++++----
 Allura/allura/lib/widgets/discuss.py            |  2 +-
 Allura/allura/lib/widgets/form_fields.py        |  3 ++-
 Allura/allura/model/notification.py             | 16 ++++++++++++----
 .../templates/widgets/attachment_add.html       |  4 ++--
 Allura/allura/templates/widgets/edit_post.html  |  4 ++--
 Allura/allura/tests/model/test_discussion.py    | 18 ++++++++++++++++++
 .../tests/functional/test_forum.py              |  5 +++++
 ForgeTracker/forgetracker/model/ticket.py       | 10 +++++++---
 .../templates/tracker_widgets/ticket_form.html  |  4 ++--
 .../forgetracker/tests/functional/test_root.py  | 12 ++++++++++++
 ForgeTracker/forgetracker/tracker_main.py       | 10 +++++++---
 .../forgetracker/widgets/ticket_form.py         |  5 +++--
 .../forgewiki/tests/functional/test_root.py     | 14 ++++++++++++++
 ForgeWiki/forgewiki/wiki_main.py                |  9 +++++++--
 15 files changed, 110 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 9ff5e6c..97a08e5 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -202,7 +202,10 @@ class ThreadController(BaseController, FeedController):
 
         file_info = kw.get('file_info', None)
         p = self.thread.add_post(**kw)
-        p.add_attachment(file_info)
+        if isinstance(file_info, list):
+            map(p.add_attachment, file_info)
+        else:
+            p.add_attachment(file_info)
         if self.thread.artifact:
             self.thread.artifact.mod_date = datetime.utcnow()
         flash('Message posted')
@@ -275,7 +278,10 @@ class PostController(BaseController):
             require_access(self.post, 'moderate')
             post_fields = self.W.edit_post.to_python(kw, None)
             file_info = post_fields.pop('file_info', None)
-            self.post.add_attachment(file_info)
+            if isinstance(file_info, list):
+                map(self.post.add_attachment, file_info)
+            else:
+                self.post.add_attachment(file_info)
             for k,v in post_fields.iteritems():
                 try:
                     setattr(self.post, k, v)
@@ -320,7 +326,10 @@ class PostController(BaseController):
         require_access(self.thread, 'post')
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
-        p.add_attachment(file_info)
+        if isinstance(file_info, list):
+            map(p.add_attachment, file_info)
+        else:
+            p.add_attachment(file_info)
         redirect(request.referer)
 
     @h.vardec
@@ -355,7 +364,10 @@ class PostController(BaseController):
     @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
-        self.post.add_attachment(file_info)
+        if isinstance(file_info, list):
+            map(self.post.add_attachment, file_info)
+        else:
+            self.post.add_attachment(file_info)
         redirect(request.referer)
 
     @expose()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index e62a993..96a48b3 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -160,9 +160,9 @@ class EditPost(ff.ForgeForm):
         for r in ffw.MarkdownEdit(name='text').resources(): yield r
         yield ew.JSScript('''$(document).ready(function () {
             $("a.attachment_form_add_button").click(function(evt){
+                evt.preventDefault();
                 $(this).hide();
                 $(".attachment_form_fields", this.parentNode).show();
-                evt.preventDefault();
             });
             $("a.cancel_edit_post").click(function(evt){
                 $("textarea", this.parentNode).val($("input.original_value", this.parentNode).val());

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/lib/widgets/form_fields.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index 1accf93..221e0fc 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -191,9 +191,10 @@ class AttachmentAdd(ew_core.Widget):
     def resources(self):
         for r in super(AttachmentAdd, self).resources(): yield r
         yield onready('''
-            $("input.attachment_form_add_button").click(function () {
+            $(".attachment_form_add_button").click(function (evt) {
                 $(this).hide();
                 $(".attachment_form_fields", this.parentNode).show();
+                evt.preventDefault();
             });
          ''')
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index eced9d8..1d03eef 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -147,10 +147,18 @@ class Notification(MappedClass):
             text = post.text
             file_info = kwargs.pop('file_info', None)
             if file_info is not None:
-                file_info.file.seek(0, 2)
-                bytecount = file_info.file.tell()
-                file_info.file.seek(0)
-                text = "%s\n\n\nAttachment: %s (%s; %s)" % (text, file_info.filename, h.do_filesizeformat(bytecount), file_info.type)
+                text = "%s\n\n\nAttachment:" % text
+                if isinstance(file_info, list):
+                    for attach in file_info:
+                        attach.file.seek(0, 2)
+                        bytecount = attach.file.tell()
+                        attach.file.seek(0)
+                        text = "%s %s (%s; %s) " % (text, attach.filename, h.do_filesizeformat(bytecount), attach.type)
+                else:
+                    file_info.file.seek(0, 2)
+                    bytecount = file_info.file.tell()
+                    file_info.file.seek(0)
+                    text = "%s %s (%s; %s) " % (text, file_info.filename, h.do_filesizeformat(bytecount), file_info.type)
 
             subject = post.subject or ''
             if post.parent_id and not subject.lower().startswith('re:'):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/templates/widgets/attachment_add.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/attachment_add.html b/Allura/allura/templates/widgets/attachment_add.html
index 8ed2ab5..3af2ce7 100644
--- a/Allura/allura/templates/widgets/attachment_add.html
+++ b/Allura/allura/templates/widgets/attachment_add.html
@@ -19,11 +19,11 @@
 <form method="post"
       action="{{action}}"
       enctype="multipart/form-data">
-      <input type="button" value="Add attachment" class="attachment_form_add_button"/>
+      <a href="#" class="btn link attachment_form_add_button">Add attachments</a>
       <ol class="attachment_form_fields" style="display:none">
         <li>
           <label for="{{name}}">File to upload</label>
-          <input type="file" class="text" name="{{name}}" id="{{name}}"/>
+          <input type="file" class="text" name="{{name}}" multiple="True" id="{{name}}"/>
         </li>
         <li>
           <label>&nbsp;</label>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/templates/widgets/edit_post.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/edit_post.html b/Allura/allura/templates/widgets/edit_post.html
index 65762f3..0fe22a7 100644
--- a/Allura/allura/templates/widgets/edit_post.html
+++ b/Allura/allura/templates/widgets/edit_post.html
@@ -27,12 +27,12 @@
     <input type="hidden" class="original_value" value="{{value.text}}">
     <span class="arw"><span></span></span><br/>
     <div class="attachment_form_fields" style="display:none; padding: 5px 0;">
-      <input type="file" class="text" name="{{att_name}}" {% if att_id %}id="{{att_id}}"{% endif %}/>
+      <input type="file" class="text" multiple="True" name="{{att_name}}" {% if att_id %}id="{{att_id}}"{% endif %}/>
     </div>
     <div style="clear:both"></div>
     <input type="submit" value="{{submit_text}}"/>
     <a href="#" class="btn link cancel_edit_post">Cancel</a> &nbsp;
-    <a href="#" class="btn link attachment_form_add_button">Add attachment</a>
+    <a href="#" class="btn link attachment_form_add_button">Add attachments</a>
   {% if widget.antispam %}{% for fld in g.antispam.extra_fields() %}
   {{fld}}{% endfor %}{% endif %}
   </form>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index ec23e3b..72920e6 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -223,6 +223,24 @@ def test_add_attachment():
     assert attach.filename == 'test.txt', attach.filename
     assert attach.content_type == 'text/plain', attach.content_type
 
+def test_notification_two_attaches():
+    d = M.Discussion(shortname='test', name='test')
+    t = M.Thread.new(discussion_id=d._id, subject='Test comment notification')
+    fs1 = FieldStorage()
+    fs1.name = 'file_info'
+    fs1.filename = 'fake.txt'
+    fs1.type = 'text/plain'
+    fs1.file = StringIO('this is the content of the fake file\n')
+    fs2 = FieldStorage()
+    fs2.name = 'file_info'
+    fs2.filename = 'fake2.txt'
+    fs2.type = 'text/plain'
+    fs2.file = StringIO('this is the content of the fake file\n')
+    t.post(text=u'test message', forum=None, subject='', file_info=[fs1, fs2])
+    ThreadLocalORMSession.flush_all()
+    n = M.Notification.query.get(subject=u'[test:wiki] Test comment notification')
+    assert '\nAttachment: fake.txt (37 Bytes; text/plain)  fake2.txt (37 Bytes; text/plain)' in n.text
+
 @with_setup(setUp, tearDown)
 def test_discussion_delete():
     d = M.Discussion(shortname='test', name='test')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index a9288c8..c319263 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -226,7 +226,12 @@ class TestForumAsync(TestController):
         r = self.app.post(url + 'attach',
                           upload_files=[('file_info', 'test.asdfasdtxt',
                                          'This is a textfile')])
+        r = self.app.post(url + 'attach',
+                          upload_files=[('file_info', 'test1.txt','This is a textfile'),
+                                        ('file_info', 'test2.txt','This is a textfile')])
         r = self.app.get(url)
+        assert "test1.txt" in r
+        assert "test2.txt" in r
         for link in r.html.findAll('a'):
             if 'attachment' in link.get('href', ''):
                 self.app.get(str(link['href']))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 175c660..6679e2a 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -833,9 +833,13 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
                     self.custom_fields[k] = v
         self.commit()
         if attachment is not None:
-            self.attach(
-                attachment.filename, attachment.file,
-                content_type=attachment.type)
+            if isinstance(attachment, list):
+                for attach in attachment:
+                    self.attach(attach.filename, attach.file, content_type=attach.type)
+            else:
+                self.attach(
+                    attachment.filename, attachment.file,
+                    content_type=attachment.type)
 
     def _move_attach(self, attachments, attach_metadata, app_config):
         for attach in attachments:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html b/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
index d9c5743..5741603 100644
--- a/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
+++ b/ForgeTracker/forgetracker/templates/tracker_widgets/ticket_form.html
@@ -99,8 +99,8 @@
       </div>
       <div style="clear:both">&nbsp;</div>
     {% endif %}
-    <div id="show_attach">
-      <input type="checkbox"> I would like to add an attachment
+    <div>
+      <a href="#" id="show_attach">Add attachments</a>
     </div>
     <div style="clear:both">&nbsp;</div>
     <div id="view_attach" style="display:none">

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 77e0dc7..a78abd9 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -537,6 +537,18 @@ class TestFunctionalController(TrackerTestController):
         download = self.app.get(str(ticket_editor.html.findAll('form')[1].findAll('a')[7]['href']))
         assert_equal(download.body, file_data)
 
+    def test_two_attachments(self):
+        file_name1 = 'test_root1.py'
+        file_name2 = 'test_root2.py'
+        file_data = file(__file__).read()
+        self.new_ticket(summary='test new attachment')
+        ticket_editor = self.app.post('/bugs/1/update_ticket',{
+            'summary':'zzz'
+        }, upload_files=[('attachment', file_name1, file_data), ('attachment', file_name2, file_data)]).follow()
+
+        assert 'test_root1.py' in ticket_editor
+        assert 'test_root2.py' in ticket_editor
+
     def test_new_image_attachment_content(self):
         h.set_context('test', 'bugs', neighborhood='Projects')
         file_name = 'neo-icon-set-454545-256x350.png'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 5476596..3d2d02d 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1293,9 +1293,13 @@ class TicketController(BaseController, FeedController):
 
         if 'attachment' in post_data:
             attachment = post_data['attachment']
-            if hasattr(attachment, 'file'):
-                self.ticket.attach(
-                    attachment.filename, attachment.file, content_type=attachment.type)
+            if isinstance(attachment, list):
+                for attach in attachment:
+                    self.ticket.attach(attach.filename, attach.file, content_type=attach.type)
+            else:
+                if hasattr(attachment, 'file'):
+                    self.ticket.attach(
+                        attachment.filename, attachment.file, content_type=attachment.type)
         for cf in c.app.globals.custom_fields or []:
             if 'custom_fields.' + cf.name in post_data:
                 value = post_data['custom_fields.' + cf.name]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeTracker/forgetracker/widgets/ticket_form.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/ticket_form.py b/ForgeTracker/forgetracker/widgets/ticket_form.py
index cb05085..edee7e5 100644
--- a/ForgeTracker/forgetracker/widgets/ticket_form.py
+++ b/ForgeTracker/forgetracker/widgets/ticket_form.py
@@ -106,7 +106,7 @@ class GenericTicketForm(ew.SimpleForm):
             ffw.ProjectUserCombo(name='assigned_to', label='Owner'),
             ffw.LabelEdit(label='Labels',name='labels', className='ticket_form_tags'),
             ew.Checkbox(name='private', label='Mark as Private', attrs={'class':'unlabeled'}),
-            ew.InputField(name='attachment', label='Attachment', field_type='file', validator=fev.FieldStorageUploadConverter(if_missing=None)),
+            ew.InputField(name='attachment', label='Attachment', field_type='file', attrs={'multiple': 'True'}, validator=fev.FieldStorageUploadConverter(if_missing=None)),
             ffw.MarkdownEdit(name='comment', label='Comment',
                         attrs={'style':'min-height:7em; width:97%'}),
             ew.SubmitButton(label=self.submit_text,name='submit',
@@ -135,7 +135,8 @@ class TicketForm(GenericTicketForm):
         for r in super(TicketForm, self).resources(): yield r
         yield ew.JSScript('''
         $(function(){
-            $('#show_attach input').click(function(){
+            $('#show_attach').click(function(evt) {
+                evt.preventDefault();
                 $('#view_attach').show();
                 $('#show_attach').hide();
             });

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index f3570b2..05c0dd1 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -348,6 +348,20 @@ class TestRootController(TestController):
         response = self.app.get('/wiki/tést/')
         assert 'test_root.py' in response
 
+    def test_attach_two_fiels(self):
+        self.app.post(
+            '/wiki/tést/update',
+            params={
+                'title':'tést',
+                'text':'sometext',
+                'labels':'',
+                'viewable_by-0.id':'all'})
+        content = file(__file__).read()
+        self.app.post('/wiki/tést/attach', upload_files=[('file_info', 'test1.py', content),('file_info', 'test2.py', content)])
+        response = self.app.get('/wiki/tést/')
+        assert 'test1.py' in response
+        assert 'test2.py' in response
+
     def test_new_text_attachment_content(self):
         self.app.post(
             '/wiki/tést/update',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/087b9ec5/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 9cc0ffc..88f1102 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -649,8 +649,13 @@ class PageController(BaseController, FeedController):
         if not self.page:
             raise exc.HTTPNotFound
         require_access(self.page, 'edit')
-        if hasattr(file_info, 'file'):
-            self.page.attach(file_info.filename, file_info.file, content_type=file_info.type)
+        if isinstance(file_info, list):
+            for attach in file_info:
+                if hasattr(attach, 'file'):
+                    self.page.attach(attach.filename, attach.file, content_type=attach.type)
+        else:
+            if hasattr(file_info, 'file'):
+                self.page.attach(file_info.filename, file_info.file, content_type=file_info.type)
         redirect(request.referer)
 
     @expose()


[47/50] [abbrv] git commit: fix indentation

Posted by tv...@apache.org.
fix indentation


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/94b75f0a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/94b75f0a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/94b75f0a

Branch: refs/heads/tv/6355
Commit: 94b75f0a158f06f3c57690c8fdae51d452cf9015
Parents: 37e91c9
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Sat May 25 13:28:20 2013 -0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Jul 11 21:30:46 2013 +0000

----------------------------------------------------------------------
 AlluraTest/alluratest/validation.py | 175 ++++++++++++++++---------------
 1 file changed, 91 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/94b75f0a/AlluraTest/alluratest/validation.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/validation.py b/AlluraTest/alluratest/validation.py
index 235d7c0..7a5fd0b 100644
--- a/AlluraTest/alluratest/validation.py
+++ b/AlluraTest/alluratest/validation.py
@@ -115,112 +115,118 @@ def report_validation_error(val_name, filename, message):
     else:
         sys.stderr.write('=' * 40 + '\n' + message)
 
+
 def dump_to_file(prefix, html):
     f = tempfile.NamedTemporaryFile(prefix=prefix, delete=False)
     f.write(html)
     f.close()
     return f.name
 
+
 def validate_html(html_or_response):
-        if hasattr(html_or_response, 'body'):
-            html = html_or_response.body
-        else:
-            html = html_or_response
+    if hasattr(html_or_response, 'body'):
+        html = html_or_response.body
+    else:
+        html = html_or_response
 
-        html = html.lstrip()
+    html = html.lstrip()
+
+    if html.startswith('<!DOCTYPE html>'):
+        return validate_html5(html)
+    else:
+        assert False, 'Non-valid HTML: ' + html[:100] + '...'
 
-        if html.startswith('<!DOCTYPE html>'):
-            return validate_html5(html)
-        else:
-            assert False, 'Non-valid HTML: ' + html[:100] + '...'
 
 def validate_json(json_or_response):
-        if hasattr(json_or_response, 'body'):
-            j = json_or_response.body
-        else:
-            j = json_or_response
+    if hasattr(json_or_response, 'body'):
+        j = json_or_response.body
+    else:
+        j = json_or_response
 
-        try:
-            obj = json.loads(j)
-        except Exception, e:
-            ok_(False, "Couldn't validate JSON: " + str(e) + ':' + j[:100] + '...')
+    try:
+        obj = json.loads(j)
+    except Exception, e:
+        ok_(False, "Couldn't validate JSON: " + str(e) + ':' + j[:100] + '...')
+
+    return obj
 
-        return obj
 
 def validate_html5(html_or_response):
-        if hasattr(html_or_response, 'body'):
-            html = html_or_response.body
-        else:
-            html = html_or_response
-        register_openers()
-        params = [("out","text"),("content",html)]
-        datagen, headers = multipart_encode(params)
-        request = urllib2.Request("http://html5.validator.nu/", datagen, headers)
-        count = 3
-        while True:
-            try:
-                resp = urllib2.urlopen(request, timeout=3).read()
+    if hasattr(html_or_response, 'body'):
+        html = html_or_response.body
+    else:
+        html = html_or_response
+    register_openers()
+    params = [("out","text"),("content",html)]
+    datagen, headers = multipart_encode(params)
+    request = urllib2.Request("http://html5.validator.nu/", datagen, headers)
+    count = 3
+    while True:
+        try:
+            resp = urllib2.urlopen(request, timeout=3).read()
+            break
+        except:
+            resp = "Couldn't connect to validation service to check the HTML"
+            count -= 1
+            if count == 0:
+                sys.stderr.write('WARNING: ' + resp + '\n')
                 break
-            except:
-                resp = "Couldn't connect to validation service to check the HTML"
-                count -= 1
-                if count == 0:
-                    sys.stderr.write('WARNING: ' + resp + '\n')
-                    break
-
-        resp = resp.replace('“','"').replace('”','"').replace('–','-')
-
-        ignored_errors = [
-            'Required attributes missing on element "object"',
-            'Stray end tag "embed".',
-            'Stray end tag "param".',
-            r'Bad value .+? for attribute "onclick" on element "input": invalid return',
-        ]
-        for ignore in ignored_errors:
-            resp = re.sub('Error: ' + ignore, 'Ignoring: ' + ignore, resp)
-
-        if 'Error:' in resp:
-            fname = dump_to_file('html5-', html)
-            message = resp.decode('ascii','ignore')
-            report_validation_error('html5', fname, message)
+
+    resp = resp.replace('“','"').replace('”','"').replace('–','-')
+
+    ignored_errors = [
+        'Required attributes missing on element "object"',
+        'Stray end tag "embed".',
+        'Stray end tag "param".',
+        r'Bad value .+? for attribute "onclick" on element "input": invalid return',
+    ]
+    for ignore in ignored_errors:
+        resp = re.sub('Error: ' + ignore, 'Ignoring: ' + ignore, resp)
+
+    if 'Error:' in resp:
+        fname = dump_to_file('html5-', html)
+        message = resp.decode('ascii','ignore')
+        report_validation_error('html5', fname, message)
 
 
 def validate_html5_chunk(html):
-        """ When you don't have a html & body tags - this adds it"""
-        # WebTest doesn't like HTML fragments without doctype,
-        # so we output them sometimes for fragments, which is hack.
-        # Unhack it here.
-        doctype = '<!DOCTYPE html>'
-        if html.startswith(doctype):
-            html = html[len(doctype):]
-
-        html = '''<!DOCTYPE html>
-        <html>
-        <head><title></title></head>
-        <body>
-        %s
-        </body></html>''' % html
-        return validate_html5(html)
+    """ When you don't have a html & body tags - this adds it"""
+    # WebTest doesn't like HTML fragments without doctype,
+    # so we output them sometimes for fragments, which is hack.
+    # Unhack it here.
+    doctype = '<!DOCTYPE html>'
+    if html.startswith(doctype):
+        html = html[len(doctype):]
+
+    html = '''<!DOCTYPE html>
+    <html>
+    <head><title></title></head>
+    <body>
+    %s
+    </body></html>''' % html
+    return validate_html5(html)
+
 
 def validate_js(html_or_response):
-        if hasattr(html_or_response, 'body'):
-            if html_or_response.status_int != 200:
-                return
-            html = html_or_response.body
-        else:
-            html = html_or_response
-        basedir = path.dirname(path.abspath(__file__))
-        jslint_dir = basedir + '/../jslint'
-        fname = dump_to_file('jslint-', html)
-        cmd = 'java -jar ' + jslint_dir + '/js.jar '+ jslint_dir +'/jslint.js ' + fname
-        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-        stdout, stderr = p.communicate(html)
-        if stdout.startswith('jslint: No problems found'):
-            os.unlink(fname)
+    if hasattr(html_or_response, 'body'):
+        if html_or_response.status_int != 200:
             return
-        stdout = stdout.decode('UTF-8', 'replace')
-        msg = '\n'.join(repr(s) for s in stdout.split('\n') if s)
-        report_validation_error('js', fname, msg)
+        html = html_or_response.body
+    else:
+        html = html_or_response
+    basedir = path.dirname(path.abspath(__file__))
+    jslint_dir = basedir + '/../jslint'
+    fname = dump_to_file('jslint-', html)
+    cmd = 'java -jar ' + jslint_dir + '/js.jar '+ jslint_dir +'/jslint.js ' + fname
+    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    stdout, stderr = p.communicate(html)
+    if stdout.startswith('jslint: No problems found'):
+        os.unlink(fname)
+        return
+    stdout = stdout.decode('UTF-8', 'replace')
+    msg = '\n'.join(repr(s) for s in stdout.split('\n') if s)
+    report_validation_error('js', fname, msg)
+
 
 def validate_page(html_or_response):
     if Config.instance().validation_enabled('html5'):
@@ -228,6 +234,7 @@ def validate_page(html_or_response):
     if Config.instance().validation_enabled('inlinejs'):
         validate_js(html_or_response)
 
+
 class AntiSpamTestApp(TestApp):
 
     def post(self, *args, **kwargs):


[39/50] [abbrv] [#4122] rename AlluraTesting dir to AlluraTest, to match the module name below

Posted by tv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/jslint/rhino.js
----------------------------------------------------------------------
diff --git a/AlluraTesting/jslint/rhino.js b/AlluraTesting/jslint/rhino.js
deleted file mode 100644
index 04be512..0000000
--- a/AlluraTesting/jslint/rhino.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// rhino.js
-// 2009-09-11
-/*
-Copyright (c) 2002 Douglas Crockford  (www.JSLint.com) Rhino Edition
-*/
-
-// This is the Rhino companion to fulljslint.js.
-
-/*global JSLINT */
-/*jslint rhino: true, strict: false */
-
-(function (a) {
-    var e, i, input;
-    if (!a[0]) {
-        print("Usage: jslint.js file.js");
-        quit(1);
-    }
-    input = readFile(a[0]);
-    if (!input) {
-        print("jslint: Couldn't open file '" + a[0] + "'.");
-        quit(1);
-    }
-    if (!JSLINT(input, {bitwise: true, eqeqeq: true, immed: true,
-            newcap: true, nomen: true, onevar: true, plusplus: true,
-            regexp: true, rhino: true, undef: true, white: true})) {
-        for (i = 0; i < JSLINT.errors.length; i += 1) {
-            e = JSLINT.errors[i];
-            if (e) {
-                print('Lint at line ' + e.line + ' character ' +
-                        e.character + ': ' + e.reason);
-                print((e.evidence || '').
-                        replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"));
-                print('');
-            }
-        }
-        quit(2);
-    } else {
-        print("jslint: No problems found in " + a[0]);
-        quit();
-    }
-}(arguments));
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/setup.py
----------------------------------------------------------------------
diff --git a/AlluraTesting/setup.py b/AlluraTesting/setup.py
deleted file mode 100644
index a449b84..0000000
--- a/AlluraTesting/setup.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#       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.
-
-from setuptools import setup, find_packages
-import sys, os
-
-setup(name='AlluraTesting',
-      version='0.1',
-      description="Allura testing support",
-      long_description="""\
-""",
-      classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
-      keywords='',
-      author='',
-      author_email='',
-      url='',
-      license='',
-      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
-      include_package_data=True,
-      zip_safe=False,
-      install_requires=[
-        "poster",
-          # -*- Extra requirements: -*-
-      ]
-      )

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/README
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/README b/AlluraTesting/twill-tests/README
deleted file mode 100644
index 59e490e..0000000
--- a/AlluraTesting/twill-tests/README
+++ /dev/null
@@ -1,19 +0,0 @@
-Twill Tests
-
-First, you'll need twill-sh:
-
-  sudo easy_install twill
-
-
-Files in this directory ending with '.twill' are tests to be run by twill-sh
-
-  twill-sh --url=http://url.of.forge.to.test/ twill-tests/*.twill
-
-e.g.,
-
-  twill-sh --url=http://re.sourceforge.net/ twill-tests/*.twill
-
-
-If you just want to run the quick "smoke tests":
-
-  twill-sh --url=... twill-tests/smoke*.twill

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/create_repo.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/create_repo.twill b/AlluraTesting/twill-tests/create_repo.twill
deleted file mode 100644
index 17b9a3a..0000000
--- a/AlluraTesting/twill-tests/create_repo.twill
+++ /dev/null
@@ -1,47 +0,0 @@
-#       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.
-
-setlocal username test_admin
-setlocal password foo
-
-clear_extra_headers
-go ./auth/
-formvalue 1 username $username
-formvalue 1 password $password
-submit
-
-code 200
-
-go ./p/test/admin/tools
-
-code 200
-
-formvalue 2 "new.ep_name" "Git"
-formvalue 2 "new.mount_point" "deleteme"
-submit
-
-code 200
-
-go ../deleteme/
-
-code 200
-
-find ready
-
-go ../admin/tools
-
-# Delete the repo :-(

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/edit_wiki_page.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/edit_wiki_page.twill b/AlluraTesting/twill-tests/edit_wiki_page.twill
deleted file mode 100644
index 2b659ec..0000000
--- a/AlluraTesting/twill-tests/edit_wiki_page.twill
+++ /dev/null
@@ -1,36 +0,0 @@
-#       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.
-
-setlocal username test_admin
-setlocal password foo
-
-clear_extra_headers
-go ./auth/
-formvalue 1 username $username
-formvalue 1 password $password
-submit
-
-code 200
-
-go ./p/test/wiki/TestWikiWord/edit
-
-code 200
-
-formvalue 3 text "This is just a test."
-submit
-
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/login.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/login.twill b/AlluraTesting/twill-tests/login.twill
deleted file mode 100644
index fbe6f67..0000000
--- a/AlluraTesting/twill-tests/login.twill
+++ /dev/null
@@ -1,27 +0,0 @@
-#       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.
-
-setlocal username test_admin
-setlocal password foo
-
-clear_extra_headers
-go ./auth/
-formvalue 1 username $username
-formvalue 1 password $password
-submit
-
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/new_issue.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/new_issue.twill b/AlluraTesting/twill-tests/new_issue.twill
deleted file mode 100644
index 7b05168..0000000
--- a/AlluraTesting/twill-tests/new_issue.twill
+++ /dev/null
@@ -1,36 +0,0 @@
-#       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.
-
-setlocal username test_admin
-setlocal password foo
-
-clear_extra_headers
-go ./auth/
-formvalue 1 username $username
-formvalue 1 password $password
-submit
-
-code 200
-
-go ./p/test/bugs/new/
-
-code 200
-
-formvalue 2 "ticket_form.summary" "test create ticket"
-submit
-
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/smoke-front-page.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/smoke-front-page.twill b/AlluraTesting/twill-tests/smoke-front-page.twill
deleted file mode 100644
index a0f4852..0000000
--- a/AlluraTesting/twill-tests/smoke-front-page.twill
+++ /dev/null
@@ -1,20 +0,0 @@
-#       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.
-
-clear_extra_headers
-go .
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/smoke-project-home.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/smoke-project-home.twill b/AlluraTesting/twill-tests/smoke-project-home.twill
deleted file mode 100644
index 3d1e8bf..0000000
--- a/AlluraTesting/twill-tests/smoke-project-home.twill
+++ /dev/null
@@ -1,20 +0,0 @@
-#       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.
-
-clear_extra_headers
-go ./p/test/home/
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/smoke-tracker-search.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/smoke-tracker-search.twill b/AlluraTesting/twill-tests/smoke-tracker-search.twill
deleted file mode 100644
index d8d03a3..0000000
--- a/AlluraTesting/twill-tests/smoke-tracker-search.twill
+++ /dev/null
@@ -1,20 +0,0 @@
-#       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.
-
-clear_extra_headers
-go ./p/test/bugs/search/
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/smoke-tracker.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/smoke-tracker.twill b/AlluraTesting/twill-tests/smoke-tracker.twill
deleted file mode 100644
index 1e9e0f7..0000000
--- a/AlluraTesting/twill-tests/smoke-tracker.twill
+++ /dev/null
@@ -1,20 +0,0 @@
-#       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.
-
-clear_extra_headers
-go ./p/test/bugs/
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/smoke-user-profile.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/smoke-user-profile.twill b/AlluraTesting/twill-tests/smoke-user-profile.twill
deleted file mode 100644
index 907f17d..0000000
--- a/AlluraTesting/twill-tests/smoke-user-profile.twill
+++ /dev/null
@@ -1,20 +0,0 @@
-#       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.
-
-clear_extra_headers
-go ./u/test_admin/profile/
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTesting/twill-tests/smoke-wiki.twill
----------------------------------------------------------------------
diff --git a/AlluraTesting/twill-tests/smoke-wiki.twill b/AlluraTesting/twill-tests/smoke-wiki.twill
deleted file mode 100644
index 03e2c56..0000000
--- a/AlluraTesting/twill-tests/smoke-wiki.twill
+++ /dev/null
@@ -1,20 +0,0 @@
-#       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.
-
-clear_extra_headers
-go ./p/test/wiki/Home/
-code 200

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/rat-excludes.txt
----------------------------------------------------------------------
diff --git a/rat-excludes.txt b/rat-excludes.txt
index 78aba56..0c0de3c 100644
--- a/rat-excludes.txt
+++ b/rat-excludes.txt
@@ -32,7 +32,7 @@ Allura/allura/public/nf/js/sylvester.js
 Allura/allura/tests/data/genshi_hello_tmpl
 Allura/allura/tests/data/test_mime/text_file.txt
 Allura/run/dummy.txt
-AlluraTesting/jslint/
+AlluraTest/jslint/
 ForgeGit/forgegit/data/post-receive_tmpl
 ForgeSVN/forgesvn/tests/data/
 solr_config/core0/conf/spellings.txt

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/run_clonedigger
----------------------------------------------------------------------
diff --git a/run_clonedigger b/run_clonedigger
index cda4b67..d7f1a1f 100755
--- a/run_clonedigger
+++ b/run_clonedigger
@@ -27,7 +27,7 @@ fi
 
 if [ "$TEST_MODULES"  == "" ]; then
     TEST_MODULES="\
-    AlluraTesting \
+    AlluraTest \
     Allura \
     ForgeBlog \
     ForgeLink \

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/run_tests
----------------------------------------------------------------------
diff --git a/run_tests b/run_tests
index fa39230..59e1825 100755
--- a/run_tests
+++ b/run_tests
@@ -27,7 +27,7 @@ fi
 
 if [ "$TEST_MODULES"  == "" ]; then
     TEST_MODULES="\
-    AlluraTesting \
+    AlluraTest \
     Allura \
     ForgeBlog \
     ForgeLink \


[49/50] [abbrv] git commit: [#6277] make forgeuserstats tmp repos not conflict with forgegit

Posted by tv...@apache.org.
[#6277] make forgeuserstats tmp repos not conflict with forgegit


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/d2a60bbb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/d2a60bbb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/d2a60bbb

Branch: refs/heads/tv/6355
Commit: d2a60bbbf547798b74a42ee87d68b6a26480a373
Parents: 3ec3fed
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue May 28 10:32:26 2013 -0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Jul 11 22:10:00 2013 +0000

----------------------------------------------------------------------
 ForgeUserStats/forgeuserstats/tests/test_model.py | 5 +++--
 ForgeUserStats/forgeuserstats/tests/test_stats.py | 8 ++++++--
 run_tests                                         | 4 ++++
 3 files changed, 13 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d2a60bbb/ForgeUserStats/forgeuserstats/tests/test_model.py
----------------------------------------------------------------------
diff --git a/ForgeUserStats/forgeuserstats/tests/test_model.py b/ForgeUserStats/forgeuserstats/tests/test_model.py
index 2203469..6940385 100644
--- a/ForgeUserStats/forgeuserstats/tests/test_model.py
+++ b/ForgeUserStats/forgeuserstats/tests/test_model.py
@@ -29,10 +29,11 @@ from allura.model import User, Project, TroveCategory
 from allura.lib import helpers as h
 from allura import model as M
 
-from forgegit.tests import with_git
-
 from forgeuserstats.model import stats as USM
 
+test_project_with_repo = 'test2'  # important to be distinct from 'test' which ForgeGit uses, so that the tests can run in parallel and not clobber each other
+with_git = td.with_tool(test_project_with_repo, 'Git', 'src-git', 'Git', type='git')
+
 class TestUserStats(unittest.TestCase):
 
     def setUp(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d2a60bbb/ForgeUserStats/forgeuserstats/tests/test_stats.py
----------------------------------------------------------------------
diff --git a/ForgeUserStats/forgeuserstats/tests/test_stats.py b/ForgeUserStats/forgeuserstats/tests/test_stats.py
index b2b20ce..bbb43f5 100644
--- a/ForgeUserStats/forgeuserstats/tests/test_stats.py
+++ b/ForgeUserStats/forgeuserstats/tests/test_stats.py
@@ -27,10 +27,14 @@ from allura.lib import helpers as h
 from allura.model import User
 from allura import model as M
 
-from forgegit.tests import with_git
 from forgewiki import model as WM
 from forgetracker import model as TM
 
+
+test_project_with_repo = 'test2'  # important to be distinct from 'test' which ForgeGit uses, so that the tests can run in parallel and not clobber each other
+with_git = td.with_tool(test_project_with_repo, 'Git', 'src-git', 'Git', type='git')
+
+
 class TestStats(TestController):
 
     def setUp(self):
@@ -185,7 +189,7 @@ class TestGitCommit(TestController, unittest.TestCase):
     @td.with_wiki
     def setup_with_tools(self):
         setup_global_objects()
-        h.set_context('test', 'src-git', neighborhood='Projects')
+        h.set_context(test_project_with_repo, 'src-git', neighborhood='Projects')
         repo_dir = pkg_resources.resource_filename(
             'forgeuserstats', 'tests/data')
         c.app.repo.fs_path = repo_dir

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d2a60bbb/run_tests
----------------------------------------------------------------------
diff --git a/run_tests b/run_tests
index 7d033b1..a85aefe 100755
--- a/run_tests
+++ b/run_tests
@@ -29,6 +29,8 @@ import textwrap
 
 def run_one(cmd, **popen_kwargs):
     print '{} running {} {}'.format(threading.current_thread(), cmd, popen_kwargs)
+    sys.stdout.flush()
+
     all_popen_kwargs = dict(shell=True, stderr=subprocess.STDOUT,
                             stdout=subprocess.PIPE,
                             bufsize=1,  # 1 == line-buffered
@@ -43,6 +45,8 @@ def run_one(cmd, **popen_kwargs):
     out_remainder, _ = proc.communicate()
     sys.stdout.write(out_remainder)
     sys.stdout.flush()
+    print 'finished {} {}'.format(cmd, popen_kwargs)
+    sys.stdout.flush()
     return proc
 
 


[48/50] [abbrv] git commit: [#4122] change ./run_tests to python, run suites in parallel

Posted by tv...@apache.org.
[#4122] change ./run_tests to python, run suites in parallel


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/3ec3fedb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/3ec3fedb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/3ec3fedb

Branch: refs/heads/tv/6355
Commit: 3ec3fedb0daad79408694f90792272549f73e5e1
Parents: ff72589
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon May 6 18:30:30 2013 -0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Jul 11 22:10:00 2013 +0000

----------------------------------------------------------------------
 run_tests | 140 ++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 104 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3ec3fedb/run_tests
----------------------------------------------------------------------
diff --git a/run_tests b/run_tests
index 59e1825..7d033b1 100755
--- a/run_tests
+++ b/run_tests
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env python
 
 #       Licensed to the Apache Software Foundation (ASF) under one
 #       or more contributor license agreements.  See the NOTICE file
@@ -17,38 +17,106 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-if [ -n "$SF_SYSTEM_FUNC" ]; then
-	if [ -z "$VIRTUAL_ENV" ]; then
-        source /var/local/env-allura/bin/activate
-	fi
-fi
-
-# main
-
-if [ "$TEST_MODULES"  == "" ]; then
-    TEST_MODULES="\
-    AlluraTest \
-    Allura \
-    ForgeBlog \
-    ForgeLink \
-    ForgeChat \
-    ForgeDiscussion \
-    ForgeGit \
-    ForgeSVN \
-    ForgeTracker \
-    ForgeWiki \
-    ForgeActivity \
-    ForgeShortUrl \
-    ForgeUserStats \
-    "
-fi
-
-# Run with --with-coverage for coverage (add --cover-html for html report)
-for module in $TEST_MODULES; do
-    (
-        echo "Running tests in module $module"
-        cd $module
-        cover_package=$(echo $module | tr "[:upper:]" "[:lower:]")
-        nosetests --cover-package=$cover_package --cover-html-dir=report.coverage --cover-erase $* || exit
-    ) || exit
-done
+import argparse
+from copy import copy
+from glob import glob
+from multiprocessing.pool import ThreadPool
+import subprocess
+import sys
+import threading
+import textwrap
+
+
+def run_one(cmd, **popen_kwargs):
+    print '{} running {} {}'.format(threading.current_thread(), cmd, popen_kwargs)
+    all_popen_kwargs = dict(shell=True, stderr=subprocess.STDOUT,
+                            stdout=subprocess.PIPE,
+                            bufsize=1,  # 1 == line-buffered
+                            close_fds='posix' in sys.builtin_module_names)
+    all_popen_kwargs.update(popen_kwargs)
+    proc = subprocess.Popen(cmd, **all_popen_kwargs)
+    while proc.poll() is None:
+        line = proc.stdout.readline()
+        sys.stdout.write(line)
+        sys.stdout.flush()
+    # wait for completion and get remainder of output
+    out_remainder, _ = proc.communicate()
+    sys.stdout.write(out_remainder)
+    sys.stdout.flush()
+    return proc
+
+
+def run_many(cmds, processes=None):
+    """
+    cmds: list of shell commands, or list of (shell cmds, popen_kwargs)
+    processes: number of processes, or None for # of CPU cores
+    """
+    thread_pool = ThreadPool(processes=processes)
+
+    async_results = []
+    for cmd_kwds in cmds:
+        if type(cmd_kwds) == ():
+            cmd = cmd_kwds
+            kwds = {}
+        else:
+            cmd = cmd_kwds[0]
+            kwds = cmd_kwds[1]
+        result = thread_pool.apply_async(run_one, args=(cmd,), kwds=kwds)
+        async_results.append(result)
+
+    thread_pool.close()
+    thread_pool.join()
+
+    procs = [async_result.get() for async_result in async_results]
+    return [p.returncode for p in procs]
+
+
+def get_packages():
+    packages = [p.split('/')[0] for p in glob("*/setup.py")]
+
+    # make it first, to catch syntax errors
+    packages.remove('AlluraTest')
+    packages.insert(0, 'AlluraTest')
+    return packages
+
+
+def check_packages(packages):
+    for pkg in packages:
+        try:
+            __import__(pkg.lower())
+        except ImportError:
+            print "Not running tests for {}, since it isn't set up".format(pkg)
+        else:
+            yield pkg
+
+
+def run_tests_in_parallel(options, nosetests_args):
+    cmds = []
+    for package in check_packages(options.packages):
+        cover_package = package.lower()
+        our_nosetests_args = copy(nosetests_args)
+        our_nosetests_args.append('--cover-package={}'.format(cover_package))
+        cmd = "nosetests {nosetests_args}".format(
+            nosetests_args=' '.join(our_nosetests_args),
+        )
+        cmds.append((cmd, dict(cwd=package)))
+    return run_many(cmds, processes=options.num_processes)
+
+
+def parse_args():
+    parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
+                                     epilog=textwrap.dedent('''
+                                        All additional arguments are passed along to nosetests
+                                          (e.g. -v --with-coverage)
+                                        Note: --cover-package will be set automatically to the appropriate value'''))
+    parser.add_argument('-n', help='Number of processes to use at once. Default: # CPUs',
+                        dest='num_processes', type=int, default=None)
+    parser.add_argument('-p', help='List of packages to run tests on. Default: all',
+                        dest='packages', choices=get_packages(), default=get_packages(),
+                        nargs='+')
+    return parser.parse_known_args()
+
+
+if __name__ == "__main__":
+    ret_codes = run_tests_in_parallel(*parse_args())
+    sys.exit(any(ret_codes))


[28/50] [abbrv] git commit: [#4213] ticket:345 fixed grammar errors and refactored

Posted by tv...@apache.org.
[#4213]  ticket:345 fixed grammar errors and refactored


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/8993951a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/8993951a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/8993951a

Branch: refs/heads/tv/6355
Commit: 8993951a56adb9e0374a4d9765d6285ab0735d4a
Parents: 0efd308
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Jun 4 18:03:22 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 06:09:58 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/helpers.py                     | 18 ++++++++++++++++++
 Allura/allura/tests/test_helpers.py              |  5 +++++
 ForgeTracker/forgetracker/import_support.py      | 17 +++++------------
 ForgeTracker/forgetracker/widgets/ticket_form.py | 18 ++----------------
 4 files changed, 30 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8993951a/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 144bef3..1604aa9 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -29,6 +29,7 @@ import cPickle as pickle
 from hashlib import sha1
 from datetime import datetime, timedelta
 from collections import defaultdict
+import shlex
 
 import tg
 import genshi.template
@@ -839,3 +840,20 @@ def ming_config_from_ini(ini_path):
     conf = appconfig('config:%s' % os.path.join(root, ini_path))
     with ming_config(**conf):
         yield
+
+
+def split_select_field_options(field_options):
+    try:
+        # shlex have problems with parsing unicode,
+        # it's better to pass properly encoded byte-string
+        field_options = shlex.split(field_options.encode('utf-8'))
+        # convert splitted string back to unicode
+        field_options = map(really_unicode, field_options)
+    except ValueError:
+        field_options = field_options.split()
+        # After regular split field_options might contain a " characters,
+        # which would break html when rendered inside tag's value attr.
+        # Escaping doesn't help here, 'cause it breaks EasyWidgets' validation,
+        # so we're getting rid of those.
+        field_options = [o.replace('"', '') for o in field_options]
+    return field_options

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8993951a/Allura/allura/tests/test_helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index 904d188..42fb963 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -249,3 +249,8 @@ def test_inject_user(context):
 def test_datetimeformat():
     from datetime import date
     assert h.datetimeformat(date(2013, 01, 01)) == '2013-01-01 00:00:00'
+
+
+def test_split_select_field_options():
+    assert_equals(h.split_select_field_options('"test message" test2'), ['test message', 'test2'])
+    assert_equals(h.split_select_field_options('"test message test2'), ['test', 'message', 'test2'])

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8993951a/ForgeTracker/forgetracker/import_support.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/import_support.py b/ForgeTracker/forgetracker/import_support.py
index 56c6947..d23cf94 100644
--- a/ForgeTracker/forgetracker/import_support.py
+++ b/ForgeTracker/forgetracker/import_support.py
@@ -18,7 +18,6 @@
 #-*- python -*-
 import logging
 import json
-import shlex
 from datetime import datetime
 from cStringIO import StringIO
 
@@ -142,19 +141,13 @@ class ImportSupport(object):
             return u._id
         return None
 
-    def check_suctom_field(self, field, value):
+    def check_custom_field(self, field, value):
         field = c.app.globals.get_custom_field(field)
-        if (field['type'] == 'select') and (value != ''):
-            field_options = h.really_unicode(field['options'])
-            try:
-                field_options = shlex.split(field_options.encode('utf-8'))
-                field_options = map(h.really_unicode, field_options)
-            except ValueError:
-                field_options = field_options.split()
-            field_options = [o.replace('"', '') for o in field_options]
+        if (field['type'] == 'select') and value:
+            field_options = h.split_select_field_options(h.really_unicode(field['options']))
             if value not in field_options:
                 field['options'] = ' '.join([field['options'], value])
-        elif (field['type'] == 'milestone') and (value != ''):
+        elif (field['type'] == 'milestone') and value:
             milestones = field['milestones']
             is_exists = False
             for milestone in milestones:
@@ -177,7 +170,7 @@ class ImportSupport(object):
             ThreadLocalORMSession.flush_all()
         if 'custom_fields' not in ticket:
             ticket['custom_fields'] = {}
-        self.check_suctom_field(field, value)
+        self.check_custom_field(field, value)
         ticket['custom_fields'][field] = value
 
     #

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8993951a/ForgeTracker/forgetracker/widgets/ticket_form.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/ticket_form.py b/ForgeTracker/forgetracker/widgets/ticket_form.py
index 9139cda..cb05085 100644
--- a/ForgeTracker/forgetracker/widgets/ticket_form.py
+++ b/ForgeTracker/forgetracker/widgets/ticket_form.py
@@ -15,8 +15,6 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-import shlex
-
 from pylons import tmpl_context as c
 from formencode import validators as fev
 
@@ -164,20 +162,8 @@ class TicketCustomField(object):
 
     def _select(field):
         options = []
-        field_options = h.really_unicode(field.options)
-        try:
-            # shlex have problems with parsing unicode,
-            # it's better to pass properly encoded byte-string
-            field_options = shlex.split(field_options.encode('utf-8'))
-            # convert splitted string back to unicode
-            field_options = map(h.really_unicode, field_options)
-        except ValueError:
-            field_options = field_options.split()
-            # After regular split field_options might contain a " characters,
-            # which would break html when rendered inside tag's value attr.
-            # Escaping doesn't help here, 'cause it breaks EasyWidgets' validation,
-            # so we're getting rid of those.
-            field_options = [o.replace('"', '') for o in field_options]
+        field_options = h.split_select_field_options(h.really_unicode(field.options))
+
         for opt in field_options:
             selected = False
             if opt.startswith('*'):


[22/50] [abbrv] git commit: Remove timer for deleted method

Posted by tv...@apache.org.
Remove timer for deleted method

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/3ae3c366
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/3ae3c366
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/3ae3c366

Branch: refs/heads/tv/6355
Commit: 3ae3c3666cae7368f30ee017356438b2e7706405
Parents: 1e27f3d
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Sun Jul 7 05:26:40 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 05:26:40 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/custom_middleware.py | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3ae3c366/Allura/allura/lib/custom_middleware.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/custom_middleware.py b/Allura/allura/lib/custom_middleware.py
index e156e94..4458c48 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -241,7 +241,6 @@ class AlluraTimerMiddleware(TimerMiddleware):
     def repo_impl_timers(self):
         timers= []
         from allura.model.repository import Repository, RepositoryImplementation
-        timers.append(Timer('base_tool.{method_name}', Repository, 'commitlog'))
         timers.append(Timer('base_tool.{method_name}', RepositoryImplementation, 'last_commit_ids'))
         with pass_on_exc(ImportError):
             from forgegit.model.git_repo import GitImplementation


[14/50] [abbrv] git commit: [#6056] Fixed KeyError when browsing invalid trees in SCM

Posted by tv...@apache.org.
[#6056] Fixed KeyError when browsing invalid trees in SCM

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/96df73a1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/96df73a1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/96df73a1

Branch: refs/heads/tv/6355
Commit: 96df73a1789843cb8dbdffcec050beaa985cb71b
Parents: 8e1581e
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 1 21:49:25 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:48:41 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py                | 5 +++--
 ForgeGit/forgegit/tests/functional/test_controllers.py | 7 +++++++
 2 files changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/96df73a1/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 4f6122d..c8d852b 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -548,8 +548,9 @@ class TreeBrowser(BaseController, DispatchIndex):
                         filename), rest
         elif rest == ('index', ):
             rest = (request.environ['PATH_INFO'].rsplit('/')[-1],)
-        tree = self._tree[next]
-        if tree is None:
+        try:
+            tree = self._tree[next]
+        except KeyError:
             raise exc.HTTPNotFound
         return self.__class__(
             self._commit,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/96df73a1/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index c4ac325..3304625 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -205,6 +205,13 @@ class TestRootController(_TestCase):
         resp = self.app.get(ci + 'tree/?format=raw')
         assert 'README' in resp, resp.showbrowser()
 
+    def test_tree_invalid(self):
+        ci = self._get_ci()
+        resp = self.app.get(ci + 'tree/foo', status=404)
+        assert_equal(resp.status_int, 404)
+        resp = self.app.get(ci + 'tree/foo/bar', status=404)
+        assert_equal(resp.status_int, 404)
+
     def test_file(self):
         ci = self._get_ci()
         resp = self.app.get(ci + 'tree/README')


[27/50] [abbrv] git commit: [#4213] ticket:346 small refactoring for trac export

Posted by tv...@apache.org.
[#4213]  ticket:346 small refactoring  for trac export


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/964c3d18
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/964c3d18
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/964c3d18

Branch: refs/heads/tv/6355
Commit: 964c3d1803292f87a1f30391c22b0f744bb7e26f
Parents: 8993951
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Thu Jun 6 15:48:32 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 06:09:58 2013 +0000

----------------------------------------------------------------------
 scripts/trac_export.py | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/964c3d18/scripts/trac_export.py
----------------------------------------------------------------------
diff --git a/scripts/trac_export.py b/scripts/trac_export.py
index fcff048..4fcb27a 100755
--- a/scripts/trac_export.py
+++ b/scripts/trac_export.py
@@ -19,7 +19,6 @@
 
 
 import sys
-from pprint import pprint
 import csv
 import urlparse
 import urllib2
@@ -77,9 +76,9 @@ class TracExport(object):
         # be get with single-ticket export (create/mod times is
         # and example).
         self.ticket_map = {}
-        self.ticket_queue = []
         self.start_id = start_id
         self.page = (start_id - 1) / self.PAGE_SIZE + 1
+        self.ticket_queue = self.next_ticket_ids()
 
     def remap_fields(self, dict):
         "Remap fields to adhere to standard taxonomy."
@@ -238,8 +237,8 @@ class TracExport(object):
 
     def next(self):
         while True:
-            if not self.ticket_queue:
-                self.ticket_queue = self.next_ticket_ids()
+            if len(self.ticket_queue) == 0:
+                raise StopIteration
             id, extra = self.ticket_queue.pop(0)
             if id >= self.start_id:
                 break


[38/50] [abbrv] git commit: [#4659] Cleanup layout for attachment widget

Posted by tv...@apache.org.
[#4659] Cleanup layout for attachment widget

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/c2ac0166
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c2ac0166
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c2ac0166

Branch: refs/heads/tv/6355
Commit: c2ac016668cda5c17226d4cb79974cfa1b3dfcc0
Parents: 779e794
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Thu Jul 11 20:19:34 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Thu Jul 11 20:19:34 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/widgets/attachment_add.html | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c2ac0166/Allura/allura/templates/widgets/attachment_add.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/attachment_add.html b/Allura/allura/templates/widgets/attachment_add.html
index 3af2ce7..51f4d5b 100644
--- a/Allura/allura/templates/widgets/attachment_add.html
+++ b/Allura/allura/templates/widgets/attachment_add.html
@@ -20,14 +20,8 @@
       action="{{action}}"
       enctype="multipart/form-data">
       <a href="#" class="btn link attachment_form_add_button">Add attachments</a>
-      <ol class="attachment_form_fields" style="display:none">
-        <li>
-          <label for="{{name}}">File to upload</label>
-          <input type="file" class="text" name="{{name}}" multiple="True" id="{{name}}"/>
-        </li>
-        <li>
-          <label>&nbsp;</label>
-          <input type="submit" value="Attach file"/>
-        </li>
-      </ol>
+      <div class="attachment_form_fields" style="display:none">
+          <input type="file" class="text" name="{{name}}" multiple="True" id="{{name}}" style="margin-left:0"/><br/>
+          <input type="submit" value="Attach files"/>
+      </div>
 </form>


[19/50] [abbrv] git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-allura

Posted by tv...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-allura


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7fc9b7de
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7fc9b7de
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7fc9b7de

Branch: refs/heads/tv/6355
Commit: 7fc9b7de2cd168436d9f16add9e55c47eb5d4a2b
Parents: 19c7673 6901e8a
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Sun Jul 7 04:28:49 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 04:28:49 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            | 11 ++++---
 Allura/allura/controllers/repository.py         | 33 ++++++++++----------
 ForgeBlog/forgeblog/main.py                     |  4 ++-
 .../forgeblog/tests/functional/test_root.py     |  6 +++-
 .../tests/functional/test_controllers.py        |  7 +++++
 ForgeWiki/forgewiki/wiki_main.py                |  2 +-
 requirements-sf.txt                             |  2 +-
 7 files changed, 40 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7fc9b7de/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------


[05/50] [abbrv] git commit: Add min-width back b/c it looks better :)

Posted by tv...@apache.org.
Add min-width back b/c it looks better :)

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ebc7e431
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ebc7e431
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ebc7e431

Branch: refs/heads/tv/6355
Commit: ebc7e43100c5fd0a83145f83562fa760c66dfcb1
Parents: ff0459c
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Jul 2 14:00:01 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Jul 2 14:00:09 2013 +0000

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ebc7e431/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 91c6fb5..1322fee 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -3008,6 +3008,7 @@ ul.dropdown ul {
 
 ul.dropdown ul li {
     float: left;
+    min-width: 100px;
     margin: 0;
     padding: 0;
 }


[33/50] [abbrv] git commit: [#6220] Add help for video embedding

Posted by tv...@apache.org.
[#6220] Add help for video embedding

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/8fd2f6fc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/8fd2f6fc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/8fd2f6fc

Branch: refs/heads/tv/6355
Commit: 8fd2f6fc77eb82cff70a605c41821717202d2f4d
Parents: f1938c5
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Jul 10 21:30:28 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jul 10 21:30:28 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/lib.html | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8fd2f6fc/Allura/allura/templates/jinja_master/lib.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/lib.html b/Allura/allura/templates/jinja_master/lib.html
index a5bfa29..a3e8d6b 100644
--- a/Allura/allura/templates/jinja_master/lib.html
+++ b/Allura/allura/templates/jinja_master/lib.html
@@ -153,6 +153,7 @@
     <li><a href="#md_ex_headers{{id}}">Headers</a></li>
     <li><a href="#md_ex_hr{{id}}">Horizontal Rules</a></li>
     <li><a href="#md_ex_img{{id}}">Images</a></li>
+    <li><a href="#md_ex_video{{id}}">Videos</a></li>
     <li><a href="#md_ex_escapes{{id}}">Escapes and HTML</a></li>
     <li><a href="#md_ex_moreheaders{{id}}">More Headers</a></li>
     <li><a href="#md_ex_toc1{{id}}">Table of Contents</a></li>
@@ -527,6 +528,18 @@ image.</p>
 </div>
 
 
+<div class="markdown_syntax_section hidden_in_modal md_ex_video{{id}}">
+<h2 id="md_ex_video{{id}}">Videos</h2>
+<p>To embed a YouTube video, use the `embed` macro (only YouTube is supported at this time):</p>
+<div class="codehilite"><pre>
+[[embed url=http://www.youtube.com/watch?v=6YbBmqUnoQM]]
+</pre></div>
+
+<p>Output:</p>
+{{g.markdown.convert('''[[embed url=http://www.youtube.com/watch?v=6YbBmqUnoQM]]''')}}
+</div>
+
+
 <div class="markdown_syntax_section hidden_in_modal md_ex_escapes{{id}}">
 <h2 id="md_ex_escapes{{id}}">Escapes and HTML</h2>
 <p>What if you want to just show asterisks, not italics?</p>
@@ -685,7 +698,7 @@ allowed, permitting basic styling and layout: &lt;div markdown style="float:left
 </pre></div>
 </div>
 
-<div class="markdown_syntax_section hidden_in_modal md_ex_project_macros{{id}}">
+<div class="markdown_syntax_section hidden_in_modal md_ex_project_macros{{id}}" id="md_ex_project_macros{{id}}">
 
 <h2 id="md_ex_download_button{{id}}">Download Button</h2>
 <p>You can display a download button that links to the best download available for the active project. Please note that if you use this macro and there is no download associated with your project, the button will not appear.</p>


[43/50] [abbrv] [#4122] rename AlluraTesting dir to AlluraTest, to match the module name below

Posted by tv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/37e91c91/AlluraTest/jslint/jslint.js
----------------------------------------------------------------------
diff --git a/AlluraTest/jslint/jslint.js b/AlluraTest/jslint/jslint.js
new file mode 100644
index 0000000..4b2ddcc
--- /dev/null
+++ b/AlluraTest/jslint/jslint.js
@@ -0,0 +1,5729 @@
+// jslint.js
+// 2010-08-05
+
+/*
+Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is 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 Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*
+    JSLINT is a global function. It takes two parameters.
+
+        var myResult = JSLINT(source, option);
+
+    The first parameter is either a string or an array of strings. If it is a
+    string, it will be split on '\n' or '\r'. If it is an array of strings, it
+    is assumed that each string represents one line. The source can be a
+    JavaScript text, or HTML text, or a Konfabulator text.
+
+    The second parameter is an optional object of options which control the
+    operation of JSLINT. Most of the options are booleans: They are all are
+    optional and have a default value of false.
+
+    If it checks out, JSLINT returns true. Otherwise, it returns false.
+
+    If false, you can inspect JSLINT.errors to find out the problems.
+    JSLINT.errors is an array of objects containing these members:
+
+    {
+        line      : The line (relative to 0) at which the lint was found
+        character : The character (relative to 0) at which the lint was found
+        reason    : The problem
+        evidence  : The text line in which the problem occurred
+        raw       : The raw message before the details were inserted
+        a         : The first detail
+        b         : The second detail
+        c         : The third detail
+        d         : The fourth detail
+    }
+
+    If a fatal error was found, a null will be the last element of the
+    JSLINT.errors array.
+
+    You can request a Function Report, which shows all of the functions
+    and the parameters and vars that they use. This can be used to find
+    implied global variables and other problems. The report is in HTML and
+    can be inserted in an HTML <body>.
+
+        var myReport = JSLINT.report(limited);
+
+    If limited is true, then the report will be limited to only errors.
+
+    You can request a data structure which contains JSLint's results.
+
+        var myData = JSLINT.data();
+
+    It returns a structure with this form:
+
+    {
+        errors: [
+            {
+                line: NUMBER,
+                character: NUMBER,
+                reason: STRING,
+                evidence: STRING
+            }
+        ],
+        functions: [
+            name: STRING,
+            line: NUMBER,
+            last: NUMBER,
+            param: [
+                STRING
+            ],
+            closure: [
+                STRING
+            ],
+            var: [
+                STRING
+            ],
+            exception: [
+                STRING
+            ],
+            outer: [
+                STRING
+            ],
+            unused: [
+                STRING
+            ],
+            global: [
+                STRING
+            ],
+            label: [
+                STRING
+            ]
+        ],
+        globals: [
+            STRING
+        ],
+        member: {
+            STRING: NUMBER
+        },
+        unuseds: [
+            {
+                name: STRING,
+                line: NUMBER
+            }
+        ],
+        implieds: [
+            {
+                name: STRING,
+                line: NUMBER
+            }
+        ],
+        urls: [
+            STRING
+        ],
+        json: BOOLEAN
+    }
+
+    Empty arrays will not be included.
+
+*/
+
+/*jslint
+    evil: true, nomen: false, onevar: false, regexp: false, strict: true
+*/
+
+/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
+    "(begin)", "(breakage)", "(context)", "(error)", "(global)",
+    "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
+    "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/",
+    "<", "<=", "==", "===", ">", ">=", ADSAFE, ActiveXObject,
+    Array, Boolean, COM, CScript, Canvas, CustomAnimation, Date, Debug, E,
+    Enumerator, Error, EvalError, FadeAnimation, Flash, FormField, Frame,
+    Function, HotKey, Image, JSON, LN10, LN2, LOG10E, LOG2E, MAX_VALUE,
+    MIN_VALUE, Math, MenuItem, MoveAnimation, NEGATIVE_INFINITY, Number,
+    Object, Option, PI, POSITIVE_INFINITY, Point, RangeError, Rectangle,
+    ReferenceError, RegExp, ResizeAnimation, RotateAnimation, SQRT1_2,
+    SQRT2, ScrollBar, String, Style, SyntaxError, System, Text, TextArea,
+    Timer, TypeError, URIError, URL, VBArray, WScript, Web, Window, XMLDOM,
+    XMLHttpRequest, "\\", a, abbr, acronym, addEventListener, address,
+    adsafe, alert, aliceblue, animator, antiquewhite, appleScript, applet,
+    apply, approved, aqua, aquamarine, area, arguments, arity, article,
+    aside, audio, autocomplete, azure, b, background,
+    "background-attachment", "background-color", "background-image",
+    "background-position", "background-repeat", base, bdo, beep, beige, big,
+    bisque, bitwise, black, blanchedalmond, block, blockquote, blue,
+    blueviolet, blur, body, border, "border-bottom", "border-bottom-color",
+    "border-bottom-style", "border-bottom-width", "border-collapse",
+    "border-color", "border-left", "border-left-color", "border-left-style",
+    "border-left-width", "border-right", "border-right-color",
+    "border-right-style", "border-right-width", "border-spacing",
+    "border-style", "border-top", "border-top-color", "border-top-style",
+    "border-top-width", "border-width", bottom, br, brown, browser,
+    burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller,
+    canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt,
+    character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
+    cite, clear, clearInterval, clearTimeout, clip, close, closeWidget,
+    closed, closure, cm, code, col, colgroup, color, command, comment,
+    condition, confirm, console, constructor, content, convertPathToHFS,
+    convertPathToPlatform, coral, cornflowerblue, cornsilk,
+    "counter-increment", "counter-reset", create, crimson, css, cursor,
+    cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,
+    darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
+    darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,
+    darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent,
+    deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize,
+    details, devel, dfn, dialog, dimension, dimgray, dir, direction,
+    display, div, dl, document, dodgerblue, dt, edition, else, em, embed,
+    empty, "empty-cells", encodeURI, encodeURIComponent, entityify, eqeqeq,
+    errors, es5, escape, eval, event, evidence, evil, ex, exception, exec, exps,
+    fieldset, figure, filesystem, firebrick, first, float, floor,
+    floralwhite, focus, focusWidget, font, "font-face", "font-family",
+    "font-size", "font-size-adjust", "font-stretch", "font-style",
+    "font-variant", "font-weight", footer, forestgreen, forin, form,
+    fragment, frame, frames, frameset, from, fromCharCode, fuchsia, fud,
+    funct, function, functions, g, gainsboro, gc, getComputedStyle,
+    ghostwhite, global, globals, gold, goldenrod, gray, green, greenyellow,
+    h1, h2, h3, h4, h5, h6, hasOwnProperty, head, header, height, help,
+    hgroup, history, honeydew, hotpink, hr, 'hta:application', html,
+    i, iTunes, id, identifier,
+    iframe, img, immed, implieds, in, include, indent, indexOf, indianred,
+    indigo, init, input, ins, isAlpha, isApplicationRunning, isDigit,
+    isFinite, isNaN, ivory, join, jslint, json, kbd, keygen, khaki,
+    konfabulatorVersion, label, labelled, lang, last, lavender,
+    lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,
+    lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral,
+    lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,
+    lightseagreen, lightskyblue, lightslategray, lightsteelblue,
+    lightyellow, lime, limegreen, line, "line-height", linen, link,
+    "list-style", "list-style-image", "list-style-position",
+    "list-style-type", load, loadClass, location, log, m, magenta, map,
+    margin, "margin-bottom", "margin-left", "margin-right", "margin-top",
+    mark, "marker-offset", maroon, match, "max-height", "max-width", maxerr,
+    maxlen, md5, media, mediumaquamarine, mediumblue, mediumorchid,
+    mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen,
+    mediumturquoise, mediumvioletred, member, menu, message, meta, meter,
+    midnightblue, "min-height", "min-width", mintcream, mistyrose, mm,
+    moccasin, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new,
+    newcap, noframes, nomen, noscript, nud, object, ol, oldlace, olive,
+    olivedrab, on, onbeforeunload, onblur, onerror, onevar, onfocus, onload,
+    onresize, onunload, opacity, open, openURL, opener, opera, optgroup,
+    option, orange, orangered, orchid, outer, outline, "outline-color",
+    "outline-style", "outline-width", output, overflow, "overflow-x",
+    "overflow-y", p, padding, "padding-bottom", "padding-left",
+    "padding-right", "padding-top", page, "page-break-after",
+    "page-break-before", palegoldenrod, palegreen, paleturquoise,
+    palevioletred, papayawhip, param, parent, parseFloat, parseInt,
+    passfail, pc, peachpuff, peru, pink, play, plum, plusplus, pop,
+    popupMenu, position, powderblue, pre, predef, preferenceGroups,
+    preferences, print, progress, prompt, prototype, pt, purple, push, px,
+    q, quit, quotes, random, range, raw, reach, readFile, readUrl, reason,
+    red, regexp, reloadWidget, removeEventListener, replace, report,
+    reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, rhino, right,
+    rosybrown, royalblue, rp, rt, ruby, runCommand, runCommandInBg,
+    saddlebrown, safe, salmon, samp, sandybrown, saveAs, savePreferences,
+    screen, script, scroll, scrollBy, scrollTo, seagreen, seal, search,
+    seashell, section, select, serialize, setInterval, setTimeout, shift,
+    showWidgetPreferences, sienna, silver, skyblue, slateblue, slategray,
+    sleep, slice, small, snow, sort, source, span, spawn, speak, split,
+    springgreen, src, stack, status, steelblue, strict, strong, style,
+    styleproperty, sub, substr, sup, supplant, suppressUpdates, sync,
+    system, table, "table-layout", tan, tbody, td, teal, tellWidget, test,
+    "text-align", "text-decoration", "text-indent", "text-shadow",
+    "text-transform", textarea, tfoot, th, thead, thistle, time, title,
+    toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,
+    turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused,
+    unwatch, updateNow, urls, value, valueOf, var, version,
+    "vertical-align", video, violet, visibility, watch, wheat, white,
+    "white-space", whitesmoke, widget, width, windows, "word-spacing",
+    "word-wrap", yahooCheckLogin, yahooLogin, yahooLogout, yellow,
+    yellowgreen, "z-index"
+*/
+
+// We build the application inside a function so that we produce only a single
+// global variable. The function will be invoked, its return value is the JSLINT
+// application itself.
+
+"use strict";
+
+var JSLINT = (function () {
+    var adsafe_id,      // The widget's ADsafe id.
+        adsafe_may,     // The widget may load approved scripts.
+        adsafe_went,    // ADSAFE.go has been called.
+        anonname,       // The guessed name for anonymous functions.
+        approved,       // ADsafe approved urls.
+
+        atrule = {
+            media      : true,
+            'font-face': true,
+            page       : true
+        },
+
+// These are operators that should not be used with the ! operator.
+
+        bang = {
+            '<': true,
+            '<=': true,
+            '==': true,
+            '===': true,
+            '!==': true,
+            '!=': true,
+            '>': true,
+            '>=': true,
+            '+': true,
+            '-': true,
+            '*': true,
+            '/': true,
+            '%': true
+        },
+
+// These are members that should not be permitted in the safe subset.
+
+        banned = {              // the member names that ADsafe prohibits.
+            'arguments'     : true,
+            callee          : true,
+            caller          : true,
+            constructor     : true,
+            'eval'          : true,
+            prototype       : true,
+            stack           : true,
+            unwatch         : true,
+            valueOf         : true,
+            watch           : true
+        },
+
+
+// These are the JSLint boolean options.
+
+        boolOptions = {
+            adsafe     : true, // if ADsafe should be enforced
+            bitwise    : true, // if bitwise operators should not be allowed
+            browser    : true, // if the standard browser globals should be predefined
+            cap        : true, // if upper case HTML should be allowed
+            css        : true, // if CSS workarounds should be tolerated
+            debug      : true, // if debugger statements should be allowed
+            devel      : true, // if logging should be allowed (console, alert, etc.)
+            eqeqeq     : true, // if === should be required
+            es5        : true, // if ES5 syntax should be allowed
+            evil       : true, // if eval should be allowed
+            forin      : true, // if for in statements must filter
+            fragment   : true, // if HTML fragments should be allowed
+            immed      : true, // if immediate invocations must be wrapped in parens
+            laxbreak   : true, // if line breaks should not be checked
+            newcap     : true, // if constructor names must be capitalized
+            nomen      : true, // if names should be checked
+            on         : true, // if HTML event handlers should be allowed
+            onevar     : true, // if only one var statement per function should be allowed
+            passfail   : true, // if the scan should stop on first error
+            plusplus   : true, // if increment/decrement should not be allowed
+            regexp     : true, // if the . should not be allowed in regexp literals
+            rhino      : true, // if the Rhino environment globals should be predefined
+            undef      : true, // if variables should be declared before used
+            safe       : true, // if use of some browser features should be restricted
+            windows    : true, // if MS Windows-specigic globals should be predefined
+            strict     : true, // require the "use strict"; pragma
+            sub        : true, // if all forms of subscript notation are tolerated
+            white      : true, // if strict whitespace rules apply
+            widget     : true  // if the Yahoo Widgets globals should be predefined
+        },
+
+// browser contains a set of global names which are commonly provided by a
+// web browser environment.
+
+        browser = {
+            addEventListener: false,
+            blur            : false,
+            clearInterval   : false,
+            clearTimeout    : false,
+            close           : false,
+            closed          : false,
+            defaultStatus   : false,
+            document        : false,
+            event           : false,
+            focus           : false,
+            frames          : false,
+            getComputedStyle: false,
+            history         : false,
+            Image           : false,
+            length          : false,
+            location        : false,
+            moveBy          : false,
+            moveTo          : false,
+            name            : false,
+            navigator       : false,
+            onbeforeunload  : true,
+            onblur          : true,
+            onerror         : true,
+            onfocus         : true,
+            onload          : true,
+            onresize        : true,
+            onunload        : true,
+            open            : false,
+            opener          : false,
+            Option          : false,
+            parent          : false,
+            print           : false,
+            removeEventListener: false,
+            resizeBy        : false,
+            resizeTo        : false,
+            screen          : false,
+            scroll          : false,
+            scrollBy        : false,
+            scrollTo        : false,
+            setInterval     : false,
+            setTimeout      : false,
+            status          : false,
+            top             : false,
+            XMLHttpRequest  : false
+        },
+
+        cssAttributeData,
+        cssAny,
+
+        cssColorData = {
+            "aliceblue"             : true,
+            "antiquewhite"          : true,
+            "aqua"                  : true,
+            "aquamarine"            : true,
+            "azure"                 : true,
+            "beige"                 : true,
+            "bisque"                : true,
+            "black"                 : true,
+            "blanchedalmond"        : true,
+            "blue"                  : true,
+            "blueviolet"            : true,
+            "brown"                 : true,
+            "burlywood"             : true,
+            "cadetblue"             : true,
+            "chartreuse"            : true,
+            "chocolate"             : true,
+            "coral"                 : true,
+            "cornflowerblue"        : true,
+            "cornsilk"              : true,
+            "crimson"               : true,
+            "cyan"                  : true,
+            "darkblue"              : true,
+            "darkcyan"              : true,
+            "darkgoldenrod"         : true,
+            "darkgray"              : true,
+            "darkgreen"             : true,
+            "darkkhaki"             : true,
+            "darkmagenta"           : true,
+            "darkolivegreen"        : true,
+            "darkorange"            : true,
+            "darkorchid"            : true,
+            "darkred"               : true,
+            "darksalmon"            : true,
+            "darkseagreen"          : true,
+            "darkslateblue"         : true,
+            "darkslategray"         : true,
+            "darkturquoise"         : true,
+            "darkviolet"            : true,
+            "deeppink"              : true,
+            "deepskyblue"           : true,
+            "dimgray"               : true,
+            "dodgerblue"            : true,
+            "firebrick"             : true,
+            "floralwhite"           : true,
+            "forestgreen"           : true,
+            "fuchsia"               : true,
+            "gainsboro"             : true,
+            "ghostwhite"            : true,
+            "gold"                  : true,
+            "goldenrod"             : true,
+            "gray"                  : true,
+            "green"                 : true,
+            "greenyellow"           : true,
+            "honeydew"              : true,
+            "hotpink"               : true,
+            "indianred"             : true,
+            "indigo"                : true,
+            "ivory"                 : true,
+            "khaki"                 : true,
+            "lavender"              : true,
+            "lavenderblush"         : true,
+            "lawngreen"             : true,
+            "lemonchiffon"          : true,
+            "lightblue"             : true,
+            "lightcoral"            : true,
+            "lightcyan"             : true,
+            "lightgoldenrodyellow"  : true,
+            "lightgreen"            : true,
+            "lightpink"             : true,
+            "lightsalmon"           : true,
+            "lightseagreen"         : true,
+            "lightskyblue"          : true,
+            "lightslategray"        : true,
+            "lightsteelblue"        : true,
+            "lightyellow"           : true,
+            "lime"                  : true,
+            "limegreen"             : true,
+            "linen"                 : true,
+            "magenta"               : true,
+            "maroon"                : true,
+            "mediumaquamarine"      : true,
+            "mediumblue"            : true,
+            "mediumorchid"          : true,
+            "mediumpurple"          : true,
+            "mediumseagreen"        : true,
+            "mediumslateblue"       : true,
+            "mediumspringgreen"     : true,
+            "mediumturquoise"       : true,
+            "mediumvioletred"       : true,
+            "midnightblue"          : true,
+            "mintcream"             : true,
+            "mistyrose"             : true,
+            "moccasin"              : true,
+            "navajowhite"           : true,
+            "navy"                  : true,
+            "oldlace"               : true,
+            "olive"                 : true,
+            "olivedrab"             : true,
+            "orange"                : true,
+            "orangered"             : true,
+            "orchid"                : true,
+            "palegoldenrod"         : true,
+            "palegreen"             : true,
+            "paleturquoise"         : true,
+            "palevioletred"         : true,
+            "papayawhip"            : true,
+            "peachpuff"             : true,
+            "peru"                  : true,
+            "pink"                  : true,
+            "plum"                  : true,
+            "powderblue"            : true,
+            "purple"                : true,
+            "red"                   : true,
+            "rosybrown"             : true,
+            "royalblue"             : true,
+            "saddlebrown"           : true,
+            "salmon"                : true,
+            "sandybrown"            : true,
+            "seagreen"              : true,
+            "seashell"              : true,
+            "sienna"                : true,
+            "silver"                : true,
+            "skyblue"               : true,
+            "slateblue"             : true,
+            "slategray"             : true,
+            "snow"                  : true,
+            "springgreen"           : true,
+            "steelblue"             : true,
+            "tan"                   : true,
+            "teal"                  : true,
+            "thistle"               : true,
+            "tomato"                : true,
+            "turquoise"             : true,
+            "violet"                : true,
+            "wheat"                 : true,
+            "white"                 : true,
+            "whitesmoke"            : true,
+            "yellow"                : true,
+            "yellowgreen"           : true
+        },
+
+        cssBorderStyle,
+        cssBreak,
+
+        cssLengthData = {
+            '%': true,
+            'cm': true,
+            'em': true,
+            'ex': true,
+            'in': true,
+            'mm': true,
+            'pc': true,
+            'pt': true,
+            'px': true
+        },
+
+        cssOverflow,
+
+        devel = {
+            alert           : false,
+            confirm         : false,
+            console         : false,
+            Debug           : false,
+            opera           : false,
+            prompt          : false
+        },
+
+        escapes = {
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '/' : '\\/',
+            '\\': '\\\\'
+        },
+
+        funct,          // The current function
+
+        functionicity = [
+            'closure', 'exception', 'global', 'label',
+            'outer', 'unused', 'var'
+        ],
+
+        functions,      // All of the functions
+
+        global,         // The global scope
+        htmltag = {
+            a:        {},
+            abbr:     {},
+            acronym:  {},
+            address:  {},
+            applet:   {},
+            area:     {empty: true, parent: ' map '},
+            article:  {},
+            aside:    {},
+            audio:    {},
+            b:        {},
+            base:     {empty: true, parent: ' head '},
+            bdo:      {},
+            big:      {},
+            blockquote: {},
+            body:     {parent: ' html noframes '},
+            br:       {empty: true},
+            button:   {},
+            canvas:   {parent: ' body p div th td '},
+            caption:  {parent: ' table '},
+            center:   {},
+            cite:     {},
+            code:     {},
+            col:      {empty: true, parent: ' table colgroup '},
+            colgroup: {parent: ' table '},
+            command:  {parent: ' menu '},
+            datalist: {},
+            dd:       {parent: ' dl '},
+            del:      {},
+            details:  {},
+            dialog:   {},
+            dfn:      {},
+            dir:      {},
+            div:      {},
+            dl:       {},
+            dt:       {parent: ' dl '},
+            em:       {},
+            embed:    {},
+            fieldset: {},
+            figure:   {},
+            font:     {},
+            footer:   {},
+            form:     {},
+            frame:    {empty: true, parent: ' frameset '},
+            frameset: {parent: ' html frameset '},
+            h1:       {},
+            h2:       {},
+            h3:       {},
+            h4:       {},
+            h5:       {},
+            h6:       {},
+            head:     {parent: ' html '},
+            header:   {},
+            hgroup:   {},
+            hr:       {empty: true},
+            'hta:application':
+                      {empty: true, parent: ' head '},
+            html:     {parent: '*'},
+            i:        {},
+            iframe:   {},
+            img:      {empty: true},
+            input:    {empty: true},
+            ins:      {},
+            kbd:      {},
+            keygen:   {},
+            label:    {},
+            legend:   {parent: ' details fieldset figure '},
+            li:       {parent: ' dir menu ol ul '},
+            link:     {empty: true, parent: ' head '},
+            map:      {},
+            mark:     {},
+            menu:     {},
+            meta:     {empty: true, parent: ' head noframes noscript '},
+            meter:    {},
+            nav:      {},
+            noframes: {parent: ' html body '},
+            noscript: {},
+            object:   {},
+            ol:       {},
+            optgroup: {parent: ' select '},
+            option:   {parent: ' optgroup select '},
+            output:   {},
+            p:        {},
+            param:    {parent: ' applet object '},
+            pre:      {},
+            progress: {},
+            q:        {},
+            rp:       {},
+            rt:       {},
+            ruby:     {},
+            s:        {},
+            samp:     {},
+            script:   {empty: true, parent: ' body div frame head iframe p pre span '},
+            section:  {},
+            select:   {},
+            small:    {},
+            span:     {},
+            source:   {},
+            strong:   {},
+            style:    {parent: ' head ', empty: true},
+            sub:      {},
+            sup:      {},
+            table:    {},
+            tbody:    {parent: ' table '},
+            td:       {parent: ' tr '},
+            textarea: {},
+            tfoot:    {parent: ' table '},
+            th:       {parent: ' tr '},
+            thead:    {parent: ' table '},
+            time:     {},
+            title:    {parent: ' head '},
+            tr:       {parent: ' table tbody thead tfoot '},
+            tt:       {},
+            u:        {},
+            ul:       {},
+            'var':    {},
+            video:    {}
+        },
+
+        ids,            // HTML ids
+        implied,        // Implied globals
+        inblock,
+        indent,
+        jsonmode,
+        lines,
+        lookahead,
+        member,
+        membersOnly,
+        nexttoken,
+        noreach,
+        option,
+        predefined,     // Global variables defined by option
+        prereg,
+        prevtoken,
+
+        rhino = {
+            defineClass : false,
+            deserialize : false,
+            gc          : false,
+            help        : false,
+            load        : false,
+            loadClass   : false,
+            print       : false,
+            quit        : false,
+            readFile    : false,
+            readUrl     : false,
+            runCommand  : false,
+            seal        : false,
+            serialize   : false,
+            spawn       : false,
+            sync        : false,
+            toint32     : false,
+            version     : false
+        },
+
+        scope,      // The current scope
+
+        windows = {
+            ActiveXObject: false,
+            CScript      : false,
+            Debug        : false,
+            Enumerator   : false,
+            System       : false,
+            VBArray      : false,
+            WScript      : false
+        },
+
+        src,
+        stack,
+
+// standard contains the global names that are provided by the
+// ECMAScript standard.
+
+        standard = {
+            'void'              : false,
+            Array               : false,
+            Boolean             : false,
+            Date                : false,
+            decodeURI           : false,
+            decodeURIComponent  : false,
+            encodeURI           : false,
+            encodeURIComponent  : false,
+            Error               : false,
+            'eval'              : false,
+            EvalError           : false,
+            Function            : false,
+            hasOwnProperty      : false,
+            isFinite            : false,
+            isNaN               : false,
+            JSON                : false,
+            Math                : false,
+            Number              : false,
+            Object              : false,
+            parseInt            : false,
+            parseFloat          : false,
+            RangeError          : false,
+            ReferenceError      : false,
+            RegExp              : false,
+            String              : false,
+            SyntaxError         : false,
+            TypeError           : false,
+            URIError            : false
+        },
+
+        standard_member = {
+            E                   : true,
+            LN2                 : true,
+            LN10                : true,
+            LOG2E               : true,
+            LOG10E              : true,
+            PI                  : true,
+            SQRT1_2             : true,
+            SQRT2               : true,
+            MAX_VALUE           : true,
+            MIN_VALUE           : true,
+            NEGATIVE_INFINITY   : true,
+            POSITIVE_INFINITY   : true
+        },
+
+        strict_mode,
+        syntax = {},
+        tab,
+        token,
+        urls,
+        warnings,
+
+// widget contains the global names which are provided to a Yahoo
+// (fna Konfabulator) widget.
+
+        widget = {
+            alert                   : true,
+            animator                : true,
+            appleScript             : true,
+            beep                    : true,
+            bytesToUIString         : true,
+            Canvas                  : true,
+            chooseColor             : true,
+            chooseFile              : true,
+            chooseFolder            : true,
+            closeWidget             : true,
+            COM                     : true,
+            convertPathToHFS        : true,
+            convertPathToPlatform   : true,
+            CustomAnimation         : true,
+            escape                  : true,
+            FadeAnimation           : true,
+            filesystem              : true,
+            Flash                   : true,
+            focusWidget             : true,
+            form                    : true,
+            FormField               : true,
+            Frame                   : true,
+            HotKey                  : true,
+            Image                   : true,
+            include                 : true,
+            isApplicationRunning    : true,
+            iTunes                  : true,
+            konfabulatorVersion     : true,
+            log                     : true,
+            md5                     : true,
+            MenuItem                : true,
+            MoveAnimation           : true,
+            openURL                 : true,
+            play                    : true,
+            Point                   : true,
+            popupMenu               : true,
+            preferenceGroups        : true,
+            preferences             : true,
+            print                   : true,
+            prompt                  : true,
+            random                  : true,
+            Rectangle               : true,
+            reloadWidget            : true,
+            ResizeAnimation         : true,
+            resolvePath             : true,
+            resumeUpdates           : true,
+            RotateAnimation         : true,
+            runCommand              : true,
+            runCommandInBg          : true,
+            saveAs                  : true,
+            savePreferences         : true,
+            screen                  : true,
+            ScrollBar               : true,
+            showWidgetPreferences   : true,
+            sleep                   : true,
+            speak                   : true,
+            Style                   : true,
+            suppressUpdates         : true,
+            system                  : true,
+            tellWidget              : true,
+            Text                    : true,
+            TextArea                : true,
+            Timer                   : true,
+            unescape                : true,
+            updateNow               : true,
+            URL                     : true,
+            Web                     : true,
+            widget                  : true,
+            Window                  : true,
+            XMLDOM                  : true,
+            XMLHttpRequest          : true,
+            yahooCheckLogin         : true,
+            yahooLogin              : true,
+            yahooLogout             : true
+        },
+
+//  xmode is used to adapt to the exceptions in html parsing.
+//  It can have these states:
+//      false   .js script file
+//      html
+//      outer
+//      script
+//      style
+//      scriptstring
+//      styleproperty
+
+        xmode,
+        xquote,
+
+// unsafe comment or string
+        ax = /@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,
+// unsafe characters that are silently deleted by one or more browsers
+// Whitelist Replacement Char, 0xfffd
+        cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\ufffc\ufffe-\uffff]/,
+// token
+        tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
+// html token
+        hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,
+// characters in strings that need escapement
+        nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
+        nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+// outer html token
+        ox = /[>&]|<[\/!]?|--/,
+// star slash
+        lx = /\*\/|\/\*/,
+// identifier
+        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
+// javascript url
+        jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
+// url badness
+        ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,
+// style
+        sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,
+        ssx = /^\s*(\.?\d+(?:\.\d+)?|[@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|<\/)/,
+// attributes characters
+        //qx = /[^a-zA-Z0-9+\-_\/ ]/,
+        qx = /[^a-zA-Z0-9+\-_\/ .#]/, // We want dots in names, period; and hashes for templating
+// query characters for ids
+        //dx = /[\[\]\/\\"'*<>.&:(){}+=#]/,
+        // allow . and /
+        dx = /[\[\]\\"'*<>&:(){}+=#]/,
+
+        rx = {
+            outer: hx,
+            html: hx,
+            style: sx,
+            styleproperty: ssx
+        };
+
+    function F() {}
+
+    if (typeof Object.create !== 'function') {
+        Object.create = function (o) {
+            F.prototype = o;
+            return new F();
+        };
+    }
+
+
+    function is_own(object, name) {
+        return Object.prototype.hasOwnProperty.call(object, name);
+    }
+
+
+    function combine(t, o) {
+        var n;
+        for (n in o) {
+            if (is_own(o, n)) {
+                t[n] = o[n];
+            }
+        }
+    }
+
+    String.prototype.entityify = function () {
+        return this.
+            replace(/&/g, '&amp;').
+            replace(/</g, '&lt;').
+            replace(/>/g, '&gt;');
+    };
+
+    String.prototype.isAlpha = function () {
+        return (this >= 'a' && this <= 'z\uffff') ||
+            (this >= 'A' && this <= 'Z\uffff');
+    };
+
+
+    String.prototype.isDigit = function () {
+        return (this >= '0' && this <= '9');
+    };
+
+
+    String.prototype.supplant = function (o) {
+        return this.replace(/\{([^{}]*)\}/g, function (a, b) {
+            var r = o[b];
+            return typeof r === 'string' || typeof r === 'number' ? r : a;
+        });
+    };
+
+    String.prototype.name = function () {
+
+// If the string looks like an identifier, then we can return it as is.
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can simply slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe
+// sequences.
+
+        if (ix.test(this)) {
+            return this;
+        }
+        if (nx.test(this)) {
+            return '"' + this.replace(nxg, function (a) {
+                var c = escapes[a];
+                if (c) {
+                    return c;
+                }
+                return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
+            }) + '"';
+        }
+        return '"' + this + '"';
+    };
+
+
+    function assume() {
+        if (!option.safe) {
+            if (option.rhino) {
+                combine(predefined, rhino);
+            }
+            if (option.devel) {
+                combine(predefined, devel);
+            }
+            if (option.browser) {
+                combine(predefined, browser);
+            }
+            if (option.windows) {
+                combine(predefined, windows);
+            }
+            if (option.widget) {
+                combine(predefined, widget);
+            }
+        }
+    }
+
+
+// Produce an error warning.
+
+    function quit(m, l, ch) {
+        throw {
+            name: 'JSLintError',
+            line: l,
+            character: ch,
+            message: m + " (" + Math.floor((l / lines.length) * 100) +
+                    "% scanned)."
+        };
+    }
+
+    function warning(m, t, a, b, c, d) {
+        var ch, l, w;
+        t = t || nexttoken;
+        if (t.id === '(end)') {  // `~
+            t = token;
+        }
+        l = t.line || 0;
+        ch = t.from || 0;
+        w = {
+            id: '(error)',
+            raw: m,
+            evidence: lines[l - 1] || '',
+            line: l,
+            character: ch,
+            a: a,
+            b: b,
+            c: c,
+            d: d
+        };
+        w.reason = m.supplant(w);
+        JSLINT.errors.push(w);
+        if (option.passfail) {
+            quit('Stopping. ', l, ch);
+        }
+        warnings += 1;
+        if (warnings >= option.maxerr) {
+            quit("Too many errors.", l, ch);
+        }
+        return w;
+    }
+
+    function warningAt(m, l, ch, a, b, c, d) {
+        return warning(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+    function error(m, t, a, b, c, d) {
+        var w = warning(m, t, a, b, c, d);
+        quit("Stopping, unable to continue.", w.line, w.character);
+    }
+
+    function errorAt(m, l, ch, a, b, c, d) {
+        return error(m, {
+            line: l,
+            from: ch
+        }, a, b, c, d);
+    }
+
+
+
+// lexical analysis
+
+    var lex = (function lex() {
+        var character, from, line, s;
+
+// Private lex methods
+
+        function nextLine() {
+            var at;
+            if (line >= lines.length) {
+                return false;
+            }
+            character = 1;
+            s = lines[line];
+            line += 1;
+            at = s.search(/ \t/);
+            if (at >= 0) {
+                warningAt("Mixed spaces and tabs.", line, at + 1);
+            }
+            s = s.replace(/\t/g, tab);
+            at = s.search(cx);
+            if (at >= 0) {
+                warningAt("Unsafe character.", line, at);
+            }
+            if (option.maxlen && option.maxlen < s.length) {
+                warningAt("Line too long.", line, s.length);
+            }
+            return true;
+        }
+
+// Produce a token object.  The token inherits from a syntax symbol.
+
+        function it(type, value) {
+            var i, t;
+            if (type === '(color)') {
+                t = {type: type};
+            } else if (type === '(punctuator)' ||
+                    (type === '(identifier)' && is_own(syntax, value))) {
+                t = syntax[value] || syntax['(error)'];
+            } else {
+                t = syntax[type];
+            }
+            t = Object.create(t);
+            if (type === '(string)' || type === '(range)') {
+                if (jx.test(value)) {
+                    warningAt("Script URL.", line, from);
+                }
+            }
+            if (type === '(identifier)') {
+                t.identifier = true;
+                if (value === '__iterator__' || value === '__proto__') {
+                    errorAt("Reserved name '{a}'.",
+                        line, from, value);
+                } else if (option.nomen &&
+                        (value.charAt(0) === '_' ||
+                         value.charAt(value.length - 1) === '_')) {
+                    warningAt("Unexpected {a} in '{b}'.", line, from,
+                        "dangling '_'", value);
+                }
+            }
+            t.value = value;
+            t.line = line;
+            t.character = character;
+            t.from = from;
+            i = t.id;
+            if (i !== '(endline)') {
+                prereg = i &&
+                    (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
+                    i === 'return');
+            }
+            return t;
+        }
+
+// Public lex methods
+
+        return {
+            init: function (source) {
+                if (typeof source === 'string') {
+                    lines = source.
+                        replace(/\r\n/g, '\n').
+                        replace(/\r/g, '\n').
+                        split('\n');
+                } else {
+                    lines = source;
+                }
+                line = 0;
+                nextLine();
+                from = 1;
+            },
+
+            range: function (begin, end) {
+                var c, value = '';
+                from = character;
+                if (s.charAt(0) !== begin) {
+                    errorAt("Expected '{a}' and instead saw '{b}'.",
+                            line, character, begin, s.charAt(0));
+                }
+                for (;;) {
+                    s = s.slice(1);
+                    character += 1;
+                    c = s.charAt(0);
+                    switch (c) {
+                    case '':
+                        errorAt("Missing '{a}'.", line, character, c);
+                        break;
+                    case end:
+                        s = s.slice(1);
+                        character += 1;
+                        return it('(range)', value);
+                    case xquote:
+                    case '\\':
+                        warningAt("Unexpected '{a}'.", line, character, c);
+                    }
+                    value += c;
+                }
+
+            },
+
+// skip all content up to marker
+
+            skip_till: function (end) {
+                            for (;;) {
+                                i = s.indexOf(end);
+                                if (i >= 0) {
+                                    break;
+                                }
+                                if (!nextLine()) {
+                                    errorAt("Unclosed {a} block.", line, character, end);
+                                }
+                            }
+                            character += i;
+                            s = s.substr(i);
+            },
+
+// token -- this is called by advance to get the next token.
+
+            token: function () {
+                var b, c, captures, d, depth, high, i, l, low, q, t;
+
+                function match(x) {
+                    var r = x.exec(s), r1;
+                    if (r) {
+                        l = r[0].length;
+                        r1 = r[1];
+                        c = r1.charAt(0);
+                        s = s.substr(l);
+                        from = character + l - r1.length;
+                        character += l;
+                        return r1;
+                    }
+                }
+
+                function string(x) {
+                    var c, j, r = '';
+
+                    if (jsonmode && x !== '"') {
+                        warningAt("Strings must use doublequote.",
+                                line, character);
+                    }
+
+                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
+                        return it('(punctuator)', x);
+                    }
+
+                    function esc(n) {
+                        var i = parseInt(s.substr(j + 1, n), 16);
+                        j += n;
+                        if (i >= 32 && i <= 126 &&
+                                i !== 34 && i !== 92 && i !== 39) {
+                            warningAt("Unnecessary escapement.", line, character);
+                        }
+                        character += n;
+                        c = String.fromCharCode(i);
+                    }
+                    j = 0;
+                    for (;;) {
+                        while (j >= s.length) {
+                            j = 0;
+                            if (xmode !== 'html' || !nextLine()) {
+                                errorAt("Unclosed string.", line, from);
+                            }
+                        }
+                        c = s.charAt(j);
+                        if (c === x) {
+                            character += 1;
+                            s = s.substr(j + 1);
+                            return it('(string)', r, x);
+                        }
+                        if (c < ' ') {
+                            if (c === '\n' || c === '\r') {
+                                break;
+                            }
+                            warningAt("Control character in string: {a}.",
+                                    line, character + j, s.slice(0, j));
+                        } else if (c === xquote) {
+                            warningAt("Bad HTML string", line, character + j);
+                        } else if (c === '<') {
+                            if (option.safe && xmode === 'html') {
+                                warningAt("ADsafe string violation.",
+                                        line, character + j);
+                            } else if (s.charAt(j + 1) === '/' && (xmode || option.safe) && s.substr(j + 2, 6) === 'script') {
+                                warningAt("Expected '<\\/' and instead saw '</'.", line, character);
+                            } else if (s.charAt(j + 1) === '!' && (xmode || option.safe)) {
+                                warningAt("Unexpected '<!' in a string.", line, character);
+                            }
+                        } else if (c === '\\') {
+                            if (xmode === 'html') {
+                                if (option.safe) {
+                                    warningAt("ADsafe string violation.",
+                                            line, character + j);
+                                }
+                            } else if (xmode === 'styleproperty') {
+                                j += 1;
+                                character += 1;
+                                c = s.charAt(j);
+                                if (c !== x) {
+                                    warningAt("Escapement in style string.",
+                                            line, character + j);
+                                }
+                            } else {
+                                j += 1;
+                                character += 1;
+                                c = s.charAt(j);
+                                switch (c) {
+                                case xquote:
+                                    warningAt("Bad HTML string", line,
+                                        character + j);
+                                    break;
+                                case '\\':
+                                case '\'':
+                                case '"':
+                                case '/':
+                                    break;
+                                case 'b':
+                                    c = '\b';
+                                    break;
+                                case 'f':
+                                    c = '\f';
+                                    break;
+                                case 'n':
+                                    c = '\n';
+                                    break;
+                                case 'r':
+                                    c = '\r';
+                                    break;
+                                case 't':
+                                    c = '\t';
+                                    break;
+                                case 'u':
+                                    esc(4);
+                                    break;
+                                case 'v':
+                                    c = '\v';
+                                    break;
+                                case 'x':
+                                    if (jsonmode) {
+                                        warningAt("Avoid \\x-.", line, character);
+                                    }
+                                    esc(2);
+                                    break;
+                                default:
+                                    warningAt("Bad escapement.", line, character);
+                                }
+                            }
+                        }
+                        r += c;
+                        character += 1;
+                        j += 1;
+                    }
+                }
+
+                for (;;) {
+                    if (!s) {
+                        return it(nextLine() ? '(endline)' : '(end)', '');
+                    }
+                    while (xmode === 'outer') {
+                        i = s.search(ox);
+                        if (i === 0) {
+                            break;
+                        } else if (i > 0) {
+                            character += 1;
+                            s = s.slice(i);
+                            break;
+                        } else {
+                            if (!nextLine()) {
+                                return it('(end)', '');
+                            }
+                        }
+                    }
+//                     t = match(rx[xmode] || tx);
+//                     if (!t) {
+//                         if (xmode === 'html') {
+//                             return it('(error)', s.charAt(0));
+//                         } else {
+//                             t = '';
+//                             c = '';
+//                             while (s && s < '!') {
+//                                 s = s.substr(1);
+//                             }
+//                             if (s) {
+//                                 errorAt("Unexpected '{a}'.",
+//                                         line, character, s.substr(0, 1));
+//                             }
+//                         }
+                    t = match(rx[xmode] || tx);
+                    if (!t) {
+                        t = '';
+                        c = '';
+                        while (s && s < '!') {
+                            s = s.substr(1);
+                        }
+                        if (s) {
+                            if (xmode === 'html') {
+                                return it('(error)', s.charAt(0));
+                            } else {
+                                errorAt("Unexpected '{a}'.",
+                                        line, character, s.substr(0, 1));
+                            }
+                        }
+                    } else {
+
+    //      identifier
+
+                        if (c.isAlpha() || c === '_' || c === '$') {
+                            return it('(identifier)', t);
+                        }
+
+    //      number
+
+                        if (c.isDigit() || (c === '.' && t.substr(1, 1).isDigit())) {
+                            if (c === '.') {
+                                t = '0' + t;
+                                c = '0';
+                            }
+                        
+                            if (xmode !== 'style' && !isFinite(Number(t))) {
+                                warningAt("Bad number '{a}'.",
+                                    line, character, t);
+                            }
+                            if (xmode !== 'style' &&
+                                     xmode !== 'styleproperty' &&
+                                     s.substr(0, 1).isAlpha()) {
+                                warningAt("Missing space after '{a}'.",
+                                        line, character, t);
+                            }
+                            if (c === '0') {
+                                d = t.substr(1, 1);
+                                if (d.isDigit()) {
+                                    if (token.id !== '.' && xmode !== 'styleproperty') {
+                                        warningAt("Don't use extra leading zeros '{a}'.",
+                                            line, character, t);
+                                    }
+                                } else if (jsonmode && (d === 'x' || d === 'X')) {
+                                    warningAt("Avoid 0x-. '{a}'.",
+                                            line, character, t);
+                                }
+                            }
+                            if (t.substr(t.length - 1) === '.') {
+                                warningAt(
+        "A trailing decimal point can be confused with a dot '{a}'.",
+                                        line, character, t);
+                            }
+                            return it('(number)', t);
+                        }
+                        switch (t) {
+
+    //      string
+
+                        case '"':
+                        case "'":
+                            return string(t);
+
+    //      // comment
+
+                        case '//':
+                            if (src || (xmode && xmode !== 'script')) {
+                                warningAt("Unexpected comment.", line, character);
+                            } else if (xmode === 'script' && /<\s*\//i.test(s)) {
+                                warningAt("Unexpected <\/ in comment.", line, character);
+                            } else if ((option.safe || xmode === 'script') && ax.test(s)) {
+                                warningAt("Dangerous comment.", line, character);
+                            }
+                            s = '';
+                            token.comment = true;
+                            break;
+
+    //      /* comment
+
+                        case '/*':
+                            if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) {
+                                warningAt("Unexpected comment.", line, character);
+                            }
+                            if (option.safe && ax.test(s)) {
+                                warningAt("ADsafe comment violation.", line, character);
+                            }
+                            for (;;) {
+                                i = s.search(lx);
+                                if (i >= 0) {
+                                    break;
+                                }
+                                if (!nextLine()) {
+                                    errorAt("Unclosed comment.", line, character);
+                                } else {
+                                    if (option.safe && ax.test(s)) {
+                                        warningAt("ADsafe comment violation.",
+                                                line, character);
+                                    }
+                                }
+                            }
+                            character += i + 2;
+                            if (s.substr(i, 1) === '/') {
+                                errorAt("Nested comment.", line, character);
+                            }
+                            s = s.substr(i + 2);
+                            token.comment = true;
+                            break;
+
+    //      /*members /*jslint /*global
+
+                        case '/*members':
+                        case '/*member':
+                        case '/*jslint':
+                        case '/*global':
+                        case '*/':
+                            return {
+                                value: t,
+                                type: 'special',
+                                line: line,
+                                character: character,
+                                from: from
+                            };
+
+                        case '':
+                            break;
+    //      /
+                        case '/':
+                            if (token.id === '/=') {
+                                errorAt(
+"A regular expression literal can be confused with '/='.", line, from);
+                            }
+                            if (prereg) {
+                                depth = 0;
+                                captures = 0;
+                                l = 0;
+                                for (;;) {
+                                    b = true;
+                                    c = s.charAt(l);
+                                    l += 1;
+                                    switch (c) {
+                                    case '':
+                                        errorAt("Unclosed regular expression.",
+                                                line, from);
+                                        return;
+                                    case '/':
+                                        if (depth > 0) {
+                                            warningAt("Unescaped '{a}'.",
+                                                    line, from + l, '/');
+                                        }
+                                        c = s.substr(0, l - 1);
+                                        q = {
+                                            g: true,
+                                            i: true,
+                                            m: true
+                                        };
+                                        while (q[s.charAt(l)] === true) {
+                                            q[s.charAt(l)] = false;
+                                            l += 1;
+                                        }
+                                        character += l;
+                                        s = s.substr(l);
+                                        q = s.charAt(0);
+                                        if (q === '/' || q === '*') {
+                                            errorAt("Confusing regular expression.",
+                                                    line, from);
+                                        }
+                                        return it('(regexp)', c);
+                                    case '\\':
+                                        c = s.charAt(l);
+                                        if (c < ' ') {
+                                            warningAt(
+"Unexpected control character in regular expression.", line, from + l);
+                                        } else if (c === '<') {
+                                            warningAt(
+"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
+                                        }
+                                        l += 1;
+                                        break;
+                                    case '(':
+                                        depth += 1;
+                                        b = false;
+                                        if (s.charAt(l) === '?') {
+                                            l += 1;
+                                            switch (s.charAt(l)) {
+                                            case ':':
+                                            case '=':
+                                            case '!':
+                                                l += 1;
+                                                break;
+                                            default:
+                                                warningAt(
+"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
+                                            }
+                                        } else {
+                                            captures += 1;
+                                        }
+                                        break;
+                                    case '|':
+                                        b = false;
+                                        break;
+                                    case ')':
+                                        if (depth === 0) {
+                                            warningAt("Unescaped '{a}'.",
+                                                    line, from + l, ')');
+                                        } else {
+                                            depth -= 1;
+                                        }
+                                        break;
+                                    case ' ':
+                                        q = 1;
+                                        while (s.charAt(l) === ' ') {
+                                            l += 1;
+                                            q += 1;
+                                        }
+                                        if (q > 1) {
+                                            warningAt(
+"Spaces are hard to count. Use {{a}}.", line, from + l, q);
+                                        }
+                                        break;
+                                    case '[':
+                                        c = s.charAt(l);
+                                        if (c === '^') {
+                                            l += 1;
+                                            if (option.regexp) {
+                                                warningAt("Insecure '{a}'.",
+                                                        line, from + l, c);
+                                            }
+                                        }
+                                        q = false;
+                                        if (c === ']') {
+                                            warningAt("Empty class.", line,
+                                                    from + l - 1);
+                                            q = true;
+                                        }
+klass:                                  do {
+                                            c = s.charAt(l);
+                                            l += 1;
+                                            switch (c) {
+                                            case '[':
+                                            case '^':
+                                                warningAt("Unescaped '{a}'.",
+                                                        line, from + l, c);
+                                                q = true;
+                                                break;
+                                            case '-':
+                                                if (q) {
+                                                    q = false;
+                                                } else {
+                                                    warningAt("Unescaped '{a}'.",
+                                                            line, from + l, '-');
+                                                    q = true;
+                                                }
+                                                break;
+                                            case ']':
+                                                if (!q) {
+                                                    warningAt("Unescaped '{a}'.",
+                                                            line, from + l - 1, '-');
+                                                }
+                                                break klass;
+                                            case '\\':
+                                                c = s.charAt(l);
+                                                if (c < ' ') {
+                                                    warningAt(
+"Unexpected control character in regular expression.", line, from + l);
+                                                } else if (c === '<') {
+                                                    warningAt(
+"Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
+                                                }
+                                                l += 1;
+                                                q = true;
+                                                break;
+                                            case '/':
+                                                warningAt("Unescaped '{a}'.",
+                                                        line, from + l - 1, '/');
+                                                q = true;
+                                                break;
+                                            case '<':
+                                                if (xmode === 'script') {
+                                                    c = s.charAt(l);
+                                                    if (c === '!' || c === '/') {
+                                                        warningAt(
+"HTML confusion in regular expression '<{a}'.", line, from + l, c);
+                                                    }
+                                                }
+                                                q = true;
+                                                break;
+                                            default:
+                                                q = true;
+                                            }
+                                        } while (c);
+                                        break;
+                                    case '.':
+                                        if (option.regexp) {
+                                            warningAt("Insecure '{a}'.", line,
+                                                    from + l, c);
+                                        }
+                                        break;
+                                    case ']':
+                                    case '?':
+                                    case '{':
+                                    case '}':
+                                    case '+':
+                                    case '*':
+                                        warningAt("Unescaped '{a}'.", line,
+                                                from + l, c);
+                                        break;
+                                    case '<':
+                                        if (xmode === 'script') {
+                                            c = s.charAt(l);
+                                            if (c === '!' || c === '/') {
+                                                warningAt(
+"HTML confusion in regular expression '<{a}'.", line, from + l, c);
+                                            }
+                                        }
+                                    }
+                                    if (b) {
+                                        switch (s.charAt(l)) {
+                                        case '?':
+                                        case '+':
+                                        case '*':
+                                            l += 1;
+                                            if (s.charAt(l) === '?') {
+                                                l += 1;
+                                            }
+                                            break;
+                                        case '{':
+                                            l += 1;
+                                            c = s.charAt(l);
+                                            if (c < '0' || c > '9') {
+                                                warningAt(
+"Expected a number and instead saw '{a}'.", line, from + l, c);
+                                            }
+                                            l += 1;
+                                            low = +c;
+                                            for (;;) {
+                                                c = s.charAt(l);
+                                                if (c < '0' || c > '9') {
+                                                    break;
+                                                }
+                                                l += 1;
+                                                low = +c + (low * 10);
+                                            }
+                                            high = low;
+                                            if (c === ',') {
+                                                l += 1;
+                                                high = Infinity;
+                                                c = s.charAt(l);
+                                                if (c >= '0' && c <= '9') {
+                                                    l += 1;
+                                                    high = +c;
+                                                    for (;;) {
+                                                        c = s.charAt(l);
+                                                        if (c < '0' || c > '9') {
+                                                            break;
+                                                        }
+                                                        l += 1;
+                                                        high = +c + (high * 10);
+                                                    }
+                                                }
+                                            }
+                                            if (s.charAt(l) !== '}') {
+                                                warningAt(
+"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
+                                            } else {
+                                                l += 1;
+                                            }
+                                            if (s.charAt(l) === '?') {
+                                                l += 1;
+                                            }
+                                            if (low > high) {
+                                                warningAt(
+"'{a}' should not be greater than '{b}'.", line, from + l, low, high);
+                                            }
+                                        }
+                                    }
+                                }
+                                c = s.substr(0, l - 1);
+                                character += l;
+                                s = s.substr(l);
+                                return it('(regexp)', c);
+                            }
+                            return it('(punctuator)', t);
+
+    //      punctuator
+
+                        case '<!--':
+                            l = line;
+                            c = character;
+                            for (;;) {
+                                i = s.indexOf('--');
+                                if (i >= 0) {
+                                    break;
+                                }
+                                i = s.indexOf('<!-');
+                                if (i >= 0) {
+                                    errorAt("Nested HTML comment.",
+                                        line, character + i);
+                                }
+                                if (!nextLine()) {
+                                    errorAt("Unclosed HTML comment.", l, c);
+                                }
+                            }
+                            l = s.indexOf('<!-');
+                            if (l >= 0 && l < i) {
+                                errorAt("Nested HTML comment.",
+                                    line, character + l);
+                            }
+                            character += i;
+                            if (s[i + 2] !== '>') {
+                                errorAt("Expected -->.", line, character);
+                            }
+                            character += 3;
+                            s = s.slice(i + 3);
+                            break;
+                        case '#':
+                            if (xmode === 'html' || xmode === 'styleproperty') {
+                                for (;;) {
+                                    c = s.charAt(0);
+                                    if ((c < '0' || c > '9') &&
+                                            (c < 'a' || c > 'f') &&
+                                            (c < 'A' || c > 'F')) {
+                                        break;
+                                    }
+                                    character += 1;
+                                    s = s.substr(1);
+                                    t += c;
+                                }
+                                if (t.length !== 4 && t.length !== 7) {
+                                    warningAt("Bad hex color '{a}'.", line,
+                                        from + l, t);
+                                }
+                                return it('(color)', t);
+                            }
+                            return it('(punctuator)', t);
+                        default:
+                            if (xmode === 'outer' && c === '&') {
+                                character += 1;
+                                s = s.substr(1);
+                                for (;;) {
+                                    c = s.charAt(0);
+                                    character += 1;
+                                    s = s.substr(1);
+                                    if (c === ';') {
+                                        break;
+                                    }
+                                    if (!((c >= '0' && c <= '9') ||
+                                            (c >= 'a' && c <= 'z') ||
+                                            c === '#')) {
+                                        errorAt("Bad entity", line, from + l,
+                                        character);
+                                    }
+                                }
+                                break;
+                            }
+                            return it('(punctuator)', t);
+                        }
+                    }
+                }
+            }
+        };
+    }());
+
+
+    function addlabel(t, type) {
+
+        if (option.safe && funct['(global)'] &&
+                typeof predefined[t] !== 'boolean') {
+            warning('ADsafe global: ' + t + '.', token);
+        } else if (t === 'hasOwnProperty') {
+            warning("'hasOwnProperty' is a really bad name.");
+        }
+
+// Define t in the current function in the current scope.
+
+        if (is_own(funct, t) && !funct['(global)']) {
+            warning(funct[t] === true ?
+                "'{a}' was used before it was defined." :
+                "'{a}' is already defined.",
+                nexttoken, t);
+        }
+        funct[t] = type;
+        if (funct['(global)']) {
+            global[t] = funct;
+            if (is_own(implied, t)) {
+                warning("'{a}' was used before it was defined.", nexttoken, t);
+                delete implied[t];
+            }
+        } else {
+            scope[t] = funct;
+        }
+    }
+
+
+    function doOption() {
+        var b, obj, filter, o = nexttoken.value, t, v;
+        switch (o) {
+        case '*/':
+            error("Unbegun comment.");
+            break;
+        case '/*members':
+        case '/*member':
+            o = '/*members';
+            if (!membersOnly) {
+                membersOnly = {};
+            }
+            obj = membersOnly;
+            break;
+        case '/*jslint':
+            if (option.safe) {
+                warning("ADsafe restriction.");
+            }
+            obj = option;
+            filter = boolOptions;
+            break;
+        case '/*global':
+            if (option.safe) {
+                warning("ADsafe restriction.");
+            }
+            obj = predefined;
+            break;
+        default:
+        }
+        t = lex.token();
+loop:   for (;;) {
+            for (;;) {
+                if (t.type === 'special' && t.value === '*/') {
+                    break loop;
+                }
+                if (t.id !== '(endline)' && t.id !== ',') {
+                    break;
+                }
+                t = lex.token();
+            }
+            if (t.type !== '(string)' && t.type !== '(identifier)' &&
+                    o !== '/*members') {
+                error("Bad option.", t);
+            }
+            v = lex.token();
+            if (v.id === ':') {
+                v = lex.token();
+                if (obj === membersOnly) {
+                    error("Expected '{a}' and instead saw '{b}'.",
+                            t, '*/', ':');
+                }
+                if (t.value === 'indent' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.white = true;
+                    obj.indent = b;
+                } else if (t.value === 'maxerr' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.maxerr = b;
+                } else if (t.value === 'maxlen' && o === '/*jslint') {
+                    b = +v.value;
+                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
+                            Math.floor(b) !== b) {
+                        error("Expected a small integer and instead saw '{a}'.",
+                                v, v.value);
+                    }
+                    obj.maxlen = b;
+                } else if (v.value === 'true') {
+                    obj[t.value] = true;
+                } else if (v.value === 'false') {
+                    obj[t.value] = false;
+                } else {
+                    error("Bad option value.", v);
+                }
+                t = lex.token();
+            } else {
+                if (o === '/*jslint') {
+                    error("Missing option value.", t);
+                }
+                obj[t.value] = false;
+                t = v;
+            }
+        }
+        if (filter) {
+            assume();
+        }
+    }
+
+
+// We need a peek function. If it has an argument, it peeks that much farther
+// ahead. It is used to distinguish
+//     for ( var i in ...
+// from
+//     for ( var i = ...
+
+    function peek(p) {
+        var i = p || 0, j = 0, t;
+
+        while (j <= i) {
+            t = lookahead[j];
+            if (!t) {
+                t = lookahead[j] = lex.token();
+            }
+            j += 1;
+        }
+        return t;
+    }
+
+
+
+// Produce the next token. It looks for programming errors.
+
+    function advance(id, t) {
+        switch (token.id) {
+        case '(number)':
+            if (nexttoken.id === '.') {
+                warning(
+"A dot following a number can be confused with a decimal point.", token);
+            }
+            break;
+        case '-':
+            if (nexttoken.id === '-' || nexttoken.id === '--') {
+                warning("Confusing minusses.");
+            }
+            break;
+        case '+':
+            if (nexttoken.id === '+' || nexttoken.id === '++') {
+                warning("Confusing plusses.");
+            }
+            break;
+        }
+        if (token.type === '(string)' || token.identifier) {
+            anonname = token.value;
+        }
+
+        if (id && nexttoken.id !== id) {
+            if (t) {
+                if (nexttoken.id === '(end)') {
+                    warning("Unmatched '{a}'.", t, t.id);
+                } else {
+                    warning(
+"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
+                            nexttoken, id, t.id, t.line, nexttoken.value);
+                }
+            } else if (nexttoken.type !== '(identifier)' ||
+                            nexttoken.value !== id) {
+                warning("Expected '{a}' and instead saw '{b}'.",
+                        nexttoken, id, nexttoken.value);
+            }
+        }
+        prevtoken = token;
+        token = nexttoken;
+        for (;;) {
+            nexttoken = lookahead.shift() || lex.token();
+            if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
+                return;
+            }
+            if (nexttoken.type === 'special') {
+                doOption();
+            } else {
+                if (nexttoken.id !== '(endline)') {
+                    break;
+                }
+            }
+        }
+    }
+
+
+// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it
+// is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is
+// like nud except that it is only used on the first token of a statement.
+// Having .fud makes it much easier to define JavaScript. I retained Pratt's
+// nomenclature.
+
+// .nud     Null denotation
+// .fud     First null denotation
+// .led     Left denotation
+//  lbp     Left binding power
+//  rbp     Right binding power
+
+// They are key to the parsing method called Top Down Operator Precedence.
+
+    function parse(rbp, initial) {
+        var left;
+        if (nexttoken.id === '(end)') {
+            error("Unexpected early end of program.", token);
+        }
+        advance();
+        if (option.safe && typeof predefined[token.value] === 'boolean' &&
+                (nexttoken.id !== '(' && nexttoken.id !== '.')) {
+            warning('ADsafe violation.', token);
+        }
+        if (initial) {
+            anonname = 'anonymous';
+            funct['(verb)'] = token.value;
+        }
+        if (initial === true && token.fud) {
+            left = token.fud();
+        } else {
+            if (token.nud) {
+                left = token.nud();
+            } else {
+                if (nexttoken.type === '(number)' && token.id === '.') {
+                    warning(
+"A leading decimal point can be confused with a dot: '.{a}'.",
+                            token, nexttoken.value);
+                    advance();
+                    return token;
+                } else {
+                    error("Expected an identifier and instead saw '{a}'.",
+                            token, token.id);
+                }
+            }
+            while (rbp < nexttoken.lbp) {
+                advance();
+                if (token.led) {
+                    left = token.led(left);
+                } else {
+                    error("Expected an operator and instead saw '{a}'.",
+                        token, token.id);
+                }
+            }
+        }
+        return left;
+    }
+
+
+// Functions for conformance of style.
+
+    function adjacent(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white || xmode === 'styleproperty' || xmode === 'style') {
+            if (left.character !== right.from && left.line === right.line) {
+                warning("Unexpected space after '{a}'.", right, left.value);
+            }
+        }
+    }
+
+    function nospace(left, right) {
+        left = left || token;
+        right = right || nexttoken;
+        if (option.white && !left.comment) {
+            if (left.line === right.line) {
+                adjacent(left, right);
+            }
+        }
+    }
+
+
+    function nonadjacent(left, right) {
+        if (option.white) {
+            left = left || token;
+            right = right || nexttoken;
+            if (left.line === right.line && left.character === right.from) {
+                warning("Missing space after '{a}'.",
+                        nexttoke

<TRUNCATED>

[18/50] [abbrv] git commit: [#5103] ticket:396 Set HEAD when switching default branch

Posted by tv...@apache.org.
[#5103] ticket:396 Set HEAD when switching default branch


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/19c76736
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/19c76736
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/19c76736

Branch: refs/heads/tv/6355
Commit: 19c7673683bc16f87a9021088f49a94244959150
Parents: a5680c0
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Jul 1 09:43:46 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:59:51 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/repository.py                       |  2 +-
 Allura/allura/model/repository.py                     | 10 ++++++++++
 ForgeGit/forgegit/model/git_repo.py                   |  7 +++++++
 .../forgegit/tests/functional/test_controllers.py     | 14 ++++++++++----
 4 files changed, 28 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/19c76736/Allura/allura/lib/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/repository.py b/Allura/allura/lib/repository.py
index 7aa7399..95a3d54 100644
--- a/Allura/allura/lib/repository.py
+++ b/Allura/allura/lib/repository.py
@@ -221,7 +221,7 @@ class RepoAdminController(DefaultAdminController):
     @expose('jinja:allura:templates/repo/default_branch.html')
     def set_default_branch_name(self, branch_name=None, **kw):
         if (request.method == 'POST') and branch_name:
-            self.repo.default_branch_name = branch_name
+            self.repo.set_default_branch(branch_name)
             redirect(request.referer)
         else:
             return dict(app=self.app,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/19c76736/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 5492ef3..32cea30 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -386,6 +386,16 @@ class Repository(Artifact, ActivityObject):
     @property
     def head(self):
         return self._impl.head
+    def set_default_branch(self, name):
+        return self._impl.set_default_branch(name)
+
+    def _log(self, rev, skip, limit):
+        head = self.commit(rev)
+        if head is None: return
+        for _id in self.commitlog([head._id], skip, limit):
+            ci = head.query.get(_id=_id)
+            ci.set_context(self)
+            yield ci
 
     def init_as_clone(self, source_path, source_name, source_url):
         self.upstream_repo.name = source_name

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/19c76736/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 6081a55..0da371d 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -445,6 +445,13 @@ class GitImplementation(M.RepositoryImplementation):
     def tags(self):
         return [Object(name=t.name, object_id=t.commit.hexsha) for t in self._git.tags if t.is_valid()]
 
+    def set_default_branch(self, name):
+        if not name:
+            return
+        # HEAD should point to default branch
+        self._git.git.symbolic_ref('HEAD', 'refs/heads/%s' % name)
+        self._repo.default_branch_name = name
+        session(self._repo).flush(self._repo)
 
 class _OpenedGitBlob(object):
     CHUNK_SIZE=4096

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/19c76736/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 841d0fb..6646318 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -21,7 +21,7 @@ import os
 import shutil
 import tempfile
 
-from nose.tools import assert_equal
+from nose.tools import assert_equal, assert_in, assert_not_in
 import tg
 import pkg_resources
 from pylons import tmpl_context as c
@@ -356,10 +356,10 @@ class TestRootController(_TestCase):
 
     def test_default_branch(self):
         assert_equal(c.app.default_branch_name, 'master')
-        c.app.repo.default_branch_name = 'zz'
+        c.app.repo.set_default_branch('zz')
         assert_equal(c.app.default_branch_name, 'zz')
-        r = self.app.get('/p/test/src-git/').follow().follow()
-        assert '<span class="scm-branch-label">zz</span>' in r
+        c.app.repo.set_default_branch('master')
+        assert_equal(c.app.default_branch_name, 'master')
 
     def test_set_default_branch(self):
         r = self.app.get('/p/test/admin/src-git/set_default_branch_name')
@@ -369,6 +369,12 @@ class TestRootController(_TestCase):
         assert '<input type="text" name="branch_name" id="branch_name"  value="zz"/>' in r
         r = self.app.get('/p/test/src-git/').follow().follow()
         assert '<span class="scm-branch-label">zz</span>' in r
+        assert_in('<span>bad</span>', r)  # 'bad' is a file name which in zz, but not in master
+
+        self.app.post('/p/test/admin/src-git/set_default_branch_name', params={'branch_name':'master'})
+        r = self.app.get('/p/test/src-git/').follow().follow()
+        assert_not_in('<span>bad</span>', r)
+        assert_in('<span>README</span>', r)
 
 
 class TestRestController(_TestCase):


[15/50] [abbrv] git commit: [#6056] Fixed _lookup error in ForgeBlog

Posted by tv...@apache.org.
[#6056] Fixed _lookup error in ForgeBlog

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/8e1581e5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/8e1581e5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/8e1581e5

Branch: refs/heads/tv/6355
Commit: 8e1581e5ab3a696bb81560f8fb994891c0a3b36f
Parents: 4358701
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 1 21:41:13 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Sun Jul 7 03:48:41 2013 +0000

----------------------------------------------------------------------
 ForgeBlog/forgeblog/main.py                       | 4 +++-
 ForgeBlog/forgeblog/tests/functional/test_root.py | 6 +++++-
 2 files changed, 8 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8e1581e5/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 24b0bf2..0b9ff70 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -261,7 +261,9 @@ class RootController(BaseController, FeedController):
         return dict()
 
     @expose()
-    def _lookup(self, year, month, name, *rest):
+    def _lookup(self, year=None, month=None, name=None, *rest):
+        if year is None or month is None or name is None:
+            raise exc.HTTPNotFound()
         slug = '/'.join((year, month, urllib2.unquote(name).decode('utf-8')))
         post = BM.BlogPost.query.get(slug=slug, app_config_id=c.app.config._id)
         if post is None:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8e1581e5/ForgeBlog/forgeblog/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/tests/functional/test_root.py b/ForgeBlog/forgeblog/tests/functional/test_root.py
index 3c13a69..4409b33 100644
--- a/ForgeBlog/forgeblog/tests/functional/test_root.py
+++ b/ForgeBlog/forgeblog/tests/functional/test_root.py
@@ -17,6 +17,7 @@
 
 import datetime
 
+from nose.tools import assert_equal
 from ming.orm.ormsession import ThreadLocalORMSession
 from mock import patch
 
@@ -203,7 +204,6 @@ class TestRootController(TestController):
         response = self.app.get('/blog/feed')
         assert '&lt;div class="markdown_content"&gt;&lt;p&gt;&lt;em&gt;sometext&lt;/em&gt;&lt;/p&gt;&lt;/div&gt;' in response
 
-
     def test_related_artifacts(self):
         self._post(title='one')
         d = self._blog_date()
@@ -213,3 +213,7 @@ class TestRootController(TestController):
         r= self.app.get('/blog/%s/one/' % d)
         assert 'Related' in r
         assert 'Blog Post: %s/two' % d in r
+
+    def test_invalid_lookup(self):
+        r = self.app.get('/blog/favicon.ico', status=404)
+        assert_equal(r.status_int, 404)


[46/50] [abbrv] git commit: remove hardcoded hostname

Posted by tv...@apache.org.
remove hardcoded hostname


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ff725898
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ff725898
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ff725898

Branch: refs/heads/tv/6355
Commit: ff725898642c6fa729b94a0038350eb03b3daca4
Parents: 94b75f0
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Sat May 25 13:29:05 2013 -0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Jul 11 21:30:46 2013 +0000

----------------------------------------------------------------------
 AlluraTest/alluratest/validation.py | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ff725898/AlluraTest/alluratest/validation.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/validation.py b/AlluraTest/alluratest/validation.py
index 7a5fd0b..39f73c3 100644
--- a/AlluraTest/alluratest/validation.py
+++ b/AlluraTest/alluratest/validation.py
@@ -47,11 +47,6 @@ from ming.utils import LazyProperty
 
 from allura.lib import utils
 
-ENABLE_CONTENT_VALIDATION = False
-# By default we want to run only validations which are fast,
-# but on special test hosts - all.
-COMPLETE_TESTS_HOST = 'sb-forge-4039'
-
 log = logging.getLogger(__name__)
 
 class Config(object):
@@ -93,9 +88,6 @@ class Config(object):
         elif env_var is not None:
             return val_type in env_var.split(',')
 
-        if self.hostname == COMPLETE_TESTS_HOST:
-            return True
-
         enabled = self.test_ini.getboolean('validation', 'validate_' + val_type)
         return enabled
 
@@ -103,9 +95,7 @@ class Config(object):
         env_var = os.getenv('ALLURA_VALIDATION')
         if env_var == 'all':
             return True
-        if self.hostname == COMPLETE_TESTS_HOST:
-            return True
-        return ENABLE_CONTENT_VALIDATION
+        return False
 
 
 def report_validation_error(val_name, filename, message):