def test_zend_view_hooks(self): test_dir = join(self.test_dir, "test_zend_view_hooks") content, positions = unmark_text( dedent("""\ <?php if($this->values) { ?> <h3>You just submitted the following values:</h3> <ul> <?php foreach ($this->values as $value) :?> <li> <?= $this-><1>escape(<2>$value); ?> </li> <?php endforeach; ?> </ul> <?= $this->form; ?> """)) phpExtraPaths = os.pathsep.join(self._ci_extra_path_dirs_) env = SimplePrefsEnvironment(phpExtraPaths=phpExtraPaths) # Test to make sure the zend hooks are only modifying the files # in the /view/scripts/ directories. We should *not* get the completions # for the above code. path = join(test_dir, "test_zend_view.phtml") writefile(path, content) buf = self.mgr.buf_from_path(path, lang=self.lang, env=env) buf.scan_if_necessary() self.assertCompletionsDoNotInclude2(buf, positions[1], [("function", "escape"), ("function", "render")]) # Test to make sure the zend hooks are only modifying the ".phtml" files # in the /view/scripts/ directories. We should *not* get the completions # for the above code. path = join(test_dir, "test_zend_view.php") writefile(path, content) buf = self.mgr.buf_from_path(path, lang=self.lang, env=env) buf.scan_if_necessary() self.assertCompletionsDoNotInclude2(buf, positions[1], [("function", "escape"), ("function", "render")]) # Now make sure we do get the completions on /view/scripts/ directories. path = join(test_dir, "views", "scripts", "test_zend_view.phtml") writefile(path, content) buf = self.mgr.buf_from_path(path, lang=self.lang, env=env) buf.scan_if_necessary() self.assertCompletionsInclude2(buf, positions[1], [("function", "escape"), ("function", "render")]) # Make sure we do not get completions on the added "(render)" function. self.assertCompletionsDoNotInclude2(buf, positions[1], [ ("function", "(render)"), ])
def test_completions_dtd(self): sample = dedent(""" <html> <body> <<|> </body> </html>""") env = SimplePrefsEnvironment() buf, data = self._get_buf_and_data(sample, self.lang, env=env) # Test HTML4... env.set_pref("defaultHTMLDecl", "-//W3C//DTD HTML 4.01//EN") self.assertCompletionsInclude2(buf, data["pos"], [("element", "script")], unload=False) self.assertCompletionsDoNotInclude2(buf, data["pos"], [("element", "section")], unload=False) # Flip to HTML5... env.set_pref("defaultHTMLDecl", "-//W3C//DTD HTML 5//EN") self.assertCompletionsInclude2(buf, data["pos"], [("element", "script")], unload=False) self.assertCompletionsInclude2(buf, data["pos"], [("element", "section")], unload=False) # And back to HTML4 again env.set_pref("defaultHTMLDecl", "-//W3C//DTD HTML 4.01//EN") self.assertCompletionsInclude2(buf, data["pos"], [("element", "script")], unload=False) self.assertCompletionsDoNotInclude2(buf, data["pos"], [("element", "section")], unload=False)
def setUp(self): if _xpcom_: # The tests are run outside of Komodo. If run with PyXPCOM up # parts codeintel will try to use the nsIDirectoryService and # will query dirs only provided by nsXREDirProvider -- which # isn't registered outside of Komodo (XRE_main() isn't called). # The KoTestService provides a backup. koTestSvc = components.classes["@activestate.com/koTestService;1"] \ .getService(components.interfaces.koITestService) koTestSvc.init() if self._ci_test_setup_mgr_: env = None if self._ci_env_prefs_ is not None: env = SimplePrefsEnvironment(**self._ci_env_prefs_) self.mgr = Manager( extra_module_dirs=self._ci_extra_module_dirs_, db_base_dir=self._ci_db_base_dir_ or test_db_base_dir, db_catalog_dirs=self._ci_db_catalog_dirs_, db_import_everything_langs=self._ci_db_import_everything_langs, env=env) self.mgr.upgrade() self.mgr.initialize()
def test_completions_dtd(self): sample = dedent(""" <html> <body> <<|> </body> </html>""") env = SimplePrefsEnvironment() buf, data = self._get_buf_and_data(sample, self.lang, env=env) # Test HTML4... env.set_pref("defaultHTMLDecl", "-//W3C//DTD HTML 4.01//EN") self.assertCompletionsInclude2(buf, data["pos"], [("element", "script")], unload=False) self.assertCompletionsDoNotInclude2(buf, data["pos"], [("element", "section")], unload=False) # Flip to HTML5... env.set_pref("defaultHTMLDecl", "-//W3C//DTD HTML 5//EN") self.assertCompletionsInclude2(buf, data["pos"], [("element", "script")], unload=False) self.assertCompletionsInclude2(buf, data["pos"], [("element", "section")], unload=False) # And back to HTML4 again env.set_pref("defaultHTMLDecl", "-//W3C//DTD HTML 4.01//EN") self.assertCompletionsInclude2(buf, data["pos"], [("element", "script")], unload=False) self.assertCompletionsDoNotInclude2(buf, data["pos"], [("element", "section")], unload=False)
def ci_setUpClass(cls): if _xpcom_: # The tests are run outside of Komodo. If run with PyXPCOM up # parts codeintel will try to use the nsIDirectoryService and # will query dirs only provided by nsXREDirProvider -- which # isn't registered outside of Komodo (XRE_main() isn't called). # The KoTestService provides a backup. koTestSvc = components.classes["@activestate.com/koTestService;1"] \ .getService(components.interfaces.koITestService) koTestSvc.init() if cls._ci_test_setup_mgr_: env = None if cls._ci_env_prefs_ is not None: env = SimplePrefsEnvironment(**cls._ci_env_prefs_) def get_extra_module_dirs(): spec = join(dirname( __file__), "..", "..", "udl", "skel", "*", "pylib") for d in glob(spec): if glob(join(spec, "lang_*.py")): yield d for d in cls._ci_extra_module_dirs_ or []: yield d cls.mgr = Manager( extra_module_dirs=get_extra_module_dirs(), db_base_dir=cls._ci_db_base_dir_ or test_db_base_dir, db_catalog_dirs=cls._ci_db_catalog_dirs_, db_import_everything_langs=cls._ci_db_import_everything_langs, env=env) cls.mgr.upgrade() cls.mgr.initialize() init_xml_catalogs()
def _codeintel_scan(): global despair, despaired env = None mtime = None catalogs = [] now = time.time() mgr = codeintel_manager(folders_id) mgr.db.event_reporter = lambda m: logger(view, 'event', m) try: env = _ci_envs_[vid] if env._folders != folders: raise KeyError if now > env._time: mtime = max(tryGetMTime(env._config_file), tryGetMTime(env._config_default_file)) if env._mtime < mtime: raise KeyError except KeyError: if env is not None: config_default_file = env._config_default_file project_dir = env._project_dir project_base_dir = env._project_base_dir config_file = env._config_file else: config_default_file = os.path.join(CODEINTEL_HOME_DIR, 'config') if not (config_default_file and os.path.exists(config_default_file)): config_default_file = None project_dir = None project_base_dir = None for folder_path in folders + [path]: if folder_path: # Try to find a suitable project directory (or best guess): for folder in ['.codeintel', '.git', '.hg', '.svn', 'trunk']: project_dir = find_back(folder_path, folder) if project_dir: if folder == '.codeintel': if project_dir == CODEINTEL_HOME_DIR or os.path.exists(os.path.join(project_dir, 'databases')): continue if folder.startswith('.'): project_base_dir = os.path.abspath(os.path.join(project_dir, '..')) else: project_base_dir = project_dir break if project_base_dir: break if not (project_dir and os.path.exists(project_dir)): project_dir = None config_file = project_dir and folder == '.codeintel' and os.path.join(project_dir, 'config') if not (config_file and os.path.exists(config_file)): config_file = None valid = True if not mgr.is_citadel_lang(lang) and not mgr.is_cpln_lang(lang): if lang in ('Console', 'Plain text'): msg = "Invalid language: %s. Available: %s" % (lang, ', '.join(set(mgr.get_citadel_langs() + mgr.get_cpln_langs()))) log.debug(msg) codeintel_log.warning(msg) valid = False codeintel_config_lang = codeintel_config.get(lang, {}) codeintel_max_recursive_dir_depth = codeintel_config_lang.get('codeintel_max_recursive_dir_depth', _codeintel_max_recursive_dir_depth) codeintel_scan_files_in_project = codeintel_config_lang.get('codeintel_scan_files_in_project', _codeintel_scan_files_in_project) codeintel_selected_catalogs = codeintel_config_lang.get('codeintel_selected_catalogs', _codeintel_selected_catalogs) avail_catalogs = mgr.db.get_catalogs_zone().avail_catalogs() # Load configuration files: all_catalogs = [] for catalog in avail_catalogs: all_catalogs.append("%s (for %s: %s)" % (catalog['name'], catalog['lang'], catalog['description'])) if catalog['lang'] == lang: if catalog['name'] in codeintel_selected_catalogs: catalogs.append(catalog['name']) msg = "Avaliable catalogs: %s" % ', '.join(all_catalogs) or None log.debug(msg) codeintel_log.debug(msg) config = { 'codeintel_max_recursive_dir_depth': codeintel_max_recursive_dir_depth, 'codeintel_scan_files_in_project': codeintel_scan_files_in_project, 'codeintel_selected_catalogs': catalogs, } config.update(codeintel_config_lang) _config = {} try: tryReadDict(config_default_file, _config) except Exception as e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) try: tryReadDict(config_file, _config) except Exception as e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) config.update(_config.get(lang, {})) for conf in ['pythonExtraPaths', 'rubyExtraPaths', 'perlExtraPaths', 'javascriptExtraPaths', 'phpExtraPaths']: v = [p.strip() for p in config.get(conf, []) + folders if p.strip()] config[conf] = os.pathsep.join(set(p if p.startswith('/') else os.path.expanduser(p) if p.startswith('~') else os.path.abspath(os.path.join(project_base_dir, p)) if project_base_dir else p for p in v if p.strip())) for conf, p in config.items(): if isinstance(p, basestring) and p.startswith('~'): config[conf] = os.path.expanduser(p) # Setup environment variables env = config.get('env', {}) _environ = dict(os.environ) for k, v in env.items(): _old = None while '$' in v and v != _old: _old = v v = os.path.expandvars(v) _environ[k] = v config['env'] = _environ env = SimplePrefsEnvironment(**config) env._valid = valid env._mtime = mtime or max(tryGetMTime(config_file), tryGetMTime(config_default_file)) env._folders = folders env._config_default_file = config_default_file env._project_dir = project_dir env._project_base_dir = project_base_dir env._config_file = config_file env.__class__.get_proj_base_dir = lambda self: project_base_dir _ci_envs_[vid] = env env._time = now + 5 # don't check again in less than five seconds msgs = [] if env._valid: if forms: calltip(view, 'tip', "") calltip(view, 'event', "") msg = "CodeIntel(%s) for %s@%s [%s]" % (', '.join(forms), path, pos, lang) msgs.append(('info', "\n%s\n%s" % (msg, "-" * len(msg)))) if catalogs: msg = "New env with catalogs for '%s': %s" % (lang, ', '.join(catalogs) or None) log.debug(msg) codeintel_log.warning(msg) msgs.append(('info', msg)) buf = mgr.buf_from_content(content.encode('utf-8'), lang, env, path or "<Unsaved>", 'utf-8') now = datetime.datetime.now() if not _ci_next_scan_.get(vid) or now > _ci_next_scan_[vid]: _ci_next_scan_[vid] = now + datetime.timedelta(seconds=10) if isinstance(buf, CitadelBuffer): despair = 0 despaired = False msg = "Updating indexes for '%s'... The first time this can take a while." % lang print(msg, file=condeintel_log_file) logger(view, 'info', msg, timeout=20000, delay=1000) if not path or is_scratch: buf.scan() # FIXME: Always scanning unsaved files (since many tabs can have unsaved files, or find other path as ID) else: if is_dirty: mtime = 1 else: mtime = os.stat(path)[stat.ST_MTIME] buf.scan(mtime=mtime, skip_scan_time_check=is_dirty) else: buf = None if callback: msg = "Doing CodeIntel for '%s' (hold on)..." % lang print(msg, file=condeintel_log_file) logger(view, 'info', msg, timeout=20000, delay=1000) callback(buf, msgs) else: logger(view, 'info', "")
def codeintel_scan(view, path, content, lang, callback=None, pos=None, forms=None): global despair for thread in threading.enumerate(): if thread.isAlive() and thread.name == "scanning thread": logger( view, 'info', "Updating indexes... The first time this can take a while. Do not despair!", timeout=20000, delay=despair) despair = 0 return logger(view, 'info', "processing `%s': please wait..." % lang) is_scratch = view.is_scratch() is_dirty = view.is_dirty() id = view.id() folders = getattr(view.window(), 'folders', lambda: [])( ) # FIXME: it's like this for backward compatibility (<= 2060) def _codeintel_scan(): global despair, despaired env = None mtime = None catalogs = [] now = time.time() mgr = codeintel_manager() mgr.db.event_reporter = lambda m: logger(view, 'event', m) try: env = _ci_envs_[id] if env._folders != folders: raise KeyError if now > env._time: mtime = max(tryGetMTime(env._config_file), tryGetMTime(env._config_default_file)) if env._mtime < mtime: raise KeyError except KeyError: if env is not None: config_default_file = env._config_default_file project_dir = env._project_dir project_base_dir = env._project_base_dir config_file = env._config_file else: config_default_file = os.path.join(CODEINTEL_HOME_DIR, 'config') if not (config_default_file and os.path.exists(config_default_file)): config_default_file = None project_dir = None project_base_dir = None if path: # Try to find a suitable project directory (or best guess): for folder in [ '.codeintel', '.git', '.hg', '.svn', 'trunk' ]: project_dir = find_folder(path, folder) if project_dir: if folder == '.codeintel': if project_dir == CODEINTEL_HOME_DIR or os.path.exists( os.path.join(project_dir, 'db')): continue if folder.startswith('.'): project_base_dir = os.path.abspath( os.path.join(project_dir, '..')) else: project_base_dir = project_dir break if not (project_dir and os.path.exists(project_dir)): project_dir = None config_file = project_dir and folder == '.codeintel' and os.path.join( project_dir, 'config') if not (config_file and os.path.exists(config_file)): config_file = None valid = True if not mgr.is_citadel_lang(lang) and not mgr.is_cpln_lang(lang): msg = "Invalid language: %s. Available: %s" % (lang, ', '.join( set(mgr.get_citadel_langs() + mgr.get_cpln_langs()))) log.debug(msg) codeintel_log.warning(msg) valid = False # Load configuration files: for catalog in mgr.db.get_catalogs_zone().avail_catalogs(): if catalog['lang'] == lang: catalogs.append(catalog['name']) config = { "codeintel_selected_catalogs": catalogs, "codeintel_max_recursive_dir_depth": 10, "codeintel_scan_files_in_project": True, } _config = {} try: tryReadDict(config_default_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % ( config_default_file, e) log.error(msg) codeintel_log.error(msg) try: tryReadDict(config_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % ( config_default_file, e) log.error(msg) codeintel_log.error(msg) config.update(_config.get(lang, {})) for conf in [ 'pythonExtraPaths', 'rubyExtraPaths', 'perlExtraPaths', 'javascriptExtraPaths', 'phpExtraPaths' ]: v = [ p.strip() for p in config.get(conf, []) + folders if p.strip() ] config[conf] = os.pathsep.join( set(p if p.startswith('/') else os.path.expanduser(p) if p. startswith('~') else os.path. abspath(os.path.join(project_base_dir, p) ) if project_base_dir else p for p in v if p.strip())) env = SimplePrefsEnvironment(**config) env._valid = valid env._mtime = mtime or max(tryGetMTime(config_file), tryGetMTime(config_default_file)) env._folders = folders env._config_default_file = config_default_file env._project_dir = project_dir env._project_base_dir = project_base_dir env._config_file = config_file env.__class__.get_proj_base_dir = lambda self: project_base_dir _ci_envs_[id] = env
def codeintel_scan(view, path, content, lang, callback=None, pos=None, forms=None): global despair for thread in threading.enumerate(): if thread.isAlive() and thread.name == "scanning thread": logger( view, "info", "Updating indexes... The first time this can take a while. Do not despair!", timeout=20000, delay=despair, ) despair = 0 return logger(view, "info", "processing `%s': please wait..." % lang) is_scratch = view.is_scratch() is_dirty = view.is_dirty() id = view.id() folders = getattr( view.window(), "folders", lambda: [] )() # FIXME: it's like this for backward compatibility (<= 2060) def _codeintel_scan(): global despair, despaired env = None mtime = None catalogs = [] now = time.time() mgr = codeintel_manager() mgr.db.event_reporter = lambda m: logger(view, "event", m) try: env = _ci_envs_[id] if env._folders != folders: raise KeyError if now > env._time: mtime = max(tryGetMTime(env._config_file), tryGetMTime(env._config_default_file)) if env._mtime < mtime: raise KeyError except KeyError: if env is not None: config_default_file = env._config_default_file project_dir = env._project_dir project_base_dir = env._project_base_dir config_file = env._config_file else: config_default_file = os.path.join(CODEINTEL_HOME_DIR, "config") if not (config_default_file and os.path.exists(config_default_file)): config_default_file = None project_dir = None project_base_dir = None if path: # Try to find a suitable project directory (or best guess): for folder in [".codeintel", ".git", ".hg", ".svn", "trunk"]: project_dir = find_folder(path, folder) if project_dir: if folder == ".codeintel": if project_dir == CODEINTEL_HOME_DIR or os.path.exists(os.path.join(project_dir, "db")): continue if folder.startswith("."): project_base_dir = os.path.abspath(os.path.join(project_dir, "..")) else: project_base_dir = project_dir break if not (project_dir and os.path.exists(project_dir)): project_dir = None config_file = project_dir and folder == ".codeintel" and os.path.join(project_dir, "config") if not (config_file and os.path.exists(config_file)): config_file = None valid = True if not mgr.is_citadel_lang(lang) and not mgr.is_cpln_lang(lang): msg = "Invalid language: %s. Available: %s" % ( lang, ", ".join(set(mgr.get_citadel_langs() + mgr.get_cpln_langs())), ) log.debug(msg) codeintel_log.warning(msg) valid = False # Load configuration files: for catalog in mgr.db.get_catalogs_zone().avail_catalogs(): if catalog["lang"] == lang: catalogs.append(catalog["name"]) config = { "codeintel_selected_catalogs": catalogs, "codeintel_max_recursive_dir_depth": 10, "codeintel_scan_files_in_project": True, } _config = {} try: tryReadDict(config_default_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) try: tryReadDict(config_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) config.update(_config.get(lang, {})) for conf in [ "pythonExtraPaths", "rubyExtraPaths", "perlExtraPaths", "javascriptExtraPaths", "phpExtraPaths", ]: v = [p.strip() for p in config.get(conf, []) + folders if p.strip()] config[conf] = os.pathsep.join( set( p if p.startswith("/") else os.path.expanduser(p) if p.startswith("~") else os.path.abspath(os.path.join(project_base_dir, p)) if project_base_dir else p for p in v if p.strip() ) ) env = SimplePrefsEnvironment(**config) env._valid = valid env._mtime = mtime or max(tryGetMTime(config_file), tryGetMTime(config_default_file)) env._folders = folders env._config_default_file = config_default_file env._project_dir = project_dir env._project_base_dir = project_base_dir env._config_file = config_file env.__class__.get_proj_base_dir = lambda self: project_base_dir _ci_envs_[id] = env
def codeintel_scan(view, path, content, lang, callback=None, pos=None, forms=None): global despair for thread in threading.enumerate(): if thread.isAlive() and thread.name == "scanning thread": logger( view, "info", "Updating indexes... The first time this can take a while. Do not despair!", timeout=20000, delay=despair, ) despair = 0 return try: lang = lang or guess_lang_from_path(path) except CodeIntelError: logger(view, "warning", "skip `%s': couldn't determine language" % path) return if lang.lower() in [l.lower() for l in view.settings().get("codeintel_disabled_languages", [])]: return is_scratch = view.is_scratch() is_dirty = view.is_dirty() folders = getattr( view.window(), "folders", lambda: [] )() # FIXME: it's like this for backward compatibility (<= 2060) def _codeintel_scan(): global _ci_mgr_, despair, despaired env = None mtime = None catalogs = [] now = time.time() try: env = _ci_envs_[path] if env._folders != folders: raise KeyError mgr = _ci_mgr_ if now > env._time: mtime = max(tryGetMTime(env._config_file), tryGetMTime(env._config_default_file)) if env._mtime < mtime: raise KeyError except KeyError: if env is not None: config_default_file = env._config_default_file project_dir = env._project_dir project_base_dir = env._project_base_dir config_file = env._config_file else: config_default_file = os.path.join(CODEINTEL_HOME_DIR, "config") if not (config_default_file and os.path.exists(config_default_file)): config_default_file = None project_dir = None project_base_dir = None if path: # Try to find a suitable project directory (or best guess): for folder in [".codeintel", ".git", ".hg", "trunk"]: project_dir = find_folder(path, folder) if project_dir and ( folder != ".codeintel" or not os.path.exists(os.path.join(project_dir, "db")) ): if folder.startswith("."): project_base_dir = os.path.abspath(os.path.join(project_dir, "..")) else: project_base_dir = project_dir break if not (project_dir and os.path.exists(project_dir)): project_dir = None config_file = project_dir and folder == ".codeintel" and os.path.join(project_dir, "config") if not (config_file and os.path.exists(config_file)): config_file = None if _ci_mgr_: mgr = _ci_mgr_ else: for thread in threading.enumerate(): if thread.name == "CodeIntel Manager": thread.finalize() # this finalizes the index, citadel and the manager and waits them to end (join) mgr = Manager( extra_module_dirs=_ci_extra_module_dirs_, db_base_dir=_ci_db_base_dir_, db_catalog_dirs=_ci_db_catalog_dirs_, db_import_everything_langs=_ci_db_import_everything_langs, db_event_reporter=lambda m: logger(view, "event", m), ) mgr.upgrade() mgr.initialize() # Connect the logging file to the handler condeintel_log_file = os.path.join(mgr.db.base_dir, "codeintel.log") codeintel_log.handlers = [logging.StreamHandler(open(condeintel_log_file, "w", 1))] msg = "Starting logging SublimeCodeIntel rev %s (%s) on %s" % ( get_git_revision()[:12], os.stat(__file__)[stat.ST_MTIME], datetime.datetime.now().ctime(), ) codeintel_log.info("%s\n%s" % (msg, "=" * len(msg))) _ci_mgr_ = mgr # Load configuration files: for catalog in mgr.db.get_catalogs_zone().avail_catalogs(): if catalog["lang"] == lang: catalogs.append(catalog["name"]) config = { "codeintel_selected_catalogs": catalogs, "codeintel_max_recursive_dir_depth": 10, "codeintel_scan_files_in_project": True, } _config = {} try: tryReadDict(config_default_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) try: tryReadDict(config_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) config.update(_config.get(lang, {})) for conf in [ "pythonExtraPaths", "rubyExtraPaths", "perlExtraPaths", "javascriptExtraPaths", "phpExtraPaths", ]: v = [p.strip() for p in config.get(conf, []) + folders if p.strip()] config[conf] = os.pathsep.join( set( p if p.startswith("/") else os.path.expanduser(p) if p.startswith("~") else os.path.abspath(os.path.join(project_base_dir, p)) if project_base_dir else p for p in v if p.strip() ) ) env = SimplePrefsEnvironment(**config) env._mtime = mtime or max(tryGetMTime(config_file), tryGetMTime(config_default_file)) env._folders = folders env._config_default_file = config_default_file env._project_dir = project_dir env._project_base_dir = project_base_dir env._config_file = config_file env.__class__.get_proj_base_dir = lambda self: project_base_dir _ci_envs_[path] = env
class PureRailsTestCase(_BaseTestCase): lang = "Ruby" ext = ".rb" heredoc_support = True env = SimplePrefsEnvironment(codeintel_selected_catalogs=['rails']) def test_catalog(self): catalogs_zone = self.mgr.db.get_catalogs_zone() for catalog_info in catalogs_zone.avail_catalogs(["rails"]): if catalog_info['selected']: rails_info = catalog_info break else: self.fail("rails not found in the available catalogs") self.failUnlessEqual(rails_info["name"], "Rails") self.failUnless(rails_info["description"] is not None) def test_railsenv_model_basic(self): test_dir = join(self.test_dir, "railsapp01", "app", "models") main_filename = "cart1.rb" main_content, main_positions = \ unmark_text(self.adjust_content(dedent("""\ class Cart < ActiveRecord::<1>Base Cart.<2>acts_as_list def octopus self.<3>insert_at(0) i = 4 print "you owe #{i.<4>gigabyte} dollars" end end """))) main_path = join(test_dir, main_filename) writefile(main_path, main_content) main_buf = self.mgr.buf_from_path(main_path) targets = [ [ ("class", "Base"), ], [ ("function", "acts_as_list"), ], [ ("function", "insert_at"), ], [ ("function", "megabyte"), ], ] for i in range(len(targets)): self.assertCompletionsInclude2(main_buf, main_positions[i + 1], targets[i]) ## Verify we don't get false hits self.assertCompletionsDoNotInclude( markup_text(main_content, pos=main_positions[i + 1]), targets[i]) @tag("global") def test_railsenv_model_toplevel_1(self): test_dir = join(self.test_dir, "railsapp01", "app", "models") main_filename = "cart1.rb" main_content, main_positions = \ unmark_text(self.adjust_content(dedent("""\ class Cart < ActiveRecord::<2>Base act<1>s_as_list end """))) main_path = join(test_dir, main_filename) writefile(main_path, main_content) main_buf = self.mgr.buf_from_path(main_path) pos_targets = [ ("function", "acts_as_list"), ("function", "acts_as_tree"), ("function", "acts_as_nested_set"), ] neg_targets = [ ("function", "add_child"), ] self.assertCompletionsInclude2(main_buf, main_positions[1], pos_targets) self.assertCompletionsDoNotInclude( markup_text(main_content, pos=main_positions[1]), neg_targets) @tag("global") def test_railsenv_model_toplevel_context(self): test_dir = join(self.test_dir, "railsapp01", "app", "models") main_filename = "cart1.rb" main_content, main_positions = \ unmark_text(self.adjust_content(dedent("""\ class Cart < ActiveRecord::Base val<1> def switch des<2>troy end end """))) main_path = join(test_dir, main_filename) writefile(main_path, main_content) main_buf = self.mgr.buf_from_path(main_path) class_targets = [ ("function", "validate"), ("function", "validate_find_options"), ("function", "validate_on_create"), ("function", "validate_on_update"), ("function", "validates_acceptance_of"), ("function", "validates_associated"), ("function", "validates_confirmation_of"), ("function", "validates_each"), ("function", "validates_exclusion_of"), ("function", "validates_format_of"), ("function", "validates_inclusion_of"), ("function", "validates_length_of"), ("function", "validates_numericality_of"), ("function", "validates_presence_of"), ("function", "validates_size_of"), ("function", "validates_uniqueness_of"), ] inst_targets = [ ("function", "destroy"), ("function", "destroy_all"), ] self.assertCompletionsInclude2(main_buf, main_positions[1], class_targets) self.assertCompletionsInclude2(main_buf, main_positions[2], inst_targets) self.assertCompletionsDoNotInclude( markup_text(main_content, pos=main_positions[1]), inst_targets) self.assertCompletionsDoNotInclude( markup_text(main_content, pos=main_positions[2]), class_targets) def test_railsenv_controller_basic(self): test_dir = join(self.test_dir, "railsapp01", "app", "controllers") main_filename = "admin_controller.rb" main_content, main_positions = \ unmark_text(self.adjust_content(dedent("""\ class ApplicationController < ActionController::<1>Base ApplicationController.<2>after_filter :check_authentication, :except => [:signin] def signin self.<3>render(:layout, "sheep".<4>pluralize) end end """))) main_path = join(test_dir, main_filename) writefile(main_path, main_content) main_buf = self.mgr.buf_from_path(main_path) targets = [ [ ("class", "Base"), ], [ ("function", "after_filter"), ], [ ("function", "render"), ], [ ("function", "pluralize"), ], ] for i in range(len(targets)): self.assertCompletionsInclude2(main_buf, main_positions[i + 1], targets[i]) ## Verify we don't get false hits self.assertCompletionsDoNotInclude( markup_text(main_content, pos=main_positions[i + 1]), targets[i]) def test_railsenv_controller_find_peer(self): test_dir = join(self.test_dir, "railsapp01", "app", "controllers") adminc_filename = "admin_controller%s" % self.ext adminc_content, adminc_positions = \ unmark_text(self.adjust_content(dedent("""\ module AppBogus # to force a choice at point 2 end class AdminController < <1>App<2>licationController aft<3>er_filter :check_authentication, :except => [:signin] AdminController.filter_parameter_logging(<6>'a', 'b') def open exp<4>ires_in 10.seconds self.<5>redirect_to("chumley") end end """))) manifest = [ (join(test_dir, "application.rb"), dedent("""\ class ApplicationController < ActionController::Base def foo end end """)), (adminc_filename, adminc_content), ] for file, content in manifest: path = join(test_dir, file) writefile(path, content) adminc_buf = self.mgr.buf_from_path(join(test_dir, adminc_filename)) targets = [ None, #0 None, #1 [ ("class", "ApplicationController"), #2 ("namespace", "AppBogus"), ], [ ("function", "after_filter"), #3 ], [ ("function", "expires_in"), #4 ("function", "expires_now") ], [ ("function", "redirect_to"), #5 ("function", "session_enabled?"), ], ] #for i in range(2, 1 + len(targets)): for i in (2, 5): self.assertCompletionsInclude2(adminc_buf, adminc_positions[i], targets[i]) self.assertCalltipIs2( adminc_buf, adminc_positions[6], dedent("""\ (*filter_words, &block) {|key, value| ...} Replace sensitive paramater data from the request log. Filters paramaters that have any of the arguments as a substring. Looks in all subhashes of the param hash for keys to filter. If a block is given, each key and value of the paramater hash and all subhashes is passed to it, the value or key can be replaced using String#replace or similar method.""")) @tag("bug65336", "knownfailure") # This test *sometimes* fails. # This test models how the behaviour described in bug 65336 # is supposed to work def test_controller_deleting_peer(self): dirs1 = [self.test_dir, "bug65336", "app"] test_controller_dir = join(*(dirs1 + ["controllers"])) test_model_dir = join(*(dirs1 + ["models"])) adminc_filename = join(test_controller_dir, "admin_controller.rb") book_path = join(test_model_dir, "book.rb") cart_path = join(test_model_dir, "cart.rb") adminc_content, adminc_positions = \ unmark_text(self.adjust_content(dedent("""\ class ApplicationController < ActionController::Base def foo x = Cart<5>.<1>new x.<2>add_i<6>tem() y = Boo<7>k.<3>new y.<4>re<8>ad() end end """))) manifest = [ (cart_path, dedent("""\ class Cart < ActiveRecord::Base def add_item(a) end end """)), (book_path, dedent("""\ class Book < ActiveRecord::Base def read(a) end end """)), (adminc_filename, adminc_content), ] for path, content in manifest: writefile(path, content) adminc_buf = self.mgr.buf_from_path(adminc_filename) targets = [ None, #0 [ ("function", "new"), #1 ], [ ("function", "add_item"), #2 ], [ ("function", "new"), #3 ], [ ("function", "read"), #4 ], ] for i in range(1, len(targets)): self.assertCompletionsInclude2(adminc_buf, adminc_positions[i], targets[i]) self.assertDefnMatches2(adminc_buf, adminc_positions[5], ilk="class", name="Cart", line=1) self.assertDefnMatches2(adminc_buf, adminc_positions[6], ilk="function", name="add_item", line=2) self.assertDefnMatches2(adminc_buf, adminc_positions[7], ilk="class", name="Book", line=1) self.assertDefnMatches2(adminc_buf, adminc_positions[8], ilk="function", name="read", line=2) os.unlink(book_path) # Rebuild and scan the controller buffer with the book file deleted. adminc_content, adminc_positions = \ unmark_text(self.adjust_content(dedent("""\ class ApplicationController < ActionController::Base def updated_funcname # Force rescan x = Cart.<1>new x.<2>add_item() y = Book.<3>new y.<4>read() end end """))) writefile(adminc_filename, adminc_content) adminc_buf = self.mgr.buf_from_path(adminc_filename) for i in (1, 2): self.assertCompletionsInclude2(adminc_buf, adminc_positions[i], targets[i]) # These two tests fail. for i in (3, 4): self.assertCompletionsAre2(adminc_buf, adminc_positions[i], None) # Make sure migration files can see the models -- not too useful, # as the code-completion will be class-level ActiveRecord only, # but we need to know the model names @tag("bug68997") def test_migration_sees_model(self): dirs1 = [self.test_dir, "bug68997", "app"] test_model_dir = join(*(dirs1 + ["models"])) book_path = join(test_model_dir, "book.rb") cart_path = join(test_model_dir, "cart.rb") dirs2 = [self.test_dir, "bug68997", "db", "migrate"] migrate_dir = join(*dirs2) migrate_path = join(migrate_dir, "001_create_books.rb") migrate_table_create_path = join(migrate_dir, "001_create_books.rb") migrate_add_data_path = join(migrate_dir, "002_add_data.rb") migrate_content, migrate_positions = \ unmark_text(self.adjust_content(dedent("""\ class CreateTitleData < ActiveRecord::Migration def self.up Cart.<1>create(:no => 1, :fields => 2, :yet => 3) end def self.down Cart.<2>delete_all end end """))) manifest = [ (cart_path, dedent("""\ class Cart < ActiveRecord::Base def add_item(a) end end """)), (book_path, dedent("""\ class Book < ActiveRecord::Base def read(a) end end """)), (migrate_table_create_path, dedent("""\ class CreateTitle < ActiveRecord::Migration def self.up create_table :books do |t| t.column 'title', :string t.column :author, :string t.column "publisher", :string t.column :rating, :float end end def self.down end end """)), (migrate_add_data_path, migrate_content), ] for path, content in manifest: writefile(path, content) migrate_buf = self.mgr.buf_from_path(migrate_add_data_path) self.assertCompletionsInclude2(migrate_buf, migrate_positions[2], [ ("function", "new"), ("function", "create"), ("function", "delete_all"), ]) self.assertCompletionsInclude2(migrate_buf, migrate_positions[1], [ ("function", "new"), ("function", "create"), ("function", "delete_all"), ]) @tag("bug68997") def test_migration_sees_model(self): dirs1 = [self.test_dir, "bug68997b", "app"] test_model_dir = join(*(dirs1 + ["models"])) book_path = join(test_model_dir, "book.rb") cart_path = join(test_model_dir, "cart.rb") dirs2 = [self.test_dir, "bug68997b", "db", "migrate"] migrate_dir = join(*dirs2) migrate_path = join(migrate_dir, "001_create_books.rb") migrate_table_create_path = join(migrate_dir, "001_create_books.rb") migrate_add_data_path = join(migrate_dir, "002_add_data.rb") migrate_content, migrate_positions = \ unmark_text(self.adjust_content(dedent("""\ class CreateTitleData < ActiveRecord::Migration def self.up Cart.<1>create(:no => 1, :fields => 2, :yet => 3) end def self.down Cart.<2>delete_all end end """))) manifest = [ (cart_path, dedent("""\ class Cart < ActiveRecord::Base def add_item(a) end end """)), (book_path, dedent("""\ class Book < ActiveRecord::Base def read(a) end end """)), (migrate_table_create_path, dedent("""\ class CreateTitle < ActiveRecord::Migration def self.up create_table :books do |t| t.column 'title', :string t.column :author, :string t.column "publisher", :string t.column :rating, :float end end def self.down end end """)), (migrate_add_data_path, migrate_content), ] for path, content in manifest: writefile(path, content) migrate_buf = self.mgr.buf_from_path(migrate_add_data_path) self.assertCompletionsInclude2(migrate_buf, migrate_positions[2], [ ("function", "new"), ("function", "create"), ("function", "delete_all"), ]) self.assertCompletionsInclude2(migrate_buf, migrate_positions[1], [ ("function", "new"), ("function", "create"), ("function", "delete_all"), ]) @tag("bug69532", "railstests") def test_functional_test_sees_model(self): dirs1 = [self.test_dir, "bug69532", "app"] test_model_dir = join(*(dirs1 + ["models"])) book_path = join(test_model_dir, "book.rb") cart_path = join(test_model_dir, "cart.rb") migrate_dir = join(self.test_dir, "bug69532", "db", "migrate") book_migrate_path = join(migrate_dir, "001_create_books.rb") cart_migrate_path = join(migrate_dir, "002_create_cart.rb") dirs2 = [self.test_dir, "bug69532", "test", "unit"] unit_dir = join(*dirs2) unit_book_path = join(unit_dir, "book_test.rb") unit_content, unit_positions = \ unmark_text(self.adjust_content(dedent("""\ require File.dirname(__FILE__) + '/../test_helper' class BookTest < Test::Unit::TestCase fixtures :books # Replace this with your real tests. def test_make_book roots = Book.<1>new horse = Cart.<2>new roots.<3>read horse.<4>add_item puts roots.<5>publisher + horse.<6>contents end end """))) manifest = [ (cart_path, dedent("""\ class Cart < ActiveRecord::Base def add_item(a) end end """)), (book_path, dedent("""\ class Book < ActiveRecord::Base def read(a) end end """)), (book_migrate_path, dedent("""\ def self.up create_table :books do |t| t.column 'title', :string t.column :author, :string t.column "publisher", :string t.column :rating, :float end create_table :dishes do |t| t.column 'year', :string t.column :manufacturer, :string end create_table :books do |t| t.column 'isbn', :string end end def self.down end """)), (cart_migrate_path, dedent("""\ def self.up create_table :carts do |t| t.column 'owner', :string t.column :contents, :string t.column "created_on", :datetime end end def self.down end """)), (unit_book_path, unit_content), ] for path, content in manifest: writefile(path, content) unit_buf = self.mgr.buf_from_path(unit_book_path) self.assertCompletionsInclude2( unit_buf, unit_positions[1], [ ("function", "new"), #("function", "create"), #("function", "delete_all"), ]) self.assertCompletionsInclude2( unit_buf, unit_positions[2], [ ("function", "new"), #("function", "create"), #("function", "delete_all"), ]) self.assertCompletionsInclude2(unit_buf, unit_positions[3], [ ("function", "read"), ]) self.assertCompletionsInclude2(unit_buf, unit_positions[4], [ ("function", "add_item"), ]) @tag("bug69532", "knownfailure", "railstests") def test_functional_test_sees_migrations(self): dirs1 = [self.test_dir, "bug69532", "app"] test_model_dir = join(*(dirs1 + ["models"])) book_path = join(test_model_dir, "book.rb") cart_path = join(test_model_dir, "cart.rb") migrate_dir = join(self.test_dir, "bug69532", "db", "migrate") book_migrate_path = join(migrate_dir, "001_create_books.rb") cart_migrate_path = join(migrate_dir, "002_create_cart.rb") dirs2 = [self.test_dir, "bug69532", "test", "unit"] unit_dir = join(*dirs2) unit_book_path = join(unit_dir, "book_test.rb") unit_content, unit_positions = \ unmark_text(self.adjust_content(dedent("""\ require File.dirname(__FILE__) + '/../test_helper' class BookTest < Test::Unit::TestCase fixtures :books # Replace this with your real tests. def test_make_book roots = Book.<1>new horse = Cart.<2>new roots.<3>read horse.<4>add_item puts roots.<5>publisher + horse.<6>contents end end """))) manifest = [ (cart_path, dedent("""\ class Cart < ActiveRecord::Base def add_item(a) end end """)), (book_path, dedent("""\ class Book < ActiveRecord::Base def read(a) end end """)), (book_migrate_path, dedent("""\ def self.up create_table :books do |t| t.column 'title', :string t.column :author, :string t.column "publisher", :string t.column :rating, :float end create_table :dishes do |t| t.column 'year', :string t.column :manufacturer, :string end create_table :books do |t| t.column 'isbn', :string end end def self.down end """)), (cart_migrate_path, dedent("""\ def self.up create_table :carts do |t| t.column 'owner', :string t.column :contents, :string t.column "created_on", :datetime end end def self.down end """)), (unit_book_path, unit_content), ] for path, content in manifest: writefile(path, content) unit_buf = self.mgr.buf_from_path(unit_book_path) self.assertCompletionsInclude2(unit_buf, unit_positions[5], [ ("function", "publisher"), ]) self.assertCompletionsInclude2(unit_buf, unit_positions[6], [ ("function", "contents"), ]) @tag("bug65443") def test_model_sees_migrations(self): dirs1 = [self.test_dir, "bug65443", "app"] test_model_dir = join(*(dirs1 + ["models"])) book_path = join(test_model_dir, "book.rb") dirs2 = [self.test_dir, "bug65443", "db", "migrate"] migrate_dir = join(*dirs2) migrate_path = join(migrate_dir, "001_create_books.rb") migrate_table_create_path = join(migrate_dir, "001_create_books.rb") migrate_add_column_path = join(migrate_dir, "002_add_book_items.rb") model_content, model_positions = \ unmark_text(self.adjust_content(dedent("""\ class Book < ActiveRecord::Base def get_title(a) return self.<1>title end end """))) manifest = [ (migrate_table_create_path, dedent("""\ class Book < ActiveRecord::Migration def self.up create_table :books do |t| t.column 'title', :string t.column :author, :string t.column "publisher", :string t.column :rating, :float end create_table :dishes do |t| t.column 'year', :string t.column :manufacturer, :string end create_table :books do |t| t.column 'isbn', :string end end def self.down end end """)), (migrate_add_column_path, dedent("""\ class Book < ActiveRecord::Migration def self.up add_column :books, "typeface", :string add_column :bookies, "bet", :string add_column 'books', :year, :string end def self.down end end """)), (book_path, model_content), ] for path, content in manifest: writefile(path, content) model_buf = self.mgr.buf_from_path(book_path) self.assertCompletionsInclude2(model_buf, model_positions[1], [ ("function", "title"), ("function", "author"), ("function", "publisher"), ("function", "isbn"), ("function", "rating"), ("function", "typeface"), ("function", "year"), ]) self.assertCompletionsDoNotInclude2(model_buf, model_positions[1], [ ("function", "bet"), ]) books_and_dishes_migration = dedent("""\ class Book < ActiveRecord::Migration def self.up create_table :dishes do |t| t.integer 'year' t.string :manufacturer t.timestamps end create_table :books do |t| t.string 'title' t.string :author t.string "publisher" end create_table :books do |t| t.column 'isbn', :string end end def self.down end end """) @tag("bug75440") def test_model_sees_rails2_migrations_1(self): dirs1 = [self.test_dir, "bug75440", "app"] test_model_dir = join(*(dirs1 + ["models"])) book_path = join(test_model_dir, "book.rb") dirs2 = [self.test_dir, "bug75440", "db", "migrate"] migrate_dir = join(*dirs2) migrate_table_create_path = join(migrate_dir, "001_create_books_and_dishes.rb") model_content, model_positions = \ unmark_text(self.adjust_content(dedent("""\ class Book < ActiveRecord::Base def get_title(a) return self.<1>title end end """))) manifest = [ (migrate_table_create_path, self.books_and_dishes_migration), (book_path, model_content), ] for path, content in manifest: writefile(path, content) model_buf = self.mgr.buf_from_path(book_path) self.assertCompletionsInclude2(model_buf, model_positions[1], [ ("function", "title"), ("function", "author"), ("function", "publisher"), ("function", "isbn"), ]) self.assertCompletionsDoNotInclude2(model_buf, model_positions[1], [ ("function", "bet"), ("function", "manufacturer"), ("function", "created_at"), ("function", "updated_at"), ]) @tag("bug75440") def test_model_sees_rails2_migrations_2(self): dirs1 = [self.test_dir, "bug75440b", "app"] test_model_dir = join(*(dirs1 + ["models"])) book_path = join(test_model_dir, "dish.rb") dirs2 = [self.test_dir, "bug75440b", "db", "migrate"] migrate_dir = join(*dirs2) migrate_table_create_path = join(migrate_dir, "001_create_books_and_dishes.rb") model_content, model_positions = \ unmark_text(self.adjust_content(dedent("""\ class Dish < ActiveRecord::Base def get_plate(a) return self.<1>year end end """))) manifest = [ (migrate_table_create_path, self.books_and_dishes_migration), (book_path, model_content), ] for path, content in manifest: writefile(path, content) model_buf = self.mgr.buf_from_path(book_path) # log.error("model_buf=%s", model_buf) self.assertCompletionsInclude2(model_buf, model_positions[1], [ ("function", "year"), ("function", "manufacturer"), ("function", "created_at"), ("function", "updated_at"), ]) self.assertCompletionsDoNotInclude2(model_buf, model_positions[1], [ ("function", "shamroobah"), ("function", "author"), ("function", "publisher"), ("function", "title"), ]) def test_controller_sees_migrations(self): dirs1 = [self.test_dir, "bug68997c", "app"] test_model_dir = join(*(dirs1 + ["models"])) book_model_path = join(test_model_dir, "book.rb") test_controller_dir = join(*(dirs1 + ["controllers"])) book_controller_path = join(test_controller_dir, "book_controller.rb") dirs2 = [self.test_dir, "bug68997c", "db", "migrate"] migrate_dir = join(*dirs2) migrate_path = join(migrate_dir, "001_create_books.rb") migrate_table_create_path = join(migrate_dir, "001_create_books.rb") migrate_add_column_path = join(migrate_dir, "002_add_book_items.rb") content, positions = \ unmark_text(self.adjust_content(dedent("""\ class BookController < ApplicationController def create book = Book.new(params[:title]) book.<1>title = "splibitsh" book.publisher<2> = "Rodoni" end end """))) manifest = [ (migrate_table_create_path, dedent("""\ class Book < ActiveRecord::Migration def self.up create_table :books do |t| t.column 'title', :string t.column :author, :string t.column "publisher", :string t.column :rating, :float end create_table :dishes do |t| t.column 'year', :string t.column :manufacturer, :string end create_table :books do |t| t.column 'isbn', :string end end def self.down end end """)), (migrate_add_column_path, dedent("""\ class Book < ActiveRecord::Migration def self.up add_column :books, "typeface", :string add_column :bookies, "bet", :string add_column 'books', :year, :string end def self.down end end """)), (book_model_path, dedent("""\ class Book < ActiveRecord::Base end """)), (book_controller_path, content), ] for mpath, mcontent in manifest: writefile(mpath, mcontent) buf = self.mgr.buf_from_path(book_controller_path) self.assertCompletionsInclude2(buf, positions[1], [ ("function", "title"), ("function", "author"), ("function", "publisher"), ("function", "isbn"), ("function", "rating"), ("function", "typeface"), ("function", "year"), ]) self.assertCompletionsDoNotInclude2(buf, positions[1], [ ("function", "bet"), ]) self.assertDefnMatches2(buf, positions[2], lang="Ruby", line=6, path=migrate_table_create_path) # This test *sometimes* fails. # This test models how the behaviour described in bug 65336 # is supposed to work @tag("failsintermittently") def test_controller_find_peer(self): dirs1 = [self.test_dir, "peers", "app"] test_controller_dir = join(*(dirs1 + ["controllers"])) test_model_dir = join(*(dirs1 + ["models"])) adminc_filename = join(test_controller_dir, "admin_controller.rb") book_path = join(test_model_dir, "book.rb") cart_path = join(test_model_dir, "cart.rb") adminc_content, adminc_positions = \ unmark_text(self.adjust_content(dedent("""\ class ApplicationController < ActionController::Base def foo x = Cart<5>.<1>new x.<2>add_i<6>tem() y = Boo<7>k.<3>new y.<4>re<8>ad() end end """))) manifest = [ (cart_path, dedent("""\ class Cart < ActiveRecord::Base def add_item(a) end end """)), (book_path, dedent("""\ class Book < ActiveRecord::Base def read(a) end end """)), (adminc_filename, adminc_content), ] for path, content in manifest: writefile(path, content) adminc_buf = self.mgr.buf_from_path(adminc_filename) targets = [ None, #0 [ ("function", "new"), #1 ], [ ("function", "add_item"), #2 ], [ ("function", "new"), #3 ], [ ("function", "read"), #4 ], ] repl_path = 'models' fixed_cart_path = cart_path.replace('models', repl_path) fixed_book_path = book_path.replace('models', repl_path) self.assertDefnMatches2(adminc_buf, adminc_positions[5], ilk="class", name="Cart", line=1, path=fixed_cart_path) self.assertDefnMatches2(adminc_buf, adminc_positions[6], ilk="function", name="add_item", line=2, path=fixed_cart_path) self.assertDefnMatches2(adminc_buf, adminc_positions[7], ilk="class", name="Book", line=1, path=fixed_book_path) self.assertDefnMatches2(adminc_buf, adminc_positions[8], ilk="function", name="read", line=2, path=fixed_book_path)
def codeintel_scan(view, path, content, lang, callback=None, pos=None, forms=None): global despair for thread in threading.enumerate(): if thread.isAlive() and thread.name == "scanning thread": logger(view, 'info', "Updating indexes... The first time this can take a while. Do not despair!", timeout=20000, delay=despair) despair = 0 return logger(view, 'info', "processing `%s': please wait..." % lang) is_scratch = view.is_scratch() is_dirty = view.is_dirty() vid = view.id() folders = getattr(view.window(), 'folders', lambda: [])() # FIXME: it's like this for backward compatibility (<= 2060) folders_id = str(hash(frozenset(folders))) view_settings = view.settings() codeintel_config = view_settings.get('codeintel_config', {}) _codeintel_max_recursive_dir_depth = view_settings.get('codeintel_max_recursive_dir_depth', 10) _codeintel_scan_files_in_project = view_settings.get('codeintel_scan_files_in_project', True) _codeintel_selected_catalogs = view_settings.get('codeintel_selected_catalogs', []) def _codeintel_scan(): global despair, despaired env = None mtime = None catalogs = [] now = time.time() mgr = codeintel_manager(folders_id) mgr.db.event_reporter = lambda m: logger(view, 'event', m) try: env = _ci_envs_[vid] if env._folders != folders: raise KeyError if now > env._time: mtime = max(tryGetMTime(env._config_file), tryGetMTime(env._config_default_file)) if env._mtime < mtime: raise KeyError except KeyError: if env is not None: config_default_file = env._config_default_file project_dir = env._project_dir project_base_dir = env._project_base_dir config_file = env._config_file else: config_default_file = os.path.join(CODEINTEL_HOME_DIR, 'config') if not (config_default_file and os.path.exists(config_default_file)): config_default_file = None project_dir = None project_base_dir = None for folder_path in folders + [path]: if folder_path: # Try to find a suitable project directory (or best guess): for folder in ['.codeintel', '.git', '.hg', '.svn', 'trunk']: project_dir = find_back(folder_path, folder) if project_dir: if folder == '.codeintel': if project_dir == CODEINTEL_HOME_DIR or os.path.exists(os.path.join(project_dir, 'databases')): continue if folder.startswith('.'): project_base_dir = os.path.abspath(os.path.join(project_dir, '..')) else: project_base_dir = project_dir break if project_base_dir: break if not (project_dir and os.path.exists(project_dir)): project_dir = None config_file = project_dir and folder == '.codeintel' and os.path.join(project_dir, 'config') if not (config_file and os.path.exists(config_file)): config_file = None valid = True if not mgr.is_citadel_lang(lang) and not mgr.is_cpln_lang(lang): if lang in ('Console', 'Plain text'): msg = "Invalid language: %s. Available: %s" % (lang, ', '.join(set(mgr.get_citadel_langs() + mgr.get_cpln_langs()))) log.debug(msg) codeintel_log.warning(msg) valid = False codeintel_config_lang = codeintel_config.get(lang, {}) codeintel_max_recursive_dir_depth = codeintel_config_lang.get('codeintel_max_recursive_dir_depth', _codeintel_max_recursive_dir_depth) codeintel_scan_files_in_project = codeintel_config_lang.get('codeintel_scan_files_in_project', _codeintel_scan_files_in_project) codeintel_selected_catalogs = codeintel_config_lang.get('codeintel_selected_catalogs', _codeintel_selected_catalogs) avail_catalogs = mgr.db.get_catalogs_zone().avail_catalogs() # Load configuration files: all_catalogs = [] for catalog in avail_catalogs: all_catalogs.append("%s (for %s: %s)" % (catalog['name'], catalog['lang'], catalog['description'])) if catalog['lang'] == lang: if catalog['name'] in codeintel_selected_catalogs: catalogs.append(catalog['name']) msg = "Avaliable catalogs: %s" % ', '.join(all_catalogs) or None log.debug(msg) codeintel_log.debug(msg) config = { 'codeintel_max_recursive_dir_depth': codeintel_max_recursive_dir_depth, 'codeintel_scan_files_in_project': codeintel_scan_files_in_project, 'codeintel_selected_catalogs': catalogs, } config.update(codeintel_config_lang) _config = {} try: tryReadDict(config_default_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) try: tryReadDict(config_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) config.update(_config.get(lang, {})) for conf in ['pythonExtraPaths', 'rubyExtraPaths', 'perlExtraPaths', 'javascriptExtraPaths', 'phpExtraPaths']: v = [p.strip() for p in config.get(conf, []) + folders if p.strip()] config[conf] = os.pathsep.join(set(p if p.startswith('/') else os.path.expanduser(p) if p.startswith('~') else os.path.abspath(os.path.join(project_base_dir, p)) if project_base_dir else p for p in v if p.strip())) for conf, p in config.items(): if isinstance(p, basestring) and p.startswith('~'): config[conf] = os.path.expanduser(p) # Setup environment variables env = config.get('env', {}) _environ = dict(os.environ) for k, v in env.items(): _old = None while '$' in v and v != _old: _old = v v = os.path.expandvars(v) _environ[k] = v config['env'] = _environ env = SimplePrefsEnvironment(**config) env._valid = valid env._mtime = mtime or max(tryGetMTime(config_file), tryGetMTime(config_default_file)) env._folders = folders env._config_default_file = config_default_file env._project_dir = project_dir env._project_base_dir = project_base_dir env._config_file = config_file env.__class__.get_proj_base_dir = lambda self: project_base_dir _ci_envs_[vid] = env
def _codeintel_scan(): global despair, despaired env = None mtime = None catalogs = [] now = time.time() mgr = codeintel_manager(folders_id) mgr.db.event_reporter = lambda m: logger(view, 'event', m) try: env = _ci_envs_[vid] if env._folders != folders: raise KeyError if now > env._time: mtime = max(tryGetMTime(env._config_file), tryGetMTime(env._config_default_file)) if env._mtime < mtime: raise KeyError except KeyError: if env is not None: config_default_file = env._config_default_file project_dir = env._project_dir project_base_dir = env._project_base_dir config_file = env._config_file else: config_default_file = os.path.join(CODEINTEL_HOME_DIR, 'config') if not (config_default_file and os.path.exists(config_default_file)): config_default_file = None project_dir = None project_base_dir = None for folder_path in folders + [path]: if folder_path: # Try to find a suitable project directory (or best guess): for folder in ['.codeintel', '.git', '.hg', '.svn', 'trunk']: project_dir = find_back(folder_path, folder) if project_dir: if folder == '.codeintel': if project_dir == CODEINTEL_HOME_DIR or os.path.exists(os.path.join(project_dir, 'databases')): continue if folder.startswith('.'): project_base_dir = os.path.abspath(os.path.join(project_dir, '..')) else: project_base_dir = project_dir break if project_base_dir: break if not (project_dir and os.path.exists(project_dir)): project_dir = None config_file = project_dir and folder == '.codeintel' and os.path.join(project_dir, 'config') if not (config_file and os.path.exists(config_file)): config_file = None valid = True if not mgr.is_citadel_lang(lang) and not mgr.is_cpln_lang(lang): if lang in ('Console', 'Plain text'): msg = "Invalid language: %s. Available: %s" % (lang, ', '.join(set(mgr.get_citadel_langs() + mgr.get_cpln_langs()))) log.debug(msg) codeintel_log.warning(msg) valid = False codeintel_config_lang = codeintel_config.get(lang, {}) codeintel_max_recursive_dir_depth = codeintel_config_lang.get('codeintel_max_recursive_dir_depth', _codeintel_max_recursive_dir_depth) codeintel_scan_files_in_project = codeintel_config_lang.get('codeintel_scan_files_in_project', _codeintel_scan_files_in_project) codeintel_selected_catalogs = codeintel_config_lang.get('codeintel_selected_catalogs', _codeintel_selected_catalogs) avail_catalogs = mgr.db.get_catalogs_zone().avail_catalogs() # Load configuration files: all_catalogs = [] for catalog in avail_catalogs: all_catalogs.append("%s (for %s: %s)" % (catalog['name'], catalog['lang'], catalog['description'])) if catalog['lang'] == lang: if catalog['name'] in codeintel_selected_catalogs: catalogs.append(catalog['name']) msg = "Avaliable catalogs: %s" % ', '.join(all_catalogs) or None log.debug(msg) codeintel_log.debug(msg) config = { 'codeintel_max_recursive_dir_depth': codeintel_max_recursive_dir_depth, 'codeintel_scan_files_in_project': codeintel_scan_files_in_project, 'codeintel_selected_catalogs': catalogs, } config.update(codeintel_config_lang) _config = {} try: tryReadDict(config_default_file, _config) except Exception as e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) try: tryReadDict(config_file, _config) except Exception as e: msg = "Malformed configuration file '%s': %s" % (config_default_file, e) log.error(msg) codeintel_log.error(msg) config.update(_config.get(lang, {})) for conf in ['pythonExtraPaths', 'rubyExtraPaths', 'perlExtraPaths', 'javascriptExtraPaths', 'phpExtraPaths']: v = [p.strip() for p in config.get(conf, []) + folders if p.strip()] config[conf] = os.pathsep.join(set(p if p.startswith('/') else os.path.expanduser(p) if p.startswith('~') else os.path.abspath(os.path.join(project_base_dir, p)) if project_base_dir else p for p in v if p.strip())) for conf, p in config.items(): if isinstance(p, basestring) and p.startswith('~'): config[conf] = os.path.expanduser(p) # Setup environment variables env = config.get('env', {}) _environ = dict(os.environ) for k, v in env.items(): _old = None while '$' in v and v != _old: _old = v v = os.path.expandvars(v) _environ[k] = v config['env'] = _environ env = SimplePrefsEnvironment(**config) env._valid = valid env._mtime = mtime or max(tryGetMTime(config_file), tryGetMTime(config_default_file)) env._folders = folders env._config_default_file = config_default_file env._project_dir = project_dir env._project_base_dir = project_base_dir env._config_file = config_file env.__class__.get_proj_base_dir = lambda self: project_base_dir _ci_envs_[vid] = env env._time = now + 5 # don't check again in less than five seconds msgs = [] if env._valid: if forms: calltip(view, 'tip', "") calltip(view, 'event', "") msg = "CodeIntel(%s) for %s@%s [%s]" % (', '.join(forms), path, pos, lang) msgs.append(('info', "\n%s\n%s" % (msg, "-" * len(msg)))) if catalogs: msg = "New env with catalogs for '%s': %s" % (lang, ', '.join(catalogs) or None) log.debug(msg) codeintel_log.warning(msg) msgs.append(('info', msg)) buf = mgr.buf_from_content(content.encode('utf-8'), lang, env, path or "<Unsaved>", 'utf-8') now = datetime.datetime.now() if not _ci_next_scan_.get(vid) or now > _ci_next_scan_[vid]: _ci_next_scan_[vid] = now + datetime.timedelta(seconds=10) if isinstance(buf, CitadelBuffer): despair = 0 despaired = False msg = "Updating indexes for '%s'... The first time this can take a while." % lang print(msg, file=condeintel_log_file) logger(view, 'info', msg, timeout=20000, delay=1000) if not path or is_scratch: buf.scan() # FIXME: Always scanning unsaved files (since many tabs can have unsaved files, or find other path as ID) else: if is_dirty: mtime = 1 else: mtime = os.stat(path)[stat.ST_MTIME] buf.scan(mtime=mtime, skip_scan_time_check=is_dirty) else: buf = None if callback: msg = "Doing CodeIntel for '%s' (hold on)..." % lang print(msg, file=condeintel_log_file) logger(view, 'info', msg, timeout=20000, delay=1000) callback(buf, msgs) else: logger(view, 'info', "")
S_RESULT = '[result]\n' TIMEOUT = 4000 _fn = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'path.ini') if os.path.isfile(_fn): with open(_fn, 'r') as f: paths = f.readline() print 'Paths:\n' + '\n'.join(paths.split(os.pathsep)) d = {} d['phpExtraPaths'] = paths d['pythonExtraPaths'] = paths d['perlExtraPaths'] = paths d['javascriptExtraPaths'] = paths d['rubyExtraPaths'] = paths env = SimplePrefsEnvironment(**d) mgr = Manager() mgr.upgrade() mgr.initialize() #------------------------ def file_text(fn): try: with open(fn, 'r') as f: text = f.readlines() return ''.join(text) except IOError as e: if e.errno == errno.ENOENT: # No such file or directory logging.error(e.strerror + ': "' + fn + '"')
def codeintel_scan(view, path, content, lang, callback=None, pos=None, forms=None): global despair for thread in threading.enumerate(): if thread.isAlive() and thread.name == "scanning thread": logger( view, 'info', "Updating indexes... The first time this can take a while. Do not despair!", timeout=20000, delay=despair) despair = 0 return try: lang = lang or guess_lang_from_path(path) except CodeIntelError: logger(view, 'warning', "skip `%s': couldn't determine language" % path) return if lang.lower() in [ l.lower() for l in view.settings().get('codeintel_disabled_languages', []) ]: return is_scratch = view.is_scratch() is_dirty = view.is_dirty() folders = getattr(view.window(), 'folders', lambda: [])( ) # FIXME: it's like this for backward compatibility (<= 2060) def _codeintel_scan(): global _ci_mgr_, despair, despaired env = None mtime = None catalogs = [] now = time.time() try: env = _ci_envs_[path] if env._folders != folders: raise KeyError mgr = _ci_mgr_ if now > env._time: mtime = max(tryGetMTime(env._config_file), tryGetMTime(env._config_default_file)) if env._mtime < mtime: raise KeyError except KeyError: if env is not None: config_default_file = env._config_default_file project_dir = env._project_dir project_base_dir = env._project_base_dir config_file = env._config_file else: config_default_file = os.path.join(CODEINTEL_HOME_DIR, 'config') if not (config_default_file and os.path.exists(config_default_file)): config_default_file = None project_dir = None project_base_dir = None if path: # Try to find a suitable project directory (or best guess): for folder in ['.codeintel', '.git', '.hg', 'trunk']: project_dir = find_folder(path, folder) if project_dir and ( folder != '.codeintel' or not os.path.exists( os.path.join(project_dir, 'db'))): if folder.startswith('.'): project_base_dir = os.path.abspath( os.path.join(project_dir, '..')) else: project_base_dir = project_dir break if not (project_dir and os.path.exists(project_dir)): project_dir = None config_file = project_dir and folder == '.codeintel' and os.path.join( project_dir, 'config') if not (config_file and os.path.exists(config_file)): config_file = None if _ci_mgr_: mgr = _ci_mgr_ else: for thread in threading.enumerate(): if thread.name == "CodeIntel Manager": thread.finalize( ) # this finalizes the index, citadel and the manager and waits them to end (join) mgr = Manager( extra_module_dirs=_ci_extra_module_dirs_, db_base_dir=_ci_db_base_dir_, db_catalog_dirs=_ci_db_catalog_dirs_, db_import_everything_langs=_ci_db_import_everything_langs, db_event_reporter=lambda m: logger(view, 'event', m), ) mgr.upgrade() mgr.initialize() # Connect the logging file to the handler condeintel_log_file = os.path.join(mgr.db.base_dir, 'codeintel.log') codeintel_log.handlers = [ logging.StreamHandler(open(condeintel_log_file, 'w', 1)) ] msg = "Starting logging SublimeCodeIntel rev %s (%s) on %s" % ( get_git_revision()[:12], os.stat(__file__)[stat.ST_MTIME], datetime.datetime.now().ctime()) codeintel_log.info("%s\n%s" % (msg, "=" * len(msg))) _ci_mgr_ = mgr # Load configuration files: for catalog in mgr.db.get_catalogs_zone().avail_catalogs(): if catalog['lang'] == lang: catalogs.append(catalog['name']) config = { "codeintel_selected_catalogs": catalogs, "codeintel_max_recursive_dir_depth": 10, "codeintel_scan_files_in_project": True, } _config = {} try: tryReadDict(config_default_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % ( config_default_file, e) log.error(msg) codeintel_log.error(msg) try: tryReadDict(config_file, _config) except Exception, e: msg = "Malformed configuration file '%s': %s" % ( config_default_file, e) log.error(msg) codeintel_log.error(msg) config.update(_config.get(lang, {})) for conf in [ 'pythonExtraPaths', 'rubyExtraPaths', 'perlExtraPaths', 'javascriptExtraPaths', 'phpExtraPaths' ]: v = [ p.strip() for p in config.get(conf, []) + folders if p.strip() ] config[conf] = os.pathsep.join( set(p if p.startswith('/') else os.path.expanduser(p) if p. startswith('~') else os.path. abspath(os.path.join(project_base_dir, p) ) if project_base_dir else p for p in v if p.strip())) env = SimplePrefsEnvironment(**config) env._mtime = mtime or max(tryGetMTime(config_file), tryGetMTime(config_default_file)) env._folders = folders env._config_default_file = config_default_file env._project_dir = project_dir env._project_base_dir = project_base_dir env._config_file = config_file env.__class__.get_proj_base_dir = lambda self: project_base_dir _ci_envs_[path] = env