-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added utility to export assets manually
- Added tests for utility
- Loading branch information
Showing
4 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import re | ||
|
||
|
||
class AssetsBundler(object): | ||
def __init__(self, env, asset): | ||
self.env = env | ||
self.asset = asset | ||
self._bundle = None | ||
|
||
@property | ||
def bundle(self): | ||
if not self._bundle: | ||
self._bundle = self.get_bundle() | ||
|
||
return self._bundle | ||
|
||
def get_bundle(self): | ||
from odoo.addons.base.models.assetsbundle import AssetsBundle | ||
self.files = self.get_files() | ||
return AssetsBundle(self.asset, self.files[0], env=self.env) | ||
|
||
def get_files(self): | ||
qweb = self.env['ir.qweb'] | ||
files = qweb._get_asset_content(self.asset) | ||
return files | ||
|
||
def get_js(self, minified=False): | ||
result = [] | ||
|
||
if minified: | ||
for js in self.bundle.javascripts: | ||
result.append(f"{js.minify()};") | ||
else: | ||
for js in self.bundle.javascripts: | ||
result.append(js.with_header(js.content, minimal=False)) | ||
|
||
return "\n".join(result) | ||
|
||
def get_css(self, minified=False): | ||
from odoo.addons.base.models.assetsbundle import AssetsBundle | ||
|
||
data = self.bundle.preprocess_css() | ||
|
||
matches = [] | ||
data = re.sub( | ||
AssetsBundle.rx_css_import, | ||
lambda matchobj: matches.append(matchobj.group(0)) and '', | ||
data | ||
) | ||
|
||
if minified: | ||
matches.append(data) | ||
else: | ||
for style in self.bundle.stylesheets: | ||
if not style.content: | ||
continue | ||
|
||
content = style.with_header(style.content) | ||
|
||
content = re.sub( | ||
AssetsBundle.rx_css_import, | ||
lambda matchobj: f"/* {matchobj.group(0)} */", | ||
content | ||
) | ||
|
||
matches.append(content) | ||
|
||
return "\n".join(matches) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
from mock import patch, MagicMock | ||
from odoo_tools.cli.odot import command | ||
from odoo_tools.api.environment import Environment | ||
|
||
|
||
def test_bundler(runner): | ||
|
||
def fake_check_odoo(self): | ||
self.manage = MagicMock() | ||
|
||
obj_path = 'odoo_tools.cli.click.manage.AssetsBundler' | ||
|
||
with patch(obj_path) as bundler, \ | ||
patch.object(Environment, 'check_odoo', autospec=True) as check_odoo: | ||
|
||
bun_instance = MagicMock() | ||
bundler.return_value = bun_instance | ||
|
||
check_odoo.side_effect = fake_check_odoo | ||
# manage.return_value = MagicMock() | ||
|
||
result = runner.invoke( | ||
command, | ||
[ | ||
'manage', | ||
'asset', | ||
'css', | ||
'base.common', | ||
] | ||
) | ||
|
||
assert result.exception is None | ||
bun_instance.get_css.assert_called_once() | ||
bun_instance.get_js.assert_not_called() | ||
|
||
result = runner.invoke( | ||
command, | ||
[ | ||
'manage', | ||
'asset', | ||
'js', | ||
'base.common', | ||
] | ||
) | ||
bun_instance.get_js.assert_called_once() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import re | ||
|
||
import pytest | ||
from mock import MagicMock, patch | ||
|
||
from odoo_tools.modules.assets import AssetsBundler | ||
|
||
|
||
@pytest.fixture | ||
def modules(): | ||
odoo = MagicMock() | ||
|
||
models = odoo.addons.base.models | ||
|
||
return { | ||
"odoo": odoo, | ||
"odoo.addons": odoo.addons, | ||
"odoo.addons.base": odoo.addons.base, | ||
"odoo.addons.base.models": odoo.addons.base.models, | ||
"odoo.addons.base.models.assetsbundle": models.assetsbundle, | ||
} | ||
|
||
|
||
class MockAsset(object): | ||
def __init__(self, name, data): | ||
self.name = name | ||
self.content = data | ||
|
||
def with_header(self, content, minimal=False): | ||
return f"/* {self.name} */\n{content}" | ||
|
||
def minify(self): | ||
return f"minified {self.content}" | ||
|
||
|
||
class MockBundle(object): | ||
rx_css_import = r".*" | ||
|
||
def __init__(self, asset, file, env=None): | ||
self.asset = asset | ||
self.file = file | ||
self.env = env | ||
|
||
self.javascripts = [ | ||
MockAsset("f1", "a"), | ||
MockAsset("f2", "b") | ||
] | ||
|
||
self.stylesheets = [ | ||
MockAsset('c1', 'c'), | ||
MockAsset('c2', 'd'), | ||
MockAsset('c2', ''), | ||
] | ||
|
||
def preprocess_css(self): | ||
result = ["prep"] | ||
|
||
for asset in self.stylesheets: | ||
result.append(asset.content) | ||
if asset.content != '': | ||
asset.content = 'm' | ||
|
||
return "\n".join(result) | ||
|
||
|
||
def test_assets_bundler(modules): | ||
asset = 'base.common' | ||
env = MagicMock() | ||
|
||
bundler = AssetsBundler(env, asset) | ||
assert bundler.env == env | ||
assert bundler.asset == asset | ||
assert bundler._bundle is None | ||
|
||
bundle_path = "odoo.addons.base.models.assetsbundle.AssetsBundle" | ||
|
||
with patch.dict('sys.modules', modules), \ | ||
patch(bundle_path, MockBundle): | ||
assert isinstance(bundler.bundle, MockBundle) | ||
assert bundler._bundle is not None | ||
|
||
js = bundler.get_js() | ||
assert js == '/* f1 */\na\n/* f2 */\nb' | ||
|
||
js_minified = bundler.get_js(minified=True) | ||
assert js_minified == 'minified a;\nminified b;' | ||
|
||
# output with headers but output not relevant, it's | ||
# just mocked to confirm different outputs | ||
bundler = AssetsBundler(env, asset) | ||
css = bundler.get_css() | ||
assert css == ( | ||
'prep\n\n' | ||
'c\n\nd\n\n\n' | ||
'/* /* c1 */ *//* */\n' | ||
'/* m *//* */\n' | ||
'/* /* c2 */ *//* */\n' | ||
'/* m *//* */' | ||
) | ||
|
||
# raw output from preprocess and matches | ||
bundler = AssetsBundler(env, asset) | ||
css_minified = bundler.get_css(minified=True) | ||
assert css_minified == 'prep\n\nc\n\nd\n\n\n\n\n\n' |