j-law-ruby 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +9 -0
- data/README.md +109 -0
- data/Rakefile +87 -0
- data/ext/j_law_ruby/extconf.rb +34 -0
- data/lib/j_law_ruby/build_support.rb +129 -0
- data/lib/j_law_ruby/c_ffi.rb +662 -0
- data/lib/j_law_ruby.rb +532 -0
- data/rake_support/vendor_rust.rb +51 -0
- data/test/test_c_ffi_adapter.rb +46 -0
- data/test/test_consumption_tax.rb +66 -0
- data/test/test_gemspec.rb +82 -0
- data/test/test_income_tax.rb +77 -0
- data/test/test_income_tax_deductions.rb +82 -0
- data/test/test_real_estate.rb +98 -0
- data/test/test_stamp_tax.rb +68 -0
- data/test/test_withholding_tax.rb +65 -0
- data/vendor/rust/Cargo.lock +235 -0
- data/vendor/rust/Cargo.toml +12 -0
- data/vendor/rust/crates/j-law-c-ffi/Cargo.toml +20 -0
- data/vendor/rust/crates/j-law-c-ffi/j_law_c_ffi.h +493 -0
- data/vendor/rust/crates/j-law-c-ffi/src/lib.rs +1553 -0
- data/vendor/rust/crates/j-law-core/Cargo.toml +18 -0
- data/vendor/rust/crates/j-law-core/src/domains/consumption_tax/calculator.rs +216 -0
- data/vendor/rust/crates/j-law-core/src/domains/consumption_tax/context.rs +29 -0
- data/vendor/rust/crates/j-law-core/src/domains/consumption_tax/mod.rs +9 -0
- data/vendor/rust/crates/j-law-core/src/domains/consumption_tax/params.rs +24 -0
- data/vendor/rust/crates/j-law-core/src/domains/consumption_tax/policy.rs +34 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/assessment.rs +76 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/calculator.rs +222 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/context.rs +79 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/deduction/calculator.rs +167 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/deduction/context.rs +172 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/deduction/expense.rs +465 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/deduction/mod.rs +20 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/deduction/params.rs +205 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/deduction/personal.rs +324 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/deduction/types.rs +61 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/mod.rs +24 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/params.rs +109 -0
- data/vendor/rust/crates/j-law-core/src/domains/income_tax/policy.rs +103 -0
- data/vendor/rust/crates/j-law-core/src/domains/mod.rs +5 -0
- data/vendor/rust/crates/j-law-core/src/domains/real_estate/calculator.rs +197 -0
- data/vendor/rust/crates/j-law-core/src/domains/real_estate/context.rs +48 -0
- data/vendor/rust/crates/j-law-core/src/domains/real_estate/mod.rs +9 -0
- data/vendor/rust/crates/j-law-core/src/domains/real_estate/params.rs +43 -0
- data/vendor/rust/crates/j-law-core/src/domains/real_estate/policy.rs +40 -0
- data/vendor/rust/crates/j-law-core/src/domains/stamp_tax/calculator.rs +321 -0
- data/vendor/rust/crates/j-law-core/src/domains/stamp_tax/context.rs +408 -0
- data/vendor/rust/crates/j-law-core/src/domains/stamp_tax/mod.rs +12 -0
- data/vendor/rust/crates/j-law-core/src/domains/stamp_tax/params.rs +190 -0
- data/vendor/rust/crates/j-law-core/src/domains/stamp_tax/policy.rs +105 -0
- data/vendor/rust/crates/j-law-core/src/domains/withholding_tax/calculator.rs +247 -0
- data/vendor/rust/crates/j-law-core/src/domains/withholding_tax/context.rs +167 -0
- data/vendor/rust/crates/j-law-core/src/domains/withholding_tax/mod.rs +9 -0
- data/vendor/rust/crates/j-law-core/src/domains/withholding_tax/params.rs +80 -0
- data/vendor/rust/crates/j-law-core/src/domains/withholding_tax/policy.rs +49 -0
- data/vendor/rust/crates/j-law-core/src/error.rs +171 -0
- data/vendor/rust/crates/j-law-core/src/lib.rs +9 -0
- data/vendor/rust/crates/j-law-core/src/types/amount.rs +232 -0
- data/vendor/rust/crates/j-law-core/src/types/citation.rs +82 -0
- data/vendor/rust/crates/j-law-core/src/types/date.rs +280 -0
- data/vendor/rust/crates/j-law-core/src/types/mod.rs +11 -0
- data/vendor/rust/crates/j-law-core/src/types/rate.rs +219 -0
- data/vendor/rust/crates/j-law-core/src/types/rounding.rs +81 -0
- data/vendor/rust/crates/j-law-registry/Cargo.toml +15 -0
- data/vendor/rust/crates/j-law-registry/data/consumption_tax/consumption_tax.json +70 -0
- data/vendor/rust/crates/j-law-registry/data/income_tax/deductions.json +327 -0
- data/vendor/rust/crates/j-law-registry/data/income_tax/income_tax.json +352 -0
- data/vendor/rust/crates/j-law-registry/data/real_estate/brokerage_fee.json +125 -0
- data/vendor/rust/crates/j-law-registry/data/stamp_tax/stamp_tax.json +674 -0
- data/vendor/rust/crates/j-law-registry/data/withholding_tax/withholding_tax.json +70 -0
- data/vendor/rust/crates/j-law-registry/src/consumption_tax_loader.rs +325 -0
- data/vendor/rust/crates/j-law-registry/src/consumption_tax_schema.rs +49 -0
- data/vendor/rust/crates/j-law-registry/src/income_tax_deduction_loader.rs +636 -0
- data/vendor/rust/crates/j-law-registry/src/income_tax_deduction_schema.rs +111 -0
- data/vendor/rust/crates/j-law-registry/src/income_tax_loader.rs +445 -0
- data/vendor/rust/crates/j-law-registry/src/income_tax_schema.rs +44 -0
- data/vendor/rust/crates/j-law-registry/src/lib.rs +20 -0
- data/vendor/rust/crates/j-law-registry/src/loader.rs +221 -0
- data/vendor/rust/crates/j-law-registry/src/schema.rs +73 -0
- data/vendor/rust/crates/j-law-registry/src/stamp_tax_loader.rs +374 -0
- data/vendor/rust/crates/j-law-registry/src/stamp_tax_schema.rs +72 -0
- data/vendor/rust/crates/j-law-registry/src/validator.rs +204 -0
- data/vendor/rust/crates/j-law-registry/src/withholding_tax_loader.rs +310 -0
- data/vendor/rust/crates/j-law-registry/src/withholding_tax_schema.rs +61 -0
- metadata +148 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "minitest/autorun"
|
|
5
|
+
require "open3"
|
|
6
|
+
require "fileutils"
|
|
7
|
+
require "bundler"
|
|
8
|
+
require_relative "../lib/j_law_ruby/build_support"
|
|
9
|
+
|
|
10
|
+
class TestGemspec < Minitest::Test
|
|
11
|
+
GEM_ROOT = File.expand_path("..", __dir__)
|
|
12
|
+
|
|
13
|
+
def test_source_gem_keeps_ruby_platform_and_extension_build
|
|
14
|
+
spec = with_native_library_placeholder { load_gemspec(binary: false) }
|
|
15
|
+
|
|
16
|
+
assert_equal Gem::Platform::RUBY, spec.fetch("platform")
|
|
17
|
+
assert_equal ["ext/j_law_ruby/extconf.rb"], spec.fetch("extensions")
|
|
18
|
+
refute_includes spec.fetch("files"), native_library_path
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_binary_gem_is_platform_specific_and_bundles_native_library
|
|
22
|
+
spec = with_native_library_placeholder { load_gemspec(binary: true) }
|
|
23
|
+
|
|
24
|
+
assert_equal Gem::Platform.local.to_s, spec.fetch("platform")
|
|
25
|
+
assert_empty spec.fetch("extensions")
|
|
26
|
+
assert_includes spec.fetch("files"), native_library_path
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def load_gemspec(binary:)
|
|
32
|
+
script = <<~RUBY
|
|
33
|
+
require "json"
|
|
34
|
+
|
|
35
|
+
spec = Gem::Specification.load("j_law_ruby.gemspec")
|
|
36
|
+
abort "failed to load gemspec" if spec.nil?
|
|
37
|
+
|
|
38
|
+
puts JSON.generate(
|
|
39
|
+
platform: spec.platform.to_s,
|
|
40
|
+
extensions: spec.extensions,
|
|
41
|
+
files: spec.files.sort
|
|
42
|
+
)
|
|
43
|
+
RUBY
|
|
44
|
+
|
|
45
|
+
stdout = nil
|
|
46
|
+
stderr = nil
|
|
47
|
+
status = nil
|
|
48
|
+
|
|
49
|
+
Bundler.with_unbundled_env do
|
|
50
|
+
stdout, stderr, status = Open3.capture3(
|
|
51
|
+
{ JLawRuby::BuildSupport::BINARY_GEM_ENV => (binary ? "1" : "0") },
|
|
52
|
+
"ruby",
|
|
53
|
+
"-e",
|
|
54
|
+
script,
|
|
55
|
+
chdir: GEM_ROOT
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
assert status.success?, stderr
|
|
60
|
+
|
|
61
|
+
JSON.parse(stdout)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def native_library_path
|
|
65
|
+
File.join(
|
|
66
|
+
"lib",
|
|
67
|
+
"j_law_ruby",
|
|
68
|
+
"native",
|
|
69
|
+
JLawRuby::BuildSupport.shared_library_filename
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def with_native_library_placeholder
|
|
74
|
+
path = File.join(GEM_ROOT, native_library_path)
|
|
75
|
+
created = !File.exist?(path)
|
|
76
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
77
|
+
File.write(path, "") if created
|
|
78
|
+
yield
|
|
79
|
+
ensure
|
|
80
|
+
FileUtils.rm_f(path) if created
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# 所得税法第89条に基づく所得税計算のテスト。
|
|
4
|
+
#
|
|
5
|
+
# 法的根拠: 所得税法 第89条第1項 / 復興財源確保法 第13条
|
|
6
|
+
# テストケースは tests/fixtures/income_tax.json から読み込む。
|
|
7
|
+
#
|
|
8
|
+
# 実行方法:
|
|
9
|
+
# rake compile && ruby -Ilib test/test_income_tax.rb
|
|
10
|
+
|
|
11
|
+
require "minitest/autorun"
|
|
12
|
+
require "json"
|
|
13
|
+
require "date"
|
|
14
|
+
require "j_law_ruby"
|
|
15
|
+
|
|
16
|
+
INCOME_TAX_FIXTURES = JSON.parse(
|
|
17
|
+
File.read(File.join(__dir__, "../../../tests/fixtures/income_tax.json"))
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# ─── データ駆動テスト ─────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
class TestIncomeTaxFixtures < Minitest::Test
|
|
23
|
+
INCOME_TAX_FIXTURES["income_tax"].each do |c|
|
|
24
|
+
define_method("test_#{c['id']}") do
|
|
25
|
+
inp = c["input"]
|
|
26
|
+
exp = c["expected"]
|
|
27
|
+
|
|
28
|
+
date = Date.parse(inp["date"])
|
|
29
|
+
r = JLawRuby::IncomeTax.calc_income_tax(
|
|
30
|
+
inp["taxable_income"], date,
|
|
31
|
+
inp["apply_reconstruction_tax"]
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
assert_equal exp["base_tax"], r.base_tax, "#{c['id']}: base_tax"
|
|
35
|
+
assert_equal exp["reconstruction_tax"], r.reconstruction_tax, "#{c['id']}: reconstruction_tax"
|
|
36
|
+
assert_equal exp["total_tax"], r.total_tax, "#{c['id']}: total_tax"
|
|
37
|
+
if exp["reconstruction_tax_applied"]
|
|
38
|
+
assert r.reconstruction_tax_applied?, "#{c['id']}: reconstruction_tax_applied"
|
|
39
|
+
else
|
|
40
|
+
refute r.reconstruction_tax_applied?, "#{c['id']}: reconstruction_tax_applied"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# ─── 言語固有テスト ──────────────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
class TestIncomeTaxLanguageSpecific < Minitest::Test
|
|
49
|
+
def test_error_date_out_of_range
|
|
50
|
+
assert_raises(RuntimeError) do
|
|
51
|
+
JLawRuby::IncomeTax.calc_income_tax(5_000_000, Date.new(1988, 12, 31), true)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_breakdown_fields
|
|
56
|
+
r = JLawRuby::IncomeTax.calc_income_tax(5_000_000, Date.new(2024, 1, 1), true)
|
|
57
|
+
refute_empty r.breakdown
|
|
58
|
+
r.breakdown.each do |step|
|
|
59
|
+
refute_empty step[:label]
|
|
60
|
+
assert_operator step[:rate_denom], :>, 0
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_inspect
|
|
65
|
+
r = JLawRuby::IncomeTax.calc_income_tax(5_000_000, Date.new(2024, 1, 1), true)
|
|
66
|
+
assert_match(/IncomeTaxResult/, r.inspect)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_type_error_invalid_date
|
|
70
|
+
assert_raises(TypeError) do
|
|
71
|
+
JLawRuby::IncomeTax.calc_income_tax(5_000_000, "2024-01-01", true)
|
|
72
|
+
end
|
|
73
|
+
assert_raises(TypeError) do
|
|
74
|
+
JLawRuby::IncomeTax.calc_income_tax(5_000_000, 20_240_101, true)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "minitest/autorun"
|
|
4
|
+
require "json"
|
|
5
|
+
require "date"
|
|
6
|
+
require "j_law_ruby"
|
|
7
|
+
|
|
8
|
+
FIXTURES = JSON.parse(
|
|
9
|
+
File.read(File.join(__dir__, "../../../tests/fixtures/income_tax_deductions.json"))
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
def build_input(input)
|
|
13
|
+
{
|
|
14
|
+
spouse: input["spouse"] && {
|
|
15
|
+
spouse_total_income_amount: input["spouse"]["spouse_total_income_amount"],
|
|
16
|
+
is_same_household: input["spouse"]["is_same_household"],
|
|
17
|
+
is_elderly: input["spouse"]["is_elderly"],
|
|
18
|
+
},
|
|
19
|
+
dependent: {
|
|
20
|
+
general_count: input.fetch("dependent", {}).fetch("general_count", 0),
|
|
21
|
+
specific_count: input.fetch("dependent", {}).fetch("specific_count", 0),
|
|
22
|
+
elderly_cohabiting_count: input.fetch("dependent", {}).fetch("elderly_cohabiting_count", 0),
|
|
23
|
+
elderly_other_count: input.fetch("dependent", {}).fetch("elderly_other_count", 0),
|
|
24
|
+
},
|
|
25
|
+
social_insurance_premium_paid: input.fetch("social_insurance_premium_paid", 0),
|
|
26
|
+
medical: input["medical"] && {
|
|
27
|
+
medical_expense_paid: input["medical"]["medical_expense_paid"],
|
|
28
|
+
reimbursed_amount: input["medical"]["reimbursed_amount"],
|
|
29
|
+
},
|
|
30
|
+
life_insurance: input["life_insurance"] && {
|
|
31
|
+
new_general_paid_amount: input["life_insurance"]["new_general_paid_amount"],
|
|
32
|
+
new_individual_pension_paid_amount: input["life_insurance"]["new_individual_pension_paid_amount"],
|
|
33
|
+
new_care_medical_paid_amount: input["life_insurance"]["new_care_medical_paid_amount"],
|
|
34
|
+
old_general_paid_amount: input["life_insurance"]["old_general_paid_amount"],
|
|
35
|
+
old_individual_pension_paid_amount: input["life_insurance"]["old_individual_pension_paid_amount"],
|
|
36
|
+
},
|
|
37
|
+
donation: input["donation"] && {
|
|
38
|
+
qualified_donation_amount: input["donation"]["qualified_donation_amount"],
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class TestIncomeTaxDeductionsFixtures < Minitest::Test
|
|
44
|
+
FIXTURES["income_tax_deductions"].each do |c|
|
|
45
|
+
define_method("test_#{c['id']}") do
|
|
46
|
+
inp = c["input"]
|
|
47
|
+
exp = c["expected"]
|
|
48
|
+
|
|
49
|
+
result = JLawRuby::IncomeTax.calc_income_deductions(
|
|
50
|
+
inp["total_income_amount"],
|
|
51
|
+
Date.parse(inp["date"]),
|
|
52
|
+
**build_input(inp)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
assert_equal exp["total_income_amount"], result.total_income_amount
|
|
56
|
+
assert_equal exp["total_deductions"], result.total_deductions
|
|
57
|
+
assert_equal exp["taxable_income_before_truncation"], result.taxable_income_before_truncation
|
|
58
|
+
assert_equal exp["taxable_income"], result.taxable_income
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class TestIncomeTaxAssessmentFixtures < Minitest::Test
|
|
64
|
+
FIXTURES["income_tax_assessment"].each do |c|
|
|
65
|
+
define_method("test_#{c['id']}") do
|
|
66
|
+
inp = c["input"]
|
|
67
|
+
exp = c["expected"]
|
|
68
|
+
|
|
69
|
+
result = JLawRuby::IncomeTax.calc_income_tax_assessment(
|
|
70
|
+
inp["total_income_amount"],
|
|
71
|
+
Date.parse(inp["date"]),
|
|
72
|
+
apply_reconstruction_tax: inp["apply_reconstruction_tax"],
|
|
73
|
+
**build_input(inp)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
assert_equal exp["taxable_income"], result.deductions.taxable_income
|
|
77
|
+
assert_equal exp["base_tax"], result.tax.base_tax
|
|
78
|
+
assert_equal exp["reconstruction_tax"], result.tax.reconstruction_tax
|
|
79
|
+
assert_equal exp["total_tax"], result.tax.total_tax
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# 宅建業法第46条に基づく媒介報酬計算のテスト。
|
|
4
|
+
#
|
|
5
|
+
# 法的根拠: 宅地建物取引業法 第46条第1項 / 国土交通省告示
|
|
6
|
+
# テストケースは tests/fixtures/real_estate.json から読み込む。
|
|
7
|
+
#
|
|
8
|
+
# 実行方法:
|
|
9
|
+
# rake compile && ruby -Ilib test/test_real_estate.rb
|
|
10
|
+
|
|
11
|
+
require "minitest/autorun"
|
|
12
|
+
require "json"
|
|
13
|
+
require "date"
|
|
14
|
+
require "j_law_ruby"
|
|
15
|
+
|
|
16
|
+
REAL_ESTATE_FIXTURES = JSON.parse(
|
|
17
|
+
File.read(File.join(__dir__, "../../../tests/fixtures/real_estate.json"))
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# ─── データ駆動テスト ─────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
class TestBrokerageFeeFixtures < Minitest::Test
|
|
23
|
+
REAL_ESTATE_FIXTURES["brokerage_fee"].each do |c|
|
|
24
|
+
define_method("test_#{c['id']}") do
|
|
25
|
+
inp = c["input"]
|
|
26
|
+
exp = c["expected"]
|
|
27
|
+
|
|
28
|
+
date = Date.parse(inp["date"])
|
|
29
|
+
r = JLawRuby::RealEstate.calc_brokerage_fee(
|
|
30
|
+
inp["price"], date,
|
|
31
|
+
inp["is_low_cost_vacant_house"], inp.fetch("is_seller", false)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
if exp.key?("total_without_tax")
|
|
35
|
+
assert_equal exp["total_without_tax"], r.total_without_tax, "#{c['id']}: total_without_tax"
|
|
36
|
+
end
|
|
37
|
+
if exp.key?("tax_amount")
|
|
38
|
+
assert_equal exp["tax_amount"], r.tax_amount, "#{c['id']}: tax_amount"
|
|
39
|
+
end
|
|
40
|
+
if exp.key?("total_with_tax")
|
|
41
|
+
assert_equal exp["total_with_tax"], r.total_with_tax, "#{c['id']}: total_with_tax"
|
|
42
|
+
end
|
|
43
|
+
if exp.key?("low_cost_special_applied")
|
|
44
|
+
if exp["low_cost_special_applied"]
|
|
45
|
+
assert r.low_cost_special_applied?, "#{c['id']}: low_cost_special_applied"
|
|
46
|
+
else
|
|
47
|
+
refute r.low_cost_special_applied?, "#{c['id']}: low_cost_special_applied"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
if exp.key?("breakdown_results")
|
|
51
|
+
actual = r.breakdown.map { |step| step[:result] }
|
|
52
|
+
assert_equal exp["breakdown_results"], actual, "#{c['id']}: breakdown_results"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# ─── 言語固有テスト ──────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
class TestBrokerageFeeLanguageSpecific < Minitest::Test
|
|
61
|
+
def test_error_date_out_of_range
|
|
62
|
+
# 1970-12-01 施行のため、それ以前の日付はエラー
|
|
63
|
+
err = assert_raises(RuntimeError) do
|
|
64
|
+
JLawRuby::RealEstate.calc_brokerage_fee(5_000_000, Date.new(1970, 11, 30), false, false)
|
|
65
|
+
end
|
|
66
|
+
assert_match(/1970-11-30/, err.message)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_breakdown_fields
|
|
70
|
+
r = JLawRuby::RealEstate.calc_brokerage_fee(5_000_000, Date.new(2024, 8, 1), false, false)
|
|
71
|
+
r.breakdown.each do |step|
|
|
72
|
+
refute_empty step[:label]
|
|
73
|
+
assert_operator step[:rate_denom], :>, 0
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_inspect
|
|
78
|
+
r = JLawRuby::RealEstate.calc_brokerage_fee(5_000_000, Date.new(2024, 8, 1), false, false)
|
|
79
|
+
assert_match(/BrokerageFeeResult/, r.inspect)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_type_error_invalid_date
|
|
83
|
+
assert_raises(TypeError) do
|
|
84
|
+
JLawRuby::RealEstate.calc_brokerage_fee(5_000_000, "2024-08-01", false, false)
|
|
85
|
+
end
|
|
86
|
+
assert_raises(TypeError) do
|
|
87
|
+
JLawRuby::RealEstate.calc_brokerage_fee(5_000_000, 20_240_801, false, false)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_negative_price_is_rejected
|
|
92
|
+
error = assert_raises(ArgumentError) do
|
|
93
|
+
JLawRuby::RealEstate.calc_brokerage_fee(-1, Date.new(2024, 8, 1), false, false)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
assert_match(/price/, error.message)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "minitest/autorun"
|
|
4
|
+
require "json"
|
|
5
|
+
require "date"
|
|
6
|
+
require "j_law_ruby"
|
|
7
|
+
|
|
8
|
+
class TestStampTax < Minitest::Test
|
|
9
|
+
FIXTURES = JSON.parse(File.read(File.join(__dir__, "../../../tests/fixtures/stamp_tax.json")))
|
|
10
|
+
|
|
11
|
+
FIXTURES["stamp_tax"].each do |tc|
|
|
12
|
+
define_method("test_#{tc['id']}") do
|
|
13
|
+
inp = tc["input"]
|
|
14
|
+
exp = tc["expected"]
|
|
15
|
+
|
|
16
|
+
date = Date.parse(inp["date"])
|
|
17
|
+
result = JLawRuby::StampTax.calc_stamp_tax(
|
|
18
|
+
inp["document_code"],
|
|
19
|
+
inp["stated_amount"],
|
|
20
|
+
date,
|
|
21
|
+
flags: inp["flags"]
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
assert_equal exp["tax_amount"], result.tax_amount, "#{tc['id']}: tax_amount"
|
|
25
|
+
assert_equal exp["rule_label"], result.rule_label, "#{tc['id']}: rule_label"
|
|
26
|
+
if exp["applied_special_rule"].nil?
|
|
27
|
+
assert_nil result.applied_special_rule, "#{tc['id']}: applied_special_rule"
|
|
28
|
+
else
|
|
29
|
+
assert_equal exp["applied_special_rule"], result.applied_special_rule, "#{tc['id']}: applied_special_rule"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_error_date_out_of_range
|
|
35
|
+
err = assert_raises(RuntimeError) do
|
|
36
|
+
JLawRuby::StampTax.calc_stamp_tax("article1_real_estate_transfer", 5_000_000, Date.new(2014, 3, 31))
|
|
37
|
+
end
|
|
38
|
+
assert_match(/2014-03-31/, err.message)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_inspect
|
|
42
|
+
result = JLawRuby::StampTax.calc_stamp_tax("article1_real_estate_transfer", 5_000_000, Date.new(2024, 8, 1))
|
|
43
|
+
assert_match(/StampTaxResult/, result.inspect)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_type_error_invalid_date
|
|
47
|
+
assert_raises(TypeError) do
|
|
48
|
+
JLawRuby::StampTax.calc_stamp_tax("article1_real_estate_transfer", 5_000_000, "2024-08-01")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_invalid_document_code
|
|
53
|
+
assert_raises(ArgumentError) do
|
|
54
|
+
JLawRuby::StampTax.calc_stamp_tax("invalid_code", 5_000_000, Date.new(2024, 8, 1))
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_invalid_flag
|
|
59
|
+
assert_raises(ArgumentError) do
|
|
60
|
+
JLawRuby::StampTax.calc_stamp_tax(
|
|
61
|
+
"article17_sales_receipt",
|
|
62
|
+
70_000,
|
|
63
|
+
Date.new(2024, 8, 1),
|
|
64
|
+
flags: ["invalid_flag"]
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "minitest/autorun"
|
|
4
|
+
require "json"
|
|
5
|
+
require "date"
|
|
6
|
+
require "j_law_ruby"
|
|
7
|
+
|
|
8
|
+
class TestWithholdingTax < Minitest::Test
|
|
9
|
+
FIXTURES = JSON.parse(File.read(File.join(__dir__, "../../../tests/fixtures/withholding_tax.json")))
|
|
10
|
+
|
|
11
|
+
FIXTURES["withholding_tax"].each do |tc|
|
|
12
|
+
define_method("test_#{tc['id']}") do
|
|
13
|
+
inp = tc["input"]
|
|
14
|
+
exp = tc["expected"]
|
|
15
|
+
|
|
16
|
+
result = JLawRuby::WithholdingTax.calc_withholding_tax(
|
|
17
|
+
inp["payment_amount"],
|
|
18
|
+
Date.parse(inp["date"]),
|
|
19
|
+
inp["category"],
|
|
20
|
+
is_submission_prize: inp["is_submission_prize"],
|
|
21
|
+
separated_consumption_tax_amount: inp["separated_consumption_tax_amount"]
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
assert_equal exp["taxable_payment_amount"], result.taxable_payment_amount
|
|
25
|
+
assert_equal exp["tax_amount"], result.tax_amount
|
|
26
|
+
assert_equal exp["net_payment_amount"], result.net_payment_amount
|
|
27
|
+
assert_equal exp["submission_prize_exempted"], result.submission_prize_exempted?
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_out_of_range_date
|
|
32
|
+
assert_raises(RuntimeError) do
|
|
33
|
+
JLawRuby::WithholdingTax.calc_withholding_tax(
|
|
34
|
+
100_000,
|
|
35
|
+
Date.new(2012, 12, 31),
|
|
36
|
+
:manuscript_and_lecture
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_breakdown_fields
|
|
42
|
+
result = JLawRuby::WithholdingTax.calc_withholding_tax(
|
|
43
|
+
1_500_000,
|
|
44
|
+
Date.new(2026, 1, 1),
|
|
45
|
+
:professional_fee
|
|
46
|
+
)
|
|
47
|
+
assert_equal 2, result.breakdown.length
|
|
48
|
+
refute_empty result.breakdown.first[:label]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_inspect
|
|
52
|
+
result = JLawRuby::WithholdingTax.calc_withholding_tax(
|
|
53
|
+
100_000,
|
|
54
|
+
Date.new(2026, 1, 1),
|
|
55
|
+
:manuscript_and_lecture
|
|
56
|
+
)
|
|
57
|
+
assert_match(/WithholdingTaxResult/, result.inspect)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_type_error_invalid_date
|
|
61
|
+
assert_raises(TypeError) do
|
|
62
|
+
JLawRuby::WithholdingTax.calc_withholding_tax(100_000, "2026-01-01", :professional_fee)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|